From 58fcf8a02559b10ed7d9b665d2a5e9c405138dc7 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Mon, 2 Sep 2024 12:52:39 +0000 Subject: [PATCH] Reject generic self types using impl defid: do not merge. 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 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 is a second attempt at achieving this, based on producing a new well-formedness checking context which is only aware of the type params of the impl block, not of the method itself. It doesn't currently work because it turns out we do need some method params under some circumstances, but raising it for completeness. 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 https://github.com/rust-lang/rust/blob/9b82580c7347f800c2550e6719e4218a60a80b28/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 --- .../rustc_hir_analysis/src/check/wfcheck.rs | 109 +++++------ .../rustc_hir_typeck/src/method/confirm.rs | 3 - src/tools/tidy/src/issues.txt | 1 - .../arbitrary-self-from-method-substs-ice.rs | 2 +- ...bitrary-self-from-method-substs-ice.stderr | 10 +- ...ary-self-from-method-substs.default.stderr | 162 +++++++++++++++- ...ary-self-from-method-substs.feature.stderr | 176 +++++++++++++++++- .../self/arbitrary-self-from-method-substs.rs | 94 +++++++++- tests/ui/type-alias-impl-trait/issue-57700.rs | 21 --- .../type-alias-impl-trait/issue-57700.stderr | 8 - 10 files changed, 486 insertions(+), 100 deletions(-) delete mode 100644 tests/ui/type-alias-impl-trait/issue-57700.rs delete mode 100644 tests/ui/type-alias-impl-trait/issue-57700.stderr diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 3627faf8dfc57..9e50ff8654581 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -903,7 +903,6 @@ 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) } @@ -1699,62 +1698,68 @@ fn check_method_receiver<'tcx>( None }; - if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, arbitrary_self_types_level) { - 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 - // have helped. - None if receiver_is_valid( - wfcx, - span, - receiver_ty, - self_ty, - Some(ArbitrarySelfTypesLevel::Basic), - ) => - { - // Report error; would have worked with `arbitrary_self_types`. - feature_err( - &tcx.sess, - sym::arbitrary_self_types, - span, - format!( - "`{receiver_ty}` cannot be used as the type of `self` without \ - the `arbitrary_self_types` feature", - ), - ) - .with_help(fluent::hir_analysis_invalid_receiver_ty_help) - .emit() - } - None | Some(ArbitrarySelfTypesLevel::Basic) - if receiver_is_valid( + let impl_block_def_id = + tcx.impl_of_method(method.def_id).unwrap_or(method.def_id).expect_local(); + + let receiver_validity = enter_wf_checking_ctxt(tcx, span, impl_block_def_id, |wfcx| { + if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, arbitrary_self_types_level) { + 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 + // have helped. + None if receiver_is_valid( wfcx, span, receiver_ty, self_ty, - Some(ArbitrarySelfTypesLevel::WithPointers), + Some(ArbitrarySelfTypesLevel::Basic), ) => - { - // Report error; would have worked with `arbitrary_self_types_pointers`. - feature_err( - &tcx.sess, - sym::arbitrary_self_types_pointers, - span, - format!( - "`{receiver_ty}` cannot be used as the type of `self` without \ - the `arbitrary_self_types_pointers` feature", - ), - ) - .with_help(fluent::hir_analysis_invalid_receiver_ty_help) - .emit() - } - _ => - // Report error; would not have worked with `arbitrary_self_types[_pointers]`. - { - tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty }) - } - }); - } - Ok(()) + { + // Report error; would have worked with `arbitrary_self_types`. + feature_err( + &tcx.sess, + sym::arbitrary_self_types, + span, + format!( + "`{receiver_ty}` cannot be used as the type of `self` without \ + the `arbitrary_self_types` feature", + ), + ) + .with_help(fluent::hir_analysis_invalid_receiver_ty_help) + .emit() + } + None | Some(ArbitrarySelfTypesLevel::Basic) + if receiver_is_valid( + wfcx, + span, + receiver_ty, + self_ty, + Some(ArbitrarySelfTypesLevel::WithPointers), + ) => + { + // Report error; would have worked with `arbitrary_self_types_pointers`. + feature_err( + &tcx.sess, + sym::arbitrary_self_types_pointers, + span, + format!( + "`{receiver_ty}` cannot be used as the type of `self` without \ + the `arbitrary_self_types_pointers` feature", + ), + ) + .with_help(fluent::hir_analysis_invalid_receiver_ty_help) + .emit() + } + _ => + // Report error; would not have worked with `arbitrary_self_types[_pointers]`. + { + tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty }) + } + }); + } + Ok(()) + }); + receiver_validity } /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 10a22eee7b74a..bd6d2dfe7de68 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -516,9 +516,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(&cause, method_self_ty, self_ty, terr) diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 5205fa1429435..cea1136d47dec 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -4122,7 +4122,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 diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs index 8bf9f97e0b91d..194500e21c3a0 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs @@ -8,7 +8,7 @@ use std::ops::Deref; struct Foo(u32); impl Foo { const fn get>(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 borrow here, since the borrowed element may contain interior mutability diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr index 9e3851f9a6e72..a243177613668 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr @@ -29,18 +29,16 @@ LL | const fn get>(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[E0799]: invalid generic `self` parameter type: `R` --> $DIR/arbitrary-self-from-method-substs-ice.rs:10:49 | LL | const fn get>(self: R) -> u32 { | ^ | - = note: see issue #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: Rc`, `self: Arc`, or `self: Pin

` (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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error: aborting due to 4 previous errors -Some errors have detailed explanations: E0015, E0493, E0658. +Some errors have detailed explanations: E0015, E0493, E0658, E0799. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr index 4cc69666b8876..419b599b0450e 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr @@ -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[E0799]: invalid generic `self` parameter type: `R` + --> $DIR/arbitrary-self-from-method-substs.rs:9:43 | LL | fn get>(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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0799]: invalid generic `self` parameter type: `&R` + --> $DIR/arbitrary-self-from-method-substs.rs:13:44 + | +LL | fn get1>(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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0799]: invalid generic `self` parameter type: `&mut R` + --> $DIR/arbitrary-self-from-method-substs.rs:17:44 + | +LL | fn get2>(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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0799]: invalid generic `self` parameter type: `Rc` + --> $DIR/arbitrary-self-from-method-substs.rs:21:44 + | +LL | fn get3>(self: std::rc::Rc) -> 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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0799]: invalid generic `self` parameter type: `&Rc` + --> $DIR/arbitrary-self-from-method-substs.rs:25:44 + | +LL | fn get4>(self: &std::rc::Rc) -> 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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0799]: invalid generic `self` parameter type: `Rc<&R>` + --> $DIR/arbitrary-self-from-method-substs.rs:29:44 + | +LL | fn get5>(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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0658]: `::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(self: FR::Receiver, other: FR) -> u32 { + | ^^^^^^^^^^^^ + | = note: see issue #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: Rc`, `self: Arc`, or `self: Pin

` (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 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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0271]: type mismatch resolving `::Receiver == Foo` + --> $DIR/arbitrary-self-from-method-substs.rs:92:9 + | +LL | foo.get6(Silly); + | ^^^^ type mismatch resolving `::Receiver == Foo` + | +note: expected this to be `Rc` + --> $DIR/arbitrary-self-from-method-substs.rs:71:21 + | +LL | type Receiver = std::rc::Rc; + | ^^^^^^^^^^^^^^^^ + = note: expected struct `Rc` + found struct `Foo` + +error[E0271]: type mismatch resolving `::Receiver == &Foo` + --> $DIR/arbitrary-self-from-method-substs.rs:96:9 + | +LL | foo.get6(Silly); + | ^^^^ type mismatch resolving `::Receiver == &Foo` + | +note: expected this to be `Rc` + --> $DIR/arbitrary-self-from-method-substs.rs:71:21 + | +LL | type Receiver = std::rc::Rc; + | ^^^^^^^^^^^^^^^^ + = note: expected struct `Rc` + found reference `&Foo` + +error[E0599]: the method `get` exists for struct `Rc>`, but its trait bounds were not satisfied + --> $DIR/arbitrary-self-from-method-substs.rs:100:7 + | +LL | struct Bar(std::marker::PhantomData); + | ------------- doesn't satisfy `Bar<_>: Deref` +... +LL | t.get(); + | ^^^ method cannot be called on `Rc>` due to unsatisfied trait bounds + | +note: the following trait bounds were not satisfied: + `<&Bar<_> as Deref>::Target = Bar<&Bar<_>>` + `<&Rc> as Deref>::Target = Bar<&Rc>>` + `<&mut Bar<_> as Deref>::Target = Bar<&mut Bar<_>>` + `<&mut Rc> as Deref>::Target = Bar<&mut Rc>>` + `> as Deref>::Target = Bar>>` + `Bar<_>: Deref` + --> $DIR/arbitrary-self-from-method-substs.rs:60:9 + | +LL | impl> Bar { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ + | | | + | | 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>`, but its trait bounds were not satisfied + --> $DIR/arbitrary-self-from-method-substs.rs:108:7 + | +LL | struct Bar(std::marker::PhantomData); + | ------------- doesn't satisfy `Bar<_>: Deref` +... +LL | t.get(); + | ^^^ method cannot be called on `&Rc>` due to unsatisfied trait bounds + | +note: the following trait bounds were not satisfied: + `<&&Rc> as Deref>::Target = Bar<&&Rc>>` + `<&Bar<_> as Deref>::Target = Bar<&Bar<_>>` + `<&Rc> as Deref>::Target = Bar<&Rc>>` + `<&mut &Rc> as Deref>::Target = Bar<&mut &Rc>>` + `<&mut Bar<_> as Deref>::Target = Bar<&mut Bar<_>>` + `<&mut Rc> as Deref>::Target = Bar<&mut Rc>>` + `> as Deref>::Target = Bar>>` + `Bar<_>: Deref` + --> $DIR/arbitrary-self-from-method-substs.rs:60:9 + | +LL | impl> Bar { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ + | | | + | | 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 -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0271, E0599, E0658, E0799. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/self/arbitrary-self-from-method-substs.feature.stderr b/tests/ui/self/arbitrary-self-from-method-substs.feature.stderr index 44e553f1a06ca..1f3efe1fc7bd6 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs.feature.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs.feature.stderr @@ -1,9 +1,179 @@ +error[E0799]: invalid generic `self` parameter type: `R` + --> $DIR/arbitrary-self-from-method-substs.rs:9:43 + | +LL | fn get>(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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0799]: invalid generic `self` parameter type: `&R` + --> $DIR/arbitrary-self-from-method-substs.rs:13:44 + | +LL | fn get1>(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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0799]: invalid generic `self` parameter type: `&mut R` + --> $DIR/arbitrary-self-from-method-substs.rs:17:44 + | +LL | fn get2>(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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0799]: invalid generic `self` parameter type: `Rc` + --> $DIR/arbitrary-self-from-method-substs.rs:21:44 + | +LL | fn get3>(self: std::rc::Rc) -> 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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0799]: invalid generic `self` parameter type: `&Rc` + --> $DIR/arbitrary-self-from-method-substs.rs:25:44 + | +LL | fn get4>(self: &std::rc::Rc) -> 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: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0799]: invalid generic `self` parameter type: `Rc<&R>` + --> $DIR/arbitrary-self-from-method-substs.rs:29:44 + | +LL | fn get5>(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: Rc`, `self: Arc`, or `self: Pin

` (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::>(); + | ^^^ expected `Rc`, found `Foo` + | + = note: expected struct `Rc` + found struct `Foo` + +error[E0308]: mismatched types + --> $DIR/arbitrary-self-from-method-substs.rs:84:5 + | +LL | smart_ptr.get::>(); + | ^^^^^^^^^ 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 `::Receiver == Foo` + --> $DIR/arbitrary-self-from-method-substs.rs:92:9 + | +LL | foo.get6(Silly); + | ^^^^ type mismatch resolving `::Receiver == Foo` + | +note: expected this to be `Rc` + --> $DIR/arbitrary-self-from-method-substs.rs:71:21 + | +LL | type Receiver = std::rc::Rc; + | ^^^^^^^^^^^^^^^^ + = note: expected struct `Rc` + found struct `Foo` + +error[E0271]: type mismatch resolving `::Receiver == &Foo` + --> $DIR/arbitrary-self-from-method-substs.rs:96:9 + | +LL | foo.get6(Silly); + | ^^^^ type mismatch resolving `::Receiver == &Foo` + | +note: expected this to be `Rc` + --> $DIR/arbitrary-self-from-method-substs.rs:71:21 + | +LL | type Receiver = std::rc::Rc; + | ^^^^^^^^^^^^^^^^ + = note: expected struct `Rc` + found reference `&Foo` + +error[E0599]: the method `get` exists for struct `Rc>`, but its trait bounds were not satisfied + --> $DIR/arbitrary-self-from-method-substs.rs:100:7 + | +LL | struct Bar(std::marker::PhantomData); + | ------------- doesn't satisfy `Bar<_>: Deref` +... +LL | t.get(); + | ^^^ method cannot be called on `Rc>` due to unsatisfied trait bounds + | +note: the following trait bounds were not satisfied: + `<&Bar<_> as Deref>::Target = Bar<&Bar<_>>` + `<&Rc> as Deref>::Target = Bar<&Rc>>` + `<&mut Bar<_> as Deref>::Target = Bar<&mut Bar<_>>` + `<&mut Rc> as Deref>::Target = Bar<&mut Rc>>` + `> as Deref>::Target = Bar>>` + `Bar<_>: Deref` + --> $DIR/arbitrary-self-from-method-substs.rs:60:9 + | +LL | impl> Bar { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ + | | | + | | 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>`, but its trait bounds were not satisfied + --> $DIR/arbitrary-self-from-method-substs.rs:108:7 + | +LL | struct Bar(std::marker::PhantomData); + | ------------- doesn't satisfy `Bar<_>: Deref` +... +LL | t.get(); + | ^^^ method cannot be called on `&Rc>` due to unsatisfied trait bounds + | +note: the following trait bounds were not satisfied: + `<&&Rc> as Deref>::Target = Bar<&&Rc>>` + `<&Bar<_> as Deref>::Target = Bar<&Bar<_>>` + `<&Rc> as Deref>::Target = Bar<&Rc>>` + `<&mut &Rc> as Deref>::Target = Bar<&mut &Rc>>` + `<&mut Bar<_> as Deref>::Target = Bar<&mut Bar<_>>` + `<&mut Rc> as Deref>::Target = Bar<&mut Rc>>` + `> as Deref>::Target = Bar>>` + `Bar<_>: Deref` + --> $DIR/arbitrary-self-from-method-substs.rs:60:9 + | +LL | impl> Bar { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ + | | | + | | 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 -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0271, E0308, E0599, E0799. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/self/arbitrary-self-from-method-substs.rs b/tests/ui/self/arbitrary-self-from-method-substs.rs index 99977ed9b8c51..f2d6585961517 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs.rs +++ b/tests/ui/self/arbitrary-self-from-method-substs.rs @@ -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>(self: R) -> u32 { - //[default]~^ ERROR: `R` cannot be used as the type of `self` + //~^ ERROR: invalid generic `self` parameter type self.0 } + fn get1>(self: &R) -> u32 { + //~^ ERROR: invalid generic `self` parameter type + self.0 + } + fn get2>(self: &mut R) -> u32 { + //~^ ERROR: invalid generic `self` parameter type + self.0 + } + fn get3>(self: std::rc::Rc) -> u32 { + //~^ ERROR: invalid generic `self` parameter type + self.0 + } + fn get4>(self: &std::rc::Rc) -> u32 { + //~^ ERROR: invalid generic `self` parameter type + self.0 + } + fn get5>(self: std::rc::Rc<&R>) -> u32 { + //~^ ERROR: invalid generic `self` parameter type + self.0 + } + fn get6(self: FR::Receiver, other: FR) -> u32 { + //[default]~^ ERROR: `::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(std::marker::PhantomData); + +impl> Bar { + fn get(self: R) {} + //[default]~^ ERROR: `R` cannot be used as the type of `self` +} + +trait FindReceiver { + type Receiver: Deref; +} + +struct Silly; +impl FindReceiver for Silly { + type Receiver = std::rc::Rc; } fn main() { let mut foo = Foo(1); foo.get::<&Foo>(); //[feature]~^ ERROR mismatched types + foo.get::>(); + //[feature]~^ ERROR mismatched types + + let smart_ptr = SmartPtr(&foo); + let smart_ptr2 = SmartPtr2(&foo); + smart_ptr.get(); // this compiles + smart_ptr.get::>(); + //[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> 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 } diff --git a/tests/ui/type-alias-impl-trait/issue-57700.rs b/tests/ui/type-alias-impl-trait/issue-57700.rs deleted file mode 100644 index 8746545ecc9ef..0000000000000 --- a/tests/ui/type-alias-impl-trait/issue-57700.rs +++ /dev/null @@ -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) -> Self::Bar; -} - -impl Foo for C { - type Bar = impl Foo; - - fn foo(self: impl Deref) -> Self::Bar { - self - //~^ Error type parameter `impl Deref` is part of concrete type but not used in parameter list for the `impl Trait` type alias - } -} - -fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-57700.stderr b/tests/ui/type-alias-impl-trait/issue-57700.stderr deleted file mode 100644 index 7efb05f40b079..0000000000000 --- a/tests/ui/type-alias-impl-trait/issue-57700.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: type parameter `impl Deref` 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 -