Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle associated types in const context #70056

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,13 +640,13 @@ impl<'hir> Map<'hir> {
/// Used exclusively for diagnostics, to avoid suggestion function calls.
pub fn is_const_context(&self, hir_id: HirId) -> bool {
let parent_id = self.get_parent_item(hir_id);
match self.get(parent_id) {
Node::Item(&Item { kind: ItemKind::Const(..), .. })
| Node::TraitItem(&TraitItem { kind: TraitItemKind::Const(..), .. })
| Node::ImplItem(&ImplItem { kind: ImplItemKind::Const(..), .. })
| Node::AnonConst(_)
| Node::Item(&Item { kind: ItemKind::Static(..), .. }) => true,
Node::Item(&Item { kind: ItemKind::Fn(ref sig, ..), .. }) => {
match self.find(parent_id) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is weird, why could find ever return None? We should fix that if it is the case (cc @Zoxc)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was encountered on enum variants like enum E { A = 1f64 }, but I didn't dig too deep.

Some(Node::Item(&Item { kind: ItemKind::Const(..), .. }))
| Some(Node::TraitItem(&TraitItem { kind: TraitItemKind::Const(..), .. }))
| Some(Node::ImplItem(&ImplItem { kind: ImplItemKind::Const(..), .. }))
| Some(Node::AnonConst(_))
| Some(Node::Item(&Item { kind: ItemKind::Static(..), .. })) => true,
Some(Node::Item(&Item { kind: ItemKind::Fn(ref sig, ..), .. })) => {
sig.header.constness == Constness::Const
}
_ => false,
Expand Down Expand Up @@ -738,6 +738,7 @@ impl<'hir> Map<'hir> {
| Node::Item(_)
| Node::ForeignItem(_)
| Node::TraitItem(_)
| Node::AnonConst(_)
estebank marked this conversation as resolved.
Show resolved Hide resolved
| Node::ImplItem(_) => return hir_id,
_ => {}
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@ rustc_queries! {
desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
}

query diagnostic_only_typeck_tables_of(key: DefId) -> &'tcx ty::TypeckTables<'tcx> {
cache_on_disk_if { key.is_local() }
load_cached(tcx, id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
ty::Projection(projection) => (false, Some(projection)),
_ => return,
};
if self.tcx.hir().is_const_context(body_id) {
err.note(
"associated types cannot be referenced in `const` contexts, \
like the length of an array",
);
return;
}

let suggest_restriction =
|generics: &hir::Generics<'_>, msg, err: &mut DiagnosticBuilder<'_>| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ LL | const Y: usize;
LL | let _array = [4; <A as Foo>::Y];
| ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
|
help: consider further restricting this bound with `+ Foo`
--> $DIR/associated-const-type-parameter-arrays-2.rs:15:16
|
LL | pub fn test<A: Foo, B: Foo>() {
| ^^^
= note: associated types cannot be referenced in `const` contexts, like the length of an array

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ LL | const Y: usize;
LL | let _array: [u32; <A as Foo>::Y];
| ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
|
help: consider further restricting this bound with `+ Foo`
--> $DIR/associated-const-type-parameter-arrays.rs:15:16
|
LL | pub fn test<A: Foo, B: Foo>() {
| ^^^
= note: associated types cannot be referenced in `const` contexts, like the length of an array

error: aborting due to previous error

Expand Down
18 changes: 0 additions & 18 deletions src/test/ui/consts/const-integer-bool-ops.rs
Original file line number Diff line number Diff line change
@@ -1,76 +1,58 @@
const X: usize = 42 && 39;
//~^ ERROR mismatched types
//~| expected `bool`, found integer
//~| ERROR mismatched types
//~| expected `bool`, found integer
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR: [i32; X] = [99; 34];
//~^ ERROR evaluation of constant value failed

const X1: usize = 42 || 39;
//~^ ERROR mismatched types
//~| expected `bool`, found integer
//~| ERROR mismatched types
//~| expected `bool`, found integer
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR1: [i32; X1] = [99; 47];
//~^ ERROR evaluation of constant value failed

const X2: usize = -42 || -39;
//~^ ERROR mismatched types
//~| expected `bool`, found integer
//~| ERROR mismatched types
//~| expected `bool`, found integer
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR2: [i32; X2] = [99; 18446744073709551607];
//~^ ERROR evaluation of constant value failed

const X3: usize = -42 && -39;
//~^ ERROR mismatched types
//~| expected `bool`, found integer
//~| ERROR mismatched types
//~| expected `bool`, found integer
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR3: [i32; X3] = [99; 6];
//~^ ERROR evaluation of constant value failed

const Y: usize = 42.0 == 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR: [i32; Y] = [99; 1];
//~^ ERROR evaluation of constant value failed

const Y1: usize = 42.0 >= 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR1: [i32; Y1] = [99; 1];
//~^ ERROR evaluation of constant value failed

const Y2: usize = 42.0 <= 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR2: [i32; Y2] = [99; 1];
//~^ ERROR evaluation of constant value failed

const Y3: usize = 42.0 > 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR3: [i32; Y3] = [99; 0];
//~^ ERROR evaluation of constant value failed

const Y4: usize = 42.0 < 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR4: [i32; Y4] = [99; 0];
//~^ ERROR evaluation of constant value failed

const Y5: usize = 42.0 != 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR5: [i32; Y5] = [99; 0];
//~^ ERROR evaluation of constant value failed

Expand Down
50 changes: 25 additions & 25 deletions src/test/ui/consts/const-integer-bool-ops.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -17,151 +17,151 @@ LL | const X: usize = 42 && 39;
| ^^^^^^^^ expected `usize`, found `bool`

error[E0080]: evaluation of constant value failed
--> $DIR/const-integer-bool-ops.rs:8:18
--> $DIR/const-integer-bool-ops.rs:5:18
|
LL | const ARR: [i32; X] = [99; 34];
| ^ referenced constant has errors

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:11:19
--> $DIR/const-integer-bool-ops.rs:8:19
|
LL | const X1: usize = 42 || 39;
| ^^ expected `bool`, found integer

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:11:25
--> $DIR/const-integer-bool-ops.rs:8:25
|
LL | const X1: usize = 42 || 39;
| ^^ expected `bool`, found integer

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:11:19
--> $DIR/const-integer-bool-ops.rs:8:19
|
LL | const X1: usize = 42 || 39;
| ^^^^^^^^ expected `usize`, found `bool`

error[E0080]: evaluation of constant value failed
--> $DIR/const-integer-bool-ops.rs:18:19
--> $DIR/const-integer-bool-ops.rs:12:19
|
LL | const ARR1: [i32; X1] = [99; 47];
| ^^ referenced constant has errors

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:21:19
--> $DIR/const-integer-bool-ops.rs:15:19
|
LL | const X2: usize = -42 || -39;
| ^^^ expected `bool`, found integer

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:21:26
--> $DIR/const-integer-bool-ops.rs:15:26
|
LL | const X2: usize = -42 || -39;
| ^^^ expected `bool`, found integer

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:21:19
--> $DIR/const-integer-bool-ops.rs:15:19
|
LL | const X2: usize = -42 || -39;
| ^^^^^^^^^^ expected `usize`, found `bool`

error[E0080]: evaluation of constant value failed
--> $DIR/const-integer-bool-ops.rs:28:19
--> $DIR/const-integer-bool-ops.rs:19:19
|
LL | const ARR2: [i32; X2] = [99; 18446744073709551607];
| ^^ referenced constant has errors

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:31:19
--> $DIR/const-integer-bool-ops.rs:22:19
|
LL | const X3: usize = -42 && -39;
| ^^^ expected `bool`, found integer

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:31:26
--> $DIR/const-integer-bool-ops.rs:22:26
|
LL | const X3: usize = -42 && -39;
| ^^^ expected `bool`, found integer

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:31:19
--> $DIR/const-integer-bool-ops.rs:22:19
|
LL | const X3: usize = -42 && -39;
| ^^^^^^^^^^ expected `usize`, found `bool`

error[E0080]: evaluation of constant value failed
--> $DIR/const-integer-bool-ops.rs:38:19
--> $DIR/const-integer-bool-ops.rs:26:19
|
LL | const ARR3: [i32; X3] = [99; 6];
| ^^ referenced constant has errors

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:41:18
--> $DIR/const-integer-bool-ops.rs:29:18
|
LL | const Y: usize = 42.0 == 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`

error[E0080]: evaluation of constant value failed
--> $DIR/const-integer-bool-ops.rs:44:19
--> $DIR/const-integer-bool-ops.rs:31:19
|
LL | const ARRR: [i32; Y] = [99; 1];
| ^ referenced constant has errors

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:47:19
--> $DIR/const-integer-bool-ops.rs:34:19
|
LL | const Y1: usize = 42.0 >= 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`

error[E0080]: evaluation of constant value failed
--> $DIR/const-integer-bool-ops.rs:50:20
--> $DIR/const-integer-bool-ops.rs:36:20
|
LL | const ARRR1: [i32; Y1] = [99; 1];
| ^^ referenced constant has errors

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:53:19
--> $DIR/const-integer-bool-ops.rs:39:19
|
LL | const Y2: usize = 42.0 <= 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`

error[E0080]: evaluation of constant value failed
--> $DIR/const-integer-bool-ops.rs:56:20
--> $DIR/const-integer-bool-ops.rs:41:20
|
LL | const ARRR2: [i32; Y2] = [99; 1];
| ^^ referenced constant has errors

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:59:19
--> $DIR/const-integer-bool-ops.rs:44:19
|
LL | const Y3: usize = 42.0 > 42.0;
| ^^^^^^^^^^^ expected `usize`, found `bool`

error[E0080]: evaluation of constant value failed
--> $DIR/const-integer-bool-ops.rs:62:20
--> $DIR/const-integer-bool-ops.rs:46:20
|
LL | const ARRR3: [i32; Y3] = [99; 0];
| ^^ referenced constant has errors

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:65:19
--> $DIR/const-integer-bool-ops.rs:49:19
|
LL | const Y4: usize = 42.0 < 42.0;
| ^^^^^^^^^^^ expected `usize`, found `bool`

error[E0080]: evaluation of constant value failed
--> $DIR/const-integer-bool-ops.rs:68:20
--> $DIR/const-integer-bool-ops.rs:51:20
|
LL | const ARRR4: [i32; Y4] = [99; 0];
| ^^ referenced constant has errors

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:71:19
--> $DIR/const-integer-bool-ops.rs:54:19
|
LL | const Y5: usize = 42.0 != 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`

error[E0080]: evaluation of constant value failed
--> $DIR/const-integer-bool-ops.rs:74:20
--> $DIR/const-integer-bool-ops.rs:56:20
|
LL | const ARRR5: [i32; Y5] = [99; 0];
| ^^ referenced constant has errors
Expand Down
1 change: 0 additions & 1 deletion src/test/ui/consts/const-tup-index-span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

const TUP: (usize,) = 5usize << 64;
//~^ ERROR mismatched types
//~| expected tuple, found `usize`
const ARR: [i32; TUP.0] = [];
//~^ ERROR evaluation of constant value failed

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-tup-index-span.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ LL | const TUP: (usize,) = 5usize << 64;
found type `usize`

error[E0080]: evaluation of constant value failed
--> $DIR/const-tup-index-span.rs:6:18
--> $DIR/const-tup-index-span.rs:5:18
|
LL | const ARR: [i32; TUP.0] = [];
| ^^^ referenced constant has errors
Expand Down
8 changes: 0 additions & 8 deletions src/test/ui/consts/enum-discr-type-err.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ LL | | }
| |_- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit
|
LL | $( $v = $s::V.try_into().unwrap(), )*
| ^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0308]: mismatched types
--> $DIR/enum-discr-type-err.rs:18:21
Expand All @@ -29,10 +25,6 @@ LL | | }
| |_- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit
|
LL | $( $v = $s::V.try_into().unwrap(), )*
| ^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

Expand Down
Loading