Skip to content

Commit

Permalink
use parent substs
Browse files Browse the repository at this point in the history
  • Loading branch information
TaKO8Ki committed Jan 16, 2023
1 parent 44a500c commit 78d2dea
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 3 deletions.
23 changes: 20 additions & 3 deletions compiler/rustc_trait_selection/src/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 =
Expand Down
16 changes: 16 additions & 0 deletions tests/ui/const-generics/generic_const_exprs/issue-101036.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]

const fn t<const N: usize>() -> u8 {
N as u8
}

#[repr(u8)]
enum T<const N: u8 = { T::<0>::A as u8 + T::<0>::B as u8 }>
where
[(); N as usize]:
{
A = t::<N>() as u8, B //~ ERROR: unconstrained generic constant
}

fn main() {}
10 changes: 10 additions & 0 deletions tests/ui/const-generics/generic_const_exprs/issue-101036.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: unconstrained generic constant
--> $DIR/issue-101036.rs:13:9
|
LL | A = t::<N>() as u8, B
| ^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); t::<N>() as u8]:`

error: aborting due to previous error

11 changes: 11 additions & 0 deletions tests/ui/const-generics/generic_const_exprs/issue-105631.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]

struct A<const B: str = 1, C>;
//~^ 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() {}
43 changes: 43 additions & 0 deletions tests/ui/const-generics/generic_const_exprs/issue-105631.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
error: generic parameters with a default must be trailing
--> $DIR/issue-105631.rs:4:16
|
LL | struct A<const B: str = 1, C>;
| ^

error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/issue-105631.rs:4:25
|
LL | struct A<const B: str = 1, C>;
| ^ 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<const B: str = 1, C>;
| ^ expected `str`, found integer

error[E0392]: parameter `C` is never used
--> $DIR/issue-105631.rs:4:28
|
LL | struct A<const B: str = 1, C>;
| ^ 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<const B: str = 1, C>;
| ^^^
|
= 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`.
14 changes: 14 additions & 0 deletions tests/ui/const-generics/generic_const_exprs/issue-106473.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]

const DEFAULT: u32 = 1;

struct V<const U: usize = DEFAULT> //~ ERROR mismatched types
where
[(); U]:;

trait Tr {}

impl Tr for V {}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0308]: mismatched types
--> $DIR/issue-106473.rs:6:27
|
LL | struct V<const U: usize = DEFAULT>
| ^^^^^^^ expected `usize`, found `u32`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

0 comments on commit 78d2dea

Please sign in to comment.