Auto merge of #88328 - fee1-dead:not-quite-const, r=oli-obk
Introduce `~const` - [x] Removed `?const` and change uses of `?const` - [x] Added `~const` to the AST. It is gated behind const_trait_impl. - [x] Validate `~const` in ast_validation. - [x] Update UI Tests - [x] Add enum `BoundConstness` (With variants `NotConst` and `ConstIfConst` allowing future extensions) - [x] Adjust trait selection and pre-existing code to use `BoundConstness`. - [ ] Optional steps for this PR - [x] Fix #88155 - [x] ~~Do something with constness bounds in chalk~~ Must be done to rust-lang/chalk (just tried to refactor, there are a lot of errors to resolve :( ) - [ ] Adjust Error messages for `~const` bounds that can't be satisfied. r? `@oli-obk`
This commit is contained in:
commit
ac50a53359
79 changed files with 501 additions and 545 deletions
|
@ -17,7 +17,6 @@ use rustc_data_structures::sync::Lrc;
|
|||
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::Constness;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use smallvec::SmallVec;
|
||||
|
@ -497,7 +496,7 @@ pub enum ImplSource<'tcx, N> {
|
|||
/// for some type parameter. The `Vec<N>` represents the
|
||||
/// obligations incurred from normalizing the where-clause (if
|
||||
/// any).
|
||||
Param(Vec<N>, Constness),
|
||||
Param(Vec<N>, ty::BoundConstness),
|
||||
|
||||
/// Virtual calls through an object.
|
||||
Object(ImplSourceObjectData<'tcx, N>),
|
||||
|
|
|
@ -33,7 +33,7 @@ impl<T> ExpectedFound<T> {
|
|||
#[derive(Clone, Debug, TypeFoldable)]
|
||||
pub enum TypeError<'tcx> {
|
||||
Mismatch,
|
||||
ConstnessMismatch(ExpectedFound<hir::Constness>),
|
||||
ConstnessMismatch(ExpectedFound<ty::BoundConstness>),
|
||||
UnsafetyMismatch(ExpectedFound<hir::Unsafety>),
|
||||
AbiMismatch(ExpectedFound<abi::Abi>),
|
||||
Mutability,
|
||||
|
@ -102,7 +102,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
|
|||
CyclicConst(_) => write!(f, "encountered a self-referencing constant"),
|
||||
Mismatch => write!(f, "types differ"),
|
||||
ConstnessMismatch(values) => {
|
||||
write!(f, "expected {} fn, found {} fn", values.expected, values.found)
|
||||
write!(f, "expected {} bound, found {} bound", values.expected, values.found)
|
||||
}
|
||||
UnsafetyMismatch(values) => {
|
||||
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::def::{CtorKind, CtorOf, DefKind, Res};
|
||||
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_span::symbol::{kw, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
|
@ -181,6 +181,25 @@ pub enum Visibility {
|
|||
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(
|
||||
Clone,
|
||||
Debug,
|
||||
|
@ -457,10 +476,6 @@ pub enum PredicateKind<'tcx> {
|
|||
/// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
|
||||
/// the `Self` type of the trait reference and `A`, `B`, and `C`
|
||||
/// would be the type parameters.
|
||||
///
|
||||
/// A trait predicate will have `Constness::Const` if it originates
|
||||
/// from a bound on a `const fn` without the `?const` opt-out (e.g.,
|
||||
/// `const fn foobar<Foo: Bar>() {}`).
|
||||
Trait(TraitPredicate<'tcx>),
|
||||
|
||||
/// `where 'a: 'b`
|
||||
|
@ -632,10 +647,7 @@ impl<'tcx> Predicate<'tcx> {
|
|||
pub struct TraitPredicate<'tcx> {
|
||||
pub trait_ref: TraitRef<'tcx>,
|
||||
|
||||
/// A trait predicate will have `Constness::Const` if it originates
|
||||
/// from a bound on a `const fn` without the `?const` opt-out (e.g.,
|
||||
/// `const fn foobar<Foo: Bar>() {}`).
|
||||
pub constness: hir::Constness,
|
||||
pub constness: BoundConstness,
|
||||
}
|
||||
|
||||
pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
|
||||
|
@ -1304,7 +1316,7 @@ impl<'tcx> ParamEnv<'tcx> {
|
|||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
|
||||
pub struct ConstnessAnd<T> {
|
||||
pub constness: Constness,
|
||||
pub constness: BoundConstness,
|
||||
pub value: T,
|
||||
}
|
||||
|
||||
|
@ -1312,18 +1324,18 @@ pub struct ConstnessAnd<T> {
|
|||
// the constness of trait bounds is being propagated correctly.
|
||||
pub trait WithConstness: Sized {
|
||||
#[inline]
|
||||
fn with_constness(self, constness: Constness) -> ConstnessAnd<Self> {
|
||||
fn with_constness(self, constness: BoundConstness) -> ConstnessAnd<Self> {
|
||||
ConstnessAnd { constness, value: self }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_const(self) -> ConstnessAnd<Self> {
|
||||
self.with_constness(Constness::Const)
|
||||
fn with_const_if_const(self) -> ConstnessAnd<Self> {
|
||||
self.with_constness(BoundConstness::ConstIfConst)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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>>(
|
||||
relation: &mut R,
|
||||
a: ast::Constness,
|
||||
b: ast::Constness,
|
||||
) -> RelateResult<'tcx, ast::Constness> {
|
||||
a: ty::BoundConstness,
|
||||
b: ty::BoundConstness,
|
||||
) -> RelateResult<'tcx, ty::BoundConstness> {
|
||||
if a != b {
|
||||
Err(TypeError::ConstnessMismatch(expected_found(relation, a, b)))
|
||||
} 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::{self, InferConst, Lift, Ty, TyCtxt};
|
||||
use rustc_data_structures::functor::IdFunctor;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Namespace;
|
||||
use rustc_hir::def_id::CRATE_DEF_INDEX;
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
|
@ -155,8 +154,8 @@ impl fmt::Debug for ty::ParamConst {
|
|||
|
||||
impl fmt::Debug for ty::TraitPredicate<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if let hir::Constness::Const = self.constness {
|
||||
write!(f, "const ")?;
|
||||
if let ty::BoundConstness::ConstIfConst = self.constness {
|
||||
write!(f, "~const ")?;
|
||||
}
|
||||
write!(f, "TraitPredicate({:?})", self.trait_ref)
|
||||
}
|
||||
|
@ -241,6 +240,7 @@ TrivialTypeFoldableAndLiftImpls! {
|
|||
crate::traits::Reveal,
|
||||
crate::ty::adjustment::AutoBorrowMutability,
|
||||
crate::ty::AdtKind,
|
||||
crate::ty::BoundConstness,
|
||||
// Including `BoundRegionKind` is a *bit* dubious, but direct
|
||||
// references to bound region appear in `ty::Error`, and aren't
|
||||
// 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> {
|
||||
self.map_bound(|trait_ref| ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: hir::Constness::NotConst,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue