@@ -8,12 +8,16 @@ use rustc_errors::{ErrorGuaranteed, StashKey};
8
8
use rustc_hir as hir;
9
9
use rustc_hir:: intravisit:: { self , Visitor } ;
10
10
use rustc_infer:: infer:: error_reporting:: TypeAnnotationNeeded :: E0282 ;
11
+ use rustc_middle:: traits:: ObligationCause ;
11
12
use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , PointerCoercion } ;
12
13
use rustc_middle:: ty:: fold:: { TypeFoldable , TypeFolder } ;
13
14
use rustc_middle:: ty:: visit:: TypeVisitableExt ;
15
+ use rustc_middle:: ty:: TypeSuperFoldable ;
14
16
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
15
17
use rustc_span:: symbol:: sym;
16
18
use rustc_span:: Span ;
19
+ use rustc_trait_selection:: solve;
20
+ use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt ;
17
21
18
22
use std:: mem;
19
23
@@ -695,24 +699,22 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
695
699
}
696
700
}
697
701
698
- fn resolve < T > ( & mut self , x : T , span : & dyn Locatable ) -> T
702
+ fn resolve < T > ( & mut self , value : T , span : & dyn Locatable ) -> T
699
703
where
700
704
T : TypeFoldable < TyCtxt < ' tcx > > ,
701
705
{
702
- let mut resolver = Resolver :: new ( self . fcx , span, self . body ) ;
703
- let x = x. fold_with ( & mut resolver) ;
704
- if cfg ! ( debug_assertions) && x. has_infer ( ) {
705
- span_bug ! ( span. to_span( self . fcx. tcx) , "writeback: `{:?}` has inference variables" , x) ;
706
- }
706
+ let value = self . fcx . resolve_vars_if_possible ( value) ;
707
+ let value = value. fold_with ( & mut Resolver :: new ( self . fcx , span, self . body ) ) ;
708
+ assert ! ( !value. has_infer( ) ) ;
707
709
708
710
// We may have introduced e.g. `ty::Error`, if inference failed, make sure
709
711
// to mark the `TypeckResults` as tainted in that case, so that downstream
710
712
// users of the typeck results don't produce extra errors, or worse, ICEs.
711
- if let Some ( e ) = resolver . replaced_with_error {
712
- self . typeck_results . tainted_by_errors = Some ( e ) ;
713
+ if let Err ( guar ) = value . error_reported ( ) {
714
+ self . typeck_results . tainted_by_errors = Some ( guar ) ;
713
715
}
714
716
715
- x
717
+ value
716
718
}
717
719
}
718
720
@@ -732,15 +734,13 @@ impl Locatable for hir::HirId {
732
734
}
733
735
}
734
736
735
- /// The Resolver. This is the type folding engine that detects
736
- /// unresolved types and so forth.
737
737
struct Resolver < ' cx , ' tcx > {
738
738
fcx : & ' cx FnCtxt < ' cx , ' tcx > ,
739
739
span : & ' cx dyn Locatable ,
740
740
body : & ' tcx hir:: Body < ' tcx > ,
741
-
742
- /// Set to `Some` if any `Ty` or `ty::Const` had to be replaced with an `Error` .
743
- replaced_with_error : Option < ErrorGuaranteed > ,
741
+ /// Whether we should normalize using the new solver, disabled
742
+ /// both when using the old solver and when resolving predicates .
743
+ should_normalize : bool ,
744
744
}
745
745
746
746
impl < ' cx , ' tcx > Resolver < ' cx , ' tcx > {
@@ -749,7 +749,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
749
749
span : & ' cx dyn Locatable ,
750
750
body : & ' tcx hir:: Body < ' tcx > ,
751
751
) -> Resolver < ' cx , ' tcx > {
752
- Resolver { fcx, span, body, replaced_with_error : None }
752
+ Resolver { fcx, span, body, should_normalize : fcx . next_trait_solver ( ) }
753
753
}
754
754
755
755
fn report_error ( & self , p : impl Into < ty:: GenericArg < ' tcx > > ) -> ErrorGuaranteed {
@@ -768,64 +768,73 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
768
768
. emit ( ) ,
769
769
}
770
770
}
771
+
772
+ fn handle_term < T > (
773
+ & mut self ,
774
+ value : T ,
775
+ outer_exclusive_binder : impl FnOnce ( T ) -> ty:: DebruijnIndex ,
776
+ new_err : impl Fn ( TyCtxt < ' tcx > , ErrorGuaranteed ) -> T ,
777
+ ) -> T
778
+ where
779
+ T : Into < ty:: GenericArg < ' tcx > > + Copy ,
780
+ T : TypeFoldable < TyCtxt < ' tcx > > ,
781
+ T : TypeSuperFoldable < TyCtxt < ' tcx > > ,
782
+ {
783
+ let tcx = self . fcx . tcx ;
784
+ // We must deeply normalize in the new solver, since later lints
785
+ // expect that types that show up in the typeck are fully
786
+ // normalized.
787
+ let value = if self . should_normalize {
788
+ let body_id = tcx. hir ( ) . body_owner_def_id ( self . body . id ( ) ) ;
789
+ let cause = ObligationCause :: misc ( self . span . to_span ( tcx) , body_id) ;
790
+ let at = self . fcx . at ( & cause, self . fcx . param_env ) ;
791
+ let universes = vec ! [ None ; outer_exclusive_binder( value) . as_usize( ) ] ;
792
+ solve:: deeply_normalize_with_skipped_universes ( at, value, universes) . unwrap_or_else (
793
+ |errors| {
794
+ let guar = self . fcx . err_ctxt ( ) . report_fulfillment_errors ( errors) ;
795
+ new_err ( tcx, guar)
796
+ } ,
797
+ )
798
+ } else {
799
+ value
800
+ } ;
801
+
802
+ if value. has_non_region_infer ( ) {
803
+ let guar = self . report_error ( value) ;
804
+ new_err ( tcx, guar)
805
+ } else {
806
+ tcx. fold_regions ( value, |_, _| tcx. lifetimes . re_erased )
807
+ }
808
+ }
771
809
}
772
810
773
811
impl < ' cx , ' tcx > TypeFolder < TyCtxt < ' tcx > > for Resolver < ' cx , ' tcx > {
774
812
fn interner ( & self ) -> TyCtxt < ' tcx > {
775
813
self . fcx . tcx
776
814
}
777
815
778
- fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
779
- let tcx = self . fcx . tcx ;
780
- match self . fcx . fully_resolve ( t) {
781
- Ok ( t) if self . fcx . next_trait_solver ( ) => {
782
- // We must normalize erasing regions here, since later lints
783
- // expect that types that show up in the typeck are fully
784
- // normalized.
785
- if let Ok ( t) = tcx. try_normalize_erasing_regions ( self . fcx . param_env , t) {
786
- t
787
- } else {
788
- tcx. fold_regions ( t, |_, _| tcx. lifetimes . re_erased )
789
- }
790
- }
791
- Ok ( t) => {
792
- // Do not anonymize late-bound regions
793
- // (e.g. keep `for<'a>` named `for<'a>`).
794
- // This allows NLL to generate error messages that
795
- // refer to the higher-ranked lifetime names written by the user.
796
- tcx. fold_regions ( t, |_, _| tcx. lifetimes . re_erased )
797
- }
798
- Err ( _) => {
799
- debug ! ( "Resolver::fold_ty: input type `{:?}` not fully resolvable" , t) ;
800
- let e = self . report_error ( t) ;
801
- self . replaced_with_error = Some ( e) ;
802
- Ty :: new_error ( self . fcx . tcx , e)
803
- }
804
- }
805
- }
806
-
807
816
fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
808
817
debug_assert ! ( !r. is_bound( ) , "Should not be resolving bound region." ) ;
809
818
self . fcx . tcx . lifetimes . re_erased
810
819
}
811
820
821
+ fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
822
+ self . handle_term ( ty, Ty :: outer_exclusive_binder, Ty :: new_error)
823
+ }
824
+
812
825
fn fold_const ( & mut self , ct : ty:: Const < ' tcx > ) -> ty:: Const < ' tcx > {
813
- match self . fcx . fully_resolve ( ct) {
814
- Ok ( ct) => self . fcx . tcx . erase_regions ( ct) ,
815
- Err ( _) => {
816
- debug ! ( "Resolver::fold_const: input const `{:?}` not fully resolvable" , ct) ;
817
- let e = self . report_error ( ct) ;
818
- self . replaced_with_error = Some ( e) ;
819
- ty:: Const :: new_error ( self . fcx . tcx , e, ct. ty ( ) )
820
- }
821
- }
826
+ self . handle_term ( ct, ty:: Const :: outer_exclusive_binder, |tcx, guar| {
827
+ ty:: Const :: new_error ( tcx, guar, ct. ty ( ) )
828
+ } )
822
829
}
823
- }
824
830
825
- ///////////////////////////////////////////////////////////////////////////
826
- // During type check, we store promises with the result of trait
827
- // lookup rather than the actual results (because the results are not
828
- // necessarily available immediately). These routines unwind the
829
- // promises. It is expected that we will have already reported any
830
- // errors that may be encountered, so if the promises store an error,
831
- // a dummy result is returned.
831
+ fn fold_predicate ( & mut self , predicate : ty:: Predicate < ' tcx > ) -> ty:: Predicate < ' tcx > {
832
+ // Do not normalize predicates in the new solver. The new solver is
833
+ // supposed to handle unnormalized predicates and incorrectly normalizing
834
+ // them can be unsound, e.g. for `WellFormed` predicates.
835
+ let prev = mem:: replace ( & mut self . should_normalize , false ) ;
836
+ let predicate = predicate. super_fold_with ( self ) ;
837
+ self . should_normalize = prev;
838
+ predicate
839
+ }
840
+ }
0 commit comments