@@ -30,7 +30,7 @@ use crate::{
3030 traits:: { NamedType , ResolvedTraitBound , Trait , TraitConstraint } ,
3131 } ,
3232 node_interner:: {
33- DependencyId , ExprId , GlobalValue , ImplSearchErrorKind , NodeInterner , TraitId ,
33+ DependencyId , ExprId , FuncId , GlobalValue , ImplSearchErrorKind , NodeInterner , TraitId ,
3434 TraitImplKind , TraitMethodId ,
3535 } ,
3636 token:: SecondaryAttribute ,
@@ -1426,7 +1426,7 @@ impl<'context> Elaborator<'context> {
14261426 // Only keep unique trait IDs: multiple trait methods might come from the same trait
14271427 // but implemented with different generics (like `Convert<Field>` and `Convert<i32>`).
14281428 let traits: HashSet < TraitId > =
1429- trait_methods. into_iter ( ) . map ( |( _, trait_id) | trait_id) . collect ( ) ;
1429+ trait_methods. iter ( ) . map ( |( _, trait_id) | * trait_id) . collect ( ) ;
14301430
14311431 let traits_in_scope: Vec < _ > = traits
14321432 . iter ( )
@@ -1457,15 +1457,18 @@ impl<'context> Elaborator<'context> {
14571457 let trait_id = * traits. iter ( ) . next ( ) . unwrap ( ) ;
14581458 let trait_ = self . interner . get_trait ( trait_id) ;
14591459 let trait_name = self . fully_qualified_trait_path ( trait_) ;
1460- let generics = trait_. as_constraint ( span) . trait_bound . trait_generics ;
1461- let trait_method_id = trait_. find_method ( method_name) . unwrap ( ) ;
14621460
14631461 self . push_err ( PathResolutionError :: TraitMethodNotInScope {
14641462 ident : Ident :: new ( method_name. into ( ) , span) ,
14651463 trait_name,
14661464 } ) ;
14671465
1468- return Some ( HirMethodReference :: TraitMethodId ( trait_method_id, generics, false ) ) ;
1466+ return Some ( self . trait_hir_method_reference (
1467+ trait_id,
1468+ trait_methods,
1469+ method_name,
1470+ span,
1471+ ) ) ;
14691472 } else {
14701473 let traits = vecmap ( traits, |trait_id| {
14711474 let trait_ = self . interner . get_trait ( trait_id) ;
@@ -1491,12 +1494,28 @@ impl<'context> Elaborator<'context> {
14911494 return None ;
14921495 }
14931496
1494- // Return a TraitMethodId with unbound generics. These will later be bound by the type-checker.
14951497 let trait_id = traits_in_scope[ 0 ] . 0 ;
1498+ Some ( self . trait_hir_method_reference ( trait_id, trait_methods, method_name, span) )
1499+ }
1500+
1501+ fn trait_hir_method_reference (
1502+ & self ,
1503+ trait_id : TraitId ,
1504+ trait_methods : Vec < ( FuncId , TraitId ) > ,
1505+ method_name : & str ,
1506+ span : Span ,
1507+ ) -> HirMethodReference {
1508+ // If we find a single trait impl method, return it so we don't have to later determine the impl
1509+ if trait_methods. len ( ) == 1 {
1510+ let ( func_id, _) = trait_methods[ 0 ] ;
1511+ return HirMethodReference :: FuncId ( func_id) ;
1512+ }
1513+
1514+ // Return a TraitMethodId with unbound generics. These will later be bound by the type-checker.
14961515 let trait_ = self . interner . get_trait ( trait_id) ;
14971516 let generics = trait_. as_constraint ( span) . trait_bound . trait_generics ;
14981517 let trait_method_id = trait_. find_method ( method_name) . unwrap ( ) ;
1499- Some ( HirMethodReference :: TraitMethodId ( trait_method_id, generics, false ) )
1518+ HirMethodReference :: TraitMethodId ( trait_method_id, generics, false )
15001519 }
15011520
15021521 fn lookup_method_in_trait_constraints (
0 commit comments