Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 08c7ff2

Browse files
Restrict const ty's regions to static when putting them in canonical var list
1 parent 4ea92e3 commit 08c7ff2

File tree

6 files changed

+100
-24
lines changed

6 files changed

+100
-24
lines changed

‎compiler/rustc_middle/src/ty/region.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ impl<'tcx> rustc_type_ir::new::Region<TyCtxt<'tcx>> for Region<'tcx> {
140140
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
141141
Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon })
142142
}
143+
144+
fn new_static(tcx: TyCtxt<'tcx>) -> Self {
145+
tcx.lifetimes.re_static
146+
}
143147
}
144148

145149
/// Region utilities

‎compiler/rustc_next_trait_solver/src/canonicalizer.rs‎

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -382,43 +382,47 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
382382
where
383383
I::Const: TypeSuperFoldable<I>,
384384
{
385+
// We could canonicalize all consts with static types, but the only ones we
386+
// *really* need to worry about are the ones that we end up putting into `CanonicalVarKind`
387+
// since canonical vars can't reference other canonical vars.
388+
let ty = c
389+
.ty()
390+
.fold_with(&mut RegionsToStatic { interner: self.interner(), binder: ty::INNERMOST });
385391
let kind = match c.kind() {
386-
ty::ConstKind::Infer(i) => {
387-
// FIXME: we should fold the ty too eventually
388-
match i {
389-
ty::InferConst::Var(vid) => {
390-
assert_eq!(
391-
self.infcx.root_ct_var(vid),
392-
vid,
393-
"region vid should have been resolved fully before canonicalization"
394-
);
395-
assert_eq!(
396-
self.infcx.probe_ct_var(vid),
397-
None,
398-
"region vid should have been resolved fully before canonicalization"
399-
);
400-
CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), c.ty())
401-
}
402-
ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect,
403-
ty::InferConst::Fresh(_) => todo!(),
392+
ty::ConstKind::Infer(i) => match i {
393+
ty::InferConst::Var(vid) => {
394+
assert_eq!(
395+
self.infcx.root_ct_var(vid),
396+
vid,
397+
"region vid should have been resolved fully before canonicalization"
398+
);
399+
assert_eq!(
400+
self.infcx.probe_ct_var(vid),
401+
None,
402+
"region vid should have been resolved fully before canonicalization"
403+
);
404+
CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), ty)
404405
}
405-
}
406+
ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect,
407+
ty::InferConst::Fresh(_) => todo!(),
408+
},
406409
ty::ConstKind::Placeholder(placeholder) => match self.canonicalize_mode {
407410
CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
408411
PlaceholderLike::new(placeholder.universe(), self.variables.len().into()),
409-
c.ty(),
412+
ty,
410413
),
411414
CanonicalizeMode::Response { .. } => {
412-
CanonicalVarKind::PlaceholderConst(placeholder, c.ty())
415+
CanonicalVarKind::PlaceholderConst(placeholder, ty)
413416
}
414417
},
415418
ty::ConstKind::Param(_) => match self.canonicalize_mode {
416419
CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
417420
PlaceholderLike::new(ty::UniverseIndex::ROOT, self.variables.len().into()),
418-
c.ty(),
421+
ty,
419422
),
420423
CanonicalizeMode::Response { .. } => panic!("param ty in response: {c:?}"),
421424
},
425+
// FIXME: See comment above -- we could fold the region separately or something.
422426
ty::ConstKind::Bound(_, _)
423427
| ty::ConstKind::Unevaluated(_)
424428
| ty::ConstKind::Value(_)
@@ -435,6 +439,35 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
435439
}),
436440
);
437441

438-
Const::new_anon_bound(self.interner(), self.binder_index, var, c.ty())
442+
Const::new_anon_bound(self.interner(), self.binder_index, var, ty)
443+
}
444+
}
445+
446+
struct RegionsToStatic<I> {
447+
interner: I,
448+
binder: ty::DebruijnIndex,
449+
}
450+
451+
impl<I: Interner> TypeFolder<I> for RegionsToStatic<I> {
452+
fn interner(&self) -> I {
453+
self.interner
454+
}
455+
456+
fn fold_binder<T>(&mut self, t: I::Binder<T>) -> I::Binder<T>
457+
where
458+
T: TypeFoldable<I>,
459+
I::Binder<T>: TypeSuperFoldable<I>,
460+
{
461+
self.binder.shift_in(1);
462+
let t = t.fold_with(self);
463+
self.binder.shift_out(1);
464+
t
465+
}
466+
467+
fn fold_region(&mut self, r: I::Region) -> I::Region {
468+
match r.kind() {
469+
ty::ReBound(db, _) if self.binder > db => r,
470+
_ => Region::new_static(self.interner()),
471+
}
439472
}
440473
}

‎compiler/rustc_type_ir/src/interner.rs‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ use smallvec::SmallVec;
22
use std::fmt::Debug;
33
use std::hash::Hash;
44

5+
use crate::fold::TypeSuperFoldable;
56
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
67
use crate::{
78
new, BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebugWithInfcx, RegionKind, TyKind,
89
UniverseIndex,
910
};
1011

11-
pub trait Interner: Sized {
12+
pub trait Interner: Sized + Copy{
1213
type DefId: Copy + Debug + Hash + Eq;
1314
type AdtDef: Copy + Debug + Hash + Eq;
1415

@@ -34,6 +35,7 @@ pub trait Interner: Sized {
3435
+ Into<Self::GenericArg>
3536
+ IntoKind<Kind = TyKind<Self>>
3637
+ TypeSuperVisitable<Self>
38+
+ TypeSuperFoldable<Self>
3739
+ Flags
3840
+ new::Ty<Self>;
3941
type Tys: Copy + Debug + Hash + Eq + IntoIterator<Item = Self::Ty>;
@@ -57,6 +59,7 @@ pub trait Interner: Sized {
5759
+ IntoKind<Kind = ConstKind<Self>>
5860
+ ConstTy<Self>
5961
+ TypeSuperVisitable<Self>
62+
+ TypeSuperFoldable<Self>
6063
+ Flags
6164
+ new::Const<Self>;
6265
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Eq;

‎compiler/rustc_type_ir/src/new.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ pub trait Ty<I: Interner<Ty = Self>> {
66

77
pub trait Region<I: Interner<Region = Self>> {
88
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
9+
10+
fn new_static(interner: I) -> Self;
911
}
1012

1113
pub trait Const<I: Interner<Const = Self>> {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//@ check-pass
2+
3+
#![feature(adt_const_params)]
4+
//~^ WARN the feature `adt_const_params` is incomplete
5+
#![feature(with_negative_coherence, negative_impls)]
6+
7+
pub trait A<const K: &'static str> {}
8+
pub trait C {}
9+
10+
11+
struct W<T>(T);
12+
13+
// Negative coherence:
14+
// Proving `W<!T>: !A<"">` requires proving `CONST alias-eq ""`, which requires proving
15+
// `CONST normalizes-to (?1c: &str)`. The type's region is uniquified, so it ends up being
16+
// put in to the canonical vars list with an infer region => ICE.
17+
impl<T> C for T where T: A<""> {}
18+
impl<T> C for W<T> {}
19+
20+
impl<T> !A<CONST> for W<T> {}
21+
const CONST: &str = "";
22+
23+
fn main() {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/regions-in-canonical.rs:3:12
3+
|
4+
LL | #![feature(adt_const_params)]
5+
| ^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
warning: 1 warning emitted
11+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /