1
1
use super :: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
2
2
use super :: { DefineOpaqueTypes , InferResult } ;
3
3
use crate :: errors:: OpaqueHiddenTypeDiag ;
4
- use crate :: infer:: { DefiningAnchor , InferCtxt , InferOk } ;
5
- use crate :: traits;
4
+ use crate :: infer:: { InferCtxt , InferOk } ;
5
+ use crate :: traits:: { self , PredicateObligation } ;
6
6
use hir:: def_id:: { DefId , LocalDefId } ;
7
7
use hir:: OpaqueTyOrigin ;
8
8
use rustc_data_structures:: fx:: FxIndexMap ;
9
9
use rustc_data_structures:: sync:: Lrc ;
10
10
use rustc_hir as hir;
11
- use rustc_middle:: traits:: ObligationCause ;
11
+ use rustc_middle:: traits:: { DefiningAnchor , ObligationCause } ;
12
12
use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
13
13
use rustc_middle:: ty:: fold:: BottomUpFolder ;
14
14
use rustc_middle:: ty:: GenericArgKind ;
@@ -48,9 +48,15 @@ impl<'tcx> InferCtxt<'tcx> {
48
48
span : Span ,
49
49
param_env : ty:: ParamEnv < ' tcx > ,
50
50
) -> InferOk < ' tcx , T > {
51
+ // We handle opaque types differently in the new solver.
52
+ if self . tcx . trait_solver_next ( ) {
53
+ return InferOk { value, obligations : vec ! [ ] } ;
54
+ }
55
+
51
56
if !value. has_opaque_types ( ) {
52
57
return InferOk { value, obligations : vec ! [ ] } ;
53
58
}
59
+
54
60
let mut obligations = vec ! [ ] ;
55
61
let replace_opaque_type = |def_id : DefId | {
56
62
def_id. as_local ( ) . is_some_and ( |def_id| self . opaque_type_origin ( def_id) . is_some ( ) )
@@ -521,17 +527,14 @@ impl<'tcx> InferCtxt<'tcx> {
521
527
origin : hir:: OpaqueTyOrigin ,
522
528
a_is_expected : bool ,
523
529
) -> InferResult < ' tcx , ( ) > {
524
- let tcx = self . tcx ;
525
- let OpaqueTypeKey { def_id, substs } = opaque_type_key;
526
-
527
530
// Ideally, we'd get the span where *this specific `ty` came
528
531
// from*, but right now we just use the span from the overall
529
532
// value being folded. In simple cases like `-> impl Foo`,
530
533
// these are the same span, but not in cases like `-> (impl
531
534
// Foo, impl Bar)`.
532
535
let span = cause. span ;
533
536
let prev = self . inner . borrow_mut ( ) . opaque_types ( ) . register (
534
- OpaqueTypeKey { def_id , substs } ,
537
+ opaque_type_key ,
535
538
OpaqueHiddenType { ty : hidden_ty, span } ,
536
539
origin,
537
540
) ;
@@ -543,6 +546,49 @@ impl<'tcx> InferCtxt<'tcx> {
543
546
Vec :: new ( )
544
547
} ;
545
548
549
+ self . add_item_bounds_for_hidden_type (
550
+ opaque_type_key,
551
+ cause,
552
+ param_env,
553
+ hidden_ty,
554
+ & mut obligations,
555
+ ) ;
556
+
557
+ Ok ( InferOk { value : ( ) , obligations } )
558
+ }
559
+
560
+ /// Registers an opaque's hidden type -- only should be used when the opaque
561
+ /// can be defined. For something more fallible -- checks the anchors, tries
562
+ /// to unify opaques in both dirs, etc. -- use `InferCtxt::handle_opaque_type`.
563
+ pub fn register_hidden_type_in_new_solver (
564
+ & self ,
565
+ opaque_type_key : OpaqueTypeKey < ' tcx > ,
566
+ param_env : ty:: ParamEnv < ' tcx > ,
567
+ hidden_ty : Ty < ' tcx > ,
568
+ ) -> InferResult < ' tcx , ( ) > {
569
+ assert ! ( self . tcx. trait_solver_next( ) ) ;
570
+ let origin = self
571
+ . opaque_type_origin ( opaque_type_key. def_id )
572
+ . expect ( "should be called for defining usages only" ) ;
573
+ self . register_hidden_type (
574
+ opaque_type_key,
575
+ ObligationCause :: dummy ( ) ,
576
+ param_env,
577
+ hidden_ty,
578
+ origin,
579
+ true ,
580
+ )
581
+ }
582
+
583
+ pub fn add_item_bounds_for_hidden_type (
584
+ & self ,
585
+ OpaqueTypeKey { def_id, substs } : OpaqueTypeKey < ' tcx > ,
586
+ cause : ObligationCause < ' tcx > ,
587
+ param_env : ty:: ParamEnv < ' tcx > ,
588
+ hidden_ty : Ty < ' tcx > ,
589
+ obligations : & mut Vec < PredicateObligation < ' tcx > > ,
590
+ ) {
591
+ let tcx = self . tcx ;
546
592
let item_bounds = tcx. explicit_item_bounds ( def_id) ;
547
593
548
594
for ( predicate, _) in item_bounds. subst_iter_copied ( tcx, substs) {
@@ -555,14 +601,15 @@ impl<'tcx> InferCtxt<'tcx> {
555
601
// FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too.
556
602
ty:: Alias ( ty:: Projection , projection_ty)
557
603
if !projection_ty. has_escaping_bound_vars ( )
558
- && !tcx. is_impl_trait_in_trait ( projection_ty. def_id ) =>
604
+ && !tcx. is_impl_trait_in_trait ( projection_ty. def_id )
605
+ && !tcx. trait_solver_next ( ) =>
559
606
{
560
607
self . infer_projection (
561
608
param_env,
562
609
projection_ty,
563
610
cause. clone ( ) ,
564
611
0 ,
565
- & mut obligations,
612
+ obligations,
566
613
)
567
614
}
568
615
// Replace all other mentions of the same opaque type with the hidden type,
@@ -588,10 +635,10 @@ impl<'tcx> InferCtxt<'tcx> {
588
635
predicate. kind ( ) . skip_binder ( )
589
636
{
590
637
if projection. term . references_error ( ) {
591
- // No point on adding these obligations since there's a type error involved.
592
- return Ok ( InferOk { value : ( ) , obligations : vec ! [ ] } ) ;
638
+ // No point on adding any obligations since there's a type error involved.
639
+ obligations. clear ( ) ;
640
+ return ;
593
641
}
594
- trace ! ( "{:#?}" , projection. term) ;
595
642
}
596
643
// Require that the predicate holds for the concrete type.
597
644
debug ! ( ?predicate) ;
@@ -602,7 +649,6 @@ impl<'tcx> InferCtxt<'tcx> {
602
649
predicate,
603
650
) ) ;
604
651
}
605
- Ok ( InferOk { value : ( ) , obligations } )
606
652
}
607
653
}
608
654
0 commit comments