Closed Dirbaio closed 2 years ago
Builds correctly with rustc 1.53.0-nightly (5e65467ef 2021-03-26)
Fails with rustc 1.53.0-nightly (9b0edb7fd 2021-03-27)
Fails with
rustc 1.53.0-nightly (9b0edb7fd 2021-03-27)
@Dirbaio 9b0edb7fd
appears to be nightly-2021-03-28, which I agree is the first regression.
searched nightlies: from nightly-2021-03-26 to nightly-2021-04-07 regressed nightly: nightly-2021-03-28 searched commits: from https://github.com/rust-lang/rust/commit/5e65467eff3d1da4712586d8402d1d2e1d6654bc to https://github.com/rust-lang/rust/commit/9b0edb7fddacd6a60a380c1ce59159de597ab270 regressed commit: https://github.com/rust-lang/rust/commit/9b0edb7fddacd6a60a380c1ce59159de597ab270
The code I originally found this in does require #![feature(const_generics)]
and #![feature(const_evaluatable_checked)]
, but while minimizing it I arrived to this.
The error also disappears when removing the braces in { 4 }
const_generics
feature enables lazy normalization. It seems that in one place a symbol name is constructed using an unevaluated const, while the other uses the evaluated one. This crates a mismatch in legacy symbol mangling scheme. The issue also disappears in -Zsymbol-mangling-version=v0
which evaluates the const during mangling.
$ rustc -Zprint-mono-items=lazy -Zverbose ...
MONO_ITEM fn <FooImpl<Const(Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:18 ~ a[317d]::{impl#1}::Foo::{constant#0}), const_param_did: Some(DefId(0:7 ~ a[317d]::FooImpl::N)) }, substs: [], promoted: None }): usize)> as Foo>::foo @@ a.7rcbfp3g-cgu.0[Internal]
input to MirNeighborCollector::monomorphize for<'r> fn(&'r <B as Bar>::Foo) {<<B as Bar>::Foo as Foo>::foo}
after subst_mir_and_normalize_erasing_regions for<'r> fn(&'r FooImpl<{ 4 }>) {<FooImpl<{ 4 }> as Foo>::foo}
after an exra normalize_erasing_regions (*) for<'r> fn(&'r FooImpl<4_usize>) {<FooImpl<4_usize> as Foo>::foo}
Verbose:
input to MirNeighborCollector::monomorphize for<'r> fn(&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) <B as Bar>::Foo) {<<B as Bar>::Foo as Foo>::foo}
after subst_mir_and_normalize_erasing_regions for<'r> fn(&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) FooImpl<Const(Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:18 ~ a[317d]::{impl#1}::Foo::{constant#0}), const_param_did: Some(DefId(0:7 ~ a[317d]::FooImpl::N)) }, substs: [], promoted: None }): usize)>) {<FooImpl<Const(Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:18 ~ a[317d]::{impl#1}::Foo::{constant#0}), const_param_did: Some(DefId(0:7 ~ a[317d]::FooImpl::N)) }, substs: [], promoted: None }): usize)> as Foo>::foo}
after an extra normalize_erasing_regions (*) for<'r> fn(&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) FooImpl<Const(Value(Scalar(0x0000000000000004)): usize)>) {<FooImpl<Const(Value(Scalar(0x0000000000000004)): usize)> as Foo>::foo}
I'm seeing a similar error: #97186, with a very similar example!
It seems that Unevaluated
generic const parameters are making their way through monomorphization and into symbol mangling, which should definitely be fixed.
Passing -Zsymbol-mangling-version=v0
also fixes the linker error in my issue.
#![feature(generic_const_exprs)]
pub trait Foo {
fn foo(&self);
}
pub struct FooImpl<const N: usize>;
impl<const N: usize> Foo for FooImpl<N> {
fn foo(&self) {}
}
pub trait Bar: 'static {
type Foo: Foo;
fn get() -> &'static Self::Foo;
}
struct BarImpl;
impl Bar for BarImpl {
type Foo = FooImpl<{{ 4 }}>;
fn get() -> &'static Self::Foo {
&FooImpl
}
}
pub fn boom<B: Bar>() {
B::get().foo();
}
fn main() {
boom::<BarImpl>();
}
still an issue but the repro is slightly different (added some {}
around { 4 }
and updated feature gate)
It seems that
Unevaluated
generic const parameters are making their way though monomorphization and into symbol mangling, which should definitely be fixed.
jup, should definitely be fixed
This code (playground)
fails to link with
rustc --version --verbose
: