@@ -24,13 +24,13 @@ use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
2424use tracing:: { debug, instrument} ;
2525
2626use super :: reverse_sccs:: ReverseSccGraph ;
27- use crate :: BorrowckInferCtxt ;
2827use crate :: consumers:: RegionInferenceContext ;
2928use crate :: session_diagnostics:: LifetimeMismatchOpaqueParam ;
3029use crate :: type_check:: canonical:: fully_perform_op_raw;
3130use crate :: type_check:: free_region_relations:: UniversalRegionRelations ;
3231use crate :: type_check:: { Locations , MirTypeckRegionConstraints } ;
3332use crate :: universal_regions:: { RegionClassification , UniversalRegions } ;
33+ use crate :: { BorrowckInferCtxt , CollectRegionConstraintsResult } ;
3434
3535mod member_constraints;
3636mod region_ctxt;
@@ -126,6 +126,31 @@ fn nll_var_to_universal_region<'tcx>(
126126 }
127127}
128128
129+ /// Record info needed to report the same name error later.
130+ #[ derive( Copy , Clone , Debug ) ]
131+ pub ( crate ) struct UnexpectedHiddenRegion < ' tcx > {
132+ // The def_id of the body where this error occurs.
133+ // Needed to handle region vars with their corresponding `infcx`.
134+ def_id : LocalDefId ,
135+ opaque_type_key : OpaqueTypeKey < ' tcx > ,
136+ hidden_type : ProvisionalHiddenType < ' tcx > ,
137+ member_region : Region < ' tcx > ,
138+ }
139+
140+ impl < ' tcx > UnexpectedHiddenRegion < ' tcx > {
141+ pub ( crate ) fn to_error ( self ) -> ( LocalDefId , DeferredOpaqueTypeError < ' tcx > ) {
142+ let UnexpectedHiddenRegion { def_id, opaque_type_key, hidden_type, member_region } = self ;
143+ (
144+ def_id,
145+ DeferredOpaqueTypeError :: UnexpectedHiddenRegion {
146+ opaque_type_key,
147+ hidden_type,
148+ member_region,
149+ } ,
150+ )
151+ }
152+ }
153+
129154/// Collect all defining uses of opaque types inside of this typeck root. This
130155/// expects the hidden type to be mapped to the definition parameters of the opaque
131156/// and errors if we end up with distinct hidden types.
@@ -176,11 +201,13 @@ struct DefiningUse<'tcx> {
176201/// It also means that this whole function is not really soundness critical as we
177202/// recheck all uses of the opaques regardless.
178203pub ( crate ) fn compute_definition_site_hidden_types < ' tcx > (
204+ def_id : LocalDefId ,
179205 infcx : & BorrowckInferCtxt < ' tcx > ,
180206 universal_region_relations : & Frozen < UniversalRegionRelations < ' tcx > > ,
181207 constraints : & MirTypeckRegionConstraints < ' tcx > ,
182208 location_map : Rc < DenseLocationMap > ,
183209 hidden_types : & mut FxIndexMap < LocalDefId , ty:: DefinitionSiteHiddenType < ' tcx > > ,
210+ unconstrained_hidden_type_errors : & mut Vec < UnexpectedHiddenRegion < ' tcx > > ,
184211 opaque_types : & [ ( OpaqueTypeKey < ' tcx > , ProvisionalHiddenType < ' tcx > ) ] ,
185212) -> Vec < DeferredOpaqueTypeError < ' tcx > > {
186213 let mut errors = Vec :: new ( ) ;
@@ -204,8 +231,10 @@ pub(crate) fn compute_definition_site_hidden_types<'tcx>(
204231 // up equal to one of their choice regions and compute the actual hidden type of
205232 // the opaque type definition. This is stored in the `root_cx`.
206233 compute_definition_site_hidden_types_from_defining_uses (
234+ def_id,
207235 & rcx,
208236 hidden_types,
237+ unconstrained_hidden_type_errors,
209238 & defining_uses,
210239 & mut errors,
211240 ) ;
@@ -274,8 +303,10 @@ fn collect_defining_uses<'tcx>(
274303
275304#[ instrument( level = "debug" , skip( rcx, hidden_types, defining_uses, errors) ) ]
276305fn compute_definition_site_hidden_types_from_defining_uses < ' tcx > (
306+ def_id : LocalDefId ,
277307 rcx : & RegionCtxt < ' _ , ' tcx > ,
278308 hidden_types : & mut FxIndexMap < LocalDefId , ty:: DefinitionSiteHiddenType < ' tcx > > ,
309+ unconstrained_hidden_type_errors : & mut Vec < UnexpectedHiddenRegion < ' tcx > > ,
279310 defining_uses : & [ DefiningUse < ' tcx > ] ,
280311 errors : & mut Vec < DeferredOpaqueTypeError < ' tcx > > ,
281312) {
@@ -293,16 +324,29 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
293324 Ok ( hidden_type) => hidden_type,
294325 Err ( r) => {
295326 debug ! ( "UnexpectedHiddenRegion: {:?}" , r) ;
296- errors. push ( DeferredOpaqueTypeError :: UnexpectedHiddenRegion {
297- hidden_type,
298- opaque_type_key,
299- member_region : ty:: Region :: new_var ( tcx, r) ,
300- } ) ;
301- let guar = tcx. dcx ( ) . span_delayed_bug (
302- hidden_type. span ,
303- "opaque type with non-universal region args" ,
304- ) ;
305- ty:: ProvisionalHiddenType :: new_error ( tcx, guar)
327+ // If we're using the next solver, the unconstrained region may be resolved by a
328+ // fully defining use from another body.
329+ // So we don't generate error eagerly here.
330+ if rcx. infcx . tcx . use_typing_mode_borrowck ( ) {
331+ unconstrained_hidden_type_errors. push ( UnexpectedHiddenRegion {
332+ def_id,
333+ hidden_type,
334+ opaque_type_key,
335+ member_region : ty:: Region :: new_var ( tcx, r) ,
336+ } ) ;
337+ continue ;
338+ } else {
339+ errors. push ( DeferredOpaqueTypeError :: UnexpectedHiddenRegion {
340+ hidden_type,
341+ opaque_type_key,
342+ member_region : ty:: Region :: new_var ( tcx, r) ,
343+ } ) ;
344+ let guar = tcx. dcx ( ) . span_delayed_bug (
345+ hidden_type. span ,
346+ "opaque type with non-universal region args" ,
347+ ) ;
348+ ty:: ProvisionalHiddenType :: new_error ( tcx, guar)
349+ }
306350 }
307351 } ;
308352
@@ -570,6 +614,40 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
570614 errors
571615}
572616
617+ /// We handle `UnexpectedHiddenRegion` error lazily in the next solver as
618+ /// there may be a fully defining use in another body.
619+ ///
620+ /// In case such a defining use does not exist, we register an error here.
621+ pub ( crate ) fn handle_unconstrained_hidden_type_errors < ' tcx > (
622+ tcx : TyCtxt < ' tcx > ,
623+ hidden_types : & mut FxIndexMap < LocalDefId , ty:: DefinitionSiteHiddenType < ' tcx > > ,
624+ unconstrained_hidden_type_errors : & mut Vec < UnexpectedHiddenRegion < ' tcx > > ,
625+ collect_region_constraints_results : & mut FxIndexMap <
626+ LocalDefId ,
627+ CollectRegionConstraintsResult < ' tcx > ,
628+ > ,
629+ ) {
630+ let mut unconstrained_hidden_type_errors = std:: mem:: take ( unconstrained_hidden_type_errors) ;
631+ unconstrained_hidden_type_errors
632+ . retain ( |unconstrained| !hidden_types. contains_key ( & unconstrained. opaque_type_key . def_id ) ) ;
633+
634+ unconstrained_hidden_type_errors. iter ( ) . for_each ( |t| {
635+ tcx. dcx ( )
636+ . span_delayed_bug ( t. hidden_type . span , "opaque type with non-universal region args" ) ;
637+ } ) ;
638+
639+ // `UnexpectedHiddenRegion` error contains region var which only makes sense in the
640+ // corresponding `infcx`.
641+ // So we need to insert the error to the body where it originates from.
642+ for error in unconstrained_hidden_type_errors {
643+ let ( def_id, error) = error. to_error ( ) ;
644+ let Some ( result) = collect_region_constraints_results. get_mut ( & def_id) else {
645+ unreachable ! ( "the body should depend on opaques type if it has opaque use" ) ;
646+ } ;
647+ result. deferred_opaque_type_errors . push ( error) ;
648+ }
649+ }
650+
573651/// In theory `apply_definition_site_hidden_types` could introduce new uses of opaque types.
574652/// We do not check these new uses so this could be unsound.
575653///
0 commit comments