Skip to content

Commit

Permalink
Rollup merge of rust-lang#99449 - compiler-errors:assoc-const-missing…
Browse files Browse the repository at this point in the history
…-item, r=lcnr

Do not resolve associated const when there is no provided value

Fixes rust-lang#98629, since now we just delay a bug when we're not able to evaluate a const item due to the value not actually being provided by anything. This means compilation proceeds forward to where the "missing item in impl" error is emitted.

----

The root issue here is that when we're looking for the defining `LeafDef` in `resolve_associated_item`, we end up getting the trait's AssocItem instead of the impl's AssocItem (which does not exist). This resolution "succeeds" even if the trait's item has no default value, and then since this item has no value to evaluate, it turns into a const eval error.

This root issue becomes problematic (as in rust-lang#98629) when this const eval error happens in wfcheck (for example, due to normalizing the param-env of something that references this const). Since this happens sooner than the check that an impl actually provides all of the items that a trait requires (which happens during later typecheck), we end up aborting compilation early with only this un-informative message.

I'm not exactly sure _why_ this bug arises due to rust-lang#96591 -- perhaps valtrees are evaluated more eagerly than in the old system?

r? `@oli-obk` or `@lcnr` since y'all are familiar with const eval and reviewed rust-lang#96591, though feel free to reassign.

This is a regression from stable to beta, so I would be open to considering this for beta backport. It seems correct to me, especially given the improvements in the other UI tests this PR touches, but may have some side-effects that I'm unaware of...?
  • Loading branch information
matthiaskrgr authored Jul 20, 2022
2 parents f0abcd4 + c8165c5 commit 19c1d52
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 34 deletions.
15 changes: 12 additions & 3 deletions compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,20 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
}
let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
match concrete {
Err(ErrorHandled::TooGeneric) => Err(if !uv.has_infer_types_or_consts() {
Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() {
NotConstEvaluatable::MentionsInfer
} else if uv.has_param_types_or_consts() {
infcx
.tcx
.sess
.delay_span_bug(span, &format!("unexpected `TooGeneric` for {:?}", uv));
NotConstEvaluatable::MentionsParam
} else {
NotConstEvaluatable::MentionsInfer
let guar = infcx.tcx.sess.delay_span_bug(
span,
format!("Missing value for constant, but no error reported?"),
);
NotConstEvaluatable::Error(guar)
}),
Err(ErrorHandled::Linted) => {
let reported = infcx
Expand Down Expand Up @@ -240,8 +246,11 @@ pub fn is_const_evaluatable<'cx, 'tcx>(

Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() {
NotConstEvaluatable::MentionsInfer
} else {
} else if uv.has_param_types_or_consts() {
NotConstEvaluatable::MentionsParam
} else {
let guar = infcx.tcx.sess.delay_span_bug(span, format!("Missing value for constant, but no error reported?"));
NotConstEvaluatable::Error(guar)
}),
Err(ErrorHandled::Linted) => {
let reported =
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_ty_utils/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,11 @@ fn resolve_associated_item<'tcx>(
return Ok(None);
}

// If the item does not have a value, then we cannot return an instance.
if !leaf_def.item.defaultness.has_value() {
return Ok(None);
}

let substs = tcx.erase_regions(substs);

// Check if we just resolved an associated `const` declaration from
Expand Down
1 change: 0 additions & 1 deletion src/test/ui/const-generics/issues/issue-86530.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ where
fn unit_literals() {
z(" ");
//~^ ERROR: the trait bound `&str: X` is not satisfied
//~| ERROR: unconstrained generic constant
}

fn main() {}
18 changes: 1 addition & 17 deletions src/test/ui/const-generics/issues/issue-86530.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,6 @@ LL | where
LL | T: X,
| ^ required by this bound in `z`

error: unconstrained generic constant
--> $DIR/issue-86530.rs:16:5
|
LL | z(" ");
| ^
|
= help: try adding a `where` bound using this expression: `where [(); T::Y]:`
note: required by a bound in `z`
--> $DIR/issue-86530.rs:11:10
|
LL | fn z<T>(t: T)
| - required by a bound in this
...
LL | [(); T::Y]: ,
| ^^^^ required by this bound in `z`

error: aborting due to 2 previous errors
error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
15 changes: 15 additions & 0 deletions src/test/ui/const-generics/issues/issue-98629.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![feature(const_trait_impl)]

trait Trait {
const N: usize;
}

impl const Trait for i32 {}
//~^ ERROR not all trait items implemented, missing: `N`

fn f()
where
[(); <i32 as Trait>::N]:,
{}

fn main() {}
12 changes: 12 additions & 0 deletions src/test/ui/const-generics/issues/issue-98629.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0046]: not all trait items implemented, missing: `N`
--> $DIR/issue-98629.rs:7:1
|
LL | const N: usize;
| -------------- `N` from trait
...
LL | impl const Trait for i32 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ missing `N` in implementation

error: aborting due to previous error

For more information about this error, try `rustc --explain E0046`.
1 change: 0 additions & 1 deletion src/test/ui/issues/issue-77919.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
fn main() {
[1; <Multiply<Five, Five>>::VAL];
//~^ ERROR: constant expression depends on a generic parameter
}
trait TypeVal<T> {
const VAL: T;
Expand Down
16 changes: 4 additions & 12 deletions src/test/ui/issues/issue-77919.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0412]: cannot find type `PhantomData` in this scope
--> $DIR/issue-77919.rs:10:9
--> $DIR/issue-77919.rs:9:9
|
LL | _n: PhantomData,
| ^^^^^^^^^^^ not found in this scope
Expand All @@ -10,31 +10,23 @@ LL | use std::marker::PhantomData;
|

error[E0412]: cannot find type `VAL` in this scope
--> $DIR/issue-77919.rs:12:63
--> $DIR/issue-77919.rs:11:63
|
LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
| - ^^^ not found in this scope
| |
| help: you might be missing a type parameter: `, VAL`

error[E0046]: not all trait items implemented, missing: `VAL`
--> $DIR/issue-77919.rs:12:1
--> $DIR/issue-77919.rs:11:1
|
LL | const VAL: T;
| ------------ `VAL` from trait
...
LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation

error: constant expression depends on a generic parameter
--> $DIR/issue-77919.rs:2:9
|
LL | [1; <Multiply<Five, Five>>::VAL];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes

error: aborting due to 4 previous errors
error: aborting due to 3 previous errors

Some errors have detailed explanations: E0046, E0412.
For more information about an error, try `rustc --explain E0046`.

0 comments on commit 19c1d52

Please sign in to comment.