From 78d2dea11efa44dbb2908ec32540575fc3227282 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Mon, 16 Jan 2023 18:48:58 +0900 Subject: [PATCH] use parent substs --- .../rustc_trait_selection/src/traits/wf.rs | 23 ++++++++-- .../generic_const_exprs/issue-101036.rs | 16 +++++++ .../generic_const_exprs/issue-101036.stderr | 10 +++++ .../generic_const_exprs/issue-105631.rs | 11 +++++ .../generic_const_exprs/issue-105631.stderr | 43 +++++++++++++++++++ .../generic_const_exprs/issue-106473.rs | 14 ++++++ .../generic_const_exprs/issue-106473.stderr | 9 ++++ 7 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 tests/ui/const-generics/generic_const_exprs/issue-101036.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/issue-101036.stderr create mode 100644 tests/ui/const-generics/generic_const_exprs/issue-105631.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/issue-105631.stderr create mode 100644 tests/ui/const-generics/generic_const_exprs/issue-106473.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/issue-106473.stderr diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index fec4047ff49ba..6719d89cc2267 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -3,8 +3,8 @@ use crate::traits; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}; +use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeVisitable}; use rustc_span::Span; use std::iter; @@ -452,7 +452,24 @@ impl<'tcx> WfPredicates<'tcx> { match ct.kind() { ty::ConstKind::Unevaluated(uv) => { if !ct.has_escaping_bound_vars() { - let obligations = self.nominal_obligations(uv.def.did, uv.substs); + let substs = if let Some(did) = uv.def.did.as_local() + && self + .tcx + .hir() + .opt_const_param_default_param_def_id( + self.tcx.hir().local_def_id_to_hir_id(did), + ) + .is_some() + && let Some(did) = self.tcx.opt_parent(uv.def.did) + { + // HACK(TaKO8Ki) `WfPredicates::nominal_obligations` calls `SubstsFolder::fold_const` in it. + // If `uv.substs` is used, it will cause an ICE because `uv.substs` does not include the const. + // `substs` argument `WfPredicates::nominal_obligations` should be parent substs here. + InternalSubsts::identity_for_item(self.tcx, did) + } else { + uv.substs + }; + let obligations = self.nominal_obligations(uv.def.did, substs); self.out.extend(obligations); let predicate = diff --git a/tests/ui/const-generics/generic_const_exprs/issue-101036.rs b/tests/ui/const-generics/generic_const_exprs/issue-101036.rs new file mode 100644 index 0000000000000..c05bca0207770 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/issue-101036.rs @@ -0,0 +1,16 @@ +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +const fn t() -> u8 { + N as u8 +} + +#[repr(u8)] +enum T::A as u8 + T::<0>::B as u8 }> +where + [(); N as usize]: +{ + A = t::() as u8, B //~ ERROR: unconstrained generic constant +} + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-101036.stderr b/tests/ui/const-generics/generic_const_exprs/issue-101036.stderr new file mode 100644 index 0000000000000..204df48aa3c3e --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/issue-101036.stderr @@ -0,0 +1,10 @@ +error: unconstrained generic constant + --> $DIR/issue-101036.rs:13:9 + | +LL | A = t::() as u8, B + | ^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); t::() as u8]:` + +error: aborting due to previous error + diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105631.rs b/tests/ui/const-generics/generic_const_exprs/issue-105631.rs new file mode 100644 index 0000000000000..05f62233c8152 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/issue-105631.rs @@ -0,0 +1,11 @@ +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +struct A; +//~^ ERROR generic parameters with a default must be trailing +//~| ERROR the size for values of type `str` cannot be known at compilation time +//~| ERROR mismatched types +//~| ERROR parameter `C` is never used +//~| ERROR `str` is forbidden as the type of a const generic parameter + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105631.stderr b/tests/ui/const-generics/generic_const_exprs/issue-105631.stderr new file mode 100644 index 0000000000000..fe3d32eb3526e --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/issue-105631.stderr @@ -0,0 +1,43 @@ +error: generic parameters with a default must be trailing + --> $DIR/issue-105631.rs:4:16 + | +LL | struct A; + | ^ + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/issue-105631.rs:4:25 + | +LL | struct A; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: constant expressions must have a statically known size + +error[E0308]: mismatched types + --> $DIR/issue-105631.rs:4:25 + | +LL | struct A; + | ^ expected `str`, found integer + +error[E0392]: parameter `C` is never used + --> $DIR/issue-105631.rs:4:28 + | +LL | struct A; + | ^ unused parameter + | + = help: consider removing `C`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `C` to be a const parameter, use `const C: usize` instead + +error: `str` is forbidden as the type of a const generic parameter + --> $DIR/issue-105631.rs:4:19 + | +LL | struct A; + | ^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: more complex types are supported with `#![feature(adt_const_params)]` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0277, E0308, E0392. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-106473.rs b/tests/ui/const-generics/generic_const_exprs/issue-106473.rs new file mode 100644 index 0000000000000..6871c172f5e0b --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/issue-106473.rs @@ -0,0 +1,14 @@ +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +const DEFAULT: u32 = 1; + +struct V //~ ERROR mismatched types +where + [(); U]:; + +trait Tr {} + +impl Tr for V {} + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-106473.stderr b/tests/ui/const-generics/generic_const_exprs/issue-106473.stderr new file mode 100644 index 0000000000000..8f1494886a521 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/issue-106473.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/issue-106473.rs:6:27 + | +LL | struct V + | ^^^^^^^ expected `usize`, found `u32` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`.