-
Notifications
You must be signed in to change notification settings - Fork 14k
arbitrary_self_types: Split the Autoderef chain #146095
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -149,6 +149,10 @@ hir_analysis_cross_crate_traits = cross-crate traits with a default impl, like ` | |
| hir_analysis_cross_crate_traits_defined = cross-crate traits with a default impl, like `{$traits}`, can only be implemented for a struct/enum type defined in the current crate | ||
| .label = can't implement cross-crate trait for type in another crate | ||
|
|
||
| hir_analysis_deref_receiver_target_diverge = `Deref::Target` does not agree with `Receiver::Target` | ||
| .label = `Deref::Target` is `{$deref_ty}` but `Receiver::Target` is `{$recv_ty}` | ||
| .note = `#![feature(arbitrary_self_types_merge_chains)]` rejects this kind of divergence | ||
|
|
||
| hir_analysis_dispatch_from_dyn_repr = structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]` | ||
|
|
||
| hir_analysis_dispatch_from_dyn_zst = the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else | ||
|
|
@@ -263,7 +267,8 @@ hir_analysis_invalid_receiver_ty_help = | |
| consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>` | ||
|
|
||
| hir_analysis_invalid_receiver_ty_help_no_arbitrary_self_types = | ||
| consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) | ||
| consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm surprised by this change. I would expect to only change the diagnostic when the feature is not enabled |
||
| alternatively, consider implement `Receiver` trait on the type of `self`, where applicable | ||
|
|
||
| hir_analysis_invalid_receiver_ty_help_nonnull_note = | ||
| `NonNull` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `NonNull` in a newtype wrapper for which you implement `Receiver` | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1720,7 +1720,9 @@ fn check_method_receiver<'tcx>( | |
| // Report error; would not have worked with `arbitrary_self_types[_pointers]`. | ||
| { | ||
| match receiver_validity_err { | ||
| ReceiverValidityError::DoesNotDeref if arbitrary_self_types_level.is_some() => { | ||
| ReceiverValidityError::DoesNotReceive | ||
| if arbitrary_self_types_level.is_some() => | ||
| { | ||
| let hint = match receiver_ty | ||
| .builtin_deref(false) | ||
| .unwrap_or(receiver_ty) | ||
|
|
@@ -1734,7 +1736,7 @@ fn check_method_receiver<'tcx>( | |
|
|
||
| tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty, hint }) | ||
| } | ||
| ReceiverValidityError::DoesNotDeref => { | ||
| ReceiverValidityError::DoesNotReceive => { | ||
| tcx.dcx().emit_err(errors::InvalidReceiverTyNoArbitrarySelfTypes { | ||
| span, | ||
| receiver_ty, | ||
|
|
@@ -1756,7 +1758,7 @@ fn check_method_receiver<'tcx>( | |
| enum ReceiverValidityError { | ||
| /// The self type does not get to the receiver type by following the | ||
| /// autoderef chain. | ||
| DoesNotDeref, | ||
| DoesNotReceive, | ||
| /// A type was found which is a method type parameter, and that's not allowed. | ||
| MethodGenericParamUsed, | ||
| } | ||
|
|
@@ -1812,17 +1814,21 @@ fn receiver_is_valid<'tcx>( | |
|
|
||
| confirm_type_is_not_a_method_generic_param(receiver_ty, method_generics)?; | ||
|
|
||
| let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_def_id, span, receiver_ty); | ||
| let cache = Default::default(); | ||
| let mut autoderef = | ||
| Autoderef::new(infcx, Some(&cache), wfcx.param_env, wfcx.body_def_id, span, receiver_ty); | ||
|
|
||
| // The `arbitrary_self_types` feature allows custom smart pointer | ||
| // types to be method receivers, as identified by following the Receiver<Target=T> | ||
| // types to be method receivers, as identified by following the Receiver<Target = T> | ||
| // chain. | ||
| if arbitrary_self_types_enabled.is_some() { | ||
| autoderef = autoderef.use_receiver_trait(); | ||
| // We are in the wf check, so we would like to deref the references in the type head. | ||
| // However, we do not want to walk `Deref` chain. | ||
| autoderef = autoderef.follow_receiver_chain(); | ||
|
Comment on lines
+1825
to
+1827
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm curious why that is here? But in |
||
| } | ||
|
|
||
| // The `arbitrary_self_types_pointers` feature allows raw pointer receivers like `self: *const Self`. | ||
| if arbitrary_self_types_enabled == Some(ArbitrarySelfTypesLevel::WithPointers) { | ||
| if matches!(arbitrary_self_types_enabled, Some(ArbitrarySelfTypesLevel::WithPointers)) { | ||
| autoderef = autoderef.include_raw_pointers(); | ||
| } | ||
|
|
||
|
|
@@ -1876,7 +1882,7 @@ fn receiver_is_valid<'tcx>( | |
| } | ||
|
|
||
| debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty); | ||
| Err(ReceiverValidityError::DoesNotDeref) | ||
| Err(ReceiverValidityError::DoesNotReceive) | ||
| } | ||
|
|
||
| fn legacy_receiver_is_implemented<'tcx>( | ||
|
|
||
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.
Are these impls required? I imagine this might be a consequence of my comment in
wfcheck?