From bf8a223685c3beaefaaeb4c16c5d6efbcacfd90f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 9 Aug 2022 08:26:55 +0000 Subject: [PATCH] Normalize instance substs during legacy symbol mangling --- compiler/rustc_symbol_mangling/src/legacy.rs | 16 ++-- .../generic_const_exprs/issue-100217.rs | 42 +++++++++++ .../generic_const_exprs/issue-73298.rs | 23 ++++++ .../generic_const_exprs/issue-82268.rs | 73 +++++++++++++++++++ .../generic_const_exprs/issue-83972.rs | 38 ++++++++++ .../generic_const_exprs/issue-84669.rs | 30 ++++++++ .../generic_const_exprs/issue-86710.rs | 73 +++++++++++++++++++ 7 files changed, 290 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/const-generics/generic_const_exprs/issue-100217.rs create mode 100644 src/test/ui/const-generics/generic_const_exprs/issue-73298.rs create mode 100644 src/test/ui/const-generics/generic_const_exprs/issue-82268.rs create mode 100644 src/test/ui/const-generics/generic_const_exprs/issue-83972.rs create mode 100644 src/test/ui/const-generics/generic_const_exprs/issue-84669.rs create mode 100644 src/test/ui/const-generics/generic_const_exprs/issue-86710.rs diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 9241fd82c745f..74fda5c5925de 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -51,8 +51,14 @@ pub(super) fn mangle<'tcx>( // Erase regions because they may not be deterministic when hashed // and should not matter anyhow. let instance_ty = tcx.erase_regions(instance_ty); + // Also normalize the instance's substs, because we want to make + // sure that we're fully evaluating any unevaluated consts that + // leak into this mangled name. + // FIXME(compiler-errors): Ideally, like the equivalent call in the + // v1 mangling shceme, this should not be needed. + let substs = tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), instance.substs); - let hash = get_symbol_hash(tcx, instance, instance_ty, instantiating_crate); + let hash = get_symbol_hash(tcx, instance.def, substs, instance_ty, instantiating_crate); let mut printer = SymbolPrinter { tcx, path: SymbolPath::new(), keep_within_component: false }; printer @@ -60,7 +66,7 @@ pub(super) fn mangle<'tcx>( def_id, if let ty::InstanceDef::DropGlue(_, _) = instance.def { // Add the name of the dropped type to the symbol name - &*instance.substs + &*substs } else { &[] }, @@ -82,7 +88,8 @@ fn get_symbol_hash<'tcx>( tcx: TyCtxt<'tcx>, // instance this name will be for - instance: Instance<'tcx>, + instance: ty::InstanceDef<'tcx>, + substs: ty::SubstsRef<'tcx>, // type of the item, without any generic // parameters substituted; this is @@ -93,7 +100,6 @@ fn get_symbol_hash<'tcx>( instantiating_crate: Option, ) -> u64 { let def_id = instance.def_id(); - let substs = instance.substs; debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs); tcx.with_stable_hashing_context(|mut hcx| { @@ -131,7 +137,7 @@ fn get_symbol_hash<'tcx>( // We want to avoid accidental collision between different types of instances. // Especially, `VTableShim`s and `ReifyShim`s may overlap with their original // instances without this. - discriminant(&instance.def).hash_stable(hcx, &mut hasher); + discriminant(&instance).hash_stable(hcx, &mut hasher); }); }); diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-100217.rs b/src/test/ui/const-generics/generic_const_exprs/issue-100217.rs new file mode 100644 index 0000000000000..acdc348a385a3 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/issue-100217.rs @@ -0,0 +1,42 @@ +// 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 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([(); 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(); +} diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-73298.rs b/src/test/ui/const-generics/generic_const_exprs/issue-73298.rs new file mode 100644 index 0000000000000..3c59e1b790a12 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/issue-73298.rs @@ -0,0 +1,23 @@ +// 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(); +} diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-82268.rs b/src/test/ui/const-generics/generic_const_exprs/issue-82268.rs new file mode 100644 index 0000000000000..d08fc5beb75f6 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/issue-82268.rs @@ -0,0 +1,73 @@ +// build-pass + +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +trait Collate { + type Pass; + type Fail; + + fn collate(self) -> (Self::Pass, Self::Fail); +} + +impl Collate for () { + type Pass = (); + type Fail = (); + + fn collate(self) -> ((), ()) { + ((), ()) + } +} + +trait CollateStep { + type Pass; + type Fail; + fn collate_step(x: X, prev: Prev) -> (Self::Pass, Self::Fail); +} + +impl CollateStep 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; +trait CollateOpStep { + type NextOp; + type Apply; +} + +impl CollateOpStep for CollateOpImpl +where + CollateOpImpl<{ MASK >> 1 }>: Sized, +{ + type NextOp = CollateOpImpl<{ MASK >> 1 }>; + type Apply = (); +} + +impl Collate for (H, T) +where + T: Collate, + Op::Apply: CollateStep, +{ + type Pass = >::Pass; + type Fail = >::Fail; + + fn collate(self) -> (Self::Pass, Self::Fail) { + >::collate_step(self.0, self.1.collate()) + } +} + +fn collate(x: X) -> (X::Pass, X::Fail) +where + X: Collate>, +{ + x.collate() +} + +fn main() { + dbg!(collate::<_, 5>(("Hello", (42, ('!', ()))))); +} diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-83972.rs b/src/test/ui/const-generics/generic_const_exprs/issue-83972.rs new file mode 100644 index 0000000000000..0063719b8528c --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/issue-83972.rs @@ -0,0 +1,38 @@ +// build-pass + +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +pub trait Foo { + fn foo(&self); +} + +pub struct FooImpl; +impl Foo for FooImpl { + 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::get().foo(); +} + +fn main() { + boom::(); +} diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-84669.rs b/src/test/ui/const-generics/generic_const_exprs/issue-84669.rs new file mode 100644 index 0000000000000..3933ff20a49c5 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/issue-84669.rs @@ -0,0 +1,30 @@ +// 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() +where + [u8; N]: Foo, + <[u8; N] as Foo>::Output: AsRef<[u8]>, +{ + <[u8; N]>::foo().as_ref(); +} + +fn main() { + bug::<3>(); +} diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-86710.rs b/src/test/ui/const-generics/generic_const_exprs/issue-86710.rs new file mode 100644 index 0000000000000..bdd8a21b3b991 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/issue-86710.rs @@ -0,0 +1,73 @@ +// build-pass + +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +use std::marker::PhantomData; + +fn main() { + let x = FooImpl::> { phantom: PhantomData }; + let _ = x.foo::>(); +} + +trait Foo +where + T: Bar, +{ + fn foo(&self) + where + T: Operation, + >::Output: Bar; +} + +struct FooImpl +where + T: Bar, +{ + phantom: PhantomData, +} + +impl Foo for FooImpl +where + T: Bar, +{ + fn foo(&self) + where + T: Operation, + >::Output: Bar, + { + <>::Output as Bar>::error_occurs_here(); + } +} + +trait Bar { + fn error_occurs_here(); +} + +struct BarImpl; + +impl Bar for BarImpl { + fn error_occurs_here() {} +} + +trait Operation { + type Output; +} + +//// Part-A: This causes error. +impl Operation> for BarImpl +where + BarImpl<{ N + M }>: Sized, +{ + type Output = BarImpl<{ N + M }>; +} + +//// Part-B: This doesn't cause error. +// impl Operation> for BarImpl { +// type Output = BarImpl; +// } + +//// Part-C: This also doesn't cause error. +// impl Operation> for BarImpl { +// type Output = BarImpl<{ M }>; +// }