@@ -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 :: * ;
@@ -245,7 +247,7 @@ pub struct InferCtxt<'tcx> {
245
247
pub tcx : TyCtxt < ' tcx > ,
246
248
247
249
/// The `DefIds` of the opaque types that may have their hidden types constrained.
248
- defining_opaque_types : & ' tcx ty:: List < LocalDefId > ,
250
+ opaque_type_mode : ty:: OpaqueTypeMode < TyCtxt < ' tcx > > ,
249
251
250
252
/// Whether this inference context should care about region obligations in
251
253
/// the root universe. Most notably, this is used during hir typeck as region
@@ -393,8 +395,8 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
393
395
self . probe_const_var ( vid) . ok ( )
394
396
}
395
397
396
- fn defining_opaque_types ( & self ) -> & ' tcx ty:: List < LocalDefId > {
397
- self . defining_opaque_types
398
+ fn opaque_type_mode ( & self ) -> ty:: OpaqueTypeMode < TyCtxt < ' tcx > > {
399
+ self . opaque_type_mode
398
400
}
399
401
}
400
402
@@ -610,7 +612,7 @@ impl fmt::Display for FixupError {
610
612
/// Used to configure inference contexts before their creation.
611
613
pub struct InferCtxtBuilder < ' tcx > {
612
614
tcx : TyCtxt < ' tcx > ,
613
- defining_opaque_types : & ' tcx ty:: List < LocalDefId > ,
615
+ opaque_type_mode : ty:: OpaqueTypeMode < TyCtxt < ' tcx > > ,
614
616
considering_regions : bool ,
615
617
skip_leak_check : bool ,
616
618
/// Whether we are in coherence mode.
@@ -625,7 +627,7 @@ impl<'tcx> TyCtxt<'tcx> {
625
627
fn infer_ctxt ( self ) -> InferCtxtBuilder < ' tcx > {
626
628
InferCtxtBuilder {
627
629
tcx : self ,
628
- defining_opaque_types : ty :: List :: empty ( ) ,
630
+ opaque_type_mode : Default :: default ( ) ,
629
631
considering_regions : true ,
630
632
skip_leak_check : false ,
631
633
intercrate : false ,
@@ -635,22 +637,23 @@ impl<'tcx> TyCtxt<'tcx> {
635
637
}
636
638
637
639
impl < ' tcx > InferCtxtBuilder < ' tcx > {
640
+ pub fn with_opaque_type_mode (
641
+ mut self ,
642
+ opaque_type_mode : ty:: OpaqueTypeMode < TyCtxt < ' tcx > > ,
643
+ ) -> Self {
644
+ self . opaque_type_mode = opaque_type_mode;
645
+ self
646
+ }
647
+
638
648
/// Whenever the `InferCtxt` should be able to handle defining uses of opaque types,
639
649
/// you need to call this function. Otherwise the opaque type will be treated opaquely.
640
650
///
641
651
/// It is only meant to be called in two places, for typeck
642
652
/// (via `Inherited::build`) and for the inference context used
643
653
/// in mir borrowck.
644
654
pub fn with_opaque_type_inference ( mut self , defining_anchor : LocalDefId ) -> Self {
645
- self . defining_opaque_types = self . tcx . opaque_types_defined_by ( defining_anchor) ;
646
- self
647
- }
648
-
649
- pub fn with_defining_opaque_types (
650
- mut self ,
651
- defining_opaque_types : & ' tcx ty:: List < LocalDefId > ,
652
- ) -> Self {
653
- self . defining_opaque_types = defining_opaque_types;
655
+ let types = self . tcx . opaque_types_defined_by ( defining_anchor) ;
656
+ self . opaque_type_mode = ty:: OpaqueTypeMode :: Define ( types) ;
654
657
self
655
658
}
656
659
@@ -689,23 +692,23 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
689
692
where
690
693
T : TypeFoldable < TyCtxt < ' tcx > > ,
691
694
{
692
- let infcx = self . with_defining_opaque_types ( canonical. defining_opaque_types ) . build ( ) ;
695
+ let infcx = self . with_opaque_type_mode ( canonical. opaque_type_mode ) . build ( ) ;
693
696
let ( value, args) = infcx. instantiate_canonical ( span, canonical) ;
694
697
( infcx, value, args)
695
698
}
696
699
697
700
pub fn build ( & mut self ) -> InferCtxt < ' tcx > {
698
701
let InferCtxtBuilder {
699
702
tcx,
700
- defining_opaque_types,
703
+ opaque_type_mode : defining_opaque_types,
701
704
considering_regions,
702
705
skip_leak_check,
703
706
intercrate,
704
707
next_trait_solver,
705
708
} = * self ;
706
709
InferCtxt {
707
710
tcx,
708
- defining_opaque_types,
711
+ opaque_type_mode : defining_opaque_types,
709
712
considering_regions,
710
713
skip_leak_check,
711
714
inner : RefCell :: new ( InferCtxtInner :: new ( ) ) ,
@@ -1234,10 +1237,30 @@ impl<'tcx> InferCtxt<'tcx> {
1234
1237
self . inner . borrow ( ) . opaque_type_storage . opaque_types . clone ( )
1235
1238
}
1236
1239
1237
- #[ inline( always) ]
1238
- pub fn can_define_opaque_ty ( & self , id : impl Into < DefId > ) -> bool {
1239
- let Some ( id) = id. into ( ) . as_local ( ) else { return false } ;
1240
- self . defining_opaque_types . contains ( & id)
1240
+ pub fn treat_opaque_ty ( & self , reveal : Reveal , def_id : DefId ) -> TreatOpaque {
1241
+ if self . intercrate {
1242
+ return TreatOpaque :: Ambiguous ;
1243
+ }
1244
+
1245
+ match reveal {
1246
+ Reveal :: All => return TreatOpaque :: Reveal ,
1247
+ Reveal :: UserFacing => { }
1248
+ }
1249
+
1250
+ match self . opaque_type_mode {
1251
+ ty:: OpaqueTypeMode :: Define ( list) => {
1252
+ if def_id. as_local ( ) . is_some_and ( |def_id| list. contains ( & def_id) ) {
1253
+ return TreatOpaque :: Define ;
1254
+ }
1255
+ }
1256
+ ty:: OpaqueTypeMode :: Reveal ( list) => {
1257
+ if def_id. as_local ( ) . is_some_and ( |def_id| list. contains ( & def_id) ) {
1258
+ return TreatOpaque :: Reveal ;
1259
+ }
1260
+ }
1261
+ }
1262
+
1263
+ TreatOpaque :: Rigid
1241
1264
}
1242
1265
1243
1266
pub fn ty_to_string ( & self , t : Ty < ' tcx > ) -> String {
0 commit comments