mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 00:03:43 +00:00
Reject generic self types.
The RFC for arbitrary self types v2 declares that we should reject
"generic" self types. This commit does so.
The definition of "generic" was unclear in the RFC, but has been
explored in
https://github.com/rust-lang/rust/issues/129147
and the conclusion is that "generic" means any `self` type which
is a type parameter defined on the method itself, or references
to such a type.
This approach was chosen because other definitions of "generic"
don't work. Specifically,
* we can't filter out generic type _arguments_, because that would
filter out Rc<Self> and all the other types of smart pointer
we want to support;
* we can't filter out all type params, because Self itself is a
type param, and because existing Rust code depends on other
type params declared on the type (as opposed to the method).
This PR decides to make a new error code for this case, instead of
reusing the existing E0307 error. This makes the code a
bit more complex, but it seems we have an opportunity to provide
specific diagnostics for this case so we should do so.
This PR filters out generic self types whether or not the
'arbitrary self types' feature is enabled. However, it's believed
that it can't have any effect on code which uses stable Rust, since
there are no stable traits which can be used to indicate a valid
generic receiver type, and thus it would have been impossible to
write code which could trigger this new error case.
It is however possible that this could break existing code which
uses either of the unstable `arbitrary_self_types` or
`receiver_trait` features. This breakage is intentional; as
we move arbitrary self types towards stabilization we don't want
to continue to support generic such types.
This PR adds lots of extra tests to arbitrary-self-from-method-substs.
Most of these are ways to trigger a "type mismatch" error which
9b82580c73/compiler/rustc_hir_typeck/src/method/confirm.rs (L519)
hopes can be minimized by filtering out generics in this way.
We remove a FIXME from confirm.rs suggesting that we make this change.
It's still possible to cause type mismatch errors, and a subsequent
PR may be able to improve diagnostics in this area, but it's harder
to cause these errors without contrived uses of the turbofish.
This is a part of the arbitrary self types v2 project,
https://github.com/rust-lang/rfcs/pull/3519
https://github.com/rust-lang/rust/issues/44874
r? @wesleywiser
This commit is contained in:
parent
8b9f0f9c1c
commit
6d8d79595e
51
compiler/rustc_error_codes/src/error_codes/E0801.md
Normal file
51
compiler/rustc_error_codes/src/error_codes/E0801.md
Normal file
@ -0,0 +1,51 @@
|
||||
The `self` parameter in a method has an invalid generic "receiver type".
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0801
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
fn foo<R: std::ops::Deref<Target=Self>>(self: R) {}
|
||||
}
|
||||
```
|
||||
|
||||
or alternatively,
|
||||
|
||||
```compile_fail,E0801
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
fn foo(self: impl std::ops::Deref<Target=Self>) {}
|
||||
}
|
||||
```
|
||||
|
||||
Methods take a special first parameter, termed `self`. It's normal to
|
||||
use `self`, `&self` or `&mut self`, which are syntactic sugar for
|
||||
`self: Self`, `self: &Self`, and `self: &mut Self` respectively.
|
||||
But it's also possible to use more sophisticated types of `self`
|
||||
parameter, for instance `std::rc::Rc<Self>`. The set of allowable
|
||||
`Self` types is extensible using the nightly feature
|
||||
[Arbitrary self types][AST].
|
||||
This will extend the valid set of `Self` types to anything which implements
|
||||
`std::ops::Deref<Target=Self>`, for example `Rc<Self>`, `Box<Self>`, or
|
||||
your own smart pointers that do the same.
|
||||
|
||||
However, even with that feature, the `self` type must be concrete.
|
||||
Generic `self` types are not permitted. Specifically, a `self` type will
|
||||
be rejected if it is a type parameter defined on the method.
|
||||
|
||||
These are OK:
|
||||
|
||||
```
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
fn foo(self) {}
|
||||
fn foo2(self: std::rc::Rc<Self>) {} // or some other similar
|
||||
// smart pointer if you enable arbitrary self types and
|
||||
// the pointer implements Deref<Target=Self>
|
||||
}
|
||||
```
|
||||
|
||||
[AST]: https://doc.rust-lang.org/unstable-book/language-features/arbitrary-self-types.html
|
@ -540,6 +540,7 @@ E0797: 0797,
|
||||
E0798: 0798,
|
||||
E0799: 0799,
|
||||
E0800: 0800,
|
||||
E0801: 0801,
|
||||
);
|
||||
)
|
||||
}
|
||||
|
@ -234,6 +234,12 @@ hir_analysis_inherent_ty_outside_relevant = cannot define inherent `impl` for a
|
||||
.help = consider moving this inherent impl into the crate defining the type if possible
|
||||
.span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items
|
||||
|
||||
hir_analysis_invalid_generic_receiver_ty = invalid generic `self` parameter type: `{$receiver_ty}`
|
||||
.note = type of `self` must not be a method generic parameter type
|
||||
|
||||
hir_analysis_invalid_generic_receiver_ty_help =
|
||||
use a concrete type such as `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`)
|
||||
|
||||
hir_analysis_invalid_receiver_ty = invalid `self` parameter type: `{$receiver_ty}`
|
||||
.note = type of `self` must be `Self` or a type that dereferences to it
|
||||
|
||||
|
@ -2,13 +2,14 @@ use std::cell::LazyCell;
|
||||
use std::ops::{ControlFlow, Deref};
|
||||
|
||||
use hir::intravisit::{self, Visitor};
|
||||
use itertools::Itertools;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
|
||||
use rustc_hir::ItemKind;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{GenericParamKind, ItemKind};
|
||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
|
||||
use rustc_macros::LintDiagnostic;
|
||||
@ -378,7 +379,7 @@ fn check_trait_item<'tcx>(
|
||||
_ => (None, trait_item.span),
|
||||
};
|
||||
check_dyn_incompatible_self_trait_by_name(tcx, trait_item);
|
||||
let mut res = check_associated_item(tcx, def_id, span, method_sig);
|
||||
let mut res = check_associated_item(tcx, def_id, span, method_sig, None);
|
||||
|
||||
if matches!(trait_item.kind, hir::TraitItemKind::Fn(..)) {
|
||||
for &assoc_ty_def_id in tcx.associated_types_for_impl_traits_in_associated_fn(def_id) {
|
||||
@ -387,6 +388,7 @@ fn check_trait_item<'tcx>(
|
||||
assoc_ty_def_id.expect_local(),
|
||||
tcx.def_span(assoc_ty_def_id),
|
||||
None,
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -904,8 +906,13 @@ fn check_impl_item<'tcx>(
|
||||
hir::ImplItemKind::Type(ty) if ty.span != DUMMY_SP => (None, ty.span),
|
||||
_ => (None, impl_item.span),
|
||||
};
|
||||
|
||||
check_associated_item(tcx, impl_item.owner_id.def_id, span, method_sig)
|
||||
check_associated_item(
|
||||
tcx,
|
||||
impl_item.owner_id.def_id,
|
||||
span,
|
||||
method_sig,
|
||||
Some(impl_item.generics),
|
||||
)
|
||||
}
|
||||
|
||||
fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), ErrorGuaranteed> {
|
||||
@ -1038,6 +1045,7 @@ fn check_associated_item(
|
||||
item_id: LocalDefId,
|
||||
span: Span,
|
||||
sig_if_method: Option<&hir::FnSig<'_>>,
|
||||
generics: Option<&hir::Generics<'_>>,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let loc = Some(WellFormedLoc::Ty(item_id));
|
||||
enter_wf_checking_ctxt(tcx, span, item_id, |wfcx| {
|
||||
@ -1070,7 +1078,7 @@ fn check_associated_item(
|
||||
hir_sig.decl,
|
||||
item.def_id.expect_local(),
|
||||
);
|
||||
check_method_receiver(wfcx, hir_sig, item, self_ty)
|
||||
check_method_receiver(wfcx, hir_sig, item, self_ty, generics)
|
||||
}
|
||||
ty::AssocKind::Type => {
|
||||
if let ty::AssocItemContainer::TraitContainer = item.container {
|
||||
@ -1692,6 +1700,7 @@ fn check_method_receiver<'tcx>(
|
||||
fn_sig: &hir::FnSig<'_>,
|
||||
method: ty::AssocItem,
|
||||
self_ty: Ty<'tcx>,
|
||||
generics: Option<&hir::Generics<'_>>,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let tcx = wfcx.tcx();
|
||||
|
||||
@ -1726,7 +1735,9 @@ fn check_method_receiver<'tcx>(
|
||||
None
|
||||
};
|
||||
|
||||
if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, arbitrary_self_types_level) {
|
||||
let receiver_validity =
|
||||
receiver_is_valid(wfcx, span, receiver_ty, self_ty, arbitrary_self_types_level, generics);
|
||||
if let Err(receiver_validity_err) = receiver_validity {
|
||||
return Err(match arbitrary_self_types_level {
|
||||
// Wherever possible, emit a message advising folks that the features
|
||||
// `arbitrary_self_types` or `arbitrary_self_types_pointers` might
|
||||
@ -1737,7 +1748,9 @@ fn check_method_receiver<'tcx>(
|
||||
receiver_ty,
|
||||
self_ty,
|
||||
Some(ArbitrarySelfTypesLevel::Basic),
|
||||
) =>
|
||||
generics,
|
||||
)
|
||||
.is_ok() =>
|
||||
{
|
||||
// Report error; would have worked with `arbitrary_self_types`.
|
||||
feature_err(
|
||||
@ -1759,7 +1772,9 @@ fn check_method_receiver<'tcx>(
|
||||
receiver_ty,
|
||||
self_ty,
|
||||
Some(ArbitrarySelfTypesLevel::WithPointers),
|
||||
) =>
|
||||
generics,
|
||||
)
|
||||
.is_ok() =>
|
||||
{
|
||||
// Report error; would have worked with `arbitrary_self_types_pointers`.
|
||||
feature_err(
|
||||
@ -1777,13 +1792,53 @@ fn check_method_receiver<'tcx>(
|
||||
_ =>
|
||||
// Report error; would not have worked with `arbitrary_self_types[_pointers]`.
|
||||
{
|
||||
tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty })
|
||||
match receiver_validity_err {
|
||||
ReceiverValidityError::DoesNotDeref => {
|
||||
tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty })
|
||||
}
|
||||
ReceiverValidityError::MethodGenericParamUsed => {
|
||||
tcx.dcx().emit_err(errors::InvalidGenericReceiverTy { span, receiver_ty })
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Error cases which may be returned from `receiver_is_valid`. These error
|
||||
/// cases are generated in this function as they may be unearthed as we explore
|
||||
/// the `autoderef` chain, but they're converted to diagnostics in the caller.
|
||||
enum ReceiverValidityError {
|
||||
/// The self type does not get to the receiver type by following the
|
||||
/// autoderef chain.
|
||||
DoesNotDeref,
|
||||
/// A type was found which is a method type parameter, and that's not allowed.
|
||||
MethodGenericParamUsed,
|
||||
}
|
||||
|
||||
/// Confirms that a type is not a type parameter referring to one of the
|
||||
/// method's type params.
|
||||
fn confirm_type_is_not_a_method_generic_param(
|
||||
ty: Ty<'_>,
|
||||
method_generics: Option<&hir::Generics<'_>>,
|
||||
) -> Result<(), ReceiverValidityError> {
|
||||
if let ty::Param(param) = ty.kind() {
|
||||
if let Some(generics) = method_generics {
|
||||
if generics
|
||||
.params
|
||||
.iter()
|
||||
.filter(|g| matches!(g.kind, GenericParamKind::Type { .. }))
|
||||
.map(|g| g.name.ident().name)
|
||||
.contains(¶m.name)
|
||||
{
|
||||
return Err(ReceiverValidityError::MethodGenericParamUsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
|
||||
/// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
|
||||
/// through a `*const/mut T` raw pointer if `arbitrary_self_types_pointers` is also enabled.
|
||||
@ -1799,7 +1854,8 @@ fn receiver_is_valid<'tcx>(
|
||||
receiver_ty: Ty<'tcx>,
|
||||
self_ty: Ty<'tcx>,
|
||||
arbitrary_self_types_enabled: Option<ArbitrarySelfTypesLevel>,
|
||||
) -> bool {
|
||||
generics: Option<&hir::Generics<'_>>,
|
||||
) -> Result<(), ReceiverValidityError> {
|
||||
let infcx = wfcx.infcx;
|
||||
let tcx = wfcx.tcx();
|
||||
let cause =
|
||||
@ -1811,9 +1867,11 @@ fn receiver_is_valid<'tcx>(
|
||||
ocx.eq(&cause, wfcx.param_env, self_ty, receiver_ty)?;
|
||||
if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(NoSolution) }
|
||||
}) {
|
||||
return true;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
confirm_type_is_not_a_method_generic_param(receiver_ty, generics)?;
|
||||
|
||||
let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_def_id, span, receiver_ty);
|
||||
|
||||
// The `arbitrary_self_types_pointers` feature allows raw pointer receivers like `self: *const Self`.
|
||||
@ -1830,6 +1888,8 @@ fn receiver_is_valid<'tcx>(
|
||||
potential_self_ty, self_ty
|
||||
);
|
||||
|
||||
confirm_type_is_not_a_method_generic_param(potential_self_ty, generics)?;
|
||||
|
||||
// Check if the self type unifies. If it does, then commit the result
|
||||
// since it may have region side-effects.
|
||||
if let Ok(()) = wfcx.infcx.commit_if_ok(|_| {
|
||||
@ -1838,7 +1898,7 @@ fn receiver_is_valid<'tcx>(
|
||||
if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(NoSolution) }
|
||||
}) {
|
||||
wfcx.register_obligations(autoderef.into_obligations());
|
||||
return true;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Without `feature(arbitrary_self_types)`, we require that each step in the
|
||||
@ -1865,7 +1925,7 @@ fn receiver_is_valid<'tcx>(
|
||||
}
|
||||
|
||||
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
|
||||
false
|
||||
Err(ReceiverValidityError::DoesNotDeref)
|
||||
}
|
||||
|
||||
fn receiver_is_implemented<'tcx>(
|
||||
|
@ -1623,6 +1623,16 @@ pub(crate) struct InvalidReceiverTy<'tcx> {
|
||||
pub receiver_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_invalid_generic_receiver_ty, code = E0801)]
|
||||
#[note]
|
||||
#[help(hir_analysis_invalid_generic_receiver_ty_help)]
|
||||
pub(crate) struct InvalidGenericReceiverTy<'tcx> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub receiver_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_cmse_inputs_stack_spill, code = E0798)]
|
||||
#[note]
|
||||
|
@ -533,9 +533,6 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||
self.register_predicates(obligations);
|
||||
}
|
||||
Err(terr) => {
|
||||
// FIXME(arbitrary_self_types): We probably should limit the
|
||||
// situations where this can occur by adding additional restrictions
|
||||
// to the feature, like the self type can't reference method args.
|
||||
if self.tcx.features().arbitrary_self_types() {
|
||||
self.err_ctxt()
|
||||
.report_mismatched_types(
|
||||
|
@ -4102,7 +4102,6 @@ ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs
|
||||
ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs
|
||||
ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs
|
||||
ui/type-alias-impl-trait/issue-57611-trait-alias.rs
|
||||
ui/type-alias-impl-trait/issue-57700.rs
|
||||
ui/type-alias-impl-trait/issue-57807-associated-type.rs
|
||||
ui/type-alias-impl-trait/issue-57961.rs
|
||||
ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs
|
||||
|
@ -8,7 +8,7 @@ use std::ops::Deref;
|
||||
struct Foo(u32);
|
||||
impl Foo {
|
||||
const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
|
||||
//~^ ERROR: `R` cannot be used as the type of `self`
|
||||
//~^ ERROR invalid generic `self` parameter type
|
||||
//~| ERROR destructor of `R` cannot be evaluated at compile-time
|
||||
self.0
|
||||
//~^ ERROR cannot call non-const fn `<R as Deref>::deref` in constant function
|
||||
|
@ -15,18 +15,16 @@ LL | const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
|
||||
LL | }
|
||||
| - value is dropped here
|
||||
|
||||
error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature
|
||||
error[E0801]: invalid generic `self` parameter type: `R`
|
||||
--> $DIR/arbitrary-self-from-method-substs-ice.rs:10:49
|
||||
|
|
||||
LL | const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
|
||||
| ^
|
||||
|
|
||||
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
|
||||
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= help: 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`)
|
||||
= note: type of `self` must not be a method generic parameter type
|
||||
= help: use a concrete type such as `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`)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0015, E0493, E0658.
|
||||
Some errors have detailed explanations: E0015, E0493, E0801.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -1,14 +1,168 @@
|
||||
error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:8:43
|
||||
error[E0801]: invalid generic `self` parameter type: `R`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:9:43
|
||||
|
|
||||
LL | fn get<R: Deref<Target = Self>>(self: R) -> u32 {
|
||||
| ^
|
||||
|
|
||||
= note: type of `self` must not be a method generic parameter type
|
||||
= help: use a concrete type such as `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`)
|
||||
|
||||
error[E0801]: invalid generic `self` parameter type: `&R`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:13:44
|
||||
|
|
||||
LL | fn get1<R: Deref<Target = Self>>(self: &R) -> u32 {
|
||||
| ^^
|
||||
|
|
||||
= note: type of `self` must not be a method generic parameter type
|
||||
= help: use a concrete type such as `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`)
|
||||
|
||||
error[E0801]: invalid generic `self` parameter type: `&mut R`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:17:44
|
||||
|
|
||||
LL | fn get2<R: Deref<Target = Self>>(self: &mut R) -> u32 {
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: type of `self` must not be a method generic parameter type
|
||||
= help: use a concrete type such as `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`)
|
||||
|
||||
error[E0801]: invalid generic `self` parameter type: `Rc<R>`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:21:44
|
||||
|
|
||||
LL | fn get3<R: Deref<Target = Self>>(self: std::rc::Rc<R>) -> u32 {
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must not be a method generic parameter type
|
||||
= help: use a concrete type such as `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`)
|
||||
|
||||
error[E0801]: invalid generic `self` parameter type: `&Rc<R>`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:25:44
|
||||
|
|
||||
LL | fn get4<R: Deref<Target = Self>>(self: &std::rc::Rc<R>) -> u32 {
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must not be a method generic parameter type
|
||||
= help: use a concrete type such as `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`)
|
||||
|
||||
error[E0801]: invalid generic `self` parameter type: `Rc<&R>`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:29:44
|
||||
|
|
||||
LL | fn get5<R: Deref<Target = Self>>(self: std::rc::Rc<&R>) -> u32 {
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must not be a method generic parameter type
|
||||
= help: use a concrete type such as `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`)
|
||||
|
||||
error[E0658]: `<FR as FindReceiver>::Receiver` cannot be used as the type of `self` without the `arbitrary_self_types` feature
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:33:37
|
||||
|
|
||||
LL | fn get6<FR: FindReceiver>(self: FR::Receiver, other: FR) -> u32 {
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
|
||||
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= help: 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`)
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:61:18
|
||||
|
|
||||
LL | fn get(self: R) {}
|
||||
| ^
|
||||
|
|
||||
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
|
||||
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= help: 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`)
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
error[E0271]: type mismatch resolving `<Silly as FindReceiver>::Receiver == Foo`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:92:9
|
||||
|
|
||||
LL | foo.get6(Silly);
|
||||
| ^^^^ type mismatch resolving `<Silly as FindReceiver>::Receiver == Foo`
|
||||
|
|
||||
note: expected this to be `Foo`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:71:21
|
||||
|
|
||||
LL | type Receiver = std::rc::Rc<Foo>;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= note: expected struct `Foo`
|
||||
found struct `Rc<Foo>`
|
||||
|
||||
error[E0271]: type mismatch resolving `<Silly as FindReceiver>::Receiver == &Foo`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:96:9
|
||||
|
|
||||
LL | foo.get6(Silly);
|
||||
| ^^^^ type mismatch resolving `<Silly as FindReceiver>::Receiver == &Foo`
|
||||
|
|
||||
note: expected this to be `&Foo`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:71:21
|
||||
|
|
||||
LL | type Receiver = std::rc::Rc<Foo>;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= note: expected reference `&Foo`
|
||||
found struct `Rc<Foo>`
|
||||
|
||||
error[E0599]: the method `get` exists for struct `Rc<Bar<_>>`, but its trait bounds were not satisfied
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:100:7
|
||||
|
|
||||
LL | struct Bar<R>(std::marker::PhantomData<R>);
|
||||
| ------------- doesn't satisfy `Bar<_>: Deref`
|
||||
...
|
||||
LL | t.get();
|
||||
| ^^^ method cannot be called on `Rc<Bar<_>>` due to unsatisfied trait bounds
|
||||
|
|
||||
note: the following trait bounds were not satisfied:
|
||||
`<&Bar<_> as Deref>::Target = Bar<&Bar<_>>`
|
||||
`<&Rc<Bar<_>> as Deref>::Target = Bar<&Rc<Bar<_>>>`
|
||||
`<&mut Bar<_> as Deref>::Target = Bar<&mut Bar<_>>`
|
||||
`<&mut Rc<Bar<_>> as Deref>::Target = Bar<&mut Rc<Bar<_>>>`
|
||||
`<Rc<Bar<_>> as Deref>::Target = Bar<Rc<Bar<_>>>`
|
||||
`Bar<_>: Deref`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:60:9
|
||||
|
|
||||
LL | impl<R: std::ops::Deref<Target = Self>> Bar<R> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------
|
||||
| | |
|
||||
| | unsatisfied trait bound introduced here
|
||||
| unsatisfied trait bound introduced here
|
||||
note: the trait `Deref` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/deref.rs:LL:COL
|
||||
= help: items from traits can only be used if the trait is implemented and in scope
|
||||
= note: the following trait defines an item `get`, perhaps you need to implement it:
|
||||
candidate #1: `SliceIndex`
|
||||
|
||||
error[E0599]: the method `get` exists for reference `&Rc<Bar<_>>`, but its trait bounds were not satisfied
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:108:7
|
||||
|
|
||||
LL | struct Bar<R>(std::marker::PhantomData<R>);
|
||||
| ------------- doesn't satisfy `Bar<_>: Deref`
|
||||
...
|
||||
LL | t.get();
|
||||
| ^^^ method cannot be called on `&Rc<Bar<_>>` due to unsatisfied trait bounds
|
||||
|
|
||||
note: the following trait bounds were not satisfied:
|
||||
`<&&Rc<Bar<_>> as Deref>::Target = Bar<&&Rc<Bar<_>>>`
|
||||
`<&Bar<_> as Deref>::Target = Bar<&Bar<_>>`
|
||||
`<&Rc<Bar<_>> as Deref>::Target = Bar<&Rc<Bar<_>>>`
|
||||
`<&mut &Rc<Bar<_>> as Deref>::Target = Bar<&mut &Rc<Bar<_>>>`
|
||||
`<&mut Bar<_> as Deref>::Target = Bar<&mut Bar<_>>`
|
||||
`<&mut Rc<Bar<_>> as Deref>::Target = Bar<&mut Rc<Bar<_>>>`
|
||||
`<Rc<Bar<_>> as Deref>::Target = Bar<Rc<Bar<_>>>`
|
||||
`Bar<_>: Deref`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:60:9
|
||||
|
|
||||
LL | impl<R: std::ops::Deref<Target = Self>> Bar<R> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------
|
||||
| | |
|
||||
| | unsatisfied trait bound introduced here
|
||||
| unsatisfied trait bound introduced here
|
||||
note: the trait `Deref` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/deref.rs:LL:COL
|
||||
= help: items from traits can only be used if the trait is implemented and in scope
|
||||
= note: the following trait defines an item `get`, perhaps you need to implement it:
|
||||
candidate #1: `SliceIndex`
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0271, E0599, E0658, E0801.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
|
@ -1,9 +1,179 @@
|
||||
error[E0801]: invalid generic `self` parameter type: `R`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:9:43
|
||||
|
|
||||
LL | fn get<R: Deref<Target = Self>>(self: R) -> u32 {
|
||||
| ^
|
||||
|
|
||||
= note: type of `self` must not be a method generic parameter type
|
||||
= help: use a concrete type such as `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`)
|
||||
|
||||
error[E0801]: invalid generic `self` parameter type: `&R`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:13:44
|
||||
|
|
||||
LL | fn get1<R: Deref<Target = Self>>(self: &R) -> u32 {
|
||||
| ^^
|
||||
|
|
||||
= note: type of `self` must not be a method generic parameter type
|
||||
= help: use a concrete type such as `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`)
|
||||
|
||||
error[E0801]: invalid generic `self` parameter type: `&mut R`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:17:44
|
||||
|
|
||||
LL | fn get2<R: Deref<Target = Self>>(self: &mut R) -> u32 {
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: type of `self` must not be a method generic parameter type
|
||||
= help: use a concrete type such as `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`)
|
||||
|
||||
error[E0801]: invalid generic `self` parameter type: `Rc<R>`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:21:44
|
||||
|
|
||||
LL | fn get3<R: Deref<Target = Self>>(self: std::rc::Rc<R>) -> u32 {
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must not be a method generic parameter type
|
||||
= help: use a concrete type such as `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`)
|
||||
|
||||
error[E0801]: invalid generic `self` parameter type: `&Rc<R>`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:25:44
|
||||
|
|
||||
LL | fn get4<R: Deref<Target = Self>>(self: &std::rc::Rc<R>) -> u32 {
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must not be a method generic parameter type
|
||||
= help: use a concrete type such as `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`)
|
||||
|
||||
error[E0801]: invalid generic `self` parameter type: `Rc<&R>`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:29:44
|
||||
|
|
||||
LL | fn get5<R: Deref<Target = Self>>(self: std::rc::Rc<&R>) -> u32 {
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must not be a method generic parameter type
|
||||
= help: use a concrete type such as `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`)
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:16:5
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:76:5
|
||||
|
|
||||
LL | foo.get::<&Foo>();
|
||||
| ^^^ expected `&Foo`, found `Foo`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:78:5
|
||||
|
|
||||
LL | foo.get::<std::rc::Rc<Foo>>();
|
||||
| ^^^ expected `Rc<Foo>`, found `Foo`
|
||||
|
|
||||
= note: expected struct `Rc<Foo>`
|
||||
found struct `Foo`
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:84:5
|
||||
|
|
||||
LL | smart_ptr.get::<SmartPtr2<Foo>>();
|
||||
| ^^^^^^^^^ expected `SmartPtr2<'_, Foo>`, found `SmartPtr<'_, Foo>`
|
||||
|
|
||||
= note: expected struct `SmartPtr2<'_, Foo>`
|
||||
found struct `SmartPtr<'_, Foo>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:86:5
|
||||
|
|
||||
LL | smart_ptr.get::<&Foo>();
|
||||
| ^^^^^^^^^ expected `&Foo`, found `SmartPtr<'_, Foo>`
|
||||
|
|
||||
= note: expected reference `&Foo`
|
||||
found struct `SmartPtr<'_, Foo, >`
|
||||
|
||||
error[E0271]: type mismatch resolving `<Silly as FindReceiver>::Receiver == Foo`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:92:9
|
||||
|
|
||||
LL | foo.get6(Silly);
|
||||
| ^^^^ type mismatch resolving `<Silly as FindReceiver>::Receiver == Foo`
|
||||
|
|
||||
note: expected this to be `Foo`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:71:21
|
||||
|
|
||||
LL | type Receiver = std::rc::Rc<Foo>;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= note: expected struct `Foo`
|
||||
found struct `Rc<Foo>`
|
||||
|
||||
error[E0271]: type mismatch resolving `<Silly as FindReceiver>::Receiver == &Foo`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:96:9
|
||||
|
|
||||
LL | foo.get6(Silly);
|
||||
| ^^^^ type mismatch resolving `<Silly as FindReceiver>::Receiver == &Foo`
|
||||
|
|
||||
note: expected this to be `&Foo`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:71:21
|
||||
|
|
||||
LL | type Receiver = std::rc::Rc<Foo>;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= note: expected reference `&Foo`
|
||||
found struct `Rc<Foo>`
|
||||
|
||||
error[E0599]: the method `get` exists for struct `Rc<Bar<_>>`, but its trait bounds were not satisfied
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:100:7
|
||||
|
|
||||
LL | struct Bar<R>(std::marker::PhantomData<R>);
|
||||
| ------------- doesn't satisfy `Bar<_>: Deref`
|
||||
...
|
||||
LL | t.get();
|
||||
| ^^^ method cannot be called on `Rc<Bar<_>>` due to unsatisfied trait bounds
|
||||
|
|
||||
note: the following trait bounds were not satisfied:
|
||||
`<&Bar<_> as Deref>::Target = Bar<&Bar<_>>`
|
||||
`<&Rc<Bar<_>> as Deref>::Target = Bar<&Rc<Bar<_>>>`
|
||||
`<&mut Bar<_> as Deref>::Target = Bar<&mut Bar<_>>`
|
||||
`<&mut Rc<Bar<_>> as Deref>::Target = Bar<&mut Rc<Bar<_>>>`
|
||||
`<Rc<Bar<_>> as Deref>::Target = Bar<Rc<Bar<_>>>`
|
||||
`Bar<_>: Deref`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:60:9
|
||||
|
|
||||
LL | impl<R: std::ops::Deref<Target = Self>> Bar<R> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------
|
||||
| | |
|
||||
| | unsatisfied trait bound introduced here
|
||||
| unsatisfied trait bound introduced here
|
||||
note: the trait `Deref` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/deref.rs:LL:COL
|
||||
= help: items from traits can only be used if the trait is implemented and in scope
|
||||
= note: the following trait defines an item `get`, perhaps you need to implement it:
|
||||
candidate #1: `SliceIndex`
|
||||
|
||||
error[E0599]: the method `get` exists for reference `&Rc<Bar<_>>`, but its trait bounds were not satisfied
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:108:7
|
||||
|
|
||||
LL | struct Bar<R>(std::marker::PhantomData<R>);
|
||||
| ------------- doesn't satisfy `Bar<_>: Deref`
|
||||
...
|
||||
LL | t.get();
|
||||
| ^^^ method cannot be called on `&Rc<Bar<_>>` due to unsatisfied trait bounds
|
||||
|
|
||||
note: the following trait bounds were not satisfied:
|
||||
`<&&Rc<Bar<_>> as Deref>::Target = Bar<&&Rc<Bar<_>>>`
|
||||
`<&Bar<_> as Deref>::Target = Bar<&Bar<_>>`
|
||||
`<&Rc<Bar<_>> as Deref>::Target = Bar<&Rc<Bar<_>>>`
|
||||
`<&mut &Rc<Bar<_>> as Deref>::Target = Bar<&mut &Rc<Bar<_>>>`
|
||||
`<&mut Bar<_> as Deref>::Target = Bar<&mut Bar<_>>`
|
||||
`<&mut Rc<Bar<_>> as Deref>::Target = Bar<&mut Rc<Bar<_>>>`
|
||||
`<Rc<Bar<_>> as Deref>::Target = Bar<Rc<Bar<_>>>`
|
||||
`Bar<_>: Deref`
|
||||
--> $DIR/arbitrary-self-from-method-substs.rs:60:9
|
||||
|
|
||||
LL | impl<R: std::ops::Deref<Target = Self>> Bar<R> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------
|
||||
| | |
|
||||
| | unsatisfied trait bound introduced here
|
||||
| unsatisfied trait bound introduced here
|
||||
note: the trait `Deref` must be implemented
|
||||
--> $SRC_DIR/core/src/ops/deref.rs:LL:COL
|
||||
= help: items from traits can only be used if the trait is implemented and in scope
|
||||
= note: the following trait defines an item `get`, perhaps you need to implement it:
|
||||
candidate #1: `SliceIndex`
|
||||
|
||||
error: aborting due to 14 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0271, E0308, E0599, E0801.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
|
@ -2,17 +2,109 @@
|
||||
#![cfg_attr(feature, feature(arbitrary_self_types))]
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
struct Foo(u32);
|
||||
impl Foo {
|
||||
fn get<R: Deref<Target = Self>>(self: R) -> u32 {
|
||||
//[default]~^ ERROR: `R` cannot be used as the type of `self`
|
||||
//~^ ERROR: invalid generic `self` parameter type
|
||||
self.0
|
||||
}
|
||||
fn get1<R: Deref<Target = Self>>(self: &R) -> u32 {
|
||||
//~^ ERROR: invalid generic `self` parameter type
|
||||
self.0
|
||||
}
|
||||
fn get2<R: Deref<Target = Self>>(self: &mut R) -> u32 {
|
||||
//~^ ERROR: invalid generic `self` parameter type
|
||||
self.0
|
||||
}
|
||||
fn get3<R: Deref<Target = Self>>(self: std::rc::Rc<R>) -> u32 {
|
||||
//~^ ERROR: invalid generic `self` parameter type
|
||||
self.0
|
||||
}
|
||||
fn get4<R: Deref<Target = Self>>(self: &std::rc::Rc<R>) -> u32 {
|
||||
//~^ ERROR: invalid generic `self` parameter type
|
||||
self.0
|
||||
}
|
||||
fn get5<R: Deref<Target = Self>>(self: std::rc::Rc<&R>) -> u32 {
|
||||
//~^ ERROR: invalid generic `self` parameter type
|
||||
self.0
|
||||
}
|
||||
fn get6<FR: FindReceiver>(self: FR::Receiver, other: FR) -> u32 {
|
||||
//[default]~^ ERROR: `<FR as FindReceiver>::Receiver` cannot be used as the type of `self`
|
||||
42
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct SmartPtr<'a, T: ?Sized>(&'a T);
|
||||
|
||||
impl<'a, T: ?Sized> Deref for SmartPtr<'a, T> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
struct SmartPtr2<'a, T: ?Sized>(&'a T);
|
||||
|
||||
impl<'a, T: ?Sized> Deref for SmartPtr2<'a, T> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
struct Bar<R>(std::marker::PhantomData<R>);
|
||||
|
||||
impl<R: std::ops::Deref<Target = Self>> Bar<R> {
|
||||
fn get(self: R) {}
|
||||
//[default]~^ ERROR: `R` cannot be used as the type of `self`
|
||||
}
|
||||
|
||||
trait FindReceiver {
|
||||
type Receiver: Deref<Target = Foo>;
|
||||
}
|
||||
|
||||
struct Silly;
|
||||
impl FindReceiver for Silly {
|
||||
type Receiver = std::rc::Rc<Foo>;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut foo = Foo(1);
|
||||
foo.get::<&Foo>();
|
||||
//[feature]~^ ERROR mismatched types
|
||||
foo.get::<std::rc::Rc<Foo>>();
|
||||
//[feature]~^ ERROR mismatched types
|
||||
|
||||
let smart_ptr = SmartPtr(&foo);
|
||||
let smart_ptr2 = SmartPtr2(&foo);
|
||||
smart_ptr.get(); // this compiles
|
||||
smart_ptr.get::<SmartPtr2<Foo>>();
|
||||
//[feature]~^ ERROR mismatched types
|
||||
smart_ptr.get::<&Foo>();
|
||||
//[feature]~^ ERROR mismatched types
|
||||
|
||||
let mut foo = Foo(1);
|
||||
// This test is slightly contrived in an attempt to generate a mismatched types
|
||||
// error for the self type below, without using the turbofish.
|
||||
foo.get6(Silly);
|
||||
//~^ ERROR type mismatch
|
||||
let mut foo = Foo(1);
|
||||
let foo = &foo;
|
||||
foo.get6(Silly);
|
||||
//~^ ERROR type mismatch
|
||||
|
||||
let t = std::rc::Rc::new(Bar(std::marker::PhantomData));
|
||||
t.get();
|
||||
//~^ ERROR its trait bounds were not satisfied
|
||||
let t = &t;
|
||||
// This is a further attempt at triggering 'type mismatch' errors
|
||||
// from arbitrary self types without resorting to the turbofish.
|
||||
// Ideally, here, t is Thing<Rc<Target=Self>> while we're going to call
|
||||
// it with a &t method receiver. However, this doesn't work since that
|
||||
// type of t becomes recursive and trait bounds can't be satisfied.
|
||||
t.get();
|
||||
//~^ ERROR its trait bounds were not satisfied
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
#![feature(arbitrary_self_types)]
|
||||
#![feature(impl_trait_in_assoc_type)]
|
||||
|
||||
use std::ops::Deref;
|
||||
|
||||
trait Foo {
|
||||
type Bar: Foo;
|
||||
|
||||
fn foo(self: impl Deref<Target = Self>) -> Self::Bar;
|
||||
}
|
||||
|
||||
impl<C> Foo for C {
|
||||
type Bar = impl Foo;
|
||||
|
||||
fn foo(self: impl Deref<Target = Self>) -> Self::Bar {
|
||||
self
|
||||
//~^ Error type parameter `impl Deref<Target = Self>` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,8 +0,0 @@
|
||||
error: type parameter `impl Deref<Target = Self>` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
--> $DIR/issue-57700.rs:16:9
|
||||
|
|
||||
LL | self
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
Loading…
Reference in New Issue
Block a user