1- use rustc_data_structures:: fx:: FxHashMap ;
1+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
22use rustc_span:: Span ;
33use rustc_span:: def_id:: DefId ;
44use tracing:: { debug, instrument, trace} ;
55
6- use crate :: error:: ConstNotUsedTraitAlias ;
76use crate :: ty:: {
87 self , GenericArg , GenericArgKind , Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable ,
98} ;
@@ -15,7 +14,12 @@ pub type OpaqueTypeKey<'tcx> = rustc_type_ir::OpaqueTypeKey<TyCtxt<'tcx>>;
1514/// list to the opaque type's own generics.
1615pub ( super ) struct ReverseMapper < ' tcx > {
1716 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+
1923 /// see call sites to fold_kind_no_missing_regions_error
2024 /// for an explanation of this field.
2125 do_not_error : bool ,
@@ -33,11 +37,12 @@ pub(super) struct ReverseMapper<'tcx> {
3337impl < ' tcx > ReverseMapper < ' tcx > {
3438 pub ( super ) fn new (
3539 tcx : TyCtxt < ' tcx > ,
36- map : FxHashMap < GenericArg < ' tcx > , GenericArg < ' tcx > > ,
40+ mapping : FxHashMap < GenericArg < ' tcx > , GenericArg < ' tcx > > ,
41+ uncaptured_args : FxHashSet < GenericArg < ' tcx > > ,
3742 span : Span ,
3843 ignore_errors : bool ,
3944 ) -> 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 }
4146 }
4247
4348 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> {
127132 }
128133 }
129134
130- match self . map . get ( & r. into ( ) ) . map ( |k| k. unpack ( ) ) {
135+ match self . mapping . get ( & r. into ( ) ) . map ( |k| k. unpack ( ) ) {
131136 Some ( GenericArgKind :: Lifetime ( r1) ) => r1,
132137 Some ( u) => panic ! ( "region mapped to unexpected kind: {u:?}" ) ,
133- None if self . do_not_error => self . tcx . lifetimes . re_static ,
134138 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 (
140148 self . span ,
141149 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 "
144152 ) ,
145153 )
146- . emit ( ) ;
154+ }
155+ . emit_unless ( self . do_not_error ) ;
147156
148- ty:: Region :: new_error ( self . cx ( ) , e )
157+ ty:: Region :: new_error ( self . cx ( ) , guar )
149158 }
150159 }
151160 }
@@ -169,27 +178,33 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
169178
170179 ty:: Param ( param) => {
171180 // 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 ( ) ) {
173182 // Found it in the generic parameters list; replace with the parameter from the
174183 // opaque type.
175184 Some ( GenericArgKind :: Type ( t1) ) => t1,
176185 Some ( u) => panic ! ( "type mapped to unexpected kind: {u:?}" ) ,
177186 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+ )
190204 }
205+ . emit_unless ( self . ignore_errors ) ;
191206
192- Ty :: new_misc_error ( self . tcx )
207+ Ty :: new_error ( self . tcx , guar )
193208 }
194209 }
195210 }
@@ -204,20 +219,30 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
204219 match ct. kind ( ) {
205220 ty:: ConstKind :: Param ( ..) => {
206221 // 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 ( ) ) {
208223 // Found it in the generic parameters list, replace with the parameter from the
209224 // opaque type.
210225 Some ( GenericArgKind :: Const ( c1) ) => c1,
211226 Some ( u) => panic ! ( "const mapped to unexpected kind: {u:?}" ) ,
212227 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 ) ;
221246
222247 ty:: Const :: new_error ( self . tcx , guar)
223248 }
0 commit comments