@@ -5,6 +5,8 @@ pub use relate::combine::CombineFields;
55pub use relate:: combine:: ObligationEmittingRelation ;
66pub use relate:: StructurallyRelateAliases ;
77pub use rustc_macros:: { TypeFoldable , TypeVisitable } ;
8+ use rustc_middle:: traits:: Reveal ;
9+ use rustc_middle:: traits:: TreatOpaque ;
810pub use rustc_middle:: ty:: IntVarValue ;
911pub use BoundRegionConversionTime :: * ;
1012pub use RegionVariableOrigin :: * ;
@@ -246,7 +248,7 @@ pub struct InferCtxt<'tcx> {
246248 pub tcx : TyCtxt < ' tcx > ,
247249
248250 /// 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 > > ,
250252
251253 /// Whether this inference context should care about region obligations in
252254 /// the root universe. Most notably, this is used during hir typeck as region
@@ -373,8 +375,8 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
373375 self . inner . borrow_mut ( ) . unwrap_region_constraints ( ) . opportunistic_resolve_var ( self . tcx , vid)
374376 }
375377
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
378380 }
379381
380382 fn opportunistic_resolve_ty_var ( & self , vid : TyVid ) -> Ty < ' tcx > {
@@ -621,7 +623,7 @@ impl fmt::Display for FixupError {
621623/// Used to configure inference contexts before their creation.
622624pub struct InferCtxtBuilder < ' tcx > {
623625 tcx : TyCtxt < ' tcx > ,
624- defining_opaque_types : & ' tcx ty:: List < LocalDefId > ,
626+ opaque_type_mode : ty:: OpaqueTypeMode < TyCtxt < ' tcx > > ,
625627 considering_regions : bool ,
626628 skip_leak_check : bool ,
627629 /// Whether we are in coherence mode.
@@ -636,7 +638,7 @@ impl<'tcx> TyCtxt<'tcx> {
636638 fn infer_ctxt ( self ) -> InferCtxtBuilder < ' tcx > {
637639 InferCtxtBuilder {
638640 tcx : self ,
639- defining_opaque_types : ty :: List :: empty ( ) ,
641+ opaque_type_mode : Default :: default ( ) ,
640642 considering_regions : true ,
641643 skip_leak_check : false ,
642644 intercrate : false ,
@@ -646,22 +648,23 @@ impl<'tcx> TyCtxt<'tcx> {
646648}
647649
648650impl < ' 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+
649659 /// Whenever the `InferCtxt` should be able to handle defining uses of opaque types,
650660 /// you need to call this function. Otherwise the opaque type will be treated opaquely.
651661 ///
652662 /// It is only meant to be called in two places, for typeck
653663 /// (via `Inherited::build`) and for the inference context used
654664 /// in mir borrowck.
655665 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) ;
665668 self
666669 }
667670
@@ -700,23 +703,23 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
700703 where
701704 T : TypeFoldable < TyCtxt < ' tcx > > ,
702705 {
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 ( ) ;
704707 let ( value, args) = infcx. instantiate_canonical ( span, canonical) ;
705708 ( infcx, value, args)
706709 }
707710
708711 pub fn build ( & mut self ) -> InferCtxt < ' tcx > {
709712 let InferCtxtBuilder {
710713 tcx,
711- defining_opaque_types,
714+ opaque_type_mode : defining_opaque_types,
712715 considering_regions,
713716 skip_leak_check,
714717 intercrate,
715718 next_trait_solver,
716719 } = * self ;
717720 InferCtxt {
718721 tcx,
719- defining_opaque_types,
722+ opaque_type_mode : defining_opaque_types,
720723 considering_regions,
721724 skip_leak_check,
722725 inner : RefCell :: new ( InferCtxtInner :: new ( ) ) ,
@@ -1240,10 +1243,30 @@ impl<'tcx> InferCtxt<'tcx> {
12401243 self . inner . borrow ( ) . opaque_type_storage . opaque_types . clone ( )
12411244 }
12421245
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
12471270 }
12481271
12491272 pub fn ty_to_string ( & self , t : Ty < ' tcx > ) -> String {
0 commit comments