@@ -6,10 +6,10 @@ use rustc_data_structures::fx::FxHashSet;
66use rustc_errors:: { codes:: * , struct_span_code_err, ErrorGuaranteed } ;
77use rustc_infer:: infer:: outlives:: env:: OutlivesEnvironment ;
88use rustc_infer:: infer:: { RegionResolutionError , TyCtxtInferExt } ;
9- use rustc_infer:: traits:: ObligationCauseCode ;
9+ use rustc_infer:: traits:: { ObligationCause , ObligationCauseCode } ;
1010use rustc_middle:: ty:: util:: CheckRegions ;
11- use rustc_middle:: ty:: GenericArgsRef ;
1211use rustc_middle:: ty:: { self , TyCtxt } ;
12+ use rustc_middle:: ty:: { GenericArgsRef , Ty } ;
1313use rustc_trait_selection:: regions:: InferCtxtRegionExt ;
1414use rustc_trait_selection:: traits:: { self , ObligationCtxt } ;
1515
@@ -115,8 +115,9 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
115115 Err ( err. emit ( ) )
116116}
117117
118- /// Confirms that every predicate imposed by dtor_predicates is
119- /// implied by assuming the predicates attached to self_type_did.
118+ /// Confirms that all predicates defined on the `Drop` impl (`drop_impl_def_id`) are able to be
119+ /// proven from within `adt_def_id`'s environment. I.e. all the predicates on the impl are
120+ /// implied by the ADT being well formed.
120121fn ensure_drop_predicates_are_implied_by_item_defn < ' tcx > (
121122 tcx : TyCtxt < ' tcx > ,
122123 drop_impl_def_id : LocalDefId ,
@@ -126,6 +127,8 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
126127 let infcx = tcx. infer_ctxt ( ) . build ( ) ;
127128 let ocx = ObligationCtxt :: new_with_diagnostics ( & infcx) ;
128129
130+ let impl_span = tcx. def_span ( drop_impl_def_id. to_def_id ( ) ) ;
131+
129132 // Take the param-env of the adt and instantiate the args that show up in
130133 // the implementation's self type. This gives us the assumptions that the
131134 // self ty of the implementation is allowed to know just from it being a
@@ -135,14 +138,27 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
135138 // We don't need to normalize this param-env or anything, since we're only
136139 // instantiating it with free params, so no additional param-env normalization
137140 // can occur on top of what has been done in the param_env query itself.
138- let param_env =
141+ //
142+ // Note: Ideally instead of instantiating the `ParamEnv` with the arguments from the impl ty we
143+ // could instead use identity args for the adt. Unfortunately this would cause any errors to
144+ // reference the params from the ADT instead of from the impl which is bad UX. To resolve
145+ // this we "rename" the ADT's params to be the impl's params which should not affect behaviour.
146+ let impl_adt_ty = Ty :: new_adt ( tcx, tcx. adt_def ( adt_def_id) , adt_to_impl_args) ;
147+ let adt_env =
139148 ty:: EarlyBinder :: bind ( tcx. param_env ( adt_def_id) ) . instantiate ( tcx, adt_to_impl_args) ;
140149
141- for ( pred, span) in tcx. predicates_of ( drop_impl_def_id) . instantiate_identity ( tcx) {
150+ let fresh_impl_args = infcx. fresh_args_for_item ( impl_span, drop_impl_def_id. to_def_id ( ) ) ;
151+ let fresh_adt_ty =
152+ tcx. impl_trait_ref ( drop_impl_def_id) . unwrap ( ) . instantiate ( tcx, fresh_impl_args) . self_ty ( ) ;
153+
154+ ocx. eq ( & ObligationCause :: dummy_with_span ( impl_span) , adt_env, fresh_adt_ty, impl_adt_ty)
155+ . unwrap ( ) ;
156+
157+ for ( clause, span) in tcx. predicates_of ( drop_impl_def_id) . instantiate ( tcx, fresh_impl_args) {
142158 let normalize_cause = traits:: ObligationCause :: misc ( span, adt_def_id) ;
143- let pred = ocx. normalize ( & normalize_cause, param_env , pred ) ;
159+ let pred = ocx. normalize ( & normalize_cause, adt_env , clause ) ;
144160 let cause = traits:: ObligationCause :: new ( span, adt_def_id, ObligationCauseCode :: DropImpl ) ;
145- ocx. register_obligation ( traits:: Obligation :: new ( tcx, cause, param_env , pred) ) ;
161+ ocx. register_obligation ( traits:: Obligation :: new ( tcx, cause, adt_env , pred) ) ;
146162 }
147163
148164 // All of the custom error reporting logic is to preserve parity with the old
@@ -176,7 +192,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
176192 return Err ( guar. unwrap ( ) ) ;
177193 }
178194
179- let errors = ocx. infcx . resolve_regions ( & OutlivesEnvironment :: new ( param_env ) ) ;
195+ let errors = ocx. infcx . resolve_regions ( & OutlivesEnvironment :: new ( adt_env ) ) ;
180196 if !errors. is_empty ( ) {
181197 let mut guar = None ;
182198 for error in errors {
0 commit comments