-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Implement arbitrary_self_types #45870
Conversation
If the feature is enabled, allow method `self` types to be any type that auto-derefs to `self`. - Currently, this supports inherent methods as well as trait methods. The plan AFAIK is to only allow this for trait methods, so I guess it won’t stay this way - Dynamic dispatch isn’t implemented yet, so the compiler will ICE if you define a trait method that takes `self: Rc<Self>` and try to call it on an `Rc<Trait>`. I will probably just make those methods non-object-safe initially.
…error Rewrote ExplicitSelf, adding a new `Other` variant for arbitrary self types. It’s a bit more sophisticated now, and checks for type equality, so you have to pass the type context and param env as arguments. There’s a borrow-checker error here that I have to fix Rewrote check_method_receiver, so it acts as if arbitrary self types are allowed, and then checks for ExplicitSelf::Other at the end and disallows it unless the feature is present.
Had to take the infer context as a parameter instead of the type context, so that the function can be called during inference
…of looping forever
- removed the inherent impls compile-fail test, because we’ll be supporting them - remove E0308-2 because it’s gonna be supported now (behind a feature gate) - replaced the mismatched method receiver error message with something better, so fixed the tests that that broke
- added some old code that used ExplicitSelf::determine to check for eqtype with the expected self type in the simple cases - this fixes problems with error messages being worse in those cases, which caused some compile-fail tests to fail
…osure, instead of infcx
I was only doing it for self_arg_ty, and ended up causing run-pass/associated-types-projection-from-known-type-in-impl.rs to fail.
…origin I doubt this changes anything, I was just trying to fix an issue with error messages and ended up doing this along with other things. Committing it separately so I can undo it easily.
… error messages that I don't understand why they changed, so the tests pass
src/librustc_typeck/check/wfcheck.rs
Outdated
}) | ||
|
||
let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver); | ||
let eq = |expected, actual| fcx.at(&cause, fcx.param_env).eq(expected, actual); |
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.
I think you want to wrap this inside a commit_if_ok
, because IIRC just an eq
isn't transactional.
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.
I don't know what you mean by transactional, but I'll try it; maybe it will help with the error messages problem
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.
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.
Sorry forgot to detail - the problem is that eq
can have side-effects even if it fails (e.g. if you equate (_, u32)
with (i32, i32)
, it will make the _
be i32
before erroring out).
(i.e. is
demand_eqtype_with_origin
"transactional"?)
Nope. You want fcx.commit_if_ok(|_| fcx.at(&cause, fcx.param_env).eq(expected, actual))
, which creates a transaction and rolls it back if the equality fails.
@@ -1,3 +1,5 @@ | |||
//~ ERROR mismatched types |
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 doesn't make sense how are you getting mismatched type errors on this line you passed DUMMY_SP
to a type error function, please use a correct span so that the error will appear in the correect line.
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.
Ya so this is the thing I was having trouble with on Gitter. In e06cd31#diff-15d40489387405cc3e23e2f9f66a74c2L519 I removed some error checks that I (still think) are redundant, and it caused the error messages to go wonky. I can't figure out why
put the error message on one line so the test suite does not think it is two errors use a substring of the error message so it fits in 100 chars for tidy
03b3294
to
7f8b003
Compare
The error wonkyness is caused by wonky constraint handling in rust/src/librustc/infer/region_inference/mod.rs Lines 630 to 642 in 02004ef
I think that converting this |
now that we've fixed the bug where constraint origins were getting overwritten, the good error messages are back (with some tweaks)
@arielb1 I fixed the bug, and the good error messages are back. There's a slight difference because instead of comparing There was also one ui test whose error message changed, presumably because of the bugfix (constraint origins are no longer being overwritten, even when we're outside of a snapshot). |
src/test/ui/span/issue-27522.stderr
Outdated
|
||
error: aborting due to previous error | ||
error: arbitrary `self` types are unstable (see issue #44874) |
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.
Could you not have this error if you already emitted an "invalid self type" error?
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.
Currently it emits both errors. I can change it though, wasn't sure whether to emit both or just the "invalid self
type" error
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.
You should change it to just emit the "invalid self type" error - you don't want to emit unnecessary feature gate errors because they are confusing.
This is LGTM, just:
r=me with these fixed |
@arielb1 should be good to go once the CI finishes running |
@bors r+ |
📌 Commit 77cd993 has been approved by |
Implement arbitrary_self_types r? @arielb1 cc @nikomatsakis Partial implementation of #44874. Supports trait and struct methods with arbitrary self types, as long as the type derefs (transitively) to `Self`. Doesn't support raw-pointer `self` yet. Methods with non-standard self types (i.e. anything other than `&self, &mut self, and Box<Self>`) are not object safe, because dynamic dispatch hasn't been implemented for them yet. I believe this is also a (partial) fix for #27941.
☀️ Test successful - status-appveyor, status-travis |
r? @arielb1
cc @nikomatsakis
Partial implementation of #44874. Supports trait and struct methods with arbitrary self types, as long as the type derefs (transitively) to
Self
. Doesn't support raw-pointerself
yet.Methods with non-standard self types (i.e. anything other than
&self, &mut self, and Box<Self>
) are not object safe, because dynamic dispatch hasn't been implemented for them yet.I believe this is also a (partial) fix for #27941.