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:: fold:: { TypeFolder , TypeSuperFoldable } ;
87use crate :: ty:: { self , GenericArg , GenericArgKind , Ty , TyCtxt , TypeFoldable } ;
98
@@ -14,7 +13,12 @@ pub type OpaqueTypeKey<'tcx> = rustc_type_ir::OpaqueTypeKey<TyCtxt<'tcx>>;
1413/// list to the opaque type's own generics.
1514pub ( super ) struct ReverseMapper < ' tcx > {
1615 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+
1822 /// see call sites to fold_kind_no_missing_regions_error
1923 /// for an explanation of this field.
2024 do_not_error : bool ,
@@ -32,11 +36,12 @@ pub(super) struct ReverseMapper<'tcx> {
3236impl < ' tcx > ReverseMapper < ' tcx > {
3337 pub ( super ) fn new (
3438 tcx : TyCtxt < ' tcx > ,
35- map : FxHashMap < GenericArg < ' tcx > , GenericArg < ' tcx > > ,
39+ mapping : FxHashMap < GenericArg < ' tcx > , GenericArg < ' tcx > > ,
40+ uncaptured_args : FxHashSet < GenericArg < ' tcx > > ,
3641 span : Span ,
3742 ignore_errors : bool ,
3843 ) -> 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 }
4045 }
4146
4247 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> {
126131 }
127132 }
128133
129- match self . map . get ( & r. into ( ) ) . map ( |k| k. unpack ( ) ) {
134+ match self . mapping . get ( & r. into ( ) ) . map ( |k| k. unpack ( ) ) {
130135 Some ( GenericArgKind :: Lifetime ( r1) ) => r1,
131136 Some ( u) => panic ! ( "region mapped to unexpected kind: {u:?}" ) ,
132- None if self . do_not_error => self . tcx . lifetimes . re_static ,
133137 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 (
139147 self . span ,
140148 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 "
143151 ) ,
144152 )
145- . emit ( ) ;
153+ }
154+ . emit_unless ( self . do_not_error ) ;
146155
147- ty:: Region :: new_error ( self . cx ( ) , e )
156+ ty:: Region :: new_error ( self . cx ( ) , guar )
148157 }
149158 }
150159 }
@@ -168,27 +177,33 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
168177
169178 ty:: Param ( param) => {
170179 // 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 ( ) ) {
172181 // Found it in the generic parameters list; replace with the parameter from the
173182 // opaque type.
174183 Some ( GenericArgKind :: Type ( t1) ) => t1,
175184 Some ( u) => panic ! ( "type mapped to unexpected kind: {u:?}" ) ,
176185 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+ )
189203 }
204+ . emit_unless ( self . ignore_errors ) ;
190205
191- Ty :: new_misc_error ( self . tcx )
206+ Ty :: new_error ( self . tcx , guar )
192207 }
193208 }
194209 }
@@ -203,20 +218,30 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
203218 match ct. kind ( ) {
204219 ty:: ConstKind :: Param ( ..) => {
205220 // 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 ( ) ) {
207222 // Found it in the generic parameters list, replace with the parameter from the
208223 // opaque type.
209224 Some ( GenericArgKind :: Const ( c1) ) => c1,
210225 Some ( u) => panic ! ( "const mapped to unexpected kind: {u:?}" ) ,
211226 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 ) ;
220245
221246 ty:: Const :: new_error ( self . tcx , guar)
222247 }
0 commit comments