@@ -5,6 +5,8 @@ pub use relate::combine::CombineFields;
5
5
pub use relate:: combine:: ObligationEmittingRelation ;
6
6
pub use relate:: StructurallyRelateAliases ;
7
7
pub use rustc_macros:: { TypeFoldable , TypeVisitable } ;
8
+ use rustc_middle:: traits:: Reveal ;
9
+ use rustc_middle:: traits:: TreatOpaque ;
8
10
pub use rustc_middle:: ty:: IntVarValue ;
9
11
pub use BoundRegionConversionTime :: * ;
10
12
pub use RegionVariableOrigin :: * ;
@@ -246,7 +248,7 @@ pub struct InferCtxt<'tcx> {
246
248
pub tcx : TyCtxt < ' tcx > ,
247
249
248
250
/// The `DefIds` of the opaque types that may have their hidden types constrained.
249
- defining_opaque_types : & ' tcx ty:: List < LocalDefId > ,
251
+ opaque_type_mode : ty:: OpaqueTypeMode < TyCtxt < ' tcx > > ,
250
252
251
253
/// Whether this inference context should care about region obligations in
252
254
/// the root universe. Most notably, this is used during hir typeck as region
@@ -373,8 +375,8 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
373
375
self . inner . borrow_mut ( ) . unwrap_region_constraints ( ) . opportunistic_resolve_var ( self . tcx , vid)
374
376
}
375
377
376
- fn defining_opaque_types ( & self ) -> & ' tcx ty:: List < LocalDefId > {
377
- self . defining_opaque_types
378
+ fn opaque_type_mode ( & self ) -> ty:: OpaqueTypeMode < TyCtxt < ' tcx > > {
379
+ self . opaque_type_mode
378
380
}
379
381
380
382
fn opportunistic_resolve_ty_var ( & self , vid : TyVid ) -> Ty < ' tcx > {
@@ -621,7 +623,7 @@ impl fmt::Display for FixupError {
621
623
/// Used to configure inference contexts before their creation.
622
624
pub struct InferCtxtBuilder < ' tcx > {
623
625
tcx : TyCtxt < ' tcx > ,
624
- defining_opaque_types : & ' tcx ty:: List < LocalDefId > ,
626
+ opaque_type_mode : ty:: OpaqueTypeMode < TyCtxt < ' tcx > > ,
625
627
considering_regions : bool ,
626
628
skip_leak_check : bool ,
627
629
/// Whether we are in coherence mode.
@@ -636,7 +638,7 @@ impl<'tcx> TyCtxt<'tcx> {
636
638
fn infer_ctxt ( self ) -> InferCtxtBuilder < ' tcx > {
637
639
InferCtxtBuilder {
638
640
tcx : self ,
639
- defining_opaque_types : ty :: List :: empty ( ) ,
641
+ opaque_type_mode : Default :: default ( ) ,
640
642
considering_regions : true ,
641
643
skip_leak_check : false ,
642
644
intercrate : false ,
@@ -646,22 +648,23 @@ impl<'tcx> TyCtxt<'tcx> {
646
648
}
647
649
648
650
impl < ' tcx > InferCtxtBuilder < ' tcx > {
651
+ pub fn with_opaque_type_mode (
652
+ mut self ,
653
+ opaque_type_mode : ty:: OpaqueTypeMode < TyCtxt < ' tcx > > ,
654
+ ) -> Self {
655
+ self . opaque_type_mode = opaque_type_mode;
656
+ self
657
+ }
658
+
649
659
/// Whenever the `InferCtxt` should be able to handle defining uses of opaque types,
650
660
/// you need to call this function. Otherwise the opaque type will be treated opaquely.
651
661
///
652
662
/// It is only meant to be called in two places, for typeck
653
663
/// (via `Inherited::build`) and for the inference context used
654
664
/// in mir borrowck.
655
665
pub fn with_opaque_type_inference ( mut self , defining_anchor : LocalDefId ) -> Self {
656
- self . defining_opaque_types = self . tcx . opaque_types_defined_by ( defining_anchor) ;
657
- self
658
- }
659
-
660
- pub fn with_defining_opaque_types (
661
- mut self ,
662
- defining_opaque_types : & ' tcx ty:: List < LocalDefId > ,
663
- ) -> Self {
664
- self . defining_opaque_types = defining_opaque_types;
666
+ let types = self . tcx . opaque_types_defined_by ( defining_anchor) ;
667
+ self . opaque_type_mode = ty:: OpaqueTypeMode :: Define ( types) ;
665
668
self
666
669
}
667
670
@@ -700,23 +703,23 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
700
703
where
701
704
T : TypeFoldable < TyCtxt < ' tcx > > ,
702
705
{
703
- let infcx = self . with_defining_opaque_types ( canonical. defining_opaque_types ) . build ( ) ;
706
+ let infcx = self . with_opaque_type_mode ( canonical. opaque_type_mode ) . build ( ) ;
704
707
let ( value, args) = infcx. instantiate_canonical ( span, canonical) ;
705
708
( infcx, value, args)
706
709
}
707
710
708
711
pub fn build ( & mut self ) -> InferCtxt < ' tcx > {
709
712
let InferCtxtBuilder {
710
713
tcx,
711
- defining_opaque_types,
714
+ opaque_type_mode : defining_opaque_types,
712
715
considering_regions,
713
716
skip_leak_check,
714
717
intercrate,
715
718
next_trait_solver,
716
719
} = * self ;
717
720
InferCtxt {
718
721
tcx,
719
- defining_opaque_types,
722
+ opaque_type_mode : defining_opaque_types,
720
723
considering_regions,
721
724
skip_leak_check,
722
725
inner : RefCell :: new ( InferCtxtInner :: new ( ) ) ,
@@ -1240,10 +1243,30 @@ impl<'tcx> InferCtxt<'tcx> {
1240
1243
self . inner . borrow ( ) . opaque_type_storage . opaque_types . clone ( )
1241
1244
}
1242
1245
1243
- #[ inline( always) ]
1244
- pub fn can_define_opaque_ty ( & self , id : impl Into < DefId > ) -> bool {
1245
- let Some ( id) = id. into ( ) . as_local ( ) else { return false } ;
1246
- self . defining_opaque_types . contains ( & id)
1246
+ pub fn treat_opaque_ty ( & self , reveal : Reveal , def_id : DefId ) -> TreatOpaque {
1247
+ if self . intercrate {
1248
+ return TreatOpaque :: Ambiguous ;
1249
+ }
1250
+
1251
+ match reveal {
1252
+ Reveal :: All => return TreatOpaque :: Reveal ,
1253
+ Reveal :: UserFacing => { }
1254
+ }
1255
+
1256
+ match self . opaque_type_mode {
1257
+ ty:: OpaqueTypeMode :: Define ( list) => {
1258
+ if def_id. as_local ( ) . is_some_and ( |def_id| list. contains ( & def_id) ) {
1259
+ return TreatOpaque :: Define ;
1260
+ }
1261
+ }
1262
+ ty:: OpaqueTypeMode :: Reveal ( list) => {
1263
+ if def_id. as_local ( ) . is_some_and ( |def_id| list. contains ( & def_id) ) {
1264
+ return TreatOpaque :: Reveal ;
1265
+ }
1266
+ }
1267
+ }
1268
+
1269
+ TreatOpaque :: Rigid
1247
1270
}
1248
1271
1249
1272
pub fn ty_to_string ( & self , t : Ty < ' tcx > ) -> String {
0 commit comments