Auto merge of #76244 - vandenheuvel:remove__paramenv__def_id, r=nikomatsakis
Removing the `def_id` field from hot `ParamEnv` to make it smaller This PR addresses https://github.com/rust-lang/rust/issues/74865.
This commit is contained in:
commit
7402a39447
35 changed files with 288 additions and 337 deletions
|
@ -26,7 +26,8 @@ pub fn explicit_outlives_bounds<'tcx>(
|
||||||
| ty::PredicateAtom::ClosureKind(..)
|
| ty::PredicateAtom::ClosureKind(..)
|
||||||
| ty::PredicateAtom::TypeOutlives(..)
|
| ty::PredicateAtom::TypeOutlives(..)
|
||||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||||
| ty::PredicateAtom::ConstEquate(..) => None,
|
| ty::PredicateAtom::ConstEquate(..)
|
||||||
|
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => None,
|
||||||
ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
|
ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
|
||||||
Some(OutlivesBound::RegionSubRegion(r_b, r_a))
|
Some(OutlivesBound::RegionSubRegion(r_b, r_a))
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
|
||||||
|
|
||||||
// `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
|
// `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
static_assert_size!(PredicateObligation<'_>, 40);
|
static_assert_size!(PredicateObligation<'_>, 32);
|
||||||
|
|
||||||
pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
|
pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
|
||||||
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
|
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
|
||||||
|
|
|
@ -236,6 +236,9 @@ impl Elaborator<'tcx> {
|
||||||
.map(|predicate| predicate_obligation(predicate, None)),
|
.map(|predicate| predicate_obligation(predicate, None)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
|
||||||
|
// Nothing to elaborate
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1228,7 +1228,8 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
|
||||||
ClosureKind(..) |
|
ClosureKind(..) |
|
||||||
Subtype(..) |
|
Subtype(..) |
|
||||||
ConstEvaluatable(..) |
|
ConstEvaluatable(..) |
|
||||||
ConstEquate(..) => continue,
|
ConstEquate(..) |
|
||||||
|
TypeWellFormedFromEnv(..) => continue,
|
||||||
};
|
};
|
||||||
if predicate.is_global() {
|
if predicate.is_global() {
|
||||||
cx.struct_span_lint(TRIVIAL_BOUNDS, span, |lint| {
|
cx.struct_span_lint(TRIVIAL_BOUNDS, span, |lint| {
|
||||||
|
|
|
@ -1399,7 +1399,7 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
|
|
||||||
query evaluate_goal(
|
query evaluate_goal(
|
||||||
goal: traits::ChalkCanonicalGoal<'tcx>
|
goal: traits::CanonicalChalkEnvironmentAndGoal<'tcx>
|
||||||
) -> Result<
|
) -> Result<
|
||||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
|
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
|
||||||
NoSolution
|
NoSolution
|
||||||
|
|
|
@ -6,14 +6,11 @@
|
||||||
//! interned Chalk types.
|
//! interned Chalk types.
|
||||||
|
|
||||||
use rustc_middle::mir::interpret::ConstValue;
|
use rustc_middle::mir::interpret::ConstValue;
|
||||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
use rustc_middle::ty::{self, AdtDef, TyCtxt};
|
||||||
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
|
|
||||||
|
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
use smallvec::SmallVec;
|
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
@ -376,31 +373,10 @@ impl<'tcx> chalk_ir::interner::HasInterner for RustInterner<'tcx> {
|
||||||
type Interner = Self;
|
type Interner = Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
|
/// A chalk environment and goal.
|
||||||
pub enum ChalkEnvironmentClause<'tcx> {
|
|
||||||
/// A normal rust `ty::Predicate` in the environment.
|
|
||||||
Predicate(ty::Predicate<'tcx>),
|
|
||||||
/// A special clause in the environment that gets lowered to
|
|
||||||
/// `chalk_ir::FromEnv::Ty`.
|
|
||||||
TypeFromEnv(Ty<'tcx>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ChalkEnvironmentClause<'tcx>> {
|
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
|
||||||
let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
|
|
||||||
folder.tcx().intern_chalk_environment_clause_list(&v)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.iter().any(|t| t.visit_with(visitor))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// We have to elaborate the environment of a chalk goal *before*
|
|
||||||
/// canonicalization. This type wraps the predicate and the elaborated
|
|
||||||
/// environment.
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
|
||||||
pub struct ChalkEnvironmentAndGoal<'tcx> {
|
pub struct ChalkEnvironmentAndGoal<'tcx> {
|
||||||
pub environment: &'tcx ty::List<ChalkEnvironmentClause<'tcx>>,
|
pub environment: &'tcx ty::List<ty::Predicate<'tcx>>,
|
||||||
pub goal: ty::Predicate<'tcx>,
|
pub goal: ty::Predicate<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,14 +26,12 @@ use std::rc::Rc;
|
||||||
|
|
||||||
pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
|
pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
|
||||||
|
|
||||||
pub type ChalkCanonicalGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx>>;
|
pub type CanonicalChalkEnvironmentAndGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx>>;
|
||||||
|
|
||||||
pub use self::ImplSource::*;
|
pub use self::ImplSource::*;
|
||||||
pub use self::ObligationCauseCode::*;
|
pub use self::ObligationCauseCode::*;
|
||||||
|
|
||||||
pub use self::chalk::{
|
pub use self::chalk::{ChalkEnvironmentAndGoal, RustInterner as ChalkRustInterner};
|
||||||
ChalkEnvironmentAndGoal, ChalkEnvironmentClause, RustInterner as ChalkRustInterner,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Depending on the stage of compilation, we want projection to be
|
/// Depending on the stage of compilation, we want projection to be
|
||||||
/// more or less conservative.
|
/// more or less conservative.
|
||||||
|
|
|
@ -91,8 +91,6 @@ pub struct CtxtInterners<'tcx> {
|
||||||
projs: InternedSet<'tcx, List<ProjectionKind>>,
|
projs: InternedSet<'tcx, List<ProjectionKind>>,
|
||||||
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
|
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
|
||||||
const_: InternedSet<'tcx, Const<'tcx>>,
|
const_: InternedSet<'tcx, Const<'tcx>>,
|
||||||
|
|
||||||
chalk_environment_clause_list: InternedSet<'tcx, List<traits::ChalkEnvironmentClause<'tcx>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> CtxtInterners<'tcx> {
|
impl<'tcx> CtxtInterners<'tcx> {
|
||||||
|
@ -110,7 +108,6 @@ impl<'tcx> CtxtInterners<'tcx> {
|
||||||
projs: Default::default(),
|
projs: Default::default(),
|
||||||
place_elems: Default::default(),
|
place_elems: Default::default(),
|
||||||
const_: Default::default(),
|
const_: Default::default(),
|
||||||
chalk_environment_clause_list: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2041,7 +2038,7 @@ direct_interners! {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! slice_interners {
|
macro_rules! slice_interners {
|
||||||
($($field:ident: $method:ident($ty:ty)),+) => (
|
($($field:ident: $method:ident($ty:ty)),+ $(,)?) => (
|
||||||
$(impl<'tcx> TyCtxt<'tcx> {
|
$(impl<'tcx> TyCtxt<'tcx> {
|
||||||
pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
|
pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
|
||||||
self.interners.$field.intern_ref(v, || {
|
self.interners.$field.intern_ref(v, || {
|
||||||
|
@ -2060,8 +2057,6 @@ slice_interners!(
|
||||||
predicates: _intern_predicates(Predicate<'tcx>),
|
predicates: _intern_predicates(Predicate<'tcx>),
|
||||||
projs: _intern_projs(ProjectionKind),
|
projs: _intern_projs(ProjectionKind),
|
||||||
place_elems: _intern_place_elems(PlaceElem<'tcx>),
|
place_elems: _intern_place_elems(PlaceElem<'tcx>),
|
||||||
chalk_environment_clause_list:
|
|
||||||
_intern_chalk_environment_clause_list(traits::ChalkEnvironmentClause<'tcx>)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
impl<'tcx> TyCtxt<'tcx> {
|
impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
@ -2460,13 +2455,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
|
if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intern_chalk_environment_clause_list(
|
|
||||||
self,
|
|
||||||
ts: &[traits::ChalkEnvironmentClause<'tcx>],
|
|
||||||
) -> &'tcx List<traits::ChalkEnvironmentClause<'tcx>> {
|
|
||||||
if ts.is_empty() { List::empty() } else { self._intern_chalk_environment_clause_list(ts) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mk_fn_sig<I>(
|
pub fn mk_fn_sig<I>(
|
||||||
self,
|
self,
|
||||||
inputs: I,
|
inputs: I,
|
||||||
|
@ -2524,18 +2512,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
|
self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_chalk_environment_clause_list<
|
|
||||||
I: InternAs<
|
|
||||||
[traits::ChalkEnvironmentClause<'tcx>],
|
|
||||||
&'tcx List<traits::ChalkEnvironmentClause<'tcx>>,
|
|
||||||
>,
|
|
||||||
>(
|
|
||||||
self,
|
|
||||||
iter: I,
|
|
||||||
) -> I::Output {
|
|
||||||
iter.intern_with(|xs| self.intern_chalk_environment_clause_list(xs))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Walks upwards from `id` to find a node which might change lint levels with attributes.
|
/// Walks upwards from `id` to find a node which might change lint levels with attributes.
|
||||||
/// It stops at `bound` and just returns it if reached.
|
/// It stops at `bound` and just returns it if reached.
|
||||||
pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
|
pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
|
||||||
|
|
|
@ -249,6 +249,9 @@ impl FlagComputation {
|
||||||
self.add_const(expected);
|
self.add_const(expected);
|
||||||
self.add_const(found);
|
self.add_const(found);
|
||||||
}
|
}
|
||||||
|
ty::PredicateAtom::TypeWellFormedFromEnv(ty) => {
|
||||||
|
self.add_ty(ty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1155,6 +1155,11 @@ pub enum PredicateAtom<'tcx> {
|
||||||
|
|
||||||
/// Constants must be equal. The first component is the const that is expected.
|
/// Constants must be equal. The first component is the const that is expected.
|
||||||
ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>),
|
ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>),
|
||||||
|
|
||||||
|
/// Represents a type found in the environment that we can use for implied bounds.
|
||||||
|
///
|
||||||
|
/// Only used for Chalk.
|
||||||
|
TypeWellFormedFromEnv(Ty<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> PredicateAtom<'tcx> {
|
impl<'tcx> PredicateAtom<'tcx> {
|
||||||
|
@ -1450,7 +1455,8 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
| PredicateAtom::ClosureKind(..)
|
| PredicateAtom::ClosureKind(..)
|
||||||
| PredicateAtom::TypeOutlives(..)
|
| PredicateAtom::TypeOutlives(..)
|
||||||
| PredicateAtom::ConstEvaluatable(..)
|
| PredicateAtom::ConstEvaluatable(..)
|
||||||
| PredicateAtom::ConstEquate(..) => None,
|
| PredicateAtom::ConstEquate(..)
|
||||||
|
| PredicateAtom::TypeWellFormedFromEnv(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1465,7 +1471,8 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
| PredicateAtom::ObjectSafe(..)
|
| PredicateAtom::ObjectSafe(..)
|
||||||
| PredicateAtom::ClosureKind(..)
|
| PredicateAtom::ClosureKind(..)
|
||||||
| PredicateAtom::ConstEvaluatable(..)
|
| PredicateAtom::ConstEvaluatable(..)
|
||||||
| PredicateAtom::ConstEquate(..) => None,
|
| PredicateAtom::ConstEquate(..)
|
||||||
|
| PredicateAtom::TypeWellFormedFromEnv(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1738,11 +1745,6 @@ pub struct ParamEnv<'tcx> {
|
||||||
///
|
///
|
||||||
/// Note: This is packed, use the reveal() method to access it.
|
/// Note: This is packed, use the reveal() method to access it.
|
||||||
packed: CopyTaggedPtr<&'tcx List<Predicate<'tcx>>, traits::Reveal, true>,
|
packed: CopyTaggedPtr<&'tcx List<Predicate<'tcx>>, traits::Reveal, true>,
|
||||||
|
|
||||||
/// If this `ParamEnv` comes from a call to `tcx.param_env(def_id)`,
|
|
||||||
/// register that `def_id` (useful for transitioning to the chalk trait
|
|
||||||
/// solver).
|
|
||||||
pub def_id: Option<DefId>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl rustc_data_structures::tagged_ptr::Tag for traits::Reveal {
|
unsafe impl rustc_data_structures::tagged_ptr::Tag for traits::Reveal {
|
||||||
|
@ -1767,7 +1769,6 @@ impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
|
||||||
f.debug_struct("ParamEnv")
|
f.debug_struct("ParamEnv")
|
||||||
.field("caller_bounds", &self.caller_bounds())
|
.field("caller_bounds", &self.caller_bounds())
|
||||||
.field("reveal", &self.reveal())
|
.field("reveal", &self.reveal())
|
||||||
.field("def_id", &self.def_id)
|
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1776,23 +1777,16 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
|
||||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||||
self.caller_bounds().hash_stable(hcx, hasher);
|
self.caller_bounds().hash_stable(hcx, hasher);
|
||||||
self.reveal().hash_stable(hcx, hasher);
|
self.reveal().hash_stable(hcx, hasher);
|
||||||
self.def_id.hash_stable(hcx, hasher);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
|
||||||
fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||||
ParamEnv::new(
|
ParamEnv::new(self.caller_bounds().fold_with(folder), self.reveal().fold_with(folder))
|
||||||
self.caller_bounds().fold_with(folder),
|
|
||||||
self.reveal().fold_with(folder),
|
|
||||||
self.def_id.fold_with(folder),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||||
self.caller_bounds().visit_with(visitor)
|
self.caller_bounds().visit_with(visitor) || self.reveal().visit_with(visitor)
|
||||||
|| self.reveal().visit_with(visitor)
|
|
||||||
|| self.def_id.visit_with(visitor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1803,7 +1797,7 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||||
/// type-checking.
|
/// type-checking.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
Self::new(List::empty(), Reveal::UserFacing, None)
|
Self::new(List::empty(), Reveal::UserFacing)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1825,17 +1819,13 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||||
/// or invoke `param_env.with_reveal_all()`.
|
/// or invoke `param_env.with_reveal_all()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn reveal_all() -> Self {
|
pub fn reveal_all() -> Self {
|
||||||
Self::new(List::empty(), Reveal::All, None)
|
Self::new(List::empty(), Reveal::All)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a trait environment with the given set of predicates.
|
/// Construct a trait environment with the given set of predicates.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(
|
pub fn new(caller_bounds: &'tcx List<Predicate<'tcx>>, reveal: Reveal) -> Self {
|
||||||
caller_bounds: &'tcx List<Predicate<'tcx>>,
|
ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, reveal) }
|
||||||
reveal: Reveal,
|
|
||||||
def_id: Option<DefId>,
|
|
||||||
) -> Self {
|
|
||||||
ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, reveal), def_id }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_user_facing(mut self) -> Self {
|
pub fn with_user_facing(mut self) -> Self {
|
||||||
|
@ -1857,12 +1847,12 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParamEnv::new(tcx.normalize_opaque_types(self.caller_bounds()), Reveal::All, self.def_id)
|
ParamEnv::new(tcx.normalize_opaque_types(self.caller_bounds()), Reveal::All)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns this same environment but with no caller bounds.
|
/// Returns this same environment but with no caller bounds.
|
||||||
pub fn without_caller_bounds(self) -> Self {
|
pub fn without_caller_bounds(self) -> Self {
|
||||||
Self::new(List::empty(), self.reveal(), self.def_id)
|
Self::new(List::empty(), self.reveal())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a suitable environment in which to perform trait
|
/// Creates a suitable environment in which to perform trait
|
||||||
|
|
|
@ -2096,6 +2096,11 @@ define_print_and_forward_display! {
|
||||||
print(c2),
|
print(c2),
|
||||||
write("`"))
|
write("`"))
|
||||||
}
|
}
|
||||||
|
ty::PredicateAtom::TypeWellFormedFromEnv(ty) => {
|
||||||
|
p!(write("the type `"),
|
||||||
|
print(ty),
|
||||||
|
write("` is found in the environment"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,6 +260,9 @@ impl fmt::Debug for ty::PredicateAtom<'tcx> {
|
||||||
write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs)
|
write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs)
|
||||||
}
|
}
|
||||||
ty::PredicateAtom::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2),
|
ty::PredicateAtom::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2),
|
||||||
|
ty::PredicateAtom::TypeWellFormedFromEnv(ty) => {
|
||||||
|
write!(f, "TypeWellFormedFromEnv({:?})", ty)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -536,6 +539,9 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateAtom<'a> {
|
||||||
ty::PredicateAtom::ConstEquate(c1, c2) => {
|
ty::PredicateAtom::ConstEquate(c1, c2) => {
|
||||||
tcx.lift(&(c1, c2)).map(|(c1, c2)| ty::PredicateAtom::ConstEquate(c1, c2))
|
tcx.lift(&(c1, c2)).map(|(c1, c2)| ty::PredicateAtom::ConstEquate(c1, c2))
|
||||||
}
|
}
|
||||||
|
ty::PredicateAtom::TypeWellFormedFromEnv(ty) => {
|
||||||
|
tcx.lift(&ty).map(ty::PredicateAtom::TypeWellFormedFromEnv)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -551,7 +557,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
|
||||||
type Lifted = ty::ParamEnv<'tcx>;
|
type Lifted = ty::ParamEnv<'tcx>;
|
||||||
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||||
tcx.lift(&self.caller_bounds())
|
tcx.lift(&self.caller_bounds())
|
||||||
.map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.def_id))
|
.map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,8 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
|
||||||
| ty::PredicateAtom::WellFormed(_)
|
| ty::PredicateAtom::WellFormed(_)
|
||||||
| ty::PredicateAtom::Projection(_)
|
| ty::PredicateAtom::Projection(_)
|
||||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||||
| ty::PredicateAtom::ConstEquate(..) => continue,
|
| ty::PredicateAtom::ConstEquate(..)
|
||||||
|
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => continue,
|
||||||
ty::PredicateAtom::ObjectSafe(_) => {
|
ty::PredicateAtom::ObjectSafe(_) => {
|
||||||
bug!("object safe predicate on function: {:#?}", predicate)
|
bug!("object safe predicate on function: {:#?}", predicate)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1261,7 +1261,8 @@ crate fn required_region_bounds(
|
||||||
| ty::PredicateAtom::ClosureKind(..)
|
| ty::PredicateAtom::ClosureKind(..)
|
||||||
| ty::PredicateAtom::RegionOutlives(..)
|
| ty::PredicateAtom::RegionOutlives(..)
|
||||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||||
| ty::PredicateAtom::ConstEquate(..) => None,
|
| ty::PredicateAtom::ConstEquate(..)
|
||||||
|
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => None,
|
||||||
ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => {
|
ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => {
|
||||||
// Search for a bound of the form `erased_self_ty
|
// Search for a bound of the form `erased_self_ty
|
||||||
// : 'a`, but be wary of something like `for<'a>
|
// : 'a`, but be wary of something like `for<'a>
|
||||||
|
|
|
@ -373,14 +373,12 @@ impl AutoTraitFinder<'tcx> {
|
||||||
computed_preds.clone().chain(user_computed_preds.iter().cloned()),
|
computed_preds.clone().chain(user_computed_preds.iter().cloned()),
|
||||||
)
|
)
|
||||||
.map(|o| o.predicate);
|
.map(|o| o.predicate);
|
||||||
new_env =
|
new_env = ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal());
|
||||||
ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal(), None);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let final_user_env = ty::ParamEnv::new(
|
let final_user_env = ty::ParamEnv::new(
|
||||||
tcx.mk_predicates(user_computed_preds.into_iter()),
|
tcx.mk_predicates(user_computed_preds.into_iter()),
|
||||||
user_env.reveal(),
|
user_env.reveal(),
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
debug!(
|
debug!(
|
||||||
"evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \
|
"evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \
|
||||||
|
|
|
@ -4,12 +4,11 @@ use crate::infer::canonical::OriginalQueryValues;
|
||||||
use crate::infer::InferCtxt;
|
use crate::infer::InferCtxt;
|
||||||
use crate::traits::query::NoSolution;
|
use crate::traits::query::NoSolution;
|
||||||
use crate::traits::{
|
use crate::traits::{
|
||||||
ChalkEnvironmentAndGoal, ChalkEnvironmentClause, FulfillmentError, FulfillmentErrorCode,
|
ChalkEnvironmentAndGoal, FulfillmentError, FulfillmentErrorCode, ObligationCause,
|
||||||
ObligationCause, PredicateObligation, SelectionError, TraitEngine,
|
PredicateObligation, SelectionError, TraitEngine,
|
||||||
};
|
};
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
|
||||||
|
|
||||||
pub struct FulfillmentContext<'tcx> {
|
pub struct FulfillmentContext<'tcx> {
|
||||||
obligations: FxIndexSet<PredicateObligation<'tcx>>,
|
obligations: FxIndexSet<PredicateObligation<'tcx>>,
|
||||||
|
@ -21,132 +20,6 @@ impl FulfillmentContext<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn environment<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
def_id: DefId,
|
|
||||||
) -> &'tcx ty::List<ChalkEnvironmentClause<'tcx>> {
|
|
||||||
use rustc_hir::{ForeignItemKind, ImplItemKind, ItemKind, Node, TraitItemKind};
|
|
||||||
use rustc_middle::ty::subst::GenericArgKind;
|
|
||||||
|
|
||||||
debug!("environment(def_id = {:?})", def_id);
|
|
||||||
|
|
||||||
// The environment of an impl Trait type is its defining function's environment.
|
|
||||||
if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
|
|
||||||
return environment(tcx, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the bounds on `Self` and the type parameters.
|
|
||||||
let ty::InstantiatedPredicates { predicates, .. } =
|
|
||||||
tcx.predicates_of(def_id).instantiate_identity(tcx);
|
|
||||||
|
|
||||||
let clauses = predicates.into_iter().map(ChalkEnvironmentClause::Predicate);
|
|
||||||
|
|
||||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
|
||||||
let node = tcx.hir().get(hir_id);
|
|
||||||
|
|
||||||
enum NodeKind {
|
|
||||||
TraitImpl,
|
|
||||||
InherentImpl,
|
|
||||||
Fn,
|
|
||||||
Other,
|
|
||||||
};
|
|
||||||
|
|
||||||
let node_kind = match node {
|
|
||||||
Node::TraitItem(item) => match item.kind {
|
|
||||||
TraitItemKind::Fn(..) => NodeKind::Fn,
|
|
||||||
_ => NodeKind::Other,
|
|
||||||
},
|
|
||||||
|
|
||||||
Node::ImplItem(item) => match item.kind {
|
|
||||||
ImplItemKind::Fn(..) => NodeKind::Fn,
|
|
||||||
_ => NodeKind::Other,
|
|
||||||
},
|
|
||||||
|
|
||||||
Node::Item(item) => match item.kind {
|
|
||||||
ItemKind::Impl { of_trait: Some(_), .. } => NodeKind::TraitImpl,
|
|
||||||
ItemKind::Impl { of_trait: None, .. } => NodeKind::InherentImpl,
|
|
||||||
ItemKind::Fn(..) => NodeKind::Fn,
|
|
||||||
_ => NodeKind::Other,
|
|
||||||
},
|
|
||||||
|
|
||||||
Node::ForeignItem(item) => match item.kind {
|
|
||||||
ForeignItemKind::Fn(..) => NodeKind::Fn,
|
|
||||||
_ => NodeKind::Other,
|
|
||||||
},
|
|
||||||
|
|
||||||
// FIXME: closures?
|
|
||||||
_ => NodeKind::Other,
|
|
||||||
};
|
|
||||||
|
|
||||||
// FIXME(eddyb) isn't the unordered nature of this a hazard?
|
|
||||||
let mut inputs = FxIndexSet::default();
|
|
||||||
|
|
||||||
match node_kind {
|
|
||||||
// In a trait impl, we assume that the header trait ref and all its
|
|
||||||
// constituents are well-formed.
|
|
||||||
NodeKind::TraitImpl => {
|
|
||||||
let trait_ref = tcx.impl_trait_ref(def_id).expect("not an impl");
|
|
||||||
|
|
||||||
// FIXME(chalk): this has problems because of late-bound regions
|
|
||||||
//inputs.extend(trait_ref.substs.iter().flat_map(|arg| arg.walk()));
|
|
||||||
inputs.extend(trait_ref.substs.iter());
|
|
||||||
}
|
|
||||||
|
|
||||||
// In an inherent impl, we assume that the receiver type and all its
|
|
||||||
// constituents are well-formed.
|
|
||||||
NodeKind::InherentImpl => {
|
|
||||||
let self_ty = tcx.type_of(def_id);
|
|
||||||
inputs.extend(self_ty.walk());
|
|
||||||
}
|
|
||||||
|
|
||||||
// In an fn, we assume that the arguments and all their constituents are
|
|
||||||
// well-formed.
|
|
||||||
NodeKind::Fn => {
|
|
||||||
let fn_sig = tcx.fn_sig(def_id);
|
|
||||||
let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig);
|
|
||||||
|
|
||||||
inputs.extend(fn_sig.inputs().iter().flat_map(|ty| ty.walk()));
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeKind::Other => (),
|
|
||||||
}
|
|
||||||
let input_clauses = inputs.into_iter().filter_map(|arg| {
|
|
||||||
match arg.unpack() {
|
|
||||||
GenericArgKind::Type(ty) => Some(ChalkEnvironmentClause::TypeFromEnv(ty)),
|
|
||||||
|
|
||||||
// FIXME(eddyb) no WF conditions from lifetimes?
|
|
||||||
GenericArgKind::Lifetime(_) => None,
|
|
||||||
|
|
||||||
// FIXME(eddyb) support const generics in Chalk
|
|
||||||
GenericArgKind::Const(_) => None,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
tcx.mk_chalk_environment_clause_list(clauses.chain(input_clauses))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// We need to wrap a `ty::Predicate` in an elaborated environment *before* we
|
|
||||||
/// canonicalize. This is due to the fact that we insert extra clauses into the
|
|
||||||
/// environment for all input types (`FromEnv`).
|
|
||||||
fn in_environment(
|
|
||||||
infcx: &InferCtxt<'_, 'tcx>,
|
|
||||||
obligation: &PredicateObligation<'tcx>,
|
|
||||||
) -> ChalkEnvironmentAndGoal<'tcx> {
|
|
||||||
assert!(!infcx.is_in_snapshot());
|
|
||||||
let obligation = infcx.resolve_vars_if_possible(obligation);
|
|
||||||
|
|
||||||
let environment = match obligation.param_env.def_id {
|
|
||||||
Some(def_id) => environment(infcx.tcx, def_id),
|
|
||||||
None if obligation.param_env.caller_bounds().is_empty() => ty::List::empty(),
|
|
||||||
// FIXME(chalk): this is hit in ui/where-clauses/where-clause-constraints-are-local-for-trait-impl
|
|
||||||
// and ui/generics/generic-static-methods
|
|
||||||
//_ => bug!("non-empty `ParamEnv` with no def-id"),
|
|
||||||
_ => ty::List::empty(),
|
|
||||||
};
|
|
||||||
|
|
||||||
ChalkEnvironmentAndGoal { environment, goal: obligation.predicate }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
||||||
fn normalize_projection_type(
|
fn normalize_projection_type(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -195,6 +68,8 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
infcx: &InferCtxt<'_, 'tcx>,
|
infcx: &InferCtxt<'_, 'tcx>,
|
||||||
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
|
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
|
||||||
|
assert!(!infcx.is_in_snapshot());
|
||||||
|
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
let mut next_round = FxIndexSet::default();
|
let mut next_round = FxIndexSet::default();
|
||||||
let mut making_progress;
|
let mut making_progress;
|
||||||
|
@ -205,10 +80,11 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
||||||
// We iterate over all obligations, and record if we are able
|
// We iterate over all obligations, and record if we are able
|
||||||
// to unambiguously prove at least one obligation.
|
// to unambiguously prove at least one obligation.
|
||||||
for obligation in self.obligations.drain(..) {
|
for obligation in self.obligations.drain(..) {
|
||||||
let goal_in_environment = in_environment(infcx, &obligation);
|
let obligation = infcx.resolve_vars_if_possible(&obligation);
|
||||||
|
let environment = obligation.param_env.caller_bounds();
|
||||||
|
let goal = ChalkEnvironmentAndGoal { environment, goal: obligation.predicate };
|
||||||
let mut orig_values = OriginalQueryValues::default();
|
let mut orig_values = OriginalQueryValues::default();
|
||||||
let canonical_goal =
|
let canonical_goal = infcx.canonicalize_query(&goal, &mut orig_values);
|
||||||
infcx.canonicalize_query(&goal_in_environment, &mut orig_values);
|
|
||||||
|
|
||||||
match infcx.tcx.evaluate_goal(canonical_goal) {
|
match infcx.tcx.evaluate_goal(canonical_goal) {
|
||||||
Ok(response) => {
|
Ok(response) => {
|
||||||
|
|
|
@ -663,6 +663,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
obligation
|
obligation
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ty::PredicateAtom::TypeWellFormedFromEnv(..) => span_bug!(
|
||||||
|
span,
|
||||||
|
"TypeWellFormedFromEnv predicate should only exist in the environment"
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ pub struct PendingPredicateObligation<'tcx> {
|
||||||
|
|
||||||
// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
|
// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
static_assert_size!(PendingPredicateObligation<'_>, 64);
|
static_assert_size!(PendingPredicateObligation<'_>, 56);
|
||||||
|
|
||||||
impl<'a, 'tcx> FulfillmentContext<'tcx> {
|
impl<'a, 'tcx> FulfillmentContext<'tcx> {
|
||||||
/// Creates a new fulfillment context.
|
/// Creates a new fulfillment context.
|
||||||
|
@ -355,6 +355,9 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
||||||
obligation.with(pred.to_predicate(self.selcx.tcx())),
|
obligation.with(pred.to_predicate(self.selcx.tcx())),
|
||||||
]))
|
]))
|
||||||
}
|
}
|
||||||
|
ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
|
||||||
|
bug!("TypeWellFormedFromEnv is only used for Chalk")
|
||||||
|
}
|
||||||
},
|
},
|
||||||
&ty::PredicateKind::Atom(atom) => match atom {
|
&ty::PredicateKind::Atom(atom) => match atom {
|
||||||
ty::PredicateAtom::Trait(ref data, _) => {
|
ty::PredicateAtom::Trait(ref data, _) => {
|
||||||
|
@ -536,6 +539,9 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
|
||||||
|
bug!("TypeWellFormedFromEnv is only used for Chalk")
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,11 +302,8 @@ pub fn normalize_param_env_or_error<'tcx>(
|
||||||
|
|
||||||
debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
|
debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
|
||||||
|
|
||||||
let elaborated_env = ty::ParamEnv::new(
|
let elaborated_env =
|
||||||
tcx.intern_predicates(&predicates),
|
ty::ParamEnv::new(tcx.intern_predicates(&predicates), unnormalized_env.reveal());
|
||||||
unnormalized_env.reveal(),
|
|
||||||
unnormalized_env.def_id,
|
|
||||||
);
|
|
||||||
|
|
||||||
// HACK: we are trying to normalize the param-env inside *itself*. The problem is that
|
// HACK: we are trying to normalize the param-env inside *itself*. The problem is that
|
||||||
// normalization expects its param-env to be already normalized, which means we have
|
// normalization expects its param-env to be already normalized, which means we have
|
||||||
|
@ -360,7 +357,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
||||||
let outlives_env: Vec<_> =
|
let outlives_env: Vec<_> =
|
||||||
non_outlives_predicates.iter().chain(&outlives_predicates).cloned().collect();
|
non_outlives_predicates.iter().chain(&outlives_predicates).cloned().collect();
|
||||||
let outlives_env =
|
let outlives_env =
|
||||||
ty::ParamEnv::new(tcx.intern_predicates(&outlives_env), unnormalized_env.reveal(), None);
|
ty::ParamEnv::new(tcx.intern_predicates(&outlives_env), unnormalized_env.reveal());
|
||||||
let outlives_predicates = match do_normalize_predicates(
|
let outlives_predicates = match do_normalize_predicates(
|
||||||
tcx,
|
tcx,
|
||||||
region_context,
|
region_context,
|
||||||
|
@ -380,11 +377,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
||||||
let mut predicates = non_outlives_predicates;
|
let mut predicates = non_outlives_predicates;
|
||||||
predicates.extend(outlives_predicates);
|
predicates.extend(outlives_predicates);
|
||||||
debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
|
debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
|
||||||
ty::ParamEnv::new(
|
ty::ParamEnv::new(tcx.intern_predicates(&predicates), unnormalized_env.reveal())
|
||||||
tcx.intern_predicates(&predicates),
|
|
||||||
unnormalized_env.reveal(),
|
|
||||||
unnormalized_env.def_id,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fully_normalize<'a, 'tcx, T>(
|
pub fn fully_normalize<'a, 'tcx, T>(
|
||||||
|
|
|
@ -276,7 +276,8 @@ fn predicates_reference_self(
|
||||||
| ty::PredicateAtom::ClosureKind(..)
|
| ty::PredicateAtom::ClosureKind(..)
|
||||||
| ty::PredicateAtom::Subtype(..)
|
| ty::PredicateAtom::Subtype(..)
|
||||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||||
| ty::PredicateAtom::ConstEquate(..) => None,
|
| ty::PredicateAtom::ConstEquate(..)
|
||||||
|
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -310,7 +311,8 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
| ty::PredicateAtom::ClosureKind(..)
|
| ty::PredicateAtom::ClosureKind(..)
|
||||||
| ty::PredicateAtom::TypeOutlives(..)
|
| ty::PredicateAtom::TypeOutlives(..)
|
||||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||||
| ty::PredicateAtom::ConstEquate(..) => false,
|
| ty::PredicateAtom::ConstEquate(..)
|
||||||
|
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => false,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -654,11 +656,7 @@ fn receiver_is_dispatchable<'tcx>(
|
||||||
.chain(iter::once(trait_predicate))
|
.chain(iter::once(trait_predicate))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
ty::ParamEnv::new(
|
ty::ParamEnv::new(tcx.intern_predicates(&caller_bounds), param_env.reveal())
|
||||||
tcx.intern_predicates(&caller_bounds),
|
|
||||||
param_env.reveal(),
|
|
||||||
param_env.def_id,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Receiver: DispatchFromDyn<Receiver[Self => U]>
|
// Receiver: DispatchFromDyn<Receiver[Self => U]>
|
||||||
|
|
|
@ -593,6 +593,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
|
||||||
|
bug!("TypeWellFormedFromEnv is only used for chalk")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,9 @@ pub fn predicate_obligations<'a, 'tcx>(
|
||||||
wf.compute(c1.into());
|
wf.compute(c1.into());
|
||||||
wf.compute(c2.into());
|
wf.compute(c2.into());
|
||||||
}
|
}
|
||||||
|
ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
|
||||||
|
bug!("TypeWellFormedFromEnv is only used for Chalk")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wf.normalize()
|
wf.normalize()
|
||||||
|
|
|
@ -31,9 +31,7 @@
|
||||||
//! not. To lower anything wrapped in a `Binder`, we first deeply find any bound
|
//! not. To lower anything wrapped in a `Binder`, we first deeply find any bound
|
||||||
//! variables from the current `Binder`.
|
//! variables from the current `Binder`.
|
||||||
|
|
||||||
use rustc_middle::traits::{
|
use rustc_middle::traits::{ChalkEnvironmentAndGoal, ChalkRustInterner as RustInterner};
|
||||||
ChalkEnvironmentAndGoal, ChalkEnvironmentClause, ChalkRustInterner as RustInterner,
|
|
||||||
};
|
|
||||||
use rustc_middle::ty::fold::TypeFolder;
|
use rustc_middle::ty::fold::TypeFolder;
|
||||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
|
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
|
@ -43,8 +41,6 @@ use rustc_span::def_id::DefId;
|
||||||
|
|
||||||
use std::collections::btree_map::{BTreeMap, Entry};
|
use std::collections::btree_map::{BTreeMap, Entry};
|
||||||
|
|
||||||
use chalk_ir::fold::shift::Shift;
|
|
||||||
|
|
||||||
/// Essentially an `Into` with a `&RustInterner` parameter
|
/// Essentially an `Into` with a `&RustInterner` parameter
|
||||||
crate trait LowerInto<'tcx, T> {
|
crate trait LowerInto<'tcx, T> {
|
||||||
/// Lower a rustc construct (e.g., `ty::TraitPredicate`) to a chalk type, consuming `self`.
|
/// Lower a rustc construct (e.g., `ty::TraitPredicate`) to a chalk type, consuming `self`.
|
||||||
|
@ -82,11 +78,13 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
|
||||||
self,
|
self,
|
||||||
interner: &RustInterner<'tcx>,
|
interner: &RustInterner<'tcx>,
|
||||||
) -> chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'tcx>>> {
|
) -> chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'tcx>>> {
|
||||||
let clauses = self.environment.into_iter().map(|clause| match clause {
|
let clauses = self.environment.into_iter().map(|predicate| {
|
||||||
ChalkEnvironmentClause::Predicate(predicate) => {
|
|
||||||
let (predicate, binders, _named_regions) =
|
let (predicate, binders, _named_regions) =
|
||||||
collect_bound_vars(interner, interner.tcx, &predicate.bound_atom(interner.tcx));
|
collect_bound_vars(interner, interner.tcx, &predicate.bound_atom(interner.tcx));
|
||||||
let consequence = match predicate {
|
let consequence = match predicate {
|
||||||
|
ty::PredicateAtom::TypeWellFormedFromEnv(ty) => {
|
||||||
|
chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(ty.lower_into(interner)))
|
||||||
|
}
|
||||||
ty::PredicateAtom::Trait(predicate, _) => chalk_ir::DomainGoal::FromEnv(
|
ty::PredicateAtom::Trait(predicate, _) => chalk_ir::DomainGoal::FromEnv(
|
||||||
chalk_ir::FromEnv::Trait(predicate.trait_ref.lower_into(interner)),
|
chalk_ir::FromEnv::Trait(predicate.trait_ref.lower_into(interner)),
|
||||||
),
|
),
|
||||||
|
@ -110,9 +108,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
|
||||||
| ty::PredicateAtom::ClosureKind(..)
|
| ty::PredicateAtom::ClosureKind(..)
|
||||||
| ty::PredicateAtom::Subtype(..)
|
| ty::PredicateAtom::Subtype(..)
|
||||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||||
| ty::PredicateAtom::ConstEquate(..) => {
|
| ty::PredicateAtom::ConstEquate(..) => bug!("unexpected predicate {}", predicate),
|
||||||
bug!("unexpected predicate {}", predicate)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let value = chalk_ir::ProgramClauseImplication {
|
let value = chalk_ir::ProgramClauseImplication {
|
||||||
consequence,
|
consequence,
|
||||||
|
@ -121,21 +117,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
|
||||||
constraints: chalk_ir::Constraints::empty(interner),
|
constraints: chalk_ir::Constraints::empty(interner),
|
||||||
};
|
};
|
||||||
chalk_ir::ProgramClauseData(chalk_ir::Binders::new(binders, value)).intern(interner)
|
chalk_ir::ProgramClauseData(chalk_ir::Binders::new(binders, value)).intern(interner)
|
||||||
}
|
|
||||||
ChalkEnvironmentClause::TypeFromEnv(ty) => {
|
|
||||||
chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
|
|
||||||
chalk_ir::VariableKinds::empty(interner),
|
|
||||||
chalk_ir::ProgramClauseImplication {
|
|
||||||
consequence: chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(
|
|
||||||
ty.lower_into(interner).shifted_in(interner),
|
|
||||||
)),
|
|
||||||
conditions: chalk_ir::Goals::empty(interner),
|
|
||||||
priority: chalk_ir::ClausePriority::High,
|
|
||||||
constraints: chalk_ir::Constraints::empty(interner),
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.intern(interner)
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let goal: chalk_ir::GoalData<RustInterner<'tcx>> = self.goal.lower_into(&interner);
|
let goal: chalk_ir::GoalData<RustInterner<'tcx>> = self.goal.lower_into(&interner);
|
||||||
|
@ -214,6 +195,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
|
||||||
| ty::PredicateAtom::ConstEquate(..) => {
|
| ty::PredicateAtom::ConstEquate(..) => {
|
||||||
chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner))
|
chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner))
|
||||||
}
|
}
|
||||||
|
ty::PredicateAtom::TypeWellFormedFromEnv(ty) => chalk_ir::GoalData::DomainGoal(
|
||||||
|
chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(ty.lower_into(interner))),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
chalk_ir::GoalData::Quantified(
|
chalk_ir::GoalData::Quantified(
|
||||||
|
@ -684,7 +668,10 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
|
||||||
| ty::PredicateAtom::ClosureKind(..)
|
| ty::PredicateAtom::ClosureKind(..)
|
||||||
| ty::PredicateAtom::Subtype(..)
|
| ty::PredicateAtom::Subtype(..)
|
||||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||||
| ty::PredicateAtom::ConstEquate(..) => bug!("unexpected predicate {}", &self),
|
| ty::PredicateAtom::ConstEquate(..)
|
||||||
|
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
|
||||||
|
bug!("unexpected predicate {}", &self)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
value.map(|value| chalk_ir::Binders::new(binders, value))
|
value.map(|value| chalk_ir::Binders::new(binders, value))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
//! Calls `chalk-solve` to solve a `ty::Predicate`
|
//! Calls `chalk-solve` to solve a `ty::Predicate`
|
||||||
//!
|
//!
|
||||||
//! In order to call `chalk-solve`, this file must convert a
|
//! In order to call `chalk-solve`, this file must convert a `CanonicalChalkEnvironmentAndGoal` into
|
||||||
//! `ChalkCanonicalGoal` into a Chalk ucanonical goal. It then calls Chalk, and
|
//! a Chalk uncanonical goal. It then calls Chalk, and converts the answer back into rustc solution.
|
||||||
//! converts the answer back into rustc solution.
|
|
||||||
|
|
||||||
crate mod db;
|
crate mod db;
|
||||||
crate mod lowering;
|
crate mod lowering;
|
||||||
|
@ -20,7 +19,7 @@ use rustc_middle::ty::{self, BoundVar, ParamTy, TyCtxt, TypeFoldable};
|
||||||
use rustc_infer::infer::canonical::{
|
use rustc_infer::infer::canonical::{
|
||||||
Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse,
|
Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse,
|
||||||
};
|
};
|
||||||
use rustc_infer::traits::{self, ChalkCanonicalGoal};
|
use rustc_infer::traits::{self, CanonicalChalkEnvironmentAndGoal};
|
||||||
|
|
||||||
use crate::chalk::db::RustIrDatabase as ChalkRustIrDatabase;
|
use crate::chalk::db::RustIrDatabase as ChalkRustIrDatabase;
|
||||||
use crate::chalk::lowering::{
|
use crate::chalk::lowering::{
|
||||||
|
@ -35,7 +34,7 @@ crate fn provide(p: &mut Providers) {
|
||||||
|
|
||||||
crate fn evaluate_goal<'tcx>(
|
crate fn evaluate_goal<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
obligation: ChalkCanonicalGoal<'tcx>,
|
obligation: CanonicalChalkEnvironmentAndGoal<'tcx>,
|
||||||
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, traits::query::NoSolution> {
|
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, traits::query::NoSolution> {
|
||||||
let interner = ChalkRustInterner { tcx };
|
let interner = ChalkRustInterner { tcx };
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,8 @@ fn compute_implied_outlives_bounds<'tcx>(
|
||||||
| ty::PredicateAtom::ClosureKind(..)
|
| ty::PredicateAtom::ClosureKind(..)
|
||||||
| ty::PredicateAtom::ObjectSafe(..)
|
| ty::PredicateAtom::ObjectSafe(..)
|
||||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||||
| ty::PredicateAtom::ConstEquate(..) => vec![],
|
| ty::PredicateAtom::ConstEquate(..)
|
||||||
|
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => vec![],
|
||||||
ty::PredicateAtom::WellFormed(arg) => {
|
ty::PredicateAtom::WellFormed(arg) => {
|
||||||
wf_args.push(arg);
|
wf_args.push(arg);
|
||||||
vec![]
|
vec![]
|
||||||
|
|
|
@ -49,6 +49,7 @@ fn not_outlives_predicate(p: &ty::Predicate<'tcx>) -> bool {
|
||||||
| ty::PredicateAtom::ClosureKind(..)
|
| ty::PredicateAtom::ClosureKind(..)
|
||||||
| ty::PredicateAtom::Subtype(..)
|
| ty::PredicateAtom::Subtype(..)
|
||||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||||
| ty::PredicateAtom::ConstEquate(..) => true,
|
| ty::PredicateAtom::ConstEquate(..)
|
||||||
|
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_data_structures::svh::Svh;
|
use rustc_data_structures::svh::Svh;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
|
@ -5,7 +6,9 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
||||||
use rustc_infer::traits::util;
|
use rustc_infer::traits::util;
|
||||||
use rustc_middle::hir::map as hir_map;
|
use rustc_middle::hir::map as hir_map;
|
||||||
use rustc_middle::ty::subst::{InternalSubsts, Subst};
|
use rustc_middle::ty::subst::{InternalSubsts, Subst};
|
||||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
|
use rustc_middle::ty::{
|
||||||
|
self, Binder, Predicate, PredicateAtom, PredicateKind, ToPredicate, Ty, TyCtxt, WithConstness,
|
||||||
|
};
|
||||||
use rustc_session::CrateDisambiguator;
|
use rustc_session::CrateDisambiguator;
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -245,7 +248,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
}
|
}
|
||||||
// Compute the bounds on Self and the type parameters.
|
// Compute the bounds on Self and the type parameters.
|
||||||
|
|
||||||
let ty::InstantiatedPredicates { predicates, .. } =
|
let ty::InstantiatedPredicates { mut predicates, .. } =
|
||||||
tcx.predicates_of(def_id).instantiate_identity(tcx);
|
tcx.predicates_of(def_id).instantiate_identity(tcx);
|
||||||
|
|
||||||
// Finally, we have to normalize the bounds in the environment, in
|
// Finally, we have to normalize the bounds in the environment, in
|
||||||
|
@ -260,11 +263,13 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
// are any errors at that point, so after type checking you can be
|
// are any errors at that point, so after type checking you can be
|
||||||
// sure that this will succeed without errors anyway.
|
// sure that this will succeed without errors anyway.
|
||||||
|
|
||||||
let unnormalized_env = ty::ParamEnv::new(
|
if tcx.sess.opts.debugging_opts.chalk {
|
||||||
tcx.intern_predicates(&predicates),
|
let environment = well_formed_types_in_env(tcx, def_id);
|
||||||
traits::Reveal::UserFacing,
|
predicates.extend(environment);
|
||||||
tcx.sess.opts.debugging_opts.chalk.then_some(def_id),
|
}
|
||||||
);
|
|
||||||
|
let unnormalized_env =
|
||||||
|
ty::ParamEnv::new(tcx.intern_predicates(&predicates), traits::Reveal::UserFacing);
|
||||||
|
|
||||||
let body_id = def_id
|
let body_id = def_id
|
||||||
.as_local()
|
.as_local()
|
||||||
|
@ -276,6 +281,122 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause)
|
traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Elaborate the environment.
|
||||||
|
///
|
||||||
|
/// Collect a list of `Predicate`'s used for building the `ParamEnv`. Adds `TypeWellFormedFromEnv`'s
|
||||||
|
/// that are assumed to be well-formed (because they come from the environment).
|
||||||
|
///
|
||||||
|
/// Used only in chalk mode.
|
||||||
|
fn well_formed_types_in_env<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
def_id: DefId,
|
||||||
|
) -> &'tcx ty::List<Predicate<'tcx>> {
|
||||||
|
use rustc_hir::{ForeignItemKind, ImplItemKind, ItemKind, Node, TraitItemKind};
|
||||||
|
use rustc_middle::ty::subst::GenericArgKind;
|
||||||
|
|
||||||
|
debug!("environment(def_id = {:?})", def_id);
|
||||||
|
|
||||||
|
// The environment of an impl Trait type is its defining function's environment.
|
||||||
|
if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
|
||||||
|
return well_formed_types_in_env(tcx, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the bounds on `Self` and the type parameters.
|
||||||
|
let ty::InstantiatedPredicates { predicates, .. } =
|
||||||
|
tcx.predicates_of(def_id).instantiate_identity(tcx);
|
||||||
|
|
||||||
|
let clauses = predicates.into_iter();
|
||||||
|
|
||||||
|
if !def_id.is_local() {
|
||||||
|
return ty::List::empty();
|
||||||
|
}
|
||||||
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
||||||
|
let node = tcx.hir().get(hir_id);
|
||||||
|
|
||||||
|
enum NodeKind {
|
||||||
|
TraitImpl,
|
||||||
|
InherentImpl,
|
||||||
|
Fn,
|
||||||
|
Other,
|
||||||
|
};
|
||||||
|
|
||||||
|
let node_kind = match node {
|
||||||
|
Node::TraitItem(item) => match item.kind {
|
||||||
|
TraitItemKind::Fn(..) => NodeKind::Fn,
|
||||||
|
_ => NodeKind::Other,
|
||||||
|
},
|
||||||
|
|
||||||
|
Node::ImplItem(item) => match item.kind {
|
||||||
|
ImplItemKind::Fn(..) => NodeKind::Fn,
|
||||||
|
_ => NodeKind::Other,
|
||||||
|
},
|
||||||
|
|
||||||
|
Node::Item(item) => match item.kind {
|
||||||
|
ItemKind::Impl { of_trait: Some(_), .. } => NodeKind::TraitImpl,
|
||||||
|
ItemKind::Impl { of_trait: None, .. } => NodeKind::InherentImpl,
|
||||||
|
ItemKind::Fn(..) => NodeKind::Fn,
|
||||||
|
_ => NodeKind::Other,
|
||||||
|
},
|
||||||
|
|
||||||
|
Node::ForeignItem(item) => match item.kind {
|
||||||
|
ForeignItemKind::Fn(..) => NodeKind::Fn,
|
||||||
|
_ => NodeKind::Other,
|
||||||
|
},
|
||||||
|
|
||||||
|
// FIXME: closures?
|
||||||
|
_ => NodeKind::Other,
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME(eddyb) isn't the unordered nature of this a hazard?
|
||||||
|
let mut inputs = FxIndexSet::default();
|
||||||
|
|
||||||
|
match node_kind {
|
||||||
|
// In a trait impl, we assume that the header trait ref and all its
|
||||||
|
// constituents are well-formed.
|
||||||
|
NodeKind::TraitImpl => {
|
||||||
|
let trait_ref = tcx.impl_trait_ref(def_id).expect("not an impl");
|
||||||
|
|
||||||
|
// FIXME(chalk): this has problems because of late-bound regions
|
||||||
|
//inputs.extend(trait_ref.substs.iter().flat_map(|arg| arg.walk()));
|
||||||
|
inputs.extend(trait_ref.substs.iter());
|
||||||
|
}
|
||||||
|
|
||||||
|
// In an inherent impl, we assume that the receiver type and all its
|
||||||
|
// constituents are well-formed.
|
||||||
|
NodeKind::InherentImpl => {
|
||||||
|
let self_ty = tcx.type_of(def_id);
|
||||||
|
inputs.extend(self_ty.walk());
|
||||||
|
}
|
||||||
|
|
||||||
|
// In an fn, we assume that the arguments and all their constituents are
|
||||||
|
// well-formed.
|
||||||
|
NodeKind::Fn => {
|
||||||
|
let fn_sig = tcx.fn_sig(def_id);
|
||||||
|
let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig);
|
||||||
|
|
||||||
|
inputs.extend(fn_sig.inputs().iter().flat_map(|ty| ty.walk()));
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeKind::Other => (),
|
||||||
|
}
|
||||||
|
let input_clauses = inputs.into_iter().filter_map(|arg| {
|
||||||
|
match arg.unpack() {
|
||||||
|
GenericArgKind::Type(ty) => {
|
||||||
|
let binder = Binder::dummy(PredicateAtom::TypeWellFormedFromEnv(ty));
|
||||||
|
Some(tcx.mk_predicate(PredicateKind::ForAll(binder)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME(eddyb) no WF conditions from lifetimes?
|
||||||
|
GenericArgKind::Lifetime(_) => None,
|
||||||
|
|
||||||
|
// FIXME(eddyb) support const generics in Chalk
|
||||||
|
GenericArgKind::Const(_) => None,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tcx.mk_predicates(clauses.chain(input_clauses))
|
||||||
|
}
|
||||||
|
|
||||||
fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
tcx.param_env(def_id).with_reveal_all_normalized(tcx)
|
tcx.param_env(def_id).with_reveal_all_normalized(tcx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,11 +202,8 @@ fn compare_predicate_entailment<'tcx>(
|
||||||
// The key step here is to update the caller_bounds's predicates to be
|
// The key step here is to update the caller_bounds's predicates to be
|
||||||
// the new hybrid bounds we computed.
|
// the new hybrid bounds we computed.
|
||||||
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_hir_id);
|
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_hir_id);
|
||||||
let param_env = ty::ParamEnv::new(
|
let param_env =
|
||||||
tcx.intern_predicates(&hybrid_preds.predicates),
|
ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates), Reveal::UserFacing);
|
||||||
Reveal::UserFacing,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
let param_env = traits::normalize_param_env_or_error(
|
let param_env = traits::normalize_param_env_or_error(
|
||||||
tcx,
|
tcx,
|
||||||
impl_m.def_id,
|
impl_m.def_id,
|
||||||
|
@ -1120,11 +1117,8 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||||
debug!("compare_type_predicate_entailment: bounds={:?}", hybrid_preds);
|
debug!("compare_type_predicate_entailment: bounds={:?}", hybrid_preds);
|
||||||
|
|
||||||
let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_hir_id);
|
let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_hir_id);
|
||||||
let param_env = ty::ParamEnv::new(
|
let param_env =
|
||||||
tcx.intern_predicates(&hybrid_preds.predicates),
|
ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates), Reveal::UserFacing);
|
||||||
Reveal::UserFacing,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
let param_env = traits::normalize_param_env_or_error(
|
let param_env = traits::normalize_param_env_or_error(
|
||||||
tcx,
|
tcx,
|
||||||
impl_ty.def_id,
|
impl_ty.def_id,
|
||||||
|
@ -1227,7 +1221,7 @@ fn compare_projection_bounds<'tcx>(
|
||||||
})
|
})
|
||||||
.to_predicate(tcx),
|
.to_predicate(tcx),
|
||||||
);
|
);
|
||||||
ty::ParamEnv::new(tcx.intern_predicates(&predicates), Reveal::UserFacing, None)
|
ty::ParamEnv::new(tcx.intern_predicates(&predicates), Reveal::UserFacing)
|
||||||
};
|
};
|
||||||
|
|
||||||
tcx.infer_ctxt().enter(move |infcx| {
|
tcx.infer_ctxt().enter(move |infcx| {
|
||||||
|
|
|
@ -814,7 +814,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
| ty::PredicateAtom::ClosureKind(..)
|
| ty::PredicateAtom::ClosureKind(..)
|
||||||
| ty::PredicateAtom::TypeOutlives(..)
|
| ty::PredicateAtom::TypeOutlives(..)
|
||||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||||
| ty::PredicateAtom::ConstEquate(..) => None,
|
| ty::PredicateAtom::ConstEquate(..)
|
||||||
|
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -3918,6 +3918,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// code is looking for a self type of a unresolved
|
// code is looking for a self type of a unresolved
|
||||||
// inference variable.
|
// inference variable.
|
||||||
ty::PredicateAtom::ClosureKind(..) => None,
|
ty::PredicateAtom::ClosureKind(..) => None,
|
||||||
|
ty::PredicateAtom::TypeWellFormedFromEnv(..) => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
|
.filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
|
||||||
|
|
|
@ -405,6 +405,7 @@ fn trait_predicate_kind<'tcx>(
|
||||||
| ty::PredicateAtom::ObjectSafe(_)
|
| ty::PredicateAtom::ObjectSafe(_)
|
||||||
| ty::PredicateAtom::ClosureKind(..)
|
| ty::PredicateAtom::ClosureKind(..)
|
||||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||||
| ty::PredicateAtom::ConstEquate(..) => None,
|
| ty::PredicateAtom::ConstEquate(..)
|
||||||
|
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,8 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
||||||
| ty::PredicateAtom::ClosureKind(..)
|
| ty::PredicateAtom::ClosureKind(..)
|
||||||
| ty::PredicateAtom::Subtype(..)
|
| ty::PredicateAtom::Subtype(..)
|
||||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||||
| ty::PredicateAtom::ConstEquate(..) => (),
|
| ty::PredicateAtom::ConstEquate(..)
|
||||||
|
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -508,7 +508,8 @@ impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
|
||||||
| ty::PredicateAtom::ObjectSafe(..)
|
| ty::PredicateAtom::ObjectSafe(..)
|
||||||
| ty::PredicateAtom::ClosureKind(..)
|
| ty::PredicateAtom::ClosureKind(..)
|
||||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||||
| ty::PredicateAtom::ConstEquate(..) => panic!("not user writable"),
|
| ty::PredicateAtom::ConstEquate(..)
|
||||||
|
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => panic!("not user writable"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0277]: the trait bound `{float}: Bar` is not satisfied
|
error[E0277]: the trait bound `{float}: Bar` is not satisfied
|
||||||
--> $DIR/type_inference.rs:27:5
|
--> $DIR/type_inference.rs:27:14
|
||||||
|
|
|
|
||||||
LL | fn only_bar<T: Bar>(_x: T) { }
|
LL | fn only_bar<T: Bar>(_x: T) { }
|
||||||
| --- required by this bound in `only_bar`
|
| --- required by this bound in `only_bar`
|
||||||
...
|
...
|
||||||
LL | only_bar(x);
|
LL | only_bar(x);
|
||||||
| ^^^^^^^^ the trait `Bar` is not implemented for `{float}`
|
| ^ the trait `Bar` is not implemented for `{float}`
|
||||||
|
|
|
|
||||||
= help: the following implementations were found:
|
= help: the following implementations were found:
|
||||||
<i32 as Bar>
|
<i32 as Bar>
|
||||||
|
|
|
@ -18,7 +18,7 @@ LL | enum MList { Cons(isize, MList), Nil }
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: ...which again requires computing drop-check constraints for `MList`, completing the cycle
|
= note: ...which again requires computing drop-check constraints for `MList`, completing the cycle
|
||||||
= note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing, def_id: None }, value: MList } }`
|
= note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: MList } }`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue