@@ -987,11 +987,13 @@ impl<'a> InferenceContext<'a> {
987987 let lhs_ty = self . infer_expr ( lhs, & lhs_expectation) ;
988988 let rhs_ty = self . table . new_type_var ( ) ;
989989
990- let func = lang_names_for_bin_op ( op) . and_then ( |( name, lang_item) | {
991- self . db . trait_data ( self . resolve_lang_item ( lang_item) ?. as_trait ( ) ?) . method_by_name ( & name)
990+ let trait_func = lang_names_for_bin_op ( op) . and_then ( |( name, lang_item) | {
991+ let trait_id = self . resolve_lang_item ( lang_item) ?. as_trait ( ) ?;
992+ let func = self . db . trait_data ( trait_id) . method_by_name ( & name) ?;
993+ Some ( ( trait_id, func) )
992994 } ) ;
993- let func = match func {
994- Some ( func ) => func ,
995+ let ( trait_ , func) = match trait_func {
996+ Some ( it ) => it ,
995997 None => {
996998 let rhs_ty = self . builtin_binary_op_rhs_expectation ( op, lhs_ty. clone ( ) ) ;
997999 let rhs_ty = self . infer_expr_coerce ( rhs, & Expectation :: from_option ( rhs_ty) ) ;
@@ -1001,7 +1003,9 @@ impl<'a> InferenceContext<'a> {
10011003 }
10021004 } ;
10031005
1004- let subst = TyBuilder :: subst_for_def ( self . db , func)
1006+ // HACK: We can use this substitution for the function because the function itself doesn't
1007+ // have its own generic parameters.
1008+ let subst = TyBuilder :: subst_for_def ( self . db , trait_, None )
10051009 . push ( lhs_ty. clone ( ) )
10061010 . push ( rhs_ty. clone ( ) )
10071011 . build ( ) ;
@@ -1280,19 +1284,7 @@ impl<'a> InferenceContext<'a> {
12801284 assert_eq ! ( self_params, 0 ) ; // method shouldn't have another Self param
12811285 let total_len = parent_params + type_params + const_params + impl_trait_params;
12821286 let mut substs = Vec :: with_capacity ( total_len) ;
1283- // Parent arguments are unknown
1284- for ( id, param) in def_generics. iter_parent ( ) {
1285- match param {
1286- TypeOrConstParamData :: TypeParamData ( _) => {
1287- substs. push ( GenericArgData :: Ty ( self . table . new_type_var ( ) ) . intern ( Interner ) ) ;
1288- }
1289- TypeOrConstParamData :: ConstParamData ( _) => {
1290- let ty = self . db . const_param_ty ( ConstParamId :: from_unchecked ( id) ) ;
1291- substs
1292- . push ( GenericArgData :: Const ( self . table . new_const_var ( ty) ) . intern ( Interner ) ) ;
1293- }
1294- }
1295- }
1287+
12961288 // handle provided arguments
12971289 if let Some ( generic_args) = generic_args {
12981290 // if args are provided, it should be all of them, but we can't rely on that
@@ -1301,7 +1293,7 @@ impl<'a> InferenceContext<'a> {
13011293 . iter ( )
13021294 . filter ( |arg| !matches ! ( arg, GenericArg :: Lifetime ( _) ) )
13031295 . take ( type_params + const_params)
1304- . zip ( def_generics. iter_id ( ) . skip ( parent_params ) )
1296+ . zip ( def_generics. iter_id ( ) )
13051297 {
13061298 if let Some ( g) = generic_arg_to_chalk (
13071299 self . db ,
@@ -1325,6 +1317,9 @@ impl<'a> InferenceContext<'a> {
13251317 }
13261318 }
13271319 } ;
1320+
1321+ // Handle everything else as unknown. This also handles generic arguments for the method's
1322+ // parent (impl or trait), which should come after those for the method.
13281323 for ( id, data) in def_generics. iter ( ) . skip ( substs. len ( ) ) {
13291324 match data {
13301325 TypeOrConstParamData :: TypeParamData ( _) => {
@@ -1362,9 +1357,13 @@ impl<'a> InferenceContext<'a> {
13621357 CallableDefId :: FunctionId ( f) => {
13631358 if let ItemContainerId :: TraitId ( trait_) = f. lookup ( self . db . upcast ( ) ) . container {
13641359 // construct a TraitRef
1365- let substs = crate :: subst_prefix (
1366- & * parameters,
1367- generics ( self . db . upcast ( ) , trait_. into ( ) ) . len ( ) ,
1360+ let params_len = parameters. len ( Interner ) ;
1361+ let trait_params_len = generics ( self . db . upcast ( ) , trait_. into ( ) ) . len ( ) ;
1362+ let substs = Substitution :: from_iter (
1363+ Interner ,
1364+ // The generic parameters for the trait come after those for the
1365+ // function.
1366+ & parameters. as_slice ( Interner ) [ params_len - trait_params_len..] ,
13681367 ) ;
13691368 self . push_obligation (
13701369 TraitRef { trait_id : to_chalk_trait_id ( trait_) , substitution : substs }
0 commit comments