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

Add ConstKind::Error and convert ErrorHandled::Reported to it. #71049

Merged
merged 4 commits into from
Apr 17, 2020

Conversation

eddyb
Copy link
Member

@eddyb eddyb commented Apr 12, 2020

By replicating the ty::Error approach to encoding "an error has occurred", all of the mechanisms that skip redundant/downstream errors are engaged and help out (see the reduction in test output).

This PR also adds ErrorHandled::Linted for the lint case because using ErrorHandled::Reported without having emitted an error that is guaranteed to stop compilation, is incorrect now.

r? @oli-obk cc @rust-lang/wg-const-eval @varkor @yodaldevoid

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 12, 2020
@bors

This comment has been minimized.

@RalfJung
Copy link
Member

This PR also adds ErrorHandled::Linted for the lint case because using ErrorHandled::Reported without having emitted an error that is guaranteed to stop compilation, is incorrect now.

Should there be a strongly worded comment somewhere to ensure this? What is the failure mode if we get this wrong (i.e., do we have a safety net that makes this ICE instead of silently doing the wrong thing)?

@eddyb
Copy link
Member Author

eddyb commented Apr 12, 2020

Should there be a strongly worded comment somewhere to ensure this? What is the failure mode if we get this wrong (i.e., do we have a safety net that makes this ICE instead of silently doing the wrong thing)?

@mark-i-m has a series of PRs where using tcx.types.err is replaced with a wrapper that uses delay_span_bug and they're finding all sorts of places in the compiler that abused error types.

And if we do #69426, we can have ErrorHandled::Reported hold an ErrorReported token.
Actually, let me do that now, so it's not forgotten.

@varkor varkor added the F-const_generics `#![feature(const_generics)]` label Apr 12, 2020
@eddyb
Copy link
Member Author

eddyb commented Apr 12, 2020

@RalfJung Implemented the more explicit route and added a comment, let me know if it's better.

@varkor I won't remove it but F-const_generics may be misleading, this is useful with regular array lengths too (in fact, most of the test that have improved error output are like that).

@varkor
Copy link
Member

varkor commented Apr 12, 2020

@eddyb: that label is simply used to track what PRs have made progress on any issue related to const generics, even if the primary purpose is not necessarily for const generics. At least, that's how I've been using it :)

@mark-i-m
Copy link
Member

cc #70866

if !x.val.needs_infer() {
return x.eval(tcx, relation.param_env()).val;
}
x.val
};

// FIXME(eddyb) doesn't look like everything below checks that `a.ty == b.ty`.
// We could probably always assert it early, as `const` generic parameters
// are not allowed to depend on other generic parameters, i.e. are concrete.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this temporary and won't always remain so, so let's not bake that assumption too deeply into the compiler.

Copy link
Member Author

Choose a reason for hiding this comment

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

We have already, this is nothing compared to everything else. It's only "temporary" in the sense that the first thing we stabilize won't have generic parameters in const parameter types.

Copy link
Member Author

Choose a reason for hiding this comment

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

Part of the problem is we'd need to stabilize something like StructuralMatch (some deep trait, unlike StructuralPartialEq/StructuralEq), because we can't just allow unrestricted types.
But even with that also it's a PITA to implement correctly, far more so than just concrete types.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure I understand all of this; I'm just saying we should avoid too deep of an architectural dependence on the fact that const params can't depend on type params so that it doesn't take a year to dig out of.

err_inval!(TypeckError) => return Err(ErrorHandled::Reported),
err_inval!(TypeckError(error_reported)) => {
return Err(ErrorHandled::Reported(error_reported));
}
// We must *always* hard error on these, even if the caller wants just a lint.
err_inval!(Layout(LayoutError::SizeOverflow(_))) => true,
Copy link
Contributor

@Centril Centril Apr 13, 2020

Choose a reason for hiding this comment

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

Hmm, this case doesn't early return so it results in Ok(_) and then report_as_lint will turn it into ErrorReported::Linted, which seems wrong?

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

This function unfortunately became a mess over time. :/ I get the feeling we are trying to shove too many different things into one code path here.

I also do not have the slightest clue what that replace_span_with business in report_as_lint is even doing.

Copy link
Member

Choose a reason for hiding this comment

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

But SizeOverflow will be a hard error even when report_as_lint is called, so always returning Linted there seems wrong, superficially.

Copy link
Contributor

Choose a reason for hiding this comment

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

This function unfortunately became a mess over time. :/ I get the feeling we are trying to shove too many different things into one code path here.

My thoughts exactly.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yea, so the must_error variable should be eliminated in favour of early returning here by calling report_as_error

Copy link
Member Author

Choose a reason for hiding this comment

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

I kept must_error but replaced Result<(), ErrorHandled> in the return type with ErrorHandled, let me know if that's enough.

Copy link
Contributor

Choose a reason for hiding this comment

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

that works, too, lgtm

Copy link
Member

Choose a reason for hiding this comment

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

Avoiding that boolean could have made the code cleaner... but maybe not, and anyway we can leave that to later.

@@ -90,7 +81,7 @@ impl<'tcx> ConstEvalErr<'tcx> {

pub fn report_as_error(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ErrorHandled {
match self.struct_error(tcx, message, |mut e| e.emit()) {
Ok(_) => ErrorHandled::Reported,
Ok(_) => ErrorHandled::Reported(ErrorReported),
Copy link
Member

Choose a reason for hiding this comment

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

Is still seems rather easy to just say ErrorReported when the compiler says that that is the type you need. Maybe the only way to construct this should be something like ErrorReported::assert_error_reported_to_user or so? Could that constructor do delay_bug just to be extra safe or does that not make sense?

Copy link
Member Author

Choose a reason for hiding this comment

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

@RalfJung We're working on that but it's not ready yet because of some abuse in the compiler (of ty::Error which we wanted to add an ErrorReported to).

I tried to make this PR not blocked on that, but write ErrorReported or error_reported everywhere relevant so e.g. @mark-i-m can find it later.

This is mostly because I only did this PR as a prerequisite for #70970.
I am fine with blocking this PR on @mark-i-m's work if fixing #70942 is not a priority.

Copy link
Member

Choose a reason for hiding this comment

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

@eddyb sure, if improving this is on your list then that's fine for me. I was just pointing out that as the final solution this still seems suboptimal.

Copy link
Member Author

Choose a reason for hiding this comment

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

I was just pointing out that as the final solution this still seems suboptimal.

Indeed. Also, I should've pointed at #69426.

Copy link
Member

Choose a reason for hiding this comment

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

Having this PR will definitely make my next PR easier.

@bors
Copy link
Contributor

bors commented Apr 15, 2020

☔ The latest upstream changes (presumably #70452) made this pull request unmergeable. Please resolve the merge conflicts.

@oli-obk
Copy link
Contributor

oli-obk commented Apr 15, 2020

r=me after a rebase

@eddyb
Copy link
Member Author

eddyb commented Apr 16, 2020

@bors r=oli-obk rollup=never

@bors
Copy link
Contributor

bors commented Apr 16, 2020

📌 Commit 77f38dc has been approved by oli-obk

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 16, 2020
@Dylan-DPC-zz
Copy link

@bors p=1

@bors
Copy link
Contributor

bors commented Apr 17, 2020

⌛ Testing commit 77f38dc with merge 8d67f57...

@bors
Copy link
Contributor

bors commented Apr 17, 2020

☀️ Test successful - checks-azure
Approved by: oli-obk
Pushing 8d67f57 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Apr 17, 2020
@bors bors merged commit 8d67f57 into rust-lang:master Apr 17, 2020
@eddyb eddyb deleted the const-err branch April 18, 2020 15:38
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Apr 22, 2020
…-obk

Detect mistyped associated consts in `Instance::resolve`.

*Based on rust-lang#71049 to prevent redundant/misleading downstream errors.*

Fixes rust-lang#70942 by refusing to resolve an associated `const` if it doesn't have the same type in the `impl` that it does in the `trait` (which we assume had errored, and `delay_span_bug` guards against bugs).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F-const_generics `#![feature(const_generics)]` merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants