-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Reject unconstrained lifetimes in type_of(assoc_ty) instead of during wfcheck of the impl item #127973
base: master
Are you sure you want to change the base?
Conversation
aaaed98
to
403b050
Compare
This comment has been minimized.
This comment has been minimized.
403b050
to
dbbcbf9
Compare
MyFrom::my_from(self.0).ok().unwrap() | ||
} | ||
} | ||
|
||
fn main() { | ||
let _pos: Phantom1<DummyT<()>> = Scope::new().my_index(); | ||
//~^ ERROR: no method named `my_index` found for struct `Scope` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is funny and should probably have some more taint tracking to get eliminated (same with the TAIT cycle above)
pub struct GenericPredicates<'tcx> { | ||
pub parent: Option<DefId>, | ||
pub predicates: &'tcx [(Clause<'tcx>, Span)], | ||
pub effects_min_tys: &'tcx ty::List<Ty<'tcx>>, | ||
pub tainted_by_errors: Result<(), ErrorGuaranteed>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Explain what it means to be tainted here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. If preferred I can also register a dummy predicate {error}: Sized
or sth, that would probably result in similar behaviour
FWIW I tried an alternative design that would taint while these can be resolved (see https://github.com/oli-obk/rust/pull/new/uplift_wf_checks3), we still have several new cycles:
|
61cec80
to
719d6e8
Compare
This comment has been minimized.
This comment has been minimized.
719d6e8
to
5229b23
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding SelectionError
-- I wonder if we should instead treat the goal as successful but constrain all the variables with Error
instead.
5229b23
to
ecab78c
Compare
This comment has been minimized.
This comment has been minimized.
if let Err(guar) = unsatisfied_predicates.error_reported() { | ||
return guar; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is necessary to avoid bogus diagnostics like
error[E0599]: the method `my_index` exists for struct `Scope<_>`, but its trait bounds were not satisfied
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:50:51
|
LL | struct Scope<T>(Phantom2<DummyT<T>>);
| --------------- method `my_index` not found for this struct because it doesn't satisfy `Scope<{type error}>: MyIndex<DummyT<{type error}>>`
...
LL | let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
| ^^^^^^^^ method cannot be called on `Scope<_>` due to unsatisfied trait bounds
|
note: trait bound `{type error}: Sized` was not satisfied
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:41:6
|
LL | impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
| ^ ^ ------------------ --------
| | |
| | unsatisfied trait bound introduced here
| unsatisfied trait bound introduced here
= help: items from traits can only be used if the trait is implemented and in scope
note: `MyIndex` defines an item `my_index`, perhaps you need to implement it
--> $DIR/ice-failed-to-resolve-instance-for-110696.rs:9:1
|
LL | trait MyIndex<T> {
| ^^^^^^^^^^^^^^^^
help: consider relaxing the type parameter's implicit `Sized` bound
|
LL | impl<T: ?Sized + MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<DummyT<T>> for Scope<U> {
| ++++++++
help: consider relaxing the type parameter's implicit `Sized` bound
|
LL | impl<T: MyFrom<Phantom2<DummyT<U>>>, U: ?Sized> MyIndex<DummyT<T>> for Scope<U> {
| ++++++++
Not sure yet how to generally avoid these (I don't want to just hide the predicate, I want to hide the entire error), but this change doesn't make things worse really, so 🤷
ecab78c
to
a1ad9fd
Compare
☔ The latest upstream changes (presumably #125443) made this pull request unmergeable. Please resolve the merge conflicts. |
a1ad9fd
to
4938b6f
Compare
This comment has been minimized.
This comment has been minimized.
4938b6f
to
ed019dc
Compare
This comment has been minimized.
This comment has been minimized.
ed019dc
to
525f049
Compare
This comment has been minimized.
This comment has been minimized.
525f049
to
12a5681
Compare
This comment has been minimized.
This comment has been minimized.
… wfcheck of the impl item
…aint the query result
12a5681
to
3377c2f
Compare
The job Click to see the possible cause of the failure (guessed by this bot)
|
Of all of the tests you've linked, as far as I can tell only only one of them continues to ICE (#125874). Am I testing them wrong, or is this true? I think we should probably reformulate this PR; it seems a bit too invasive for me to be comfortable with landing it, and I think we can find an approach that requires tracking less state than what this PR does. |
I wonder if we can get most of the way just by stripping lifetimes that are unmentioned in the signature in lowering or generics_of, and then making the error reporting on "unknown lifetime" figure out that it's an unconstrained one |
Opened to discuss as part of https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types/topic/unconstrained.20lifetimes.20in.20impls
Lifetimes are allowed to be unconstrained on impls because it made some libcore macros simpler and it was a breaking change to fix it. This becomes a problem when the lifetime is used in a nonconstraining way (e.g. in an associated item), but in a way that it can be used (e.g. via associated types). Associated functions are not an issue, because they must already have a compatible signature to the trait's assoc function decls, which means unconstrained lifetimes can't be a part of them (except via assoc types).
While the current system is sound, it also doesn't mention in the diagnostic why the lifetime is not permitted when it is permitted in other situations.
Instead of rejecting those lifetimes in wfcheck, we now reject them in
type_of
of associated types. Thus, during hir ty lowering of assoc types, we report any types with unconstrained lifetimes. since this is happening on the hir, we have a fairly good span to report to the user.We could instead walk the hir and look for the offending lifetime (just for improving the span), but I have a deeper reason for this change:
We can now move the remainder of the check from wfcheck to explicit_predicates_of, which already computes the necessary information, and is on a regular query code path, so we can taint it and suppress follow-up errors and ICEs
fixes #123141
fixes #124350
fixes #125874
fixes #126942