未验证 提交 8aad12b8 编写于 作者: D Dylan DPC 提交者: GitHub

Rollup merge of #71758 - jackh726:chalk-remove, r=jackh726

Remove leftover chalk types

Split out from #69406

Since the other PR is having memory problems with `parallel-compiler = true`, figured I should split this out. Surprisingly, this actually changes some errors, and I'm not quite sure why.

r? @nikomatsakis
......@@ -16,7 +16,7 @@
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
use crate::infer::{InferCtxt, InferOk, InferResult, NLLRegionVariableOrigin};
use crate::traits::query::{Fallible, NoSolution};
use crate::traits::{DomainGoal, TraitEngine};
use crate::traits::TraitEngine;
use crate::traits::{Obligation, ObligationCause, PredicateObligation};
use rustc_data_structures::captures::Captures;
use rustc_index::vec::Idx;
......@@ -671,10 +671,6 @@ fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {
});
}
fn push_domain_goal(&mut self, _: DomainGoal<'tcx>) {
bug!("should never be invoked with eager normalization")
}
fn normalization() -> NormalizationStrategy {
NormalizationStrategy::Eager
}
......
......@@ -23,7 +23,6 @@
use crate::infer::InferCtxt;
use crate::infer::{ConstVarValue, ConstVariableValue};
use crate::traits::DomainGoal;
use rustc_data_structures::fx::FxHashMap;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::fold::{TypeFoldable, TypeVisitor};
......@@ -78,10 +77,6 @@ pub trait TypeRelatingDelegate<'tcx> {
/// delegate.
fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>);
/// Push a domain goal that will need to be proved for the two types to
/// be related. Used for lazy normalization.
fn push_domain_goal(&mut self, domain_goal: DomainGoal<'tcx>);
/// Creates a new universe index. Used when instantiating placeholders.
fn create_next_universe(&mut self) -> ty::UniverseIndex;
......@@ -265,7 +260,6 @@ fn relate_projection_ty(
value_ty: Ty<'tcx>,
) -> Ty<'tcx> {
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use crate::traits::WhereClause;
use rustc_span::DUMMY_SP;
match value_ty.kind {
......@@ -279,12 +273,7 @@ fn relate_projection_ty(
var
}
_ => {
let projection = ty::ProjectionPredicate { projection_ty, ty: value_ty };
self.delegate
.push_domain_goal(DomainGoal::Holds(WhereClause::ProjectionEq(projection)));
value_ty
}
_ => bug!("should never be invoked with eager normalization"),
}
}
......
......@@ -838,10 +838,6 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {
tcx.par_body_owners(|def_id| tcx.ensure().mir_borrowck(def_id));
});
sess.time("dumping_chalk_like_clauses", || {
rustc_traits::lowering::dump_program_clauses(tcx);
});
sess.time("MIR_effect_checking", || {
for def_id in tcx.body_owners() {
mir::transform::check_unsafety::check_unsafety(tcx, def_id.to_def_id())
......
......@@ -51,7 +51,6 @@
use crate::mir;
use crate::mir::interpret::{GlobalId, LitToConstInput};
use crate::traits;
use crate::traits::query::{
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
......
use crate::dep_graph::SerializedDepNodeIndex;
use crate::mir;
use crate::mir::interpret::{GlobalId, LitToConstInput};
use crate::traits;
use crate::traits::query::{
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
......@@ -224,19 +223,6 @@ fn describe_as_module(def_id: DefId, tcx: TyCtxt<'_>) -> String {
anon
desc { "erasing regions from `{:?}`", ty }
}
query program_clauses_for(_: DefId) -> Clauses<'tcx> {
desc { "generating chalk-style clauses" }
}
query program_clauses_for_env(_: traits::Environment<'tcx>) -> Clauses<'tcx> {
desc { "generating chalk-style clauses for environment" }
}
// Get the chalk-style environment of the given item.
query environment(_: DefId) -> traits::Environment<'tcx> {
desc { "return a chalk-style environment" }
}
}
Linking {
......
......@@ -9,7 +9,7 @@
use crate::mir::interpret::ErrorHandled;
use crate::ty::subst::SubstsRef;
use crate::ty::{self, AdtKind, List, Ty, TyCtxt};
use crate::ty::{self, AdtKind, Ty, TyCtxt};
use rustc_ast::ast;
use rustc_hir as hir;
......@@ -307,162 +307,6 @@ pub struct DerivedObligationCause<'tcx> {
pub parent_code: Rc<ObligationCauseCode<'tcx>>,
}
/// The following types:
/// * `WhereClause`,
/// * `WellFormed`,
/// * `FromEnv`,
/// * `DomainGoal`,
/// * `Goal`,
/// * `Clause`,
/// * `Environment`,
/// * `InEnvironment`,
/// are used for representing the trait system in the form of
/// logic programming clauses. They are part of the interface
/// for the chalk SLG solver.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
pub enum WhereClause<'tcx> {
Implemented(ty::TraitPredicate<'tcx>),
ProjectionEq(ty::ProjectionPredicate<'tcx>),
RegionOutlives(ty::RegionOutlivesPredicate<'tcx>),
TypeOutlives(ty::TypeOutlivesPredicate<'tcx>),
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
pub enum WellFormed<'tcx> {
Trait(ty::TraitPredicate<'tcx>),
Ty(Ty<'tcx>),
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
pub enum FromEnv<'tcx> {
Trait(ty::TraitPredicate<'tcx>),
Ty(Ty<'tcx>),
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
pub enum DomainGoal<'tcx> {
Holds(WhereClause<'tcx>),
WellFormed(WellFormed<'tcx>),
FromEnv(FromEnv<'tcx>),
Normalize(ty::ProjectionPredicate<'tcx>),
}
pub type PolyDomainGoal<'tcx> = ty::Binder<DomainGoal<'tcx>>;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
pub enum QuantifierKind {
Universal,
Existential,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
pub enum GoalKind<'tcx> {
Implies(Clauses<'tcx>, Goal<'tcx>),
And(Goal<'tcx>, Goal<'tcx>),
Not(Goal<'tcx>),
DomainGoal(DomainGoal<'tcx>),
Quantified(QuantifierKind, ty::Binder<Goal<'tcx>>),
Subtype(Ty<'tcx>, Ty<'tcx>),
CannotProve,
}
pub type Goal<'tcx> = &'tcx GoalKind<'tcx>;
pub type Goals<'tcx> = &'tcx List<Goal<'tcx>>;
impl<'tcx> DomainGoal<'tcx> {
pub fn into_goal(self) -> GoalKind<'tcx> {
GoalKind::DomainGoal(self)
}
pub fn into_program_clause(self) -> ProgramClause<'tcx> {
ProgramClause {
goal: self,
hypotheses: ty::List::empty(),
category: ProgramClauseCategory::Other,
}
}
}
impl<'tcx> GoalKind<'tcx> {
pub fn from_poly_domain_goal(
domain_goal: PolyDomainGoal<'tcx>,
tcx: TyCtxt<'tcx>,
) -> GoalKind<'tcx> {
match domain_goal.no_bound_vars() {
Some(p) => p.into_goal(),
None => GoalKind::Quantified(
QuantifierKind::Universal,
domain_goal.map_bound(|p| tcx.mk_goal(p.into_goal())),
),
}
}
}
/// This matches the definition from Page 7 of "A Proof Procedure for the Logic of Hereditary
/// Harrop Formulas".
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub enum Clause<'tcx> {
Implies(ProgramClause<'tcx>),
ForAll(ty::Binder<ProgramClause<'tcx>>),
}
impl Clause<'tcx> {
pub fn category(self) -> ProgramClauseCategory {
match self {
Clause::Implies(clause) => clause.category,
Clause::ForAll(clause) => clause.skip_binder().category,
}
}
}
/// Multiple clauses.
pub type Clauses<'tcx> = &'tcx List<Clause<'tcx>>;
/// A "program clause" has the form `D :- G1, ..., Gn`. It is saying
/// that the domain goal `D` is true if `G1...Gn` are provable. This
/// is equivalent to the implication `G1..Gn => D`; we usually write
/// it with the reverse implication operator `:-` to emphasize the way
/// that programs are actually solved (via backchaining, which starts
/// with the goal to solve and proceeds from there).
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub struct ProgramClause<'tcx> {
/// This goal will be considered true ...
pub goal: DomainGoal<'tcx>,
/// ... if we can prove these hypotheses (there may be no hypotheses at all):
pub hypotheses: Goals<'tcx>,
/// Useful for filtering clauses.
pub category: ProgramClauseCategory,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
pub enum ProgramClauseCategory {
ImpliedBound,
WellFormed,
Other,
}
/// A set of clauses that we assume to be true.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub struct Environment<'tcx> {
pub clauses: Clauses<'tcx>,
}
impl Environment<'tcx> {
pub fn with<G>(self, goal: G) -> InEnvironment<'tcx, G> {
InEnvironment { environment: self, goal }
}
}
/// Something (usually a goal), along with an environment.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub struct InEnvironment<'tcx, G> {
pub environment: Environment<'tcx>,
pub goal: G,
}
#[derive(Clone, Debug, TypeFoldable)]
pub enum SelectionError<'tcx> {
Unimplemented,
......
use crate::traits;
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use crate::ty::{self, Lift, Ty, TyCtxt};
use rustc_span::symbol::Symbol;
use smallvec::SmallVec;
use crate::ty::{Lift, TyCtxt};
use std::collections::{BTreeMap, BTreeSet};
use std::fmt;
use std::rc::Rc;
......@@ -106,295 +102,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
impl<'tcx> fmt::Display for traits::WhereClause<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
use crate::traits::WhereClause::*;
// Bypass `ty::print` because it does not print out anonymous regions.
// FIXME(eddyb) implement a custom `PrettyPrinter`, or move this to `ty::print`.
fn write_region_name<'tcx>(
r: ty::Region<'tcx>,
fmt: &mut fmt::Formatter<'_>,
) -> fmt::Result {
match r {
ty::ReLateBound(index, br) => match br {
ty::BoundRegion::BrNamed(_, name) => write!(fmt, "{}", name),
ty::BoundRegion::BrAnon(var) => {
if *index == ty::INNERMOST {
write!(fmt, "'^{}", var)
} else {
write!(fmt, "'^{}_{}", index.index(), var)
}
}
_ => write!(fmt, "'_"),
},
_ => write!(fmt, "{}", r),
}
}
match self {
Implemented(trait_ref) => write!(fmt, "Implemented({})", trait_ref),
ProjectionEq(projection) => write!(fmt, "ProjectionEq({})", projection),
RegionOutlives(predicate) => {
write!(fmt, "RegionOutlives({}: ", predicate.0)?;
write_region_name(predicate.1, fmt)?;
write!(fmt, ")")
}
TypeOutlives(predicate) => {
write!(fmt, "TypeOutlives({}: ", predicate.0)?;
write_region_name(predicate.1, fmt)?;
write!(fmt, ")")
}
}
}
}
impl<'tcx> fmt::Display for traits::WellFormed<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
use crate::traits::WellFormed::*;
match self {
Trait(trait_ref) => write!(fmt, "WellFormed({})", trait_ref),
Ty(ty) => write!(fmt, "WellFormed({})", ty),
}
}
}
impl<'tcx> fmt::Display for traits::FromEnv<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
use crate::traits::FromEnv::*;
match self {
Trait(trait_ref) => write!(fmt, "FromEnv({})", trait_ref),
Ty(ty) => write!(fmt, "FromEnv({})", ty),
}
}
}
impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
use crate::traits::DomainGoal::*;
match self {
Holds(wc) => write!(fmt, "{}", wc),
WellFormed(wf) => write!(fmt, "{}", wf),
FromEnv(from_env) => write!(fmt, "{}", from_env),
Normalize(projection) => {
write!(fmt, "Normalize({} -> {})", projection.projection_ty, projection.ty)
}
}
}
}
impl fmt::Display for traits::QuantifierKind {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
use crate::traits::QuantifierKind::*;
match self {
Universal => write!(fmt, "forall"),
Existential => write!(fmt, "exists"),
}
}
}
/// Collect names for regions / types bound by a quantified goal / clause.
/// This collector does not try to do anything clever like in `ty::print`, it's just used
/// for debug output in tests anyway.
struct BoundNamesCollector {
// Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway.
regions: BTreeSet<Symbol>,
// Sort by `BoundVar` index, so usually this should be equivalent to the order given
// by the list of type parameters.
types: BTreeMap<u32, Symbol>,
binder_index: ty::DebruijnIndex,
}
impl BoundNamesCollector {
fn new() -> Self {
BoundNamesCollector {
regions: BTreeSet::new(),
types: BTreeMap::new(),
binder_index: ty::INNERMOST,
}
}
fn is_empty(&self) -> bool {
self.regions.is_empty() && self.types.is_empty()
}
fn write_names(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut start = true;
for r in &self.regions {
if !start {
write!(fmt, ", ")?;
}
start = false;
write!(fmt, "{}", r)?;
}
for t in self.types.values() {
if !start {
write!(fmt, ", ")?;
}
start = false;
write!(fmt, "{}", t)?;
}
Ok(())
}
}
impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector {
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> bool {
self.binder_index.shift_in(1);
let result = t.super_visit_with(self);
self.binder_index.shift_out(1);
result
}
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
match t.kind {
ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
self.types.insert(
bound_ty.var.as_u32(),
match bound_ty.kind {
ty::BoundTyKind::Param(name) => name,
ty::BoundTyKind::Anon => {
Symbol::intern(&format!("^{}", bound_ty.var.as_u32()))
}
},
);
}
_ => (),
};
t.super_visit_with(self)
}
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
match c.val {
ty::ConstKind::Bound(debruijn, bound_var) if debruijn == self.binder_index => {
self.types.insert(
bound_var.as_u32(),
Symbol::intern(&format!("^{}", bound_var.as_u32())),
);
}
_ => (),
}
c.super_visit_with(self)
}
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
match r {
ty::ReLateBound(index, br) if *index == self.binder_index => match br {
ty::BoundRegion::BrNamed(_, name) => {
self.regions.insert(*name);
}
ty::BoundRegion::BrAnon(var) => {
self.regions.insert(Symbol::intern(&format!("'^{}", var)));
}
_ => (),
},
_ => (),
};
r.super_visit_with(self)
}
}
impl<'tcx> fmt::Display for traits::Goal<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
use crate::traits::GoalKind::*;
match self {
Implies(hypotheses, goal) => {
write!(fmt, "if (")?;
for (index, hyp) in hypotheses.iter().enumerate() {
if index > 0 {
write!(fmt, ", ")?;
}
write!(fmt, "{}", hyp)?;
}
write!(fmt, ") {{ {} }}", goal)
}
And(goal1, goal2) => write!(fmt, "({} && {})", goal1, goal2),
Not(goal) => write!(fmt, "not {{ {} }}", goal),
DomainGoal(goal) => write!(fmt, "{}", goal),
Quantified(qkind, goal) => {
let mut collector = BoundNamesCollector::new();
goal.skip_binder().visit_with(&mut collector);
if !collector.is_empty() {
write!(fmt, "{}<", qkind)?;
collector.write_names(fmt)?;
write!(fmt, "> {{ ")?;
}
write!(fmt, "{}", goal.skip_binder())?;
if !collector.is_empty() {
write!(fmt, " }}")?;
}
Ok(())
}
Subtype(a, b) => write!(fmt, "{} <: {}", a, b),
CannotProve => write!(fmt, "CannotProve"),
}
}
}
impl<'tcx> fmt::Display for traits::ProgramClause<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let traits::ProgramClause { goal, hypotheses, .. } = self;
write!(fmt, "{}", goal)?;
if !hypotheses.is_empty() {
write!(fmt, " :- ")?;
for (index, condition) in hypotheses.iter().enumerate() {
if index > 0 {
write!(fmt, ", ")?;
}
write!(fmt, "{}", condition)?;
}
}
write!(fmt, ".")
}
}
impl<'tcx> fmt::Display for traits::Clause<'tcx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
use crate::traits::Clause::*;
match self {
Implies(clause) => write!(fmt, "{}", clause),
ForAll(clause) => {
let mut collector = BoundNamesCollector::new();
clause.skip_binder().visit_with(&mut collector);
if !collector.is_empty() {
write!(fmt, "forall<")?;
collector.write_names(fmt)?;
write!(fmt, "> {{ ")?;
}
write!(fmt, "{}", clause.skip_binder())?;
if !collector.is_empty() {
write!(fmt, " }}")?;
}
Ok(())
}
}
}
}
///////////////////////////////////////////////////////////////////////////
// Lift implementations
......@@ -592,63 +299,3 @@ fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
}
}
}
impl<'a, 'tcx> Lift<'tcx> for traits::Environment<'a> {
type Lifted = traits::Environment<'tcx>;
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
tcx.lift(&self.clauses).map(|clauses| traits::Environment { clauses })
}
}
impl<'a, 'tcx, G: Lift<'tcx>> Lift<'tcx> for traits::InEnvironment<'a, G> {
type Lifted = traits::InEnvironment<'tcx, G::Lifted>;
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
tcx.lift(&self.environment).and_then(|environment| {
tcx.lift(&self.goal).map(|goal| traits::InEnvironment { environment, goal })
})
}
}
///////////////////////////////////////////////////////////////////////////
// TypeFoldable implementations.
CloneTypeFoldableAndLiftImpls! {
traits::QuantifierKind,
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<traits::Goal<'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_goals(&v)
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.iter().any(|t| t.visit_with(visitor))
}
}
impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
let v = (**self).fold_with(folder);
folder.tcx().mk_goal(v)
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
(**self).visit_with(visitor)
}
}
CloneTypeFoldableAndLiftImpls! {
traits::ProgramClauseCategory,
}
impl<'tcx> TypeFoldable<'tcx> for traits::Clauses<'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_clauses(&v)
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.iter().any(|t| t.visit_with(visitor))
}
}
......@@ -16,7 +16,6 @@
use crate::mir::interpret::{Allocation, ConstValue, Scalar};
use crate::mir::{interpret, Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
use crate::traits;
use crate::traits::{Clause, Clauses, Goal, GoalKind, Goals};
use crate::ty::query;
use crate::ty::steal::Steal;
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
......@@ -92,9 +91,6 @@ pub struct CtxtInterners<'tcx> {
region: InternedSet<'tcx, RegionKind>,
existential_predicates: InternedSet<'tcx, List<ExistentialPredicate<'tcx>>>,
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
clauses: InternedSet<'tcx, List<Clause<'tcx>>>,
goal: InternedSet<'tcx, GoalKind<'tcx>>,
goal_list: InternedSet<'tcx, List<Goal<'tcx>>>,
projs: InternedSet<'tcx, List<ProjectionKind>>,
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
const_: InternedSet<'tcx, Const<'tcx>>,
......@@ -111,9 +107,6 @@ fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
existential_predicates: Default::default(),
canonical_var_infos: Default::default(),
predicates: Default::default(),
clauses: Default::default(),
goal: Default::default(),
goal_list: Default::default(),
projs: Default::default(),
place_elems: Default::default(),
const_: Default::default(),
......@@ -1573,11 +1566,8 @@ fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
nop_lift! {type_; Ty<'a> => Ty<'tcx>}
nop_lift! {region; Region<'a> => Region<'tcx>}
nop_lift! {goal; Goal<'a> => Goal<'tcx>}
nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
nop_list_lift! {goal_list; Goal<'a> => Goal<'tcx>}
nop_list_lift! {clauses; Clause<'a> => Clause<'tcx>}
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
......@@ -1988,12 +1978,6 @@ fn borrow(&self) -> &RegionKind {
}
}
impl<'tcx> Borrow<GoalKind<'tcx>> for Interned<'tcx, GoalKind<'tcx>> {
fn borrow<'a>(&'a self) -> &'a GoalKind<'tcx> {
&self.0
}
}
impl<'tcx> Borrow<[ExistentialPredicate<'tcx>]>
for Interned<'tcx, List<ExistentialPredicate<'tcx>>>
{
......@@ -2014,18 +1998,6 @@ fn borrow<'a>(&'a self) -> &'a Const<'tcx> {
}
}
impl<'tcx> Borrow<[Clause<'tcx>]> for Interned<'tcx, List<Clause<'tcx>>> {
fn borrow<'a>(&'a self) -> &'a [Clause<'tcx>] {
&self.0[..]
}
}
impl<'tcx> Borrow<[Goal<'tcx>]> for Interned<'tcx, List<Goal<'tcx>>> {
fn borrow<'a>(&'a self) -> &'a [Goal<'tcx>] {
&self.0[..]
}
}
macro_rules! direct_interners {
($($name:ident: $method:ident($ty:ty)),+) => {
$(impl<'tcx> PartialEq for Interned<'tcx, $ty> {
......@@ -2052,11 +2024,7 @@ pub fn $method(self, v: $ty) -> &'tcx $ty {
}
}
direct_interners!(
region: mk_region(RegionKind),
goal: mk_goal(GoalKind<'tcx>),
const_: mk_const(Const<'tcx>)
);
direct_interners!(region: mk_region(RegionKind), const_: mk_const(Const<'tcx>));
macro_rules! slice_interners {
($($field:ident: $method:ident($ty:ty)),+) => (
......@@ -2076,8 +2044,6 @@ pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo),
existential_predicates: _intern_existential_predicates(ExistentialPredicate<'tcx>),
predicates: _intern_predicates(Predicate<'tcx>),
clauses: _intern_clauses(Clause<'tcx>),
goal_list: _intern_goals(Goal<'tcx>),
projs: _intern_projs(ProjectionKind),
place_elems: _intern_place_elems(PlaceElem<'tcx>)
);
......@@ -2465,14 +2431,6 @@ pub fn intern_canonical_var_infos(self, ts: &[CanonicalVarInfo]) -> CanonicalVar
if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
}
pub fn intern_clauses(self, ts: &[Clause<'tcx>]) -> Clauses<'tcx> {
if ts.is_empty() { List::empty() } else { self._intern_clauses(ts) }
}
pub fn intern_goals(self, ts: &[Goal<'tcx>]) -> Goals<'tcx> {
if ts.is_empty() { List::empty() } else { self._intern_goals(ts) }
}
pub fn mk_fn_sig<I>(
self,
inputs: I,
......@@ -2530,14 +2488,6 @@ pub fn mk_substs_trait(self, self_ty: Ty<'tcx>, rest: &[GenericArg<'tcx>]) -> Su
self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
}
pub fn mk_clauses<I: InternAs<[Clause<'tcx>], Clauses<'tcx>>>(self, iter: I) -> I::Output {
iter.intern_with(|xs| self.intern_clauses(xs))
}
pub fn mk_goals<I: InternAs<[Goal<'tcx>], Goals<'tcx>>>(self, iter: I) -> I::Output {
iter.intern_with(|xs| self.intern_goals(xs))
}
/// 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.
pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
......
......@@ -2,7 +2,6 @@
use crate::infer::canonical::Canonical;
use crate::mir;
use crate::traits;
use crate::ty::fast_reject::SimplifiedType;
use crate::ty::subst::{GenericArg, SubstsRef};
use crate::ty::{self, Ty, TyCtxt};
......@@ -260,17 +259,6 @@ fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
}
}
impl<'tcx> Key for traits::Environment<'tcx> {
type CacheSelector = DefaultCacheSelector;
fn query_crate(&self) -> CrateNum {
LOCAL_CRATE
}
fn default_span(&self, _: TyCtxt<'_>) -> Span {
DUMMY_SP
}
}
impl Key for Symbol {
type CacheSelector = DefaultCacheSelector;
......
......@@ -27,7 +27,6 @@
OutlivesBound,
};
use crate::traits::specialization_graph;
use crate::traits::Clauses;
use crate::traits::{self, Vtable};
use crate::ty::steal::Steal;
use crate::ty::subst::{GenericArg, SubstsRef};
......
......@@ -5,7 +5,6 @@
//! subtyping, type equality, etc.
use crate::mir::interpret::{get_slice_bytes, ConstValue};
use crate::traits;
use crate::ty::error::{ExpectedFound, TypeError};
use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
......@@ -786,229 +785,6 @@ fn relate<R: TypeRelation<'tcx>>(
}
}
impl<'tcx> Relate<'tcx> for traits::WhereClause<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: &traits::WhereClause<'tcx>,
b: &traits::WhereClause<'tcx>,
) -> RelateResult<'tcx, traits::WhereClause<'tcx>> {
use crate::traits::WhereClause::*;
match (a, b) {
(Implemented(a_pred), Implemented(b_pred)) => {
Ok(Implemented(relation.relate(a_pred, b_pred)?))
}
(ProjectionEq(a_pred), ProjectionEq(b_pred)) => {
Ok(ProjectionEq(relation.relate(a_pred, b_pred)?))
}
(RegionOutlives(a_pred), RegionOutlives(b_pred)) => {
Ok(RegionOutlives(ty::OutlivesPredicate(
relation.relate(&a_pred.0, &b_pred.0)?,
relation.relate(&a_pred.1, &b_pred.1)?,
)))
}
(TypeOutlives(a_pred), TypeOutlives(b_pred)) => {
Ok(TypeOutlives(ty::OutlivesPredicate(
relation.relate(&a_pred.0, &b_pred.0)?,
relation.relate(&a_pred.1, &b_pred.1)?,
)))
}
_ => Err(TypeError::Mismatch),
}
}
}
impl<'tcx> Relate<'tcx> for traits::WellFormed<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: &traits::WellFormed<'tcx>,
b: &traits::WellFormed<'tcx>,
) -> RelateResult<'tcx, traits::WellFormed<'tcx>> {
use crate::traits::WellFormed::*;
match (a, b) {
(Trait(a_pred), Trait(b_pred)) => Ok(Trait(relation.relate(a_pred, b_pred)?)),
(Ty(a_ty), Ty(b_ty)) => Ok(Ty(relation.relate(a_ty, b_ty)?)),
_ => Err(TypeError::Mismatch),
}
}
}
impl<'tcx> Relate<'tcx> for traits::FromEnv<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: &traits::FromEnv<'tcx>,
b: &traits::FromEnv<'tcx>,
) -> RelateResult<'tcx, traits::FromEnv<'tcx>> {
use crate::traits::FromEnv::*;
match (a, b) {
(Trait(a_pred), Trait(b_pred)) => Ok(Trait(relation.relate(a_pred, b_pred)?)),
(Ty(a_ty), Ty(b_ty)) => Ok(Ty(relation.relate(a_ty, b_ty)?)),
_ => Err(TypeError::Mismatch),
}
}
}
impl<'tcx> Relate<'tcx> for traits::DomainGoal<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: &traits::DomainGoal<'tcx>,
b: &traits::DomainGoal<'tcx>,
) -> RelateResult<'tcx, traits::DomainGoal<'tcx>> {
use crate::traits::DomainGoal::*;
match (a, b) {
(Holds(a_wc), Holds(b_wc)) => Ok(Holds(relation.relate(a_wc, b_wc)?)),
(WellFormed(a_wf), WellFormed(b_wf)) => Ok(WellFormed(relation.relate(a_wf, b_wf)?)),
(FromEnv(a_fe), FromEnv(b_fe)) => Ok(FromEnv(relation.relate(a_fe, b_fe)?)),
(Normalize(a_pred), Normalize(b_pred)) => {
Ok(Normalize(relation.relate(a_pred, b_pred)?))
}
_ => Err(TypeError::Mismatch),
}
}
}
impl<'tcx> Relate<'tcx> for traits::Goal<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: &traits::Goal<'tcx>,
b: &traits::Goal<'tcx>,
) -> RelateResult<'tcx, traits::Goal<'tcx>> {
use crate::traits::GoalKind::*;
match (a, b) {
(Implies(a_clauses, a_goal), Implies(b_clauses, b_goal)) => {
let clauses = relation.relate(a_clauses, b_clauses)?;
let goal = relation.relate(a_goal, b_goal)?;
Ok(relation.tcx().mk_goal(Implies(clauses, goal)))
}
(And(a_left, a_right), And(b_left, b_right)) => {
let left = relation.relate(a_left, b_left)?;
let right = relation.relate(a_right, b_right)?;
Ok(relation.tcx().mk_goal(And(left, right)))
}
(Not(a_goal), Not(b_goal)) => {
let goal = relation.relate(a_goal, b_goal)?;
Ok(relation.tcx().mk_goal(Not(goal)))
}
(DomainGoal(a_goal), DomainGoal(b_goal)) => {
let goal = relation.relate(a_goal, b_goal)?;
Ok(relation.tcx().mk_goal(DomainGoal(goal)))
}
(Quantified(a_qkind, a_goal), Quantified(b_qkind, b_goal)) if a_qkind == b_qkind => {
let goal = relation.relate(a_goal, b_goal)?;
Ok(relation.tcx().mk_goal(Quantified(*a_qkind, goal)))
}
(CannotProve, CannotProve) => Ok(*a),
_ => Err(TypeError::Mismatch),
}
}
}
impl<'tcx> Relate<'tcx> for traits::Goals<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: &traits::Goals<'tcx>,
b: &traits::Goals<'tcx>,
) -> RelateResult<'tcx, traits::Goals<'tcx>> {
if a.len() != b.len() {
return Err(TypeError::Mismatch);
}
let tcx = relation.tcx();
let goals = a.iter().zip(b.iter()).map(|(a, b)| relation.relate(a, b));
Ok(tcx.mk_goals(goals)?)
}
}
impl<'tcx> Relate<'tcx> for traits::Clause<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: &traits::Clause<'tcx>,
b: &traits::Clause<'tcx>,
) -> RelateResult<'tcx, traits::Clause<'tcx>> {
use crate::traits::Clause::*;
match (a, b) {
(Implies(a_clause), Implies(b_clause)) => {
let clause = relation.relate(a_clause, b_clause)?;
Ok(Implies(clause))
}
(ForAll(a_clause), ForAll(b_clause)) => {
let clause = relation.relate(a_clause, b_clause)?;
Ok(ForAll(clause))
}
_ => Err(TypeError::Mismatch),
}
}
}
impl<'tcx> Relate<'tcx> for traits::Clauses<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: &traits::Clauses<'tcx>,
b: &traits::Clauses<'tcx>,
) -> RelateResult<'tcx, traits::Clauses<'tcx>> {
if a.len() != b.len() {
return Err(TypeError::Mismatch);
}
let tcx = relation.tcx();
let clauses = a.iter().zip(b.iter()).map(|(a, b)| relation.relate(a, b));
Ok(tcx.mk_clauses(clauses)?)
}
}
impl<'tcx> Relate<'tcx> for traits::ProgramClause<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: &traits::ProgramClause<'tcx>,
b: &traits::ProgramClause<'tcx>,
) -> RelateResult<'tcx, traits::ProgramClause<'tcx>> {
Ok(traits::ProgramClause {
goal: relation.relate(&a.goal, &b.goal)?,
hypotheses: relation.relate(&a.hypotheses, &b.hypotheses)?,
category: traits::ProgramClauseCategory::Other,
})
}
}
impl<'tcx> Relate<'tcx> for traits::Environment<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: &traits::Environment<'tcx>,
b: &traits::Environment<'tcx>,
) -> RelateResult<'tcx, traits::Environment<'tcx>> {
Ok(traits::Environment { clauses: relation.relate(&a.clauses, &b.clauses)? })
}
}
impl<'tcx, G> Relate<'tcx> for traits::InEnvironment<'tcx, G>
where
G: Relate<'tcx>,
{
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: &traits::InEnvironment<'tcx, G>,
b: &traits::InEnvironment<'tcx, G>,
) -> RelateResult<'tcx, traits::InEnvironment<'tcx, G>> {
Ok(traits::InEnvironment {
environment: relation.relate(&a.environment, &b.environment)?,
goal: relation.relate(&a.goal, &b.goal)?,
})
}
}
///////////////////////////////////////////////////////////////////////////
// Error handling
......
......@@ -207,38 +207,6 @@ pub fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
Self::for_item(tcx, def_id, |param, _| tcx.mk_param_from_def(param))
}
/// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked
/// var bound at index `0`. For types, we use a `BoundVar` index equal to
/// the type parameter index. For regions, we use the `BoundRegion::BrNamed`
/// variant (which has a `DefId`).
pub fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
Self::for_item(tcx, def_id, |param, _| match param.kind {
ty::GenericParamDefKind::Type { .. } => tcx
.mk_ty(ty::Bound(
ty::INNERMOST,
ty::BoundTy {
var: ty::BoundVar::from(param.index),
kind: ty::BoundTyKind::Param(param.name),
},
))
.into(),
ty::GenericParamDefKind::Lifetime => tcx
.mk_region(ty::RegionKind::ReLateBound(
ty::INNERMOST,
ty::BoundRegion::BrNamed(param.def_id, param.name),
))
.into(),
ty::GenericParamDefKind::Const => tcx
.mk_const(ty::Const {
val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)),
ty: tcx.type_of(param.def_id),
})
.into(),
})
}
/// Creates a `InternalSubsts` for generic parameter definitions,
/// by calling closures to obtain each kind.
/// The closures get to observe the `InternalSubsts` as they're
......
......@@ -4,7 +4,6 @@
use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::{self, Ty};
use rustc_trait_selection::traits::query::Fallible;
use rustc_trait_selection::traits::DomainGoal;
use crate::borrow_check::constraints::OutlivesConstraint;
use crate::borrow_check::type_check::{BorrowCheckContext, Locations};
......@@ -100,10 +99,6 @@ fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {
}
}
fn push_domain_goal(&mut self, _: DomainGoal<'tcx>) {
bug!("should never be invoked with eager normalization")
}
fn normalization() -> NormalizationStrategy {
NormalizationStrategy::Eager
}
......
......@@ -15,7 +15,6 @@
mod dropck_outlives;
mod evaluate_obligation;
mod implied_outlives_bounds;
pub mod lowering;
mod normalize_erasing_regions;
mod normalize_projection_ty;
mod type_op;
......@@ -26,7 +25,6 @@ pub fn provide(p: &mut Providers<'_>) {
dropck_outlives::provide(p);
evaluate_obligation::provide(p);
implied_outlives_bounds::provide(p);
lowering::provide(p);
normalize_projection_ty::provide(p);
normalize_erasing_regions::provide(p);
type_op::provide(p);
......
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def_id::DefId;
use rustc_middle::traits::{
Clause, Clauses, DomainGoal, Environment, FromEnv, ProgramClause, ProgramClauseCategory,
};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, Ty, TyCtxt};
struct ClauseVisitor<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
round: &'a mut FxHashSet<Clause<'tcx>>,
}
impl ClauseVisitor<'a, 'tcx> {
fn new(tcx: TyCtxt<'tcx>, round: &'a mut FxHashSet<Clause<'tcx>>) -> Self {
ClauseVisitor { tcx, round }
}
fn visit_ty(&mut self, ty: Ty<'tcx>) {
match ty.kind {
ty::Projection(data) => {
self.round.extend(
self.tcx
.program_clauses_for(data.item_def_id)
.iter()
.filter(|c| c.category() == ProgramClauseCategory::ImpliedBound)
.cloned(),
);
}
ty::Dynamic(..) => {
// FIXME: trait object rules are not yet implemented
}
ty::Adt(def, ..) => {
self.round.extend(
self.tcx
.program_clauses_for(def.did)
.iter()
.filter(|c| c.category() == ProgramClauseCategory::ImpliedBound)
.cloned(),
);
}
ty::Foreign(def_id)
| ty::FnDef(def_id, ..)
| ty::Closure(def_id, ..)
| ty::Generator(def_id, ..)
| ty::Opaque(def_id, ..) => {
self.round.extend(
self.tcx
.program_clauses_for(def_id)
.iter()
.filter(|c| c.category() == ProgramClauseCategory::ImpliedBound)
.cloned(),
);
}
ty::Bool
| ty::Char
| ty::Int(..)
| ty::Uint(..)
| ty::Float(..)
| ty::Str
| ty::Array(..)
| ty::Slice(..)
| ty::RawPtr(..)
| ty::FnPtr(..)
| ty::Tuple(..)
| ty::Ref(..)
| ty::Never
| ty::Infer(..)
| ty::Placeholder(..)
| ty::Param(..)
| ty::Bound(..) => (),
ty::GeneratorWitness(..) | ty::UnnormalizedProjection(..) | ty::Error => {
bug!("unexpected type {:?}", ty);
}
}
}
fn visit_from_env(&mut self, from_env: FromEnv<'tcx>) {
match from_env {
FromEnv::Trait(predicate) => {
self.round.extend(
self.tcx
.program_clauses_for(predicate.def_id())
.iter()
.filter(|c| c.category() == ProgramClauseCategory::ImpliedBound)
.cloned(),
);
}
FromEnv::Ty(ty) => self.visit_ty(ty),
}
}
fn visit_domain_goal(&mut self, domain_goal: DomainGoal<'tcx>) {
// The only domain goals we can find in an environment are:
// * `DomainGoal::Holds(..)`
// * `DomainGoal::FromEnv(..)`
// The former do not lead to any implied bounds. So we only need
// to visit the latter.
if let DomainGoal::FromEnv(from_env) = domain_goal {
self.visit_from_env(from_env);
}
}
fn visit_program_clause(&mut self, clause: ProgramClause<'tcx>) {
self.visit_domain_goal(clause.goal);
// No need to visit `clause.hypotheses`: they are always of the form
// `FromEnv(...)` and were visited at a previous round.
}
fn visit_clause(&mut self, clause: Clause<'tcx>) {
match clause {
Clause::Implies(clause) => self.visit_program_clause(clause),
Clause::ForAll(clause) => self.visit_program_clause(*clause.skip_binder()),
}
}
}
crate fn program_clauses_for_env<'tcx>(
tcx: TyCtxt<'tcx>,
environment: Environment<'tcx>,
) -> Clauses<'tcx> {
debug!("program_clauses_for_env(environment={:?})", environment);
let mut last_round = FxHashSet::default();
{
let mut visitor = ClauseVisitor::new(tcx, &mut last_round);
for &clause in environment.clauses {
visitor.visit_clause(clause);
}
}
let mut closure = last_round.clone();
let mut next_round = FxHashSet::default();
while !last_round.is_empty() {
let mut visitor = ClauseVisitor::new(tcx, &mut next_round);
for clause in last_round.drain() {
visitor.visit_clause(clause);
}
last_round.extend(next_round.drain().filter(|&clause| closure.insert(clause)));
}
debug!("program_clauses_for_env: closure = {:#?}", closure);
tcx.mk_clauses(closure.into_iter())
}
crate fn environment(tcx: TyCtxt<'_>, def_id: DefId) -> Environment<'_> {
use super::{IntoFromEnvGoal, Lower};
use rustc_hir::{ForeignItemKind, ImplItemKind, ItemKind, Node, TraitItemKind};
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(|predicate| predicate.lower())
.map(|domain_goal| domain_goal.map_bound(|bound| bound.into_from_env_goal()))
.map(|domain_goal| domain_goal.map_bound(|bound| bound.into_program_clause()))
// `ForAll` because each `domain_goal` is a `PolyDomainGoal` and
// could bound lifetimes.
.map(Clause::ForAll);
let hir_id = tcx.hir().as_local_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 = FxHashSet::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");
inputs.extend(trait_ref.substs.iter().flat_map(|&arg| arg.walk()));
}
// 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 clauses = clauses.chain(
inputs
.into_iter()
.filter_map(|arg| {
match arg.unpack() {
GenericArgKind::Type(ty) => Some(FromEnv::Ty(ty)),
// FIXME(eddyb) no WF conditions from lifetimes?
GenericArgKind::Lifetime(_) => None,
// FIXME(eddyb) support const generics in Chalk
GenericArgKind::Const(_) => None,
}
})
.map(DomainGoal::FromEnv)
.map(|domain_goal| domain_goal.into_program_clause())
.map(Clause::Implies),
);
debug!("environment: clauses = {:?}", clauses);
Environment { clauses: tcx.mk_clauses(clauses) }
}
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册