typeck: always expose explicit enum discriminant AnonConsts' parent in generics_of.

This commit is contained in:
Eduard-Mihai Burtescu 2020-04-06 00:14:52 +03:00
parent 2c29f0cc8e
commit 926c7a298d
6 changed files with 83 additions and 2 deletions

View File

@ -1178,9 +1178,11 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
match parent_node {
// HACK(eddyb) this provides the correct generics for repeat
// expressions' count (i.e. `N` in `[x; N]`), as they shouldn't
// be able to cause query cycle errors.
// expressions' count (i.e. `N` in `[x; N]`), and explicit
// `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`),
// as they shouldn't be able to cause query cycle errors.
Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
| Node::Variant(Variant { disr_expr: Some(ref constant), .. })
if constant.hir_id == hir_id =>
{
Some(parent_def_id.to_def_id())

View File

@ -0,0 +1,16 @@
#![feature(arbitrary_enum_discriminant, core_intrinsics)]
extern crate core;
use core::intrinsics::discriminant_value;
#[repr(usize)]
enum MyWeirdOption<T> {
None = 0,
Some(T) = std::mem::size_of::<T>(),
//~^ ERROR constant expression depends on a generic parameter
}
fn main() {
assert_eq!(discriminant_value(&MyWeirdOption::<u8>::None), 0);
assert_eq!(discriminant_value(&MyWeirdOption::Some(0u8)), 1);
}

View File

@ -0,0 +1,10 @@
error: constant expression depends on a generic parameter
--> $DIR/issue-70453-generics-in-discr-ice-2.rs:9:15
|
LL | Some(T) = std::mem::size_of::<T>(),
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes
error: aborting due to previous error

View File

@ -0,0 +1,17 @@
#![feature(core_intrinsics)]
extern crate core;
use core::intrinsics::discriminant_value;
#[repr(usize)]
enum MyWeirdOption<T> {
//~^ ERROR parameter `T` is never used
None = 0,
Some = std::mem::size_of::<T>(),
//~^ ERROR constant expression depends on a generic parameter
}
fn main() {
assert_eq!(discriminant_value(&MyWeirdOption::<u8>::None), 0);
assert_eq!(discriminant_value(&MyWeirdOption::<u8>::Some), 1);
}

View File

@ -0,0 +1,19 @@
error: constant expression depends on a generic parameter
--> $DIR/issue-70453-generics-in-discr-ice.rs:10:12
|
LL | Some = std::mem::size_of::<T>(),
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes
error[E0392]: parameter `T` is never used
--> $DIR/issue-70453-generics-in-discr-ice.rs:7:20
|
LL | enum MyWeirdOption<T> {
| ^ unused parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `std::marker::PhantomData`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0392`.

View File

@ -0,0 +1,17 @@
// run-pass
#![feature(arbitrary_enum_discriminant, core_intrinsics)]
extern crate core;
use core::intrinsics::discriminant_value;
#[repr(usize)]
enum MyWeirdOption<T> {
None = 0,
Some(T) = core::mem::size_of::<*mut T>(),
}
fn main() {
assert_eq!(discriminant_value(&MyWeirdOption::<()>::None), 0);
assert_eq!(discriminant_value(&MyWeirdOption::Some(())), core::mem::size_of::<usize>() as u64);
}