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