@@ -987,11 +987,13 @@ impl<'a> InferenceContext<'a> {
987
987
let lhs_ty = self . infer_expr ( lhs, & lhs_expectation) ;
988
988
let rhs_ty = self . table . new_type_var ( ) ;
989
989
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) )
992
994
} ) ;
993
- let func = match func {
994
- Some ( func ) => func ,
995
+ let ( trait_ , func) = match trait_func {
996
+ Some ( it ) => it ,
995
997
None => {
996
998
let rhs_ty = self . builtin_binary_op_rhs_expectation ( op, lhs_ty. clone ( ) ) ;
997
999
let rhs_ty = self . infer_expr_coerce ( rhs, & Expectation :: from_option ( rhs_ty) ) ;
@@ -1001,7 +1003,9 @@ impl<'a> InferenceContext<'a> {
1001
1003
}
1002
1004
} ;
1003
1005
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 )
1005
1009
. push ( lhs_ty. clone ( ) )
1006
1010
. push ( rhs_ty. clone ( ) )
1007
1011
. build ( ) ;
@@ -1280,19 +1284,7 @@ impl<'a> InferenceContext<'a> {
1280
1284
assert_eq ! ( self_params, 0 ) ; // method shouldn't have another Self param
1281
1285
let total_len = parent_params + type_params + const_params + impl_trait_params;
1282
1286
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
+
1296
1288
// handle provided arguments
1297
1289
if let Some ( generic_args) = generic_args {
1298
1290
// 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> {
1301
1293
. iter ( )
1302
1294
. filter ( |arg| !matches ! ( arg, GenericArg :: Lifetime ( _) ) )
1303
1295
. take ( type_params + const_params)
1304
- . zip ( def_generics. iter_id ( ) . skip ( parent_params ) )
1296
+ . zip ( def_generics. iter_id ( ) )
1305
1297
{
1306
1298
if let Some ( g) = generic_arg_to_chalk (
1307
1299
self . db ,
@@ -1325,6 +1317,9 @@ impl<'a> InferenceContext<'a> {
1325
1317
}
1326
1318
}
1327
1319
} ;
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.
1328
1323
for ( id, data) in def_generics. iter ( ) . skip ( substs. len ( ) ) {
1329
1324
match data {
1330
1325
TypeOrConstParamData :: TypeParamData ( _) => {
@@ -1362,9 +1357,13 @@ impl<'a> InferenceContext<'a> {
1362
1357
CallableDefId :: FunctionId ( f) => {
1363
1358
if let ItemContainerId :: TraitId ( trait_) = f. lookup ( self . db . upcast ( ) ) . container {
1364
1359
// 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..] ,
1368
1367
) ;
1369
1368
self . push_obligation (
1370
1369
TraitRef { trait_id : to_chalk_trait_id ( trait_) , substitution : substs }
0 commit comments