@@ -4,7 +4,8 @@ use rustc_hir as hir;
44use rustc_hir:: def_id:: DefId ;
55use rustc_hir:: lang_items:: LangItem ;
66use 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 } ;
89use rustc_span:: Span ;
910
1011use std:: iter;
@@ -505,22 +506,24 @@ impl<'tcx> WfPredicates<'tcx> {
505506 cause,
506507 depth,
507508 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+ ) )
511512 . to_predicate ( self . tcx ( ) ) ,
512513 ) ) ;
513514 }
514515 }
515516
516- ty:: Generator ( ..) => {
517+ ty:: Generator ( did , substs , ..) => {
517518 // Walk ALL the types in the generator: this will
518519 // include the upvar types as well as the yield
519520 // type. Note that this is mildly distinct from
520521 // the closure case, where we have to be careful
521522 // about the signature of the closure. We don't
522523 // have the problem of implied bounds here since
523524 // generators don't take arguments.
525+ let obligations = self . nominal_obligations ( did, substs) ;
526+ self . out . extend ( obligations) ;
524527 }
525528
526529 ty:: Closure ( did, substs) => {
@@ -572,18 +575,16 @@ impl<'tcx> WfPredicates<'tcx> {
572575 }
573576
574577 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 ( ) {
581582 let obligations = self . nominal_obligations ( did, substs) ;
582583 self . out . extend ( obligations) ;
583584 }
584585 }
585586
586- ty:: Dynamic ( data, r) => {
587+ ty:: Dynamic ( data, r, _ ) => {
587588 // WfObject
588589 //
589590 // Here, we defer WF checking due to higher-ranked
@@ -605,7 +606,8 @@ impl<'tcx> WfPredicates<'tcx> {
605606 cause. clone ( ) ,
606607 depth,
607608 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) ,
609611 )
610612 } ) ) ;
611613 }
@@ -624,22 +626,14 @@ impl<'tcx> WfPredicates<'tcx> {
624626 // See also the comment on `fn obligations`, describing "livelock"
625627 // prevention, which happens before this can be reached.
626628 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+ ) ) ;
643637 }
644638
645639 ty:: TyAlias ( def_id, substs) => {
@@ -707,213 +701,7 @@ impl<'tcx> WfPredicates<'tcx> {
707701 }
708702 } ;
709703
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) ;
917705 }
918706 }
919707
0 commit comments