1- use crate :: traits:: specialization_graph;
1+ use crate :: traits:: specialization_graph:: { self , LeafDef , Node } ;
22
33use super :: assembly:: structural_traits:: AsyncCallableRelevantTypes ;
44use super :: assembly:: { self , structural_traits, Candidate } ;
@@ -9,7 +9,6 @@ use rustc_infer::infer::InferCtxt;
99use rustc_infer:: traits:: query:: NoSolution ;
1010use rustc_infer:: traits:: solve:: inspect:: ProbeKind ;
1111use rustc_infer:: traits:: solve:: MaybeCause ;
12- use rustc_infer:: traits:: specialization_graph:: LeafDef ;
1312use rustc_infer:: traits:: Reveal ;
1413use rustc_middle:: traits:: solve:: { CandidateSource , Certainty , Goal , QueryResult } ;
1514use rustc_middle:: traits:: BuiltinImplSource ;
@@ -235,14 +234,38 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
235234 //
236235 // And then map these args to the args of the defining impl of `Assoc`, going
237236 // from `[u32, u64]` to `[u32, i32, u64]`.
238- let impl_args_with_gat =
239- goal. predicate . alias . args . rebase_onto ( tcx, goal_trait_ref. def_id , impl_args) ;
240- let args = ecx. translate_args (
241- goal. param_env ,
242- impl_def_id,
243- impl_args_with_gat,
244- assoc_def. defining_node ,
245- ) ;
237+ let args = match assoc_def. defining_node {
238+ Node :: Trait ( _) => goal. predicate . alias . args ,
239+ Node :: Impl ( target_impl_def_id) => {
240+ let impl_args_with_gat = goal. predicate . alias . args . rebase_onto (
241+ tcx,
242+ goal_trait_ref. def_id ,
243+ impl_args,
244+ ) ;
245+ if target_impl_def_id == impl_def_id {
246+ // Same impl, no need to rebase.
247+ impl_args_with_gat
248+ } else {
249+ let target_args = ecx. fresh_args_for_item ( target_impl_def_id) ;
250+ let target_trait_ref = tcx
251+ . impl_trait_ref ( target_impl_def_id)
252+ . unwrap ( )
253+ . instantiate ( tcx, target_args) ;
254+ // Relate source impl to target impl by equating trait refs.
255+ ecx. eq ( goal. param_env , impl_trait_ref, target_trait_ref) ?;
256+ // Also add predicates since they may be needed to constrain the
257+ // target impl's params.
258+ ecx. add_goals (
259+ GoalSource :: Misc ,
260+ tcx. predicates_of ( target_impl_def_id)
261+ . instantiate ( tcx, target_args)
262+ . into_iter ( )
263+ . map ( |( pred, _) | goal. with ( tcx, pred) ) ,
264+ ) ;
265+ impl_args_with_gat. rebase_onto ( tcx, impl_def_id, target_args)
266+ }
267+ }
268+ } ;
246269
247270 if !tcx. check_args_compatible ( assoc_def. item . def_id , args) {
248271 return error_response (
0 commit comments