Add ty::BoundConstness
This commit is contained in:
parent
c75aeaac0b
commit
80e1ee5aee
18 changed files with 80 additions and 80 deletions
|
@ -17,7 +17,6 @@ use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::{Applicability, DiagnosticBuilder};
|
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::Constness;
|
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -497,7 +496,7 @@ pub enum ImplSource<'tcx, N> {
|
||||||
/// for some type parameter. The `Vec<N>` represents the
|
/// for some type parameter. The `Vec<N>` represents the
|
||||||
/// obligations incurred from normalizing the where-clause (if
|
/// obligations incurred from normalizing the where-clause (if
|
||||||
/// any).
|
/// any).
|
||||||
Param(Vec<N>, Constness),
|
Param(Vec<N>, ty::BoundConstness),
|
||||||
|
|
||||||
/// Virtual calls through an object.
|
/// Virtual calls through an object.
|
||||||
Object(ImplSourceObjectData<'tcx, N>),
|
Object(ImplSourceObjectData<'tcx, N>),
|
||||||
|
|
|
@ -33,7 +33,7 @@ impl<T> ExpectedFound<T> {
|
||||||
#[derive(Clone, Debug, TypeFoldable)]
|
#[derive(Clone, Debug, TypeFoldable)]
|
||||||
pub enum TypeError<'tcx> {
|
pub enum TypeError<'tcx> {
|
||||||
Mismatch,
|
Mismatch,
|
||||||
ConstnessMismatch(ExpectedFound<hir::Constness>),
|
ConstnessMismatch(ExpectedFound<ty::BoundConstness>),
|
||||||
UnsafetyMismatch(ExpectedFound<hir::Unsafety>),
|
UnsafetyMismatch(ExpectedFound<hir::Unsafety>),
|
||||||
AbiMismatch(ExpectedFound<abi::Abi>),
|
AbiMismatch(ExpectedFound<abi::Abi>),
|
||||||
Mutability,
|
Mutability,
|
||||||
|
@ -102,7 +102,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
|
||||||
CyclicConst(_) => write!(f, "encountered a self-referencing constant"),
|
CyclicConst(_) => write!(f, "encountered a self-referencing constant"),
|
||||||
Mismatch => write!(f, "types differ"),
|
Mismatch => write!(f, "types differ"),
|
||||||
ConstnessMismatch(values) => {
|
ConstnessMismatch(values) => {
|
||||||
write!(f, "expected {} fn, found {} fn", values.expected, values.found)
|
write!(f, "expected {} bound, found {} bound", values.expected, values.found)
|
||||||
}
|
}
|
||||||
UnsafetyMismatch(values) => {
|
UnsafetyMismatch(values) => {
|
||||||
write!(f, "expected {} fn, found {} fn", values.expected, values.found)
|
write!(f, "expected {} fn, found {} fn", values.expected, values.found)
|
||||||
|
|
|
@ -37,7 +37,7 @@ use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
||||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, CRATE_DEF_INDEX};
|
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, CRATE_DEF_INDEX};
|
||||||
use rustc_hir::{Constness, Node};
|
use rustc_hir::Node;
|
||||||
use rustc_macros::HashStable;
|
use rustc_macros::HashStable;
|
||||||
use rustc_span::symbol::{kw, Ident, Symbol};
|
use rustc_span::symbol::{kw, Ident, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -181,6 +181,25 @@ pub enum Visibility {
|
||||||
Invisible,
|
Invisible,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
|
||||||
|
pub enum BoundConstness {
|
||||||
|
/// `T: Trait`
|
||||||
|
NotConst,
|
||||||
|
/// `T: ~const Trait`
|
||||||
|
///
|
||||||
|
/// Requires resolving to const only when we are in a const context.
|
||||||
|
ConstIfConst,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for BoundConstness {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::NotConst => f.write_str("normal"),
|
||||||
|
Self::ConstIfConst => f.write_str("`~const`"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone,
|
||||||
Debug,
|
Debug,
|
||||||
|
@ -628,9 +647,7 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
pub struct TraitPredicate<'tcx> {
|
pub struct TraitPredicate<'tcx> {
|
||||||
pub trait_ref: TraitRef<'tcx>,
|
pub trait_ref: TraitRef<'tcx>,
|
||||||
|
|
||||||
/// A trait predicate will have `Constness::Const` if it originates
|
pub constness: BoundConstness,
|
||||||
/// from a bound marked with `~const`.
|
|
||||||
pub constness: hir::Constness,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
|
pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
|
||||||
|
@ -1299,7 +1316,7 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
|
||||||
pub struct ConstnessAnd<T> {
|
pub struct ConstnessAnd<T> {
|
||||||
pub constness: Constness,
|
pub constness: BoundConstness,
|
||||||
pub value: T,
|
pub value: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1307,18 +1324,18 @@ pub struct ConstnessAnd<T> {
|
||||||
// the constness of trait bounds is being propagated correctly.
|
// the constness of trait bounds is being propagated correctly.
|
||||||
pub trait WithConstness: Sized {
|
pub trait WithConstness: Sized {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_constness(self, constness: Constness) -> ConstnessAnd<Self> {
|
fn with_constness(self, constness: BoundConstness) -> ConstnessAnd<Self> {
|
||||||
ConstnessAnd { constness, value: self }
|
ConstnessAnd { constness, value: self }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_const(self) -> ConstnessAnd<Self> {
|
fn with_const_if_const(self) -> ConstnessAnd<Self> {
|
||||||
self.with_constness(Constness::Const)
|
self.with_constness(BoundConstness::ConstIfConst)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn without_const(self) -> ConstnessAnd<Self> {
|
fn without_const(self) -> ConstnessAnd<Self> {
|
||||||
self.with_constness(Constness::NotConst)
|
self.with_constness(BoundConstness::NotConst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,12 +200,12 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Relate<'tcx> for ast::Constness {
|
impl<'tcx> Relate<'tcx> for ty::BoundConstness {
|
||||||
fn relate<R: TypeRelation<'tcx>>(
|
fn relate<R: TypeRelation<'tcx>>(
|
||||||
relation: &mut R,
|
relation: &mut R,
|
||||||
a: ast::Constness,
|
a: ty::BoundConstness,
|
||||||
b: ast::Constness,
|
b: ty::BoundConstness,
|
||||||
) -> RelateResult<'tcx, ast::Constness> {
|
) -> RelateResult<'tcx, ty::BoundConstness> {
|
||||||
if a != b {
|
if a != b {
|
||||||
Err(TypeError::ConstnessMismatch(expected_found(relation, a, b)))
|
Err(TypeError::ConstnessMismatch(expected_found(relation, a, b)))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,7 +8,6 @@ use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||||
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
|
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
|
||||||
use crate::ty::{self, InferConst, Lift, Ty, TyCtxt};
|
use crate::ty::{self, InferConst, Lift, Ty, TyCtxt};
|
||||||
use rustc_data_structures::functor::IdFunctor;
|
use rustc_data_structures::functor::IdFunctor;
|
||||||
use rustc_hir as hir;
|
|
||||||
use rustc_hir::def::Namespace;
|
use rustc_hir::def::Namespace;
|
||||||
use rustc_hir::def_id::CRATE_DEF_INDEX;
|
use rustc_hir::def_id::CRATE_DEF_INDEX;
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
|
@ -155,8 +154,8 @@ impl fmt::Debug for ty::ParamConst {
|
||||||
|
|
||||||
impl fmt::Debug for ty::TraitPredicate<'tcx> {
|
impl fmt::Debug for ty::TraitPredicate<'tcx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
if let hir::Constness::Const = self.constness {
|
if let ty::BoundConstness::ConstIfConst = self.constness {
|
||||||
write!(f, "const ")?;
|
write!(f, "~const ")?;
|
||||||
}
|
}
|
||||||
write!(f, "TraitPredicate({:?})", self.trait_ref)
|
write!(f, "TraitPredicate({:?})", self.trait_ref)
|
||||||
}
|
}
|
||||||
|
@ -241,6 +240,7 @@ TrivialTypeFoldableAndLiftImpls! {
|
||||||
crate::traits::Reveal,
|
crate::traits::Reveal,
|
||||||
crate::ty::adjustment::AutoBorrowMutability,
|
crate::ty::adjustment::AutoBorrowMutability,
|
||||||
crate::ty::AdtKind,
|
crate::ty::AdtKind,
|
||||||
|
crate::ty::BoundConstness,
|
||||||
// Including `BoundRegionKind` is a *bit* dubious, but direct
|
// Including `BoundRegionKind` is a *bit* dubious, but direct
|
||||||
// references to bound region appear in `ty::Error`, and aren't
|
// references to bound region appear in `ty::Error`, and aren't
|
||||||
// really meant to be folded. In general, we can only fold a fully
|
// really meant to be folded. In general, we can only fold a fully
|
||||||
|
|
|
@ -878,7 +878,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
|
||||||
pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
|
pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
|
||||||
self.map_bound(|trait_ref| ty::TraitPredicate {
|
self.map_bound(|trait_ref| ty::TraitPredicate {
|
||||||
trait_ref,
|
trait_ref,
|
||||||
constness: hir::Constness::NotConst,
|
constness: ty::BoundConstness::NotConst,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use rustc_hir as hir;
|
|
||||||
use rustc_infer::infer::canonical::Canonical;
|
use rustc_infer::infer::canonical::Canonical;
|
||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
use rustc_middle::mir::ConstraintCategory;
|
use rustc_middle::mir::ConstraintCategory;
|
||||||
|
@ -88,7 +87,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
self.prove_predicates(
|
self.prove_predicates(
|
||||||
Some(ty::PredicateKind::Trait(ty::TraitPredicate {
|
Some(ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||||
trait_ref,
|
trait_ref,
|
||||||
constness: hir::Constness::NotConst,
|
constness: ty::BoundConstness::NotConst,
|
||||||
})),
|
})),
|
||||||
locations,
|
locations,
|
||||||
category,
|
category,
|
||||||
|
|
|
@ -821,7 +821,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
|
||||||
param_env,
|
param_env,
|
||||||
Binder::dummy(TraitPredicate {
|
Binder::dummy(TraitPredicate {
|
||||||
trait_ref,
|
trait_ref,
|
||||||
constness: hir::Constness::Const,
|
constness: ty::BoundConstness::ConstIfConst,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -831,7 +831,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
|
||||||
});
|
});
|
||||||
|
|
||||||
match implsrc {
|
match implsrc {
|
||||||
Ok(Some(ImplSource::Param(_, hir::Constness::Const))) => {
|
Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => {
|
||||||
debug!(
|
debug!(
|
||||||
"const_trait_impl: provided {:?} via where-clause in {:?}",
|
"const_trait_impl: provided {:?} via where-clause in {:?}",
|
||||||
trait_ref, param_env
|
trait_ref, param_env
|
||||||
|
|
|
@ -285,7 +285,7 @@ impl AutoTraitFinder<'tcx> {
|
||||||
def_id: trait_did,
|
def_id: trait_did,
|
||||||
substs: infcx.tcx.mk_substs_trait(ty, &[]),
|
substs: infcx.tcx.mk_substs_trait(ty, &[]),
|
||||||
},
|
},
|
||||||
constness: hir::Constness::NotConst,
|
constness: ty::BoundConstness::NotConst,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let computed_preds = param_env.caller_bounds().iter();
|
let computed_preds = param_env.caller_bounds().iter();
|
||||||
|
|
|
@ -778,7 +778,7 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot(
|
||||||
let obligation = Obligation::new(
|
let obligation = Obligation::new(
|
||||||
ObligationCause::dummy(),
|
ObligationCause::dummy(),
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
ty::Binder::dummy(ty::TraitPredicate { trait_ref, constness: hir::Constness::NotConst }),
|
ty::Binder::dummy(ty::TraitPredicate { trait_ref, constness: ty::BoundConstness::NotConst }),
|
||||||
);
|
);
|
||||||
|
|
||||||
let implsrc = tcx.infer_ctxt().enter(|infcx| {
|
let implsrc = tcx.infer_ctxt().enter(|infcx| {
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
//! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation
|
//! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::Constness;
|
|
||||||
use rustc_index::bit_set::GrowableBitSet;
|
use rustc_index::bit_set::GrowableBitSet;
|
||||||
use rustc_infer::infer::InferOk;
|
use rustc_infer::infer::InferOk;
|
||||||
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
|
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
|
||||||
|
@ -75,7 +74,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
ProjectionCandidate(idx) => {
|
ProjectionCandidate(idx) => {
|
||||||
let obligations = self.confirm_projection_candidate(obligation, idx)?;
|
let obligations = self.confirm_projection_candidate(obligation, idx)?;
|
||||||
// FIXME(jschievink): constness
|
// FIXME(jschievink): constness
|
||||||
Ok(ImplSource::Param(obligations, Constness::NotConst))
|
Ok(ImplSource::Param(obligations, ty::BoundConstness::NotConst))
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectCandidate(idx) => {
|
ObjectCandidate(idx) => {
|
||||||
|
@ -113,7 +112,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// This indicates something like `Trait + Send: Send`. In this case, we know that
|
// This indicates something like `Trait + Send: Send`. In this case, we know that
|
||||||
// this holds because that's what the object type is telling us, and there's really
|
// this holds because that's what the object type is telling us, and there's really
|
||||||
// no additional obligations to prove and no types in particular to unify, etc.
|
// no additional obligations to prove and no types in particular to unify, etc.
|
||||||
Ok(ImplSource::Param(Vec::new(), Constness::NotConst))
|
Ok(ImplSource::Param(Vec::new(), ty::BoundConstness::NotConst))
|
||||||
}
|
}
|
||||||
|
|
||||||
BuiltinUnsizeCandidate => {
|
BuiltinUnsizeCandidate => {
|
||||||
|
|
|
@ -32,7 +32,6 @@ use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::ErrorReported;
|
use rustc_errors::ErrorReported;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::Constness;
|
|
||||||
use rustc_infer::infer::LateBoundRegionConversionTime;
|
use rustc_infer::infer::LateBoundRegionConversionTime;
|
||||||
use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
|
use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
|
||||||
use rustc_middle::mir::abstract_const::NotConstEvaluatable;
|
use rustc_middle::mir::abstract_const::NotConstEvaluatable;
|
||||||
|
@ -130,8 +129,8 @@ pub struct SelectionContext<'cx, 'tcx> {
|
||||||
/// and a negative impl
|
/// and a negative impl
|
||||||
allow_negative_impls: bool,
|
allow_negative_impls: bool,
|
||||||
|
|
||||||
/// Do we only want const impls when we have a const trait predicate?
|
/// Are we in a const context that needs `~const` bounds to be const?
|
||||||
const_impls_required: bool,
|
is_in_const_context: bool,
|
||||||
|
|
||||||
/// The mode that trait queries run in, which informs our error handling
|
/// The mode that trait queries run in, which informs our error handling
|
||||||
/// policy. In essence, canonicalized queries need their errors propagated
|
/// policy. In essence, canonicalized queries need their errors propagated
|
||||||
|
@ -224,7 +223,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
intercrate: false,
|
intercrate: false,
|
||||||
intercrate_ambiguity_causes: None,
|
intercrate_ambiguity_causes: None,
|
||||||
allow_negative_impls: false,
|
allow_negative_impls: false,
|
||||||
const_impls_required: false,
|
is_in_const_context: false,
|
||||||
query_mode: TraitQueryMode::Standard,
|
query_mode: TraitQueryMode::Standard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,7 +235,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
intercrate: true,
|
intercrate: true,
|
||||||
intercrate_ambiguity_causes: None,
|
intercrate_ambiguity_causes: None,
|
||||||
allow_negative_impls: false,
|
allow_negative_impls: false,
|
||||||
const_impls_required: false,
|
is_in_const_context: false,
|
||||||
query_mode: TraitQueryMode::Standard,
|
query_mode: TraitQueryMode::Standard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,7 +251,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
intercrate: false,
|
intercrate: false,
|
||||||
intercrate_ambiguity_causes: None,
|
intercrate_ambiguity_causes: None,
|
||||||
allow_negative_impls,
|
allow_negative_impls,
|
||||||
const_impls_required: false,
|
is_in_const_context: false,
|
||||||
query_mode: TraitQueryMode::Standard,
|
query_mode: TraitQueryMode::Standard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,7 +267,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
intercrate: false,
|
intercrate: false,
|
||||||
intercrate_ambiguity_causes: None,
|
intercrate_ambiguity_causes: None,
|
||||||
allow_negative_impls: false,
|
allow_negative_impls: false,
|
||||||
const_impls_required: false,
|
is_in_const_context: false,
|
||||||
query_mode,
|
query_mode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,7 +282,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
intercrate: false,
|
intercrate: false,
|
||||||
intercrate_ambiguity_causes: None,
|
intercrate_ambiguity_causes: None,
|
||||||
allow_negative_impls: false,
|
allow_negative_impls: false,
|
||||||
const_impls_required: matches!(constness, hir::Constness::Const),
|
is_in_const_context: matches!(constness, hir::Constness::Const),
|
||||||
query_mode: TraitQueryMode::Standard,
|
query_mode: TraitQueryMode::Standard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,14 +315,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the trait predicate is considerd `const` to this selection context.
|
||||||
|
pub fn is_trait_predicate_const(&self, pred: ty::TraitPredicate<'_>) -> bool {
|
||||||
|
match pred.constness {
|
||||||
|
ty::BoundConstness::ConstIfConst if self.is_in_const_context => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if the predicate is considered `const` to
|
/// Returns `true` if the predicate is considered `const` to
|
||||||
/// this selection context.
|
/// this selection context.
|
||||||
pub fn is_predicate_const(&self, pred: ty::Predicate<'_>) -> bool {
|
pub fn is_predicate_const(&self, pred: ty::Predicate<'_>) -> bool {
|
||||||
match pred.kind().skip_binder() {
|
match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Trait(ty::TraitPredicate {
|
ty::PredicateKind::Trait(pred) => self.is_trait_predicate_const(pred),
|
||||||
constness: hir::Constness::Const,
|
|
||||||
..
|
|
||||||
}) if self.const_impls_required => true,
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1074,8 +1078,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
|
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
// Respect const trait obligations
|
// Respect const trait obligations
|
||||||
if self.const_impls_required {
|
if self.is_trait_predicate_const(obligation.predicate.skip_binder()) {
|
||||||
if let hir::Constness::Const = obligation.predicate.skip_binder().constness {
|
|
||||||
if Some(obligation.predicate.skip_binder().trait_ref.def_id)
|
if Some(obligation.predicate.skip_binder().trait_ref.def_id)
|
||||||
!= tcx.lang_items().sized_trait()
|
!= tcx.lang_items().sized_trait()
|
||||||
// const Sized bounds are skipped
|
// const Sized bounds are skipped
|
||||||
|
@ -1086,7 +1089,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
if tcx.impl_constness(def_id) == hir::Constness::Const => {}
|
if tcx.impl_constness(def_id) == hir::Constness::Const => {}
|
||||||
// const param
|
// const param
|
||||||
ParamCandidate(ty::ConstnessAnd {
|
ParamCandidate(ty::ConstnessAnd {
|
||||||
constness: hir::Constness::Const,
|
constness: ty::BoundConstness::ConstIfConst,
|
||||||
..
|
..
|
||||||
}) => {}
|
}) => {}
|
||||||
// auto trait impl
|
// auto trait impl
|
||||||
|
@ -1100,7 +1103,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Treat negative impls as unimplemented, and reservation impls as ambiguity.
|
// Treat negative impls as unimplemented, and reservation impls as ambiguity.
|
||||||
if let ImplCandidate(def_id) = candidate {
|
if let ImplCandidate(def_id) = candidate {
|
||||||
|
@ -1495,7 +1497,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// probably best characterized as a "hack", since we might prefer to just do our
|
// probably best characterized as a "hack", since we might prefer to just do our
|
||||||
// best to *not* create essentially duplicate candidates in the first place.
|
// best to *not* create essentially duplicate candidates in the first place.
|
||||||
other.value.bound_vars().len() <= victim.value.bound_vars().len()
|
other.value.bound_vars().len() <= victim.value.bound_vars().len()
|
||||||
} else if other.value == victim.value && victim.constness == Constness::NotConst {
|
} else if other.value == victim.value && victim.constness == ty::BoundConstness::NotConst {
|
||||||
// Drop otherwise equivalent non-const candidates in favor of const candidates.
|
// Drop otherwise equivalent non-const candidates in favor of const candidates.
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -20,7 +20,7 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::intravisit::{walk_generics, Visitor as _};
|
use rustc_hir::intravisit::{walk_generics, Visitor as _};
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::{Constness, GenericArg, GenericArgs};
|
use rustc_hir::{GenericArg, GenericArgs};
|
||||||
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, Subst, SubstsRef};
|
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, Subst, SubstsRef};
|
||||||
use rustc_middle::ty::GenericParamDefKind;
|
use rustc_middle::ty::GenericParamDefKind;
|
||||||
use rustc_middle::ty::{self, Const, DefIdTree, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, Const, DefIdTree, Ty, TyCtxt, TypeFoldable};
|
||||||
|
@ -47,8 +47,6 @@ pub trait AstConv<'tcx> {
|
||||||
|
|
||||||
fn item_def_id(&self) -> Option<DefId>;
|
fn item_def_id(&self) -> Option<DefId>;
|
||||||
|
|
||||||
fn default_constness_for_trait_bounds(&self) -> Constness;
|
|
||||||
|
|
||||||
/// Returns predicates in scope of the form `X: Foo<T>`, where `X`
|
/// Returns predicates in scope of the form `X: Foo<T>`, where `X`
|
||||||
/// is a type parameter `X` with the given id `def_id` and T
|
/// is a type parameter `X` with the given id `def_id` and T
|
||||||
/// matches `assoc_name`. This is a subset of the full set of
|
/// matches `assoc_name`. This is a subset of the full set of
|
||||||
|
@ -724,7 +722,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
&self,
|
&self,
|
||||||
trait_ref: &hir::TraitRef<'_>,
|
trait_ref: &hir::TraitRef<'_>,
|
||||||
span: Span,
|
span: Span,
|
||||||
constness: Constness,
|
constness: ty::BoundConstness,
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
bounds: &mut Bounds<'tcx>,
|
bounds: &mut Bounds<'tcx>,
|
||||||
speculative: bool,
|
speculative: bool,
|
||||||
|
@ -795,7 +793,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let bound_vars = tcx.late_bound_vars(hir_id);
|
let bound_vars = tcx.late_bound_vars(hir_id);
|
||||||
let poly_trait_ref =
|
let poly_trait_ref =
|
||||||
ty::Binder::bind_with_vars(ty::TraitRef::new(trait_def_id, substs), bound_vars);
|
ty::Binder::bind_with_vars(ty::TraitRef::new(trait_def_id, substs), bound_vars);
|
||||||
bounds.trait_bounds.push((poly_trait_ref, span, Constness::NotConst));
|
bounds.trait_bounds.push((poly_trait_ref, span, ty::BoundConstness::NotConst));
|
||||||
|
|
||||||
let mut dup_bindings = FxHashMap::default();
|
let mut dup_bindings = FxHashMap::default();
|
||||||
for binding in assoc_bindings {
|
for binding in assoc_bindings {
|
||||||
|
@ -920,14 +918,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
bounds: &mut Bounds<'tcx>,
|
bounds: &mut Bounds<'tcx>,
|
||||||
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
||||||
) {
|
) {
|
||||||
let constness = self.default_constness_for_trait_bounds();
|
|
||||||
for ast_bound in ast_bounds {
|
for ast_bound in ast_bounds {
|
||||||
match *ast_bound {
|
match *ast_bound {
|
||||||
hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => {
|
hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => {
|
||||||
self.instantiate_poly_trait_ref(
|
self.instantiate_poly_trait_ref(
|
||||||
&b.trait_ref,
|
&b.trait_ref,
|
||||||
b.span,
|
b.span,
|
||||||
Constness::NotConst,
|
ty::BoundConstness::NotConst,
|
||||||
param_ty,
|
param_ty,
|
||||||
bounds,
|
bounds,
|
||||||
false,
|
false,
|
||||||
|
@ -937,7 +934,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
self.instantiate_poly_trait_ref(
|
self.instantiate_poly_trait_ref(
|
||||||
&b.trait_ref,
|
&b.trait_ref,
|
||||||
b.span,
|
b.span,
|
||||||
constness,
|
ty::BoundConstness::ConstIfConst,
|
||||||
param_ty,
|
param_ty,
|
||||||
bounds,
|
bounds,
|
||||||
false,
|
false,
|
||||||
|
@ -1251,7 +1248,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
} = self.instantiate_poly_trait_ref(
|
} = self.instantiate_poly_trait_ref(
|
||||||
&trait_bound.trait_ref,
|
&trait_bound.trait_ref,
|
||||||
trait_bound.span,
|
trait_bound.span,
|
||||||
Constness::NotConst,
|
ty::BoundConstness::NotConst,
|
||||||
dummy_self,
|
dummy_self,
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
false,
|
false,
|
||||||
|
@ -1330,7 +1327,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
.filter(|(trait_ref, _, _)| !tcx.trait_is_auto(trait_ref.def_id()));
|
.filter(|(trait_ref, _, _)| !tcx.trait_is_auto(trait_ref.def_id()));
|
||||||
|
|
||||||
for (base_trait_ref, span, constness) in regular_traits_refs_spans {
|
for (base_trait_ref, span, constness) in regular_traits_refs_spans {
|
||||||
assert_eq!(constness, Constness::NotConst);
|
assert_eq!(constness, ty::BoundConstness::NotConst);
|
||||||
|
|
||||||
for obligation in traits::elaborate_trait_ref(tcx, base_trait_ref) {
|
for obligation in traits::elaborate_trait_ref(tcx, base_trait_ref) {
|
||||||
debug!(
|
debug!(
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
//! Bounds are restrictions applied to some types after they've been converted into the
|
//! Bounds are restrictions applied to some types after they've been converted into the
|
||||||
//! `ty` form from the HIR.
|
//! `ty` form from the HIR.
|
||||||
|
|
||||||
use rustc_hir::Constness;
|
|
||||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
|
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
@ -30,7 +29,7 @@ pub struct Bounds<'tcx> {
|
||||||
|
|
||||||
/// A list of trait bounds. So if you had `T: Debug` this would be
|
/// A list of trait bounds. So if you had `T: Debug` this would be
|
||||||
/// `T: Debug`. Note that the self-type is explicit here.
|
/// `T: Debug`. Note that the self-type is explicit here.
|
||||||
pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span, Constness)>,
|
pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span, ty::BoundConstness)>,
|
||||||
|
|
||||||
/// A list of projection equality bounds. So if you had `T:
|
/// A list of projection equality bounds. So if you had `T:
|
||||||
/// Iterator<Item = u32>` this would include `<T as
|
/// Iterator<Item = u32>` this would include `<T as
|
||||||
|
|
|
@ -180,10 +180,6 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_constness_for_trait_bounds(&self) -> hir::Constness {
|
|
||||||
self.tcx.hir().get(self.body_id).constness_for_typeck()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_type_parameter_bounds(
|
fn get_type_parameter_bounds(
|
||||||
&self,
|
&self,
|
||||||
_: Span,
|
_: Span,
|
||||||
|
|
|
@ -365,10 +365,6 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
|
||||||
Some(self.item_def_id)
|
Some(self.item_def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_constness_for_trait_bounds(&self) -> hir::Constness {
|
|
||||||
self.node().constness_for_typeck()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_type_parameter_bounds(
|
fn get_type_parameter_bounds(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
@ -664,7 +660,6 @@ impl ItemCtxt<'tcx> {
|
||||||
only_self_bounds: OnlySelfBounds,
|
only_self_bounds: OnlySelfBounds,
|
||||||
assoc_name: Option<Ident>,
|
assoc_name: Option<Ident>,
|
||||||
) -> Vec<(ty::Predicate<'tcx>, Span)> {
|
) -> Vec<(ty::Predicate<'tcx>, Span)> {
|
||||||
let constness = self.default_constness_for_trait_bounds();
|
|
||||||
let from_ty_params = ast_generics
|
let from_ty_params = ast_generics
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -677,7 +672,7 @@ impl ItemCtxt<'tcx> {
|
||||||
Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name),
|
Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name),
|
||||||
None => true,
|
None => true,
|
||||||
})
|
})
|
||||||
.flat_map(|b| predicates_from_bound(self, ty, b, constness));
|
.flat_map(|b| predicates_from_bound(self, ty, b));
|
||||||
|
|
||||||
let from_where_clauses = ast_generics
|
let from_where_clauses = ast_generics
|
||||||
.where_clause
|
.where_clause
|
||||||
|
@ -703,7 +698,7 @@ impl ItemCtxt<'tcx> {
|
||||||
})
|
})
|
||||||
.filter_map(move |b| bt.map(|bt| (bt, b)))
|
.filter_map(move |b| bt.map(|bt| (bt, b)))
|
||||||
})
|
})
|
||||||
.flat_map(|(bt, b)| predicates_from_bound(self, bt, b, constness));
|
.flat_map(|(bt, b)| predicates_from_bound(self, bt, b));
|
||||||
|
|
||||||
from_ty_params.chain(from_where_clauses).collect()
|
from_ty_params.chain(from_where_clauses).collect()
|
||||||
}
|
}
|
||||||
|
@ -2031,7 +2026,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
||||||
let mut is_default_impl_trait = None;
|
let mut is_default_impl_trait = None;
|
||||||
|
|
||||||
let icx = ItemCtxt::new(tcx, def_id);
|
let icx = ItemCtxt::new(tcx, def_id);
|
||||||
let constness = icx.default_constness_for_trait_bounds();
|
|
||||||
|
|
||||||
const NO_GENERICS: &hir::Generics<'_> = &hir::Generics::empty();
|
const NO_GENERICS: &hir::Generics<'_> = &hir::Generics::empty();
|
||||||
|
|
||||||
|
@ -2227,8 +2221,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
||||||
match bound {
|
match bound {
|
||||||
hir::GenericBound::Trait(poly_trait_ref, modifier) => {
|
hir::GenericBound::Trait(poly_trait_ref, modifier) => {
|
||||||
let constness = match modifier {
|
let constness = match modifier {
|
||||||
hir::TraitBoundModifier::None => hir::Constness::NotConst,
|
hir::TraitBoundModifier::None => ty::BoundConstness::NotConst,
|
||||||
hir::TraitBoundModifier::MaybeConst => constness,
|
hir::TraitBoundModifier::MaybeConst => ty::BoundConstness::ConstIfConst,
|
||||||
// We ignore `where T: ?Sized`, it is already part of
|
// We ignore `where T: ?Sized`, it is already part of
|
||||||
// type parameter `T`.
|
// type parameter `T`.
|
||||||
hir::TraitBoundModifier::Maybe => continue,
|
hir::TraitBoundModifier::Maybe => continue,
|
||||||
|
@ -2491,14 +2485,13 @@ fn predicates_from_bound<'tcx>(
|
||||||
astconv: &dyn AstConv<'tcx>,
|
astconv: &dyn AstConv<'tcx>,
|
||||||
param_ty: Ty<'tcx>,
|
param_ty: Ty<'tcx>,
|
||||||
bound: &'tcx hir::GenericBound<'tcx>,
|
bound: &'tcx hir::GenericBound<'tcx>,
|
||||||
constness: hir::Constness,
|
|
||||||
) -> Vec<(ty::Predicate<'tcx>, Span)> {
|
) -> Vec<(ty::Predicate<'tcx>, Span)> {
|
||||||
match *bound {
|
match *bound {
|
||||||
hir::GenericBound::Trait(ref tr, modifier) => {
|
hir::GenericBound::Trait(ref tr, modifier) => {
|
||||||
let constness = match modifier {
|
let constness = match modifier {
|
||||||
hir::TraitBoundModifier::Maybe => return vec![],
|
hir::TraitBoundModifier::Maybe => return vec![],
|
||||||
hir::TraitBoundModifier::MaybeConst => constness,
|
hir::TraitBoundModifier::MaybeConst => ty::BoundConstness::ConstIfConst,
|
||||||
hir::TraitBoundModifier::None => hir::Constness::NotConst,
|
hir::TraitBoundModifier::None => ty::BoundConstness::NotConst,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
|
|
|
@ -68,7 +68,6 @@
|
||||||
use crate::constrained_generic_params as cgp;
|
use crate::constrained_generic_params as cgp;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_hir as hir;
|
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::{InferCtxt, RegionckMode, TyCtxtInferExt};
|
use rustc_infer::infer::{InferCtxt, RegionckMode, TyCtxtInferExt};
|
||||||
|
@ -368,7 +367,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
|
||||||
// items.
|
// items.
|
||||||
ty::PredicateKind::Trait(ty::TraitPredicate {
|
ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||||
trait_ref,
|
trait_ref,
|
||||||
constness: hir::Constness::NotConst,
|
constness: ty::BoundConstness::NotConst,
|
||||||
}) => {
|
}) => {
|
||||||
if !matches!(
|
if !matches!(
|
||||||
trait_predicate_kind(tcx, predicate),
|
trait_predicate_kind(tcx, predicate),
|
||||||
|
@ -399,7 +398,7 @@ fn trait_predicate_kind<'tcx>(
|
||||||
match predicate.kind().skip_binder() {
|
match predicate.kind().skip_binder() {
|
||||||
ty::PredicateKind::Trait(ty::TraitPredicate {
|
ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||||
trait_ref,
|
trait_ref,
|
||||||
constness: hir::Constness::NotConst,
|
constness: ty::BoundConstness::NotConst,
|
||||||
}) => Some(tcx.trait_def(trait_ref.def_id).specialization_kind),
|
}) => Some(tcx.trait_def(trait_ref.def_id).specialization_kind),
|
||||||
ty::PredicateKind::Trait(_)
|
ty::PredicateKind::Trait(_)
|
||||||
| ty::PredicateKind::RegionOutlives(_)
|
| ty::PredicateKind::RegionOutlives(_)
|
||||||
|
|
|
@ -548,7 +548,7 @@ pub fn hir_trait_to_predicates<'tcx>(
|
||||||
&item_cx,
|
&item_cx,
|
||||||
hir_trait,
|
hir_trait,
|
||||||
DUMMY_SP,
|
DUMMY_SP,
|
||||||
hir::Constness::NotConst,
|
ty::BoundConstness::NotConst,
|
||||||
self_ty,
|
self_ty,
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
true,
|
true,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue