1
Fork 0

Rollup merge of #99449 - compiler-errors:assoc-const-missing-item, r=lcnr

Do not resolve associated const when there is no provided value

Fixes #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 #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 #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 #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...?
This commit is contained in:
Guillaume Gomez 2022-07-23 23:34:30 +02:00 committed by GitHub
commit 3648dd552a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 50 additions and 43 deletions

View file

@ -185,14 +185,20 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
} }
let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span)); let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
match concrete { 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 infcx
.tcx .tcx
.sess .sess
.delay_span_bug(span, &format!("unexpected `TooGeneric` for {:?}", uv)); .delay_span_bug(span, &format!("unexpected `TooGeneric` for {:?}", uv));
NotConstEvaluatable::MentionsParam NotConstEvaluatable::MentionsParam
} else { } 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) => { Err(ErrorHandled::Linted) => {
let reported = infcx let reported = infcx
@ -240,8 +246,11 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() { Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() {
NotConstEvaluatable::MentionsInfer NotConstEvaluatable::MentionsInfer
} else { } else if uv.has_param_types_or_consts() {
NotConstEvaluatable::MentionsParam 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) => { Err(ErrorHandled::Linted) => {
let reported = let reported =

View file

@ -280,6 +280,11 @@ fn resolve_associated_item<'tcx>(
return Ok(None); 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); let substs = tcx.erase_regions(substs);
// Check if we just resolved an associated `const` declaration from // Check if we just resolved an associated `const` declaration from

View file

@ -15,7 +15,6 @@ where
fn unit_literals() { fn unit_literals() {
z(" "); z(" ");
//~^ ERROR: the trait bound `&str: X` is not satisfied //~^ ERROR: the trait bound `&str: X` is not satisfied
//~| ERROR: unconstrained generic constant
} }
fn main() {} fn main() {}

View file

@ -15,22 +15,6 @@ LL | where
LL | T: X, LL | T: X,
| ^ required by this bound in `z` | ^ required by this bound in `z`
error: unconstrained generic constant error: aborting due to previous error
--> $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
For more information about this error, try `rustc --explain E0277`. For more information about this error, try `rustc --explain E0277`.

View file

@ -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() {}

View file

@ -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`.

View file

@ -1,6 +1,5 @@
fn main() { fn main() {
[1; <Multiply<Five, Five>>::VAL]; [1; <Multiply<Five, Five>>::VAL];
//~^ ERROR: constant expression depends on a generic parameter
} }
trait TypeVal<T> { trait TypeVal<T> {
const VAL: T; const VAL: T;

View file

@ -1,5 +1,5 @@
error[E0412]: cannot find type `PhantomData` in this scope error[E0412]: cannot find type `PhantomData` in this scope
--> $DIR/issue-77919.rs:10:9 --> $DIR/issue-77919.rs:9:9
| |
LL | _n: PhantomData, LL | _n: PhantomData,
| ^^^^^^^^^^^ not found in this scope | ^^^^^^^^^^^ not found in this scope
@ -10,7 +10,7 @@ LL | use std::marker::PhantomData;
| |
error[E0412]: cannot find type `VAL` in this scope 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> {} LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
| - ^^^ not found in this scope | - ^^^ not found in this scope
@ -18,7 +18,7 @@ LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
| help: you might be missing a type parameter: `, VAL` | help: you might be missing a type parameter: `, VAL`
error[E0046]: not all trait items implemented, missing: `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; LL | const VAL: T;
| ------------ `VAL` from trait | ------------ `VAL` from trait
@ -26,15 +26,7 @@ LL | const VAL: T;
LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {} LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation
error: constant expression depends on a generic parameter error: aborting due to 3 previous errors
--> $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
Some errors have detailed explanations: E0046, E0412. Some errors have detailed explanations: E0046, E0412.
For more information about an error, try `rustc --explain E0046`. For more information about an error, try `rustc --explain E0046`.

View file

@ -30,15 +30,7 @@ LL | const VAL: T;
LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {} LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation
error: constant expression depends on a generic parameter error: aborting due to 3 previous errors
--> $DIR/ice-6252.rs:13: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
Some errors have detailed explanations: E0046, E0412. Some errors have detailed explanations: E0046, E0412.
For more information about an error, try `rustc --explain E0046`. For more information about an error, try `rustc --explain E0046`.