@@ -2,17 +2,13 @@ use crate::check::regionck::RegionCtxt;
22use crate :: hir;
33use crate :: hir:: def_id:: { DefId , LocalDefId } ;
44use rustc_errors:: { struct_span_err, ErrorGuaranteed } ;
5- use rustc_infer:: infer:: outlives:: env:: OutlivesEnvironment ;
6- use rustc_infer:: infer:: { InferOk , RegionckMode , TyCtxtInferExt } ;
7- use rustc_infer:: traits:: TraitEngineExt as _;
85use rustc_middle:: ty:: error:: TypeError ;
96use rustc_middle:: ty:: relate:: { Relate , RelateResult , TypeRelation } ;
10- use rustc_middle:: ty:: subst:: { Subst , SubstsRef } ;
11- use rustc_middle:: ty:: { self , EarlyBinder , Predicate , Ty , TyCtxt } ;
7+ use rustc_middle:: ty:: subst:: SubstsRef ;
8+ use rustc_middle:: ty:: { self , Predicate , Ty , TyCtxt } ;
129use rustc_span:: Span ;
13- use rustc_trait_selection:: traits:: error_reporting:: InferCtxtExt ;
1410use rustc_trait_selection:: traits:: query:: dropck_outlives:: AtExt ;
15- use rustc_trait_selection:: traits:: { ObligationCause , TraitEngine , TraitEngineExt } ;
11+ use rustc_trait_selection:: traits:: ObligationCause ;
1612
1713/// This function confirms that the `Drop` implementation identified by
1814/// `drop_impl_did` is not any more specialized than the type it is
@@ -39,8 +35,8 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
3935 ensure_drop_params_and_item_params_correspond (
4036 tcx,
4137 drop_impl_did. expect_local ( ) ,
42- dtor_self_type,
4338 adt_def. did ( ) ,
39+ self_to_impl_substs,
4440 ) ?;
4541
4642 ensure_drop_predicates_are_implied_by_item_defn (
@@ -67,75 +63,34 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
6763fn ensure_drop_params_and_item_params_correspond < ' tcx > (
6864 tcx : TyCtxt < ' tcx > ,
6965 drop_impl_did : LocalDefId ,
70- drop_impl_ty : Ty < ' tcx > ,
7166 self_type_did : DefId ,
67+ drop_impl_substs : SubstsRef < ' tcx > ,
7268) -> Result < ( ) , ErrorGuaranteed > {
73- let drop_impl_hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( drop_impl_did) ;
74-
75- // check that the impl type can be made to match the trait type.
76-
77- tcx. infer_ctxt ( ) . enter ( |ref infcx| {
78- let impl_param_env = tcx. param_env ( self_type_did) ;
79- let tcx = infcx. tcx ;
80- let mut fulfillment_cx = <dyn TraitEngine < ' _ > >:: new ( tcx) ;
81-
82- let named_type = tcx. type_of ( self_type_did) ;
83-
84- let drop_impl_span = tcx. def_span ( drop_impl_did) ;
85- let fresh_impl_substs =
86- infcx. fresh_substs_for_item ( drop_impl_span, drop_impl_did. to_def_id ( ) ) ;
87- let fresh_impl_self_ty = EarlyBinder ( drop_impl_ty) . subst ( tcx, fresh_impl_substs) ;
88-
89- let cause = & ObligationCause :: misc ( drop_impl_span, drop_impl_hir_id) ;
90- match infcx. at ( cause, impl_param_env) . eq ( named_type, fresh_impl_self_ty) {
91- Ok ( InferOk { obligations, .. } ) => {
92- fulfillment_cx. register_predicate_obligations ( infcx, obligations) ;
93- }
94- Err ( _) => {
95- let item_span = tcx. def_span ( self_type_did) ;
96- let self_descr = tcx. def_kind ( self_type_did) . descr ( self_type_did) ;
97- let reported = struct_span_err ! (
98- tcx. sess,
99- drop_impl_span,
100- E0366 ,
101- "`Drop` impls cannot be specialized"
102- )
103- . span_note (
104- item_span,
105- & format ! (
106- "use the same sequence of generic type, lifetime and const parameters \
107- as the {self_descr} definition",
108- ) ,
109- )
110- . emit ( ) ;
111- return Err ( reported) ;
112- }
69+ let Err ( arg) = tcx. uses_unique_generic_params ( drop_impl_substs, false ) else {
70+ return Ok ( ( ) )
71+ } ;
72+
73+ let drop_impl_span = tcx. def_span ( drop_impl_did) ;
74+ let item_span = tcx. def_span ( self_type_did) ;
75+ let self_descr = tcx. def_kind ( self_type_did) . descr ( self_type_did) ;
76+ let mut err =
77+ struct_span_err ! ( tcx. sess, drop_impl_span, E0366 , "`Drop` impls cannot be specialized" ) ;
78+ match arg {
79+ ty:: util:: NotUniqueParam :: DuplicateParam ( arg) => {
80+ err. note ( & format ! ( "`{arg}` is mentioned multiple times" ) )
11381 }
114-
115- let errors = fulfillment_cx. select_all_or_error ( & infcx) ;
116- if !errors. is_empty ( ) {
117- // this could be reached when we get lazy normalization
118- let reported = infcx. report_fulfillment_errors ( & errors, None , false ) ;
119- return Err ( reported) ;
82+ ty:: util:: NotUniqueParam :: NotParam ( arg) => {
83+ err. note ( & format ! ( "`{arg}` is not a generic parameter" ) )
12084 }
121-
122- // NB. It seems a bit... suspicious to use an empty param-env
123- // here. The correct thing, I imagine, would be
124- // `OutlivesEnvironment::new(impl_param_env)`, which would
125- // allow region solving to take any `a: 'b` relations on the
126- // impl into account. But I could not create a test case where
127- // it did the wrong thing, so I chose to preserve existing
128- // behavior, since it ought to be simply more
129- // conservative. -nmatsakis
130- let outlives_env = OutlivesEnvironment :: new ( ty:: ParamEnv :: empty ( ) ) ;
131-
132- infcx. resolve_regions_and_report_errors (
133- drop_impl_did. to_def_id ( ) ,
134- & outlives_env,
135- RegionckMode :: default ( ) ,
136- ) ;
137- Ok ( ( ) )
138- } )
85+ } ;
86+ err. span_note (
87+ item_span,
88+ & format ! (
89+ "use the same sequence of generic type, lifetime and const parameters \
90+ as the {self_descr} definition",
91+ ) ,
92+ ) ;
93+ Err ( err. emit ( ) )
13994}
14095
14196/// Confirms that every predicate imposed by dtor_predicates is
0 commit comments