@@ -4,7 +4,8 @@ use rustc_hir as hir;
4
4
use rustc_hir:: def_id:: DefId ;
5
5
use rustc_hir:: lang_items:: LangItem ;
6
6
use rustc_middle:: ty:: subst:: { GenericArg , GenericArgKind , SubstsRef } ;
7
- use rustc_middle:: ty:: { self , ToPredicate , Ty , TyCtxt , TypeVisitable } ;
7
+ use rustc_middle:: ty:: walk:: TypeWalker ;
8
+ use rustc_middle:: ty:: { self , ParamEnv , Subst , ToPredicate , Ty , TyCtxt , TypeVisitable } ;
8
9
use rustc_span:: Span ;
9
10
10
11
use std:: iter;
@@ -505,22 +506,24 @@ impl<'tcx> WfPredicates<'tcx> {
505
506
cause,
506
507
depth,
507
508
param_env,
508
- ty:: Binder :: dummy ( ty:: PredicateKind :: TypeOutlives ( ty :: OutlivesPredicate (
509
- rty, r,
510
- ) ) )
509
+ ty:: Binder :: dummy ( ty:: PredicateKind :: TypeOutlives (
510
+ ty :: OutlivesPredicate ( rty, r) ,
511
+ ) )
511
512
. to_predicate ( self . tcx ( ) ) ,
512
513
) ) ;
513
514
}
514
515
}
515
516
516
- ty:: Generator ( ..) => {
517
+ ty:: Generator ( did , substs , ..) => {
517
518
// Walk ALL the types in the generator: this will
518
519
// include the upvar types as well as the yield
519
520
// type. Note that this is mildly distinct from
520
521
// the closure case, where we have to be careful
521
522
// about the signature of the closure. We don't
522
523
// have the problem of implied bounds here since
523
524
// generators don't take arguments.
525
+ let obligations = self . nominal_obligations ( did, substs) ;
526
+ self . out . extend ( obligations) ;
524
527
}
525
528
526
529
ty:: Closure ( did, substs) => {
@@ -572,18 +575,16 @@ impl<'tcx> WfPredicates<'tcx> {
572
575
}
573
576
574
577
ty:: Opaque ( did, substs) => {
575
- // all of the requirements on type parameters
576
- // should've been checked by the instantiation
577
- // of whatever returned this exact `impl Trait`.
578
-
579
- // for named opaque `impl Trait` types we still need to check them
580
- if ty:: is_impl_trait_defn ( self . infcx . tcx , did) . is_none ( ) {
578
+ // All of the requirements on type parameters
579
+ // have already been checked for `impl Trait` in
580
+ // return position. We do need to check type-alias-impl-trait though.
581
+ if ty:: is_impl_trait_defn ( self . tcx , did) . is_none ( ) {
581
582
let obligations = self . nominal_obligations ( did, substs) ;
582
583
self . out . extend ( obligations) ;
583
584
}
584
585
}
585
586
586
- ty:: Dynamic ( data, r) => {
587
+ ty:: Dynamic ( data, r, _ ) => {
587
588
// WfObject
588
589
//
589
590
// Here, we defer WF checking due to higher-ranked
@@ -605,7 +606,8 @@ impl<'tcx> WfPredicates<'tcx> {
605
606
cause. clone ( ) ,
606
607
depth,
607
608
param_env,
608
- ty:: Binder :: dummy ( ty:: PredicateKind :: ObjectSafe ( did) ) . to_predicate ( tcx) ,
609
+ ty:: Binder :: dummy ( ty:: PredicateKind :: ObjectSafe ( did) )
610
+ . to_predicate ( tcx) ,
609
611
)
610
612
} ) ) ;
611
613
}
@@ -624,22 +626,14 @@ impl<'tcx> WfPredicates<'tcx> {
624
626
// See also the comment on `fn obligations`, describing "livelock"
625
627
// prevention, which happens before this can be reached.
626
628
ty:: Infer ( _) => {
627
- let ty = self . infcx . shallow_resolve ( ty) ;
628
- if let ty:: Infer ( ty:: TyVar ( _) ) = ty. kind ( ) {
629
- // Not yet resolved, but we've made progress.
630
- let cause = self . cause ( traits:: WellFormed ( None ) ) ;
631
- self . out . push ( traits:: Obligation :: with_depth (
632
- cause,
633
- self . recursion_depth ,
634
- param_env,
635
- ty:: Binder :: dummy ( ty:: PredicateKind :: WellFormed ( ty. into ( ) ) )
636
- . to_predicate ( self . tcx ( ) ) ,
637
- ) ) ;
638
- } else {
639
- // Yes, resolved, proceed with the result.
640
- // FIXME(eddyb) add the type to `walker` instead of recursing.
641
- self . compute ( ty. into ( ) ) ;
642
- }
629
+ let cause = self . cause ( traits:: WellFormed ( None ) ) ;
630
+ self . out . push ( traits:: Obligation :: with_depth (
631
+ cause,
632
+ self . recursion_depth ,
633
+ param_env,
634
+ ty:: Binder :: dummy ( ty:: PredicateKind :: WellFormed ( ty. into ( ) ) )
635
+ . to_predicate ( self . tcx ( ) ) ,
636
+ ) ) ;
643
637
}
644
638
645
639
ty:: TyAlias ( def_id, substs) => {
@@ -707,213 +701,7 @@ impl<'tcx> WfPredicates<'tcx> {
707
701
}
708
702
} ;
709
703
710
- debug ! ( "wf bounds for ty={:?} ty.kind={:#?}" , ty, ty. kind( ) ) ;
711
-
712
- match * ty. kind ( ) {
713
- ty:: Bool
714
- | ty:: Char
715
- | ty:: Int ( ..)
716
- | ty:: Uint ( ..)
717
- | ty:: Float ( ..)
718
- | ty:: Error ( _)
719
- | ty:: Str
720
- | ty:: GeneratorWitness ( ..)
721
- | ty:: Never
722
- | ty:: Param ( _)
723
- | ty:: Bound ( ..)
724
- | ty:: Placeholder ( ..)
725
- | ty:: Foreign ( ..) => {
726
- // WfScalar, WfParameter, etc
727
- }
728
-
729
- // Can only infer to `ty::Int(_) | ty::Uint(_)`.
730
- ty:: Infer ( ty:: IntVar ( _) ) => { }
731
-
732
- // Can only infer to `ty::Float(_)`.
733
- ty:: Infer ( ty:: FloatVar ( _) ) => { }
734
-
735
- ty:: Slice ( subty) => {
736
- self . require_sized ( subty, traits:: SliceOrArrayElem ) ;
737
- }
738
-
739
- ty:: Array ( subty, _) => {
740
- self . require_sized ( subty, traits:: SliceOrArrayElem ) ;
741
- // Note that we handle the len is implicitly checked while walking `arg`.
742
- }
743
-
744
- ty:: Tuple ( ref tys) => {
745
- if let Some ( ( _last, rest) ) = tys. split_last ( ) {
746
- for & elem in rest {
747
- self . require_sized ( elem, traits:: TupleElem ) ;
748
- }
749
- }
750
- }
751
-
752
- ty:: RawPtr ( _) => {
753
- // Simple cases that are WF if their type args are WF.
754
- }
755
-
756
- ty:: Projection ( data) => {
757
- walker. skip_current_subtree ( ) ; // Subtree handled by compute_projection.
758
- self . compute_projection ( data) ;
759
- }
760
-
761
- ty:: Adt ( def, substs) => {
762
- // WfNominalType
763
- let obligations = self . nominal_obligations ( def. did ( ) , substs) ;
764
- self . out . extend ( obligations) ;
765
- }
766
-
767
- ty:: FnDef ( did, substs) => {
768
- let obligations = self . nominal_obligations ( did, substs) ;
769
- self . out . extend ( obligations) ;
770
- }
771
-
772
- ty:: Ref ( r, rty, _) => {
773
- // WfReference
774
- if !r. has_escaping_bound_vars ( ) && !rty. has_escaping_bound_vars ( ) {
775
- let cause = self . cause ( traits:: ReferenceOutlivesReferent ( ty) ) ;
776
- self . out . push ( traits:: Obligation :: with_depth (
777
- cause,
778
- depth,
779
- param_env,
780
- ty:: Binder :: dummy ( ty:: PredicateKind :: TypeOutlives (
781
- ty:: OutlivesPredicate ( rty, r) ,
782
- ) )
783
- . to_predicate ( self . tcx ( ) ) ,
784
- ) ) ;
785
- }
786
- }
787
-
788
- ty:: Generator ( did, substs, ..) => {
789
- // Walk ALL the types in the generator: this will
790
- // include the upvar types as well as the yield
791
- // type. Note that this is mildly distinct from
792
- // the closure case, where we have to be careful
793
- // about the signature of the closure. We don't
794
- // have the problem of implied bounds here since
795
- // generators don't take arguments.
796
- let obligations = self . nominal_obligations ( did, substs) ;
797
- self . out . extend ( obligations) ;
798
- }
799
-
800
- ty:: Closure ( did, substs) => {
801
- // Only check the upvar types for WF, not the rest
802
- // of the types within. This is needed because we
803
- // capture the signature and it may not be WF
804
- // without the implied bounds. Consider a closure
805
- // like `|x: &'a T|` -- it may be that `T: 'a` is
806
- // not known to hold in the creator's context (and
807
- // indeed the closure may not be invoked by its
808
- // creator, but rather turned to someone who *can*
809
- // verify that).
810
- //
811
- // The special treatment of closures here really
812
- // ought not to be necessary either; the problem
813
- // is related to #25860 -- there is no way for us
814
- // to express a fn type complete with the implied
815
- // bounds that it is assuming. I think in reality
816
- // the WF rules around fn are a bit messed up, and
817
- // that is the rot problem: `fn(&'a T)` should
818
- // probably always be WF, because it should be
819
- // shorthand for something like `where(T: 'a) {
820
- // fn(&'a T) }`, as discussed in #25860.
821
- walker. skip_current_subtree ( ) ; // subtree handled below
822
- // FIXME(eddyb) add the type to `walker` instead of recursing.
823
- self . compute ( substs. as_closure ( ) . tupled_upvars_ty ( ) . into ( ) ) ;
824
- // Note that we cannot skip the generic types
825
- // types. Normally, within the fn
826
- // body where they are created, the generics will
827
- // always be WF, and outside of that fn body we
828
- // are not directly inspecting closure types
829
- // anyway, except via auto trait matching (which
830
- // only inspects the upvar types).
831
- // But when a closure is part of a type-alias-impl-trait
832
- // then the function that created the defining site may
833
- // have had more bounds available than the type alias
834
- // specifies. This may cause us to have a closure in the
835
- // hidden type that is not actually well formed and
836
- // can cause compiler crashes when the user abuses unsafe
837
- // code to procure such a closure.
838
- // See src/test/ui/type-alias-impl-trait/wf_check_closures.rs
839
- let obligations = self . nominal_obligations ( did, substs) ;
840
- self . out . extend ( obligations) ;
841
- }
842
-
843
- ty:: FnPtr ( _) => {
844
- // let the loop iterate into the argument/return
845
- // types appearing in the fn signature
846
- }
847
-
848
- ty:: Opaque ( did, substs) => {
849
- // All of the requirements on type parameters
850
- // have already been checked for `impl Trait` in
851
- // return position. We do need to check type-alias-impl-trait though.
852
- if ty:: is_impl_trait_defn ( self . tcx , did) . is_none ( ) {
853
- let obligations = self . nominal_obligations ( did, substs) ;
854
- self . out . extend ( obligations) ;
855
- }
856
- }
857
-
858
- ty:: Dynamic ( data, r, _) => {
859
- // WfObject
860
- //
861
- // Here, we defer WF checking due to higher-ranked
862
- // regions. This is perhaps not ideal.
863
- self . from_object_ty ( ty, data, r) ;
864
-
865
- // FIXME(#27579) RFC also considers adding trait
866
- // obligations that don't refer to Self and
867
- // checking those
868
-
869
- let defer_to_coercion = self . tcx ( ) . features ( ) . object_safe_for_dispatch ;
870
-
871
- if !defer_to_coercion {
872
- let cause = self . cause ( traits:: WellFormed ( None ) ) ;
873
- let component_traits = data. auto_traits ( ) . chain ( data. principal_def_id ( ) ) ;
874
- let tcx = self . tcx ( ) ;
875
- self . out . extend ( component_traits. map ( |did| {
876
- traits:: Obligation :: with_depth (
877
- cause. clone ( ) ,
878
- depth,
879
- param_env,
880
- ty:: Binder :: dummy ( ty:: PredicateKind :: ObjectSafe ( did) )
881
- . to_predicate ( tcx) ,
882
- )
883
- } ) ) ;
884
- }
885
- }
886
-
887
- // Inference variables are the complicated case, since we don't
888
- // know what type they are. We do two things:
889
- //
890
- // 1. Check if they have been resolved, and if so proceed with
891
- // THAT type.
892
- // 2. If not, we've at least simplified things (e.g., we went
893
- // from `Vec<$0>: WF` to `$0: WF`), so we can
894
- // register a pending obligation and keep
895
- // moving. (Goal is that an "inductive hypothesis"
896
- // is satisfied to ensure termination.)
897
- // See also the comment on `fn obligations`, describing "livelock"
898
- // prevention, which happens before this can be reached.
899
- ty:: Infer ( _) => {
900
- let cause = self . cause ( traits:: WellFormed ( None ) ) ;
901
- self . out . push ( traits:: Obligation :: with_depth (
902
- cause,
903
- self . recursion_depth ,
904
- param_env,
905
- ty:: Binder :: dummy ( ty:: PredicateKind :: WellFormed ( ty. into ( ) ) )
906
- . to_predicate ( self . tcx ( ) ) ,
907
- ) ) ;
908
- }
909
-
910
- ty:: TyAlias ( did, substs) => {
911
- let obligations = self . nominal_obligations ( did, substs) ;
912
- self . out . extend ( obligations) ;
913
- }
914
- }
915
-
916
- debug ! ( ?self . out) ;
704
+ self . compute_ty ( ty, & mut walker, depth, param_env) ;
917
705
}
918
706
}
919
707
0 commit comments