Change:
This code fails to link with :
Builds correctly with Fails with
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 to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.0</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
The code I originally found this in does require and , but while minimizing it I arrived to this. The error also disappears when removing the braces in
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 which evaluates the const during mangling. Verbose:
I'm seeing a similar error: , with a very similar example! It seems that generic const parameters are making their way through monomorphization and into symbol mangling, which should definitely be fixed. Passing also fixes the linker error in my issue.
still an issue but the repro is slightly different ( some around and updated feature gate)
jup, should definitely be fixed

Discussion:
debug!("QueryNormalizer: result = {:#?}", result); debug!("QueryNormalizer: obligations = {:#?}", obligations); self.obligations.extend(obligations); <del> Ok(result.normalized_ty) </del> <ins> let res = result.normalized_ty; // `tcx.normalize_projection_ty` may normalize to a type that still has // unevaluated consts, so keep normalizing here if that's the case. if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) { Ok(res.try_super_fold_with(self)?) } else { Ok(res) } </ins> } ty::Projection(data) => {

debug!("QueryNormalizer: result = {:#?}", result); debug!("QueryNormalizer: obligations = {:#?}", obligations); self.obligations.extend(obligations); <del> Ok(crate::traits::project::PlaceholderReplacer::replace_placeholders( </del> <ins> let res = crate::traits::project::PlaceholderReplacer::replace_placeholders( </ins> infcx, mapped_regions, mapped_types, mapped_consts, &self.universes, result.normalized_ty, <del> )) </del> <ins> ); // `tcx.normalize_projection_ty` may normalize to a type that still has // unevaluated consts, so keep normalizing here if that's the case. if res != ty && res.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) { Ok(res.try_super_fold_with(self)?) } else { Ok(res) } </ins> } _ => ty.try_super_fold_with(self), })()?; self.cache.insert(ty, res); Ok(res) }

<ins> // build-pass #![allow(incomplete_features)] #![feature(generic_const_exprs)] trait TraitOne { const MY_NUM: usize; type MyErr: std::fmt::Debug; fn do_one_stuff(arr: [u8; Self::MY_NUM]) -> Result<(), Self::MyErr>; } trait TraitTwo { fn do_two_stuff(); } impl<O: TraitOne> TraitTwo for O where [(); Self::MY_NUM]:, { fn do_two_stuff() { O::do_one_stuff([5; Self::MY_NUM]).unwrap() } } struct Blargotron; #[derive(Debug)] struct ErrTy<const N: usize>([(); N]); impl TraitOne for Blargotron { const MY_NUM: usize = 3; type MyErr = ErrTy<{ Self::MY_NUM }>; fn do_one_stuff(_arr: [u8; Self::MY_NUM]) -> Result<(), Self::MyErr> { Ok(()) } } fn main() { Blargotron::do_two_stuff(); } </ins>

<ins> // build-pass #![allow(incomplete_features)] #![feature(generic_const_exprs)] use std::convert::AsMut; use std::default::Default; trait Foo: Sized { type Baz: Default + AsMut<[u8]>; fn bar() { Self::Baz::default().as_mut(); } } impl Foo for () { type Baz = [u8; 1 * 1]; //type Baz = [u8; 1]; } fn main() { <() as Foo>::bar(); } </ins>

<ins> // build-pass #![allow(incomplete_features)] #![feature(generic_const_exprs)] trait Collate<Op> { type Pass; type Fail; fn collate(self) -> (Self::Pass, Self::Fail); } impl<Op> Collate<Op> for () { type Pass = (); type Fail = (); fn collate(self) -> ((), ()) { ((), ()) } } trait CollateStep<X, Prev> { type Pass; type Fail; fn collate_step(x: X, prev: Prev) -> (Self::Pass, Self::Fail); } impl<X, P, F> CollateStep<X, (P, F)> for () { type Pass = (X, P); type Fail = F; fn collate_step(x: X, (p, f): (P, F)) -> ((X, P), F) { ((x, p), f) } } struct CollateOpImpl<const MASK: u32>; trait CollateOpStep { type NextOp; type Apply; } impl<const MASK: u32> CollateOpStep for CollateOpImpl<MASK> where CollateOpImpl<{ MASK >> 1 }>: Sized, { type NextOp = CollateOpImpl<{ MASK >> 1 }>; type Apply = (); } impl<H, T, Op: CollateOpStep> Collate<Op> for (H, T) where T: Collate<Op::NextOp>, Op::Apply: CollateStep<H, (T::Pass, T::Fail)>, { type Pass = <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::Pass; type Fail = <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::Fail; fn collate(self) -> (Self::Pass, Self::Fail) { <Op::Apply as CollateStep<H, (T::Pass, T::Fail)>>::collate_step(self.0, self.1.collate()) } } fn collate<X, const MASK: u32>(x: X) -> (X::Pass, X::Fail) where X: Collate<CollateOpImpl<MASK>>, { x.collate() } fn main() { dbg!(collate::<_, 5>(("Hello", (42, ('!', ()))))); } </ins>

<ins> // build-pass #![allow(incomplete_features)] #![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>(); } </ins>

<ins> // build-pass #![feature(generic_const_exprs)] #![allow(incomplete_features)] trait Foo { type Output; fn foo() -> Self::Output; } impl Foo for [u8; 3] { type Output = [u8; 1 + 2]; fn foo() -> [u8; 3] { [1u8; 3] } } fn bug<const N: usize>() where [u8; N]: Foo, <[u8; N] as Foo>::Output: AsRef<[u8]>, { <[u8; N]>::foo().as_ref(); } fn main() { bug::<3>(); } </ins>

<ins> // build-pass #![allow(incomplete_features)] #![feature(generic_const_exprs)] use std::marker::PhantomData; fn main() { let x = FooImpl::<BarImpl<1>> { phantom: PhantomData }; let _ = x.foo::<BarImpl<1>>(); } trait Foo<T> where T: Bar, { fn foo<U>(&self) where T: Operation<U>, <T as Operation<U>>::Output: Bar; } struct FooImpl<T> where T: Bar, { phantom: PhantomData<T>, } impl<T> Foo<T> for FooImpl<T> where T: Bar, { fn foo<U>(&self) where T: Operation<U>, <T as Operation<U>>::Output: Bar, { <<T as Operation<U>>::Output as Bar>::error_occurs_here(); } } trait Bar { fn error_occurs_here(); } struct BarImpl<const N: usize>; impl<const N: usize> Bar for BarImpl<N> { fn error_occurs_here() {} } trait Operation<Rhs> { type Output; } //// Part-A: This causes error. impl<const M: usize, const N: usize> Operation<BarImpl<M>> for BarImpl<N> where BarImpl<{ N + M }>: Sized, { type Output = BarImpl<{ N + M }>; } //// Part-B: This doesn't cause error. // impl<const M: usize, const N: usize> Operation<BarImpl<M>> for BarImpl<N> { //     type Output = BarImpl<M>; // } //// Part-C: This also doesn't cause error. // impl<const M: usize, const N: usize> Operation<BarImpl<M>> for BarImpl<N> { //     type Output = BarImpl<{ M }>; // } </ins>