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

Do not resolve associated const when there is no provided value #99449

Merged
merged 1 commit into from
Jul 24, 2022
Merged
Show file tree
Hide file tree
Changes from all 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: 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() {
Copy link
Member Author

Choose a reason for hiding this comment

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

TooGeneric here is a bit of a misnomer, since it really should be "not concrete" or something.

Copy link
Contributor

Choose a reason for hiding this comment

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

🤔 it's weird that we have to actually deal with TooGeneric here 🤔

this should already be guarded against by the uniify_failure_kind. Do any tests change if you always use

let guar = infcx.tcx.sess.delay_span_bug(
                    span,
                    format!("Missing value for constant, but no error reported?"),
                );
                NotConstEvaluatable::Error(guar)

Copy link
Member Author

@compiler-errors compiler-errors Jul 19, 2022

Choose a reason for hiding this comment

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

I changed this to always delay a bug, and not specially deal with TooGeneric in the case of infer/param types:

        match concrete {
            Err(ErrorHandled::TooGeneric) => Err({
                let guar = infcx.tcx.sess.delay_span_bug(
                    span,
                    format!("Missing value for constant, but no error reported?"),
                );
                NotConstEvaluatable::Error(guar)
            }),

and I get two ICEs, see this gist: https://gist.github.com/compiler-errors/146cd973d15ddc7fcfee6ff28a9ac5e0

Was that what you were asking me to try, @lcnr?

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, so InferCtxt::const_eval_resolve is not not doing what we need for this

if substs.has_infer_types_or_consts() {
let ac = AbstractConst::new(self.tcx, unevaluated.shrink());
if let Ok(None) = ac {
substs = InternalSubsts::identity_for_item(self.tcx, unevaluated.def.did);
} else {
return Err(ErrorHandled::TooGeneric);
}
}

I guess what we should do is:
match on AbstractConst::new(self.tcx, unevaluated.shrink());

Ok(None) is already correct.
Err(emitted) -> NotConstEvaluatable::Error(emitted)
Ok(Some(x)) -> the inference vars aren't used in the anon const, replace them with placeholders

feel free to do that in this PR, otherwise r=me

Copy link
Member Author

Choose a reason for hiding this comment

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

@lcnr: I'm gonna do it in a follow-up PR, since this solution doesn't really rely on that change, does it?

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.
compiler-errors marked this conversation as resolved.
Show resolved Hide resolved
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`.
10 changes: 1 addition & 9 deletions src/tools/clippy/tests/ui/crashes/ice-6252.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,7 @@ LL | const VAL: T;
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/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
error: aborting due to 3 previous errors

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