Skip to content

Commit 4815a60

Browse files
Improve code
1 parent 29d628c commit 4815a60

File tree

3 files changed

+30
-240
lines changed

3 files changed

+30
-240
lines changed

compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_hir as hir;
1212
use rustc_hir::def::DefKind;
1313
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
1414
use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams};
15-
use rustc_middle::ty::{self, CrateInherentImpls, Subst, Ty, TyCtxt};
15+
use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt};
1616
use rustc_span::symbol::sym;
1717
use rustc_span::Span;
1818

compiler/rustc_hir_analysis/src/variance/constraints.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use hir::def_id::{DefId, LocalDefId};
77
use rustc_hir as hir;
88
use rustc_hir::def::DefKind;
99
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
10-
use rustc_middle::ty::{self, Ty, TyCtxt};
10+
use rustc_middle::ty::{self, Subst, Ty, TyCtxt};
1111

1212
use super::terms::VarianceTerm::*;
1313
use super::terms::*;
@@ -257,8 +257,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
257257
self.add_constraints_from_invariant_substs(current, substs, variance);
258258
}
259259

260-
ty::TyAlias(_, substs) => {
261-
self.add_constraints_from_invariant_substs(current, substs, variance);
260+
ty::TyAlias(def_id, substs) => {
261+
let binder_ty = self.tcx().bound_type_of(def_id);
262+
let ty = binder_ty.subst(self.tcx(), substs);
263+
self.add_constraints_from_ty(current, ty, variance);
262264
}
263265

264266
ty::Dynamic(data, r, _) => {

compiler/rustc_trait_selection/src/traits/wf.rs

+24-236
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use rustc_hir as hir;
44
use rustc_hir::def_id::DefId;
55
use rustc_hir::lang_items::LangItem;
66
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};
89
use rustc_span::Span;
910

1011
use 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

Comments
 (0)