@@ -2,17 +2,13 @@ use crate::check::regionck::RegionCtxt;
2
2
use crate :: hir;
3
3
use crate :: hir:: def_id:: { DefId , LocalDefId } ;
4
4
use 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 _;
8
5
use rustc_middle:: ty:: error:: TypeError ;
9
6
use 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 } ;
12
9
use rustc_span:: Span ;
13
- use rustc_trait_selection:: traits:: error_reporting:: InferCtxtExt ;
14
10
use rustc_trait_selection:: traits:: query:: dropck_outlives:: AtExt ;
15
- use rustc_trait_selection:: traits:: { ObligationCause , TraitEngine , TraitEngineExt } ;
11
+ use rustc_trait_selection:: traits:: ObligationCause ;
16
12
17
13
/// This function confirms that the `Drop` implementation identified by
18
14
/// `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
39
35
ensure_drop_params_and_item_params_correspond (
40
36
tcx,
41
37
drop_impl_did. expect_local ( ) ,
42
- dtor_self_type,
43
38
adt_def. did ( ) ,
39
+ self_to_impl_substs,
44
40
) ?;
45
41
46
42
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
67
63
fn ensure_drop_params_and_item_params_correspond < ' tcx > (
68
64
tcx : TyCtxt < ' tcx > ,
69
65
drop_impl_did : LocalDefId ,
70
- drop_impl_ty : Ty < ' tcx > ,
71
66
self_type_did : DefId ,
67
+ drop_impl_substs : SubstsRef < ' tcx > ,
72
68
) -> 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" ) )
113
81
}
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" ) )
120
84
}
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 ( ) )
139
94
}
140
95
141
96
/// Confirms that every predicate imposed by dtor_predicates is
0 commit comments