1
- use rustc_data_structures:: fx:: FxHashMap ;
1
+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
2
2
use rustc_span:: Span ;
3
3
use rustc_span:: def_id:: DefId ;
4
4
use tracing:: { debug, instrument, trace} ;
5
5
6
- use crate :: error:: ConstNotUsedTraitAlias ;
7
6
use crate :: ty:: fold:: { TypeFolder , TypeSuperFoldable } ;
8
7
use crate :: ty:: { self , GenericArg , GenericArgKind , Ty , TyCtxt , TypeFoldable } ;
9
8
@@ -14,7 +13,12 @@ pub type OpaqueTypeKey<'tcx> = rustc_type_ir::OpaqueTypeKey<TyCtxt<'tcx>>;
14
13
/// list to the opaque type's own generics.
15
14
pub ( super ) struct ReverseMapper < ' tcx > {
16
15
tcx : TyCtxt < ' tcx > ,
17
- map : FxHashMap < GenericArg < ' tcx > , GenericArg < ' tcx > > ,
16
+
17
+ mapping : FxHashMap < GenericArg < ' tcx > , GenericArg < ' tcx > > ,
18
+
19
+ /// List of uncaptured args (which are bivariant)
20
+ uncaptured_args : FxHashSet < GenericArg < ' tcx > > ,
21
+
18
22
/// see call sites to fold_kind_no_missing_regions_error
19
23
/// for an explanation of this field.
20
24
do_not_error : bool ,
@@ -32,11 +36,12 @@ pub(super) struct ReverseMapper<'tcx> {
32
36
impl < ' tcx > ReverseMapper < ' tcx > {
33
37
pub ( super ) fn new (
34
38
tcx : TyCtxt < ' tcx > ,
35
- map : FxHashMap < GenericArg < ' tcx > , GenericArg < ' tcx > > ,
39
+ mapping : FxHashMap < GenericArg < ' tcx > , GenericArg < ' tcx > > ,
40
+ uncaptured_args : FxHashSet < GenericArg < ' tcx > > ,
36
41
span : Span ,
37
42
ignore_errors : bool ,
38
43
) -> Self {
39
- Self { tcx, map , do_not_error : false , ignore_errors, span }
44
+ Self { tcx, mapping , uncaptured_args , do_not_error : false , ignore_errors, span }
40
45
}
41
46
42
47
fn fold_kind_no_missing_regions_error ( & mut self , kind : GenericArg < ' tcx > ) -> GenericArg < ' tcx > {
@@ -126,25 +131,29 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
126
131
}
127
132
}
128
133
129
- match self . map . get ( & r. into ( ) ) . map ( |k| k. unpack ( ) ) {
134
+ match self . mapping . get ( & r. into ( ) ) . map ( |k| k. unpack ( ) ) {
130
135
Some ( GenericArgKind :: Lifetime ( r1) ) => r1,
131
136
Some ( u) => panic ! ( "region mapped to unexpected kind: {u:?}" ) ,
132
- None if self . do_not_error => self . tcx . lifetimes . re_static ,
133
137
None => {
134
- let e = self
135
- . tcx
136
- . dcx ( )
137
- . struct_span_err ( self . span , "non-defining opaque type use in defining scope" )
138
- . with_span_label (
138
+ let guar = if self . uncaptured_args . contains ( & r. into ( ) ) {
139
+ // FIXME(precise_capturing_of_types): Mention `use<>` list
140
+ // and add an structured suggestion.
141
+ self . tcx . dcx ( ) . struct_span_err (
142
+ self . span ,
143
+ format ! ( "hidden type mentions uncaptured lifetime parameter `{r}`" ) ,
144
+ )
145
+ } else {
146
+ self . tcx . dcx ( ) . struct_span_err (
139
147
self . span ,
140
148
format ! (
141
- "lifetime `{r}` is part of concrete type but not used in \
142
- parameter list of the `impl Trait` type alias "
149
+ "lifetime `{r}` is mentioned in hidden type of type alias impl \
150
+ trait, but is not declared in its generic args "
143
151
) ,
144
152
)
145
- . emit ( ) ;
153
+ }
154
+ . emit_unless ( self . do_not_error ) ;
146
155
147
- ty:: Region :: new_error ( self . cx ( ) , e )
156
+ ty:: Region :: new_error ( self . cx ( ) , guar )
148
157
}
149
158
}
150
159
}
@@ -168,27 +177,33 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
168
177
169
178
ty:: Param ( param) => {
170
179
// Look it up in the generic parameters list.
171
- match self . map . get ( & ty. into ( ) ) . map ( |k| k. unpack ( ) ) {
180
+ match self . mapping . get ( & ty. into ( ) ) . map ( |k| k. unpack ( ) ) {
172
181
// Found it in the generic parameters list; replace with the parameter from the
173
182
// opaque type.
174
183
Some ( GenericArgKind :: Type ( t1) ) => t1,
175
184
Some ( u) => panic ! ( "type mapped to unexpected kind: {u:?}" ) ,
176
185
None => {
177
- debug ! ( ?param, ?self . map) ;
178
- if !self . ignore_errors {
179
- self . tcx
180
- . dcx ( )
181
- . struct_span_err (
182
- self . span ,
183
- format ! (
184
- "type parameter `{ty}` is part of concrete type but not \
185
- used in parameter list for the `impl Trait` type alias"
186
- ) ,
187
- )
188
- . emit ( ) ;
186
+ debug ! ( ?param, ?self . mapping) ;
187
+ let guar = if self . uncaptured_args . contains ( & ty. into ( ) ) {
188
+ // FIXME(precise_capturing_of_types): Mention `use<>` list
189
+ // and add an structured suggestion.
190
+ self . tcx . dcx ( ) . struct_span_err (
191
+ self . span ,
192
+ format ! ( "hidden type mentions uncaptured type parameter `{ty}`" ) ,
193
+ )
194
+ } else {
195
+ self . tcx . dcx ( ) . struct_span_err (
196
+ self . span ,
197
+ format ! (
198
+ "type parameter `{ty}` is mentioned in hidden type of \
199
+ type alias impl trait, but is not declared in its generic \
200
+ args"
201
+ ) ,
202
+ )
189
203
}
204
+ . emit_unless ( self . ignore_errors ) ;
190
205
191
- Ty :: new_misc_error ( self . tcx )
206
+ Ty :: new_error ( self . tcx , guar )
192
207
}
193
208
}
194
209
}
@@ -203,20 +218,30 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
203
218
match ct. kind ( ) {
204
219
ty:: ConstKind :: Param ( ..) => {
205
220
// Look it up in the generic parameters list.
206
- match self . map . get ( & ct. into ( ) ) . map ( |k| k. unpack ( ) ) {
221
+ match self . mapping . get ( & ct. into ( ) ) . map ( |k| k. unpack ( ) ) {
207
222
// Found it in the generic parameters list, replace with the parameter from the
208
223
// opaque type.
209
224
Some ( GenericArgKind :: Const ( c1) ) => c1,
210
225
Some ( u) => panic ! ( "const mapped to unexpected kind: {u:?}" ) ,
211
226
None => {
212
- let guar = self
213
- . tcx
214
- . dcx ( )
215
- . create_err ( ConstNotUsedTraitAlias {
216
- ct : ct. to_string ( ) ,
217
- span : self . span ,
218
- } )
219
- . emit_unless ( self . ignore_errors ) ;
227
+ let guar = if self . uncaptured_args . contains ( & ct. into ( ) ) {
228
+ // FIXME(precise_capturing_of_types): Mention `use<>` list
229
+ // and add an structured suggestion.
230
+ self . tcx . dcx ( ) . struct_span_err (
231
+ self . span ,
232
+ format ! ( "hidden type mentions uncaptured const parameter `{ct}`" ) ,
233
+ )
234
+ } else {
235
+ self . tcx . dcx ( ) . struct_span_err (
236
+ self . span ,
237
+ format ! (
238
+ "const parameter `{ct}` is mentioned in hidden type of \
239
+ type alias impl trait, but is not declared in its generic \
240
+ args"
241
+ ) ,
242
+ )
243
+ }
244
+ . emit_unless ( self . ignore_errors ) ;
220
245
221
246
ty:: Const :: new_error ( self . tcx , guar)
222
247
}
0 commit comments