Restrict const ty's regions to static when putting them in canonical var list
This commit is contained in:
parent
4ea92e3c7a
commit
08c7ff2264
@ -140,6 +140,10 @@ impl<'tcx> rustc_type_ir::new::Region<TyCtxt<'tcx>> for Region<'tcx> {
|
|||||||
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
|
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
|
||||||
Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon })
|
Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new_static(tcx: TyCtxt<'tcx>) -> Self {
|
||||||
|
tcx.lifetimes.re_static
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Region utilities
|
/// Region utilities
|
||||||
|
@ -382,10 +382,14 @@ fn fold_const(&mut self, c: I::Const) -> I::Const
|
|||||||
where
|
where
|
||||||
I::Const: TypeSuperFoldable<I>,
|
I::Const: TypeSuperFoldable<I>,
|
||||||
{
|
{
|
||||||
|
// We could canonicalize all consts with static types, but the only ones we
|
||||||
|
// *really* need to worry about are the ones that we end up putting into `CanonicalVarKind`
|
||||||
|
// since canonical vars can't reference other canonical vars.
|
||||||
|
let ty = c
|
||||||
|
.ty()
|
||||||
|
.fold_with(&mut RegionsToStatic { interner: self.interner(), binder: ty::INNERMOST });
|
||||||
let kind = match c.kind() {
|
let kind = match c.kind() {
|
||||||
ty::ConstKind::Infer(i) => {
|
ty::ConstKind::Infer(i) => match i {
|
||||||
// FIXME: we should fold the ty too eventually
|
|
||||||
match i {
|
|
||||||
ty::InferConst::Var(vid) => {
|
ty::InferConst::Var(vid) => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
self.infcx.root_ct_var(vid),
|
self.infcx.root_ct_var(vid),
|
||||||
@ -397,28 +401,28 @@ fn fold_const(&mut self, c: I::Const) -> I::Const
|
|||||||
None,
|
None,
|
||||||
"region vid should have been resolved fully before canonicalization"
|
"region vid should have been resolved fully before canonicalization"
|
||||||
);
|
);
|
||||||
CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), c.ty())
|
CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), ty)
|
||||||
}
|
}
|
||||||
ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect,
|
ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect,
|
||||||
ty::InferConst::Fresh(_) => todo!(),
|
ty::InferConst::Fresh(_) => todo!(),
|
||||||
}
|
},
|
||||||
}
|
|
||||||
ty::ConstKind::Placeholder(placeholder) => match self.canonicalize_mode {
|
ty::ConstKind::Placeholder(placeholder) => match self.canonicalize_mode {
|
||||||
CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
|
CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
|
||||||
PlaceholderLike::new(placeholder.universe(), self.variables.len().into()),
|
PlaceholderLike::new(placeholder.universe(), self.variables.len().into()),
|
||||||
c.ty(),
|
ty,
|
||||||
),
|
),
|
||||||
CanonicalizeMode::Response { .. } => {
|
CanonicalizeMode::Response { .. } => {
|
||||||
CanonicalVarKind::PlaceholderConst(placeholder, c.ty())
|
CanonicalVarKind::PlaceholderConst(placeholder, ty)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ty::ConstKind::Param(_) => match self.canonicalize_mode {
|
ty::ConstKind::Param(_) => match self.canonicalize_mode {
|
||||||
CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
|
CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
|
||||||
PlaceholderLike::new(ty::UniverseIndex::ROOT, self.variables.len().into()),
|
PlaceholderLike::new(ty::UniverseIndex::ROOT, self.variables.len().into()),
|
||||||
c.ty(),
|
ty,
|
||||||
),
|
),
|
||||||
CanonicalizeMode::Response { .. } => panic!("param ty in response: {c:?}"),
|
CanonicalizeMode::Response { .. } => panic!("param ty in response: {c:?}"),
|
||||||
},
|
},
|
||||||
|
// FIXME: See comment above -- we could fold the region separately or something.
|
||||||
ty::ConstKind::Bound(_, _)
|
ty::ConstKind::Bound(_, _)
|
||||||
| ty::ConstKind::Unevaluated(_)
|
| ty::ConstKind::Unevaluated(_)
|
||||||
| ty::ConstKind::Value(_)
|
| ty::ConstKind::Value(_)
|
||||||
@ -435,6 +439,35 @@ fn fold_const(&mut self, c: I::Const) -> I::Const
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
Const::new_anon_bound(self.interner(), self.binder_index, var, c.ty())
|
Const::new_anon_bound(self.interner(), self.binder_index, var, ty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RegionsToStatic<I> {
|
||||||
|
interner: I,
|
||||||
|
binder: ty::DebruijnIndex,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> TypeFolder<I> for RegionsToStatic<I> {
|
||||||
|
fn interner(&self) -> I {
|
||||||
|
self.interner
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_binder<T>(&mut self, t: I::Binder<T>) -> I::Binder<T>
|
||||||
|
where
|
||||||
|
T: TypeFoldable<I>,
|
||||||
|
I::Binder<T>: TypeSuperFoldable<I>,
|
||||||
|
{
|
||||||
|
self.binder.shift_in(1);
|
||||||
|
let t = t.fold_with(self);
|
||||||
|
self.binder.shift_out(1);
|
||||||
|
t
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_region(&mut self, r: I::Region) -> I::Region {
|
||||||
|
match r.kind() {
|
||||||
|
ty::ReBound(db, _) if self.binder > db => r,
|
||||||
|
_ => Region::new_static(self.interner()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,14 @@
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
use crate::fold::TypeSuperFoldable;
|
||||||
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
||||||
use crate::{
|
use crate::{
|
||||||
new, BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebugWithInfcx, RegionKind, TyKind,
|
new, BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebugWithInfcx, RegionKind, TyKind,
|
||||||
UniverseIndex,
|
UniverseIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Interner: Sized {
|
pub trait Interner: Sized + Copy {
|
||||||
type DefId: Copy + Debug + Hash + Eq;
|
type DefId: Copy + Debug + Hash + Eq;
|
||||||
type AdtDef: Copy + Debug + Hash + Eq;
|
type AdtDef: Copy + Debug + Hash + Eq;
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ pub trait Interner: Sized {
|
|||||||
+ Into<Self::GenericArg>
|
+ Into<Self::GenericArg>
|
||||||
+ IntoKind<Kind = TyKind<Self>>
|
+ IntoKind<Kind = TyKind<Self>>
|
||||||
+ TypeSuperVisitable<Self>
|
+ TypeSuperVisitable<Self>
|
||||||
|
+ TypeSuperFoldable<Self>
|
||||||
+ Flags
|
+ Flags
|
||||||
+ new::Ty<Self>;
|
+ new::Ty<Self>;
|
||||||
type Tys: Copy + Debug + Hash + Eq + IntoIterator<Item = Self::Ty>;
|
type Tys: Copy + Debug + Hash + Eq + IntoIterator<Item = Self::Ty>;
|
||||||
@ -57,6 +59,7 @@ pub trait Interner: Sized {
|
|||||||
+ IntoKind<Kind = ConstKind<Self>>
|
+ IntoKind<Kind = ConstKind<Self>>
|
||||||
+ ConstTy<Self>
|
+ ConstTy<Self>
|
||||||
+ TypeSuperVisitable<Self>
|
+ TypeSuperVisitable<Self>
|
||||||
|
+ TypeSuperFoldable<Self>
|
||||||
+ Flags
|
+ Flags
|
||||||
+ new::Const<Self>;
|
+ new::Const<Self>;
|
||||||
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
||||||
|
@ -6,6 +6,8 @@ pub trait Ty<I: Interner<Ty = Self>> {
|
|||||||
|
|
||||||
pub trait Region<I: Interner<Region = Self>> {
|
pub trait Region<I: Interner<Region = Self>> {
|
||||||
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
|
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
|
||||||
|
|
||||||
|
fn new_static(interner: I) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Const<I: Interner<Const = Self>> {
|
pub trait Const<I: Interner<Const = Self>> {
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(adt_const_params)]
|
||||||
|
//~^ WARN the feature `adt_const_params` is incomplete
|
||||||
|
#![feature(with_negative_coherence, negative_impls)]
|
||||||
|
|
||||||
|
pub trait A<const K: &'static str> {}
|
||||||
|
pub trait C {}
|
||||||
|
|
||||||
|
|
||||||
|
struct W<T>(T);
|
||||||
|
|
||||||
|
// Negative coherence:
|
||||||
|
// Proving `W<!T>: !A<"">` requires proving `CONST alias-eq ""`, which requires proving
|
||||||
|
// `CONST normalizes-to (?1c: &str)`. The type's region is uniquified, so it ends up being
|
||||||
|
// put in to the canonical vars list with an infer region => ICE.
|
||||||
|
impl<T> C for T where T: A<""> {}
|
||||||
|
impl<T> C for W<T> {}
|
||||||
|
|
||||||
|
impl<T> !A<CONST> for W<T> {}
|
||||||
|
const CONST: &str = "";
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,11 @@
|
|||||||
|
warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/regions-in-canonical.rs:3:12
|
||||||
|
|
|
||||||
|
LL | #![feature(adt_const_params)]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
Loading…
Reference in New Issue
Block a user