mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
Add some tests
This commit is contained in:
parent
b28221e74f
commit
c75f7283bf
17
tests/ui/impl-trait/call_method_ambiguous.next.stderr
Normal file
17
tests/ui/impl-trait/call_method_ambiguous.next.stderr
Normal file
@ -0,0 +1,17 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/call_method_ambiguous.rs:29:13
|
||||
|
|
||||
LL | let mut iter = foo(n - 1, m);
|
||||
| ^^^^^^^^
|
||||
LL |
|
||||
LL | assert_eq!(iter.get(), 1);
|
||||
| ---- type must be known at this point
|
||||
|
|
||||
help: consider giving `iter` an explicit type
|
||||
|
|
||||
LL | let mut iter: /* Type */ = foo(n - 1, m);
|
||||
| ++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
39
tests/ui/impl-trait/call_method_ambiguous.rs
Normal file
39
tests/ui/impl-trait/call_method_ambiguous.rs
Normal file
@ -0,0 +1,39 @@
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[current] run-pass
|
||||
|
||||
#![feature(precise_capturing)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait Get {
|
||||
fn get(&mut self) -> u32;
|
||||
}
|
||||
|
||||
impl Get for () {
|
||||
fn get(&mut self) -> u32 {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Get for &mut T
|
||||
where
|
||||
T: Get,
|
||||
{
|
||||
fn get(&mut self) -> u32 {
|
||||
T::get(self) + 1
|
||||
}
|
||||
}
|
||||
|
||||
fn foo(n: usize, m: &mut ()) -> impl use<'_> Get {
|
||||
if n > 0 {
|
||||
let mut iter = foo(n - 1, m);
|
||||
//[next]~^ type annotations needed
|
||||
assert_eq!(iter.get(), 1);
|
||||
}
|
||||
m
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let g = foo(1, &mut ()).get();
|
||||
assert_eq!(g, 1);
|
||||
}
|
17
tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr
Normal file
17
tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr
Normal file
@ -0,0 +1,17 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/call_method_on_inherent_impl.rs:18:13
|
||||
|
|
||||
LL | let x = my_foo();
|
||||
| ^
|
||||
LL |
|
||||
LL | x.my_debug();
|
||||
| - type must be known at this point
|
||||
|
|
||||
help: consider giving `x` an explicit type
|
||||
|
|
||||
LL | let x: /* Type */ = my_foo();
|
||||
| ++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
25
tests/ui/impl-trait/call_method_on_inherent_impl.rs
Normal file
25
tests/ui/impl-trait/call_method_on_inherent_impl.rs
Normal file
@ -0,0 +1,25 @@
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[current] check-pass
|
||||
|
||||
trait MyDebug {
|
||||
fn my_debug(&self);
|
||||
}
|
||||
|
||||
impl<T> MyDebug for T
|
||||
where
|
||||
T: std::fmt::Debug,
|
||||
{
|
||||
fn my_debug(&self) {}
|
||||
}
|
||||
|
||||
fn my_foo() -> impl std::fmt::Debug {
|
||||
if false {
|
||||
let x = my_foo();
|
||||
//[next]~^ type annotations needed
|
||||
x.my_debug();
|
||||
}
|
||||
()
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,16 @@
|
||||
error[E0599]: no method named `my_debug` found for reference `&impl Debug` in the current scope
|
||||
--> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:16:11
|
||||
|
|
||||
LL | x.my_debug();
|
||||
| ^^^^^^^^ method not found in `&impl Debug`
|
||||
|
|
||||
= help: items from traits can only be used if the trait is implemented and in scope
|
||||
note: `MyDebug` defines an item `my_debug`, perhaps you need to implement it
|
||||
--> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:4:1
|
||||
|
|
||||
LL | trait MyDebug {
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
@ -0,0 +1,17 @@
|
||||
error[E0282]: type annotations needed for `&_`
|
||||
--> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:14:13
|
||||
|
|
||||
LL | let x = &my_foo();
|
||||
| ^
|
||||
LL |
|
||||
LL | x.my_debug();
|
||||
| -------- type must be known at this point
|
||||
|
|
||||
help: consider giving `x` an explicit type, where the placeholders `_` are specified
|
||||
|
|
||||
LL | let x: &_ = &my_foo();
|
||||
| ++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
@ -0,0 +1,22 @@
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
trait MyDebug {
|
||||
fn my_debug(&self);
|
||||
}
|
||||
|
||||
impl MyDebug for &() {
|
||||
fn my_debug(&self) {}
|
||||
}
|
||||
|
||||
fn my_foo() -> impl std::fmt::Debug {
|
||||
if false {
|
||||
let x = &my_foo();
|
||||
//[next]~^ ERROR: type annotations needed
|
||||
x.my_debug();
|
||||
//[current]~^ ERROR: no method named `my_debug`
|
||||
}
|
||||
()
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,40 @@
|
||||
error[E0599]: no method named `my_debug` found for opaque type `impl Debug` in the current scope
|
||||
--> $DIR/call_method_on_inherent_impl_ref.rs:20:11
|
||||
|
|
||||
LL | fn my_debug(&self);
|
||||
| -------- the method is available for `&impl Debug` here
|
||||
...
|
||||
LL | x.my_debug();
|
||||
| ^^^^^^^^ method not found in `impl Debug`
|
||||
|
|
||||
= help: items from traits can only be used if the trait is implemented and in scope
|
||||
note: `MyDebug` defines an item `my_debug`, perhaps you need to implement it
|
||||
--> $DIR/call_method_on_inherent_impl_ref.rs:4:1
|
||||
|
|
||||
LL | trait MyDebug {
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error[E0391]: cycle detected when computing type of opaque `my_foo::{opaque#0}`
|
||||
--> $DIR/call_method_on_inherent_impl_ref.rs:15:16
|
||||
|
|
||||
LL | fn my_foo() -> impl std::fmt::Debug {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires type-checking `my_foo`...
|
||||
--> $DIR/call_method_on_inherent_impl_ref.rs:20:9
|
||||
|
|
||||
LL | x.my_debug();
|
||||
| ^
|
||||
= note: ...which requires evaluating trait selection obligation `my_foo::{opaque#0}: core::marker::Unpin`...
|
||||
= note: ...which again requires computing type of opaque `my_foo::{opaque#0}`, completing the cycle
|
||||
note: cycle used when computing type of `my_foo::{opaque#0}`
|
||||
--> $DIR/call_method_on_inherent_impl_ref.rs:15:16
|
||||
|
|
||||
LL | fn my_foo() -> impl std::fmt::Debug {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0391, E0599.
|
||||
For more information about an error, try `rustc --explain E0391`.
|
@ -0,0 +1,31 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/call_method_on_inherent_impl_ref.rs:18:13
|
||||
|
|
||||
LL | let x = my_foo();
|
||||
| ^
|
||||
LL |
|
||||
LL | x.my_debug();
|
||||
| - type must be known at this point
|
||||
|
|
||||
help: consider giving `x` an explicit type
|
||||
|
|
||||
LL | let x: /* Type */ = my_foo();
|
||||
| ++++++++++++
|
||||
|
||||
error[E0282]: type annotations needed for `&_`
|
||||
--> $DIR/call_method_on_inherent_impl_ref.rs:28:13
|
||||
|
|
||||
LL | let x = &my_bar();
|
||||
| ^
|
||||
LL |
|
||||
LL | x.my_debug();
|
||||
| -------- type must be known at this point
|
||||
|
|
||||
help: consider giving `x` an explicit type, where the placeholders `_` are specified
|
||||
|
|
||||
LL | let x: &_ = &my_bar();
|
||||
| ++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
35
tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs
Normal file
35
tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs
Normal file
@ -0,0 +1,35 @@
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
trait MyDebug {
|
||||
fn my_debug(&self);
|
||||
}
|
||||
|
||||
impl<T> MyDebug for &T
|
||||
where
|
||||
T: std::fmt::Debug,
|
||||
{
|
||||
fn my_debug(&self) {}
|
||||
}
|
||||
|
||||
fn my_foo() -> impl std::fmt::Debug {
|
||||
//[current]~^ cycle
|
||||
if false {
|
||||
let x = my_foo();
|
||||
//[next]~^ type annotations needed
|
||||
x.my_debug();
|
||||
//[current]~^ no method named `my_debug` found
|
||||
}
|
||||
()
|
||||
}
|
||||
|
||||
fn my_bar() -> impl std::fmt::Debug {
|
||||
if false {
|
||||
let x = &my_bar();
|
||||
//[next]~^ type annotations needed
|
||||
x.my_debug();
|
||||
}
|
||||
()
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,37 @@
|
||||
error[E0599]: no method named `fmt` found for opaque type `impl Debug` in the current scope
|
||||
--> $DIR/call_method_without_import.rs:17:11
|
||||
|
|
||||
LL | x.fmt(f);
|
||||
| ^^^ method not found in `impl Debug`
|
||||
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
||||
|
|
||||
= note: the method is available for `impl Debug` here
|
||||
|
|
||||
= help: items from traits can only be used if the trait is in scope
|
||||
help: trait `Debug` which provides `fmt` is implemented but not in scope; perhaps you want to import it
|
||||
|
|
||||
LL + use std::fmt::Debug;
|
||||
|
|
||||
|
||||
error[E0599]: no method named `fmt` found for mutable reference `&mut impl Debug` in the current scope
|
||||
--> $DIR/call_method_without_import.rs:26:11
|
||||
|
|
||||
LL | x.fmt(f);
|
||||
| ^^^ method not found in `&mut impl Debug`
|
||||
|
|
||||
= help: items from traits can only be used if the trait is in scope
|
||||
help: the following traits which provide `fmt` are implemented but not in scope; perhaps you want to import one of them
|
||||
|
|
||||
LL + use std::fmt::Binary;
|
||||
|
|
||||
LL + use std::fmt::Debug;
|
||||
|
|
||||
LL + use std::fmt::Display;
|
||||
|
|
||||
LL + use std::fmt::LowerExp;
|
||||
|
|
||||
and 5 other candidates
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
42
tests/ui/impl-trait/call_method_without_import.rs
Normal file
42
tests/ui/impl-trait/call_method_without_import.rs
Normal file
@ -0,0 +1,42 @@
|
||||
//! Test that opaque types only pick up methods from traits in their bounds
|
||||
//! if the trait is imported.
|
||||
//!
|
||||
//! FIXME: always look through the bounds of an opaque type to see if there are
|
||||
//! methods that could be called on any of the bound traits, irrespective of
|
||||
//! imported traits.
|
||||
|
||||
//@ revisions: import no_import
|
||||
//@[import] check-pass
|
||||
|
||||
#[cfg(import)]
|
||||
use std::fmt::Debug as _;
|
||||
|
||||
fn foo(f: &mut std::fmt::Formatter<'_>) -> impl std::fmt::Debug {
|
||||
if false {
|
||||
let x = foo(f);
|
||||
x.fmt(f);
|
||||
//[no_import]~^ ERROR: no method named `fmt` found
|
||||
}
|
||||
()
|
||||
}
|
||||
|
||||
fn foo1(f: &mut std::fmt::Formatter<'_>) -> impl std::fmt::Debug {
|
||||
if false {
|
||||
let x = &mut foo(f);
|
||||
x.fmt(f);
|
||||
//[no_import]~^ ERROR: no method named `fmt` found
|
||||
}
|
||||
()
|
||||
}
|
||||
|
||||
// inconsistent with this
|
||||
fn bar<T>(t: impl std::fmt::Debug, f: &mut std::fmt::Formatter<'_>) {
|
||||
t.fmt(f);
|
||||
}
|
||||
|
||||
// and the desugared version, of course
|
||||
fn baz<T: std::fmt::Debug>(t: T, f: &mut std::fmt::Formatter<'_>) {
|
||||
t.fmt(f);
|
||||
}
|
||||
|
||||
fn main() {}
|
36
tests/ui/impl-trait/method-resolution.current.stderr
Normal file
36
tests/ui/impl-trait/method-resolution.current.stderr
Normal file
@ -0,0 +1,36 @@
|
||||
error[E0599]: no method named `bar` found for struct `Bar<impl Sized>` in the current scope
|
||||
--> $DIR/method-resolution.rs:23:11
|
||||
|
|
||||
LL | struct Bar<T>(T);
|
||||
| ------------- method `bar` not found for this struct
|
||||
...
|
||||
LL | x.bar();
|
||||
| ^^^ method not found in `Bar<impl Sized>`
|
||||
|
|
||||
= note: the method was found for
|
||||
- `Bar<u32>`
|
||||
|
||||
error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}`
|
||||
--> $DIR/method-resolution.rs:19:24
|
||||
|
|
||||
LL | fn foo(x: bool) -> Bar<impl Sized> {
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires type-checking `foo`...
|
||||
--> $DIR/method-resolution.rs:23:9
|
||||
|
|
||||
LL | x.bar();
|
||||
| ^
|
||||
= note: ...which requires evaluating trait selection obligation `Bar<foo::{opaque#0}>: core::marker::Unpin`...
|
||||
= note: ...which again requires computing type of opaque `foo::{opaque#0}`, completing the cycle
|
||||
note: cycle used when computing type of `foo::{opaque#0}`
|
||||
--> $DIR/method-resolution.rs:19:24
|
||||
|
|
||||
LL | fn foo(x: bool) -> Bar<impl Sized> {
|
||||
| ^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0391, E0599.
|
||||
For more information about an error, try `rustc --explain E0391`.
|
29
tests/ui/impl-trait/method-resolution.rs
Normal file
29
tests/ui/impl-trait/method-resolution.rs
Normal file
@ -0,0 +1,29 @@
|
||||
//! Check that we do not constrain hidden types during method resolution.
|
||||
//! Otherwise we'd pick up that calling `bar` can be satisfied iff `u32`
|
||||
//! is the hidden type of the RPIT.
|
||||
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[next] check-pass
|
||||
|
||||
trait Trait {}
|
||||
|
||||
impl Trait for u32 {}
|
||||
|
||||
struct Bar<T>(T);
|
||||
|
||||
impl Bar<u32> {
|
||||
fn bar(self) {}
|
||||
}
|
||||
|
||||
fn foo(x: bool) -> Bar<impl Sized> {
|
||||
//[current]~^ ERROR: cycle detected
|
||||
if x {
|
||||
let x = foo(false);
|
||||
x.bar();
|
||||
//[current]~^ ERROR: no method named `bar` found
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn main() {}
|
20
tests/ui/impl-trait/method-resolution2.next.stderr
Normal file
20
tests/ui/impl-trait/method-resolution2.next.stderr
Normal file
@ -0,0 +1,20 @@
|
||||
error[E0034]: multiple applicable items in scope
|
||||
--> $DIR/method-resolution2.rs:25:11
|
||||
|
|
||||
LL | x.bar();
|
||||
| ^^^ multiple `bar` found
|
||||
|
|
||||
note: candidate #1 is defined in an impl for the type `Bar<T>`
|
||||
--> $DIR/method-resolution2.rs:19:5
|
||||
|
|
||||
LL | fn bar(self) {}
|
||||
| ^^^^^^^^^^^^
|
||||
note: candidate #2 is defined in an impl for the type `Bar<u32>`
|
||||
--> $DIR/method-resolution2.rs:15:5
|
||||
|
|
||||
LL | fn bar(self) {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0034`.
|
31
tests/ui/impl-trait/method-resolution2.rs
Normal file
31
tests/ui/impl-trait/method-resolution2.rs
Normal file
@ -0,0 +1,31 @@
|
||||
//! Check that the method call does not constrain the RPIT to `i32`, even though
|
||||
//! `i32` is the only trait that satisfies the RPIT's trait bounds.
|
||||
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[current] check-pass
|
||||
|
||||
trait Trait {}
|
||||
|
||||
impl Trait for i32 {}
|
||||
|
||||
struct Bar<T>(T);
|
||||
|
||||
impl Bar<u32> {
|
||||
fn bar(self) {}
|
||||
}
|
||||
|
||||
impl<T: Trait> Bar<T> {
|
||||
fn bar(self) {}
|
||||
}
|
||||
|
||||
fn foo(x: bool) -> Bar<impl Trait> {
|
||||
if x {
|
||||
let x = foo(false);
|
||||
x.bar();
|
||||
//[next]~^ ERROR: multiple applicable items in scope
|
||||
}
|
||||
Bar(42_i32)
|
||||
}
|
||||
|
||||
fn main() {}
|
37
tests/ui/impl-trait/method-resolution3.current.stderr
Normal file
37
tests/ui/impl-trait/method-resolution3.current.stderr
Normal file
@ -0,0 +1,37 @@
|
||||
error[E0599]: no method named `bar` found for struct `Bar<impl Sized>` in the current scope
|
||||
--> $DIR/method-resolution3.rs:22:11
|
||||
|
|
||||
LL | struct Bar<T>(T);
|
||||
| ------------- method `bar` not found for this struct
|
||||
...
|
||||
LL | x.bar();
|
||||
| ^^^ method not found in `Bar<impl Sized>`
|
||||
|
|
||||
= note: the method was found for
|
||||
- `Bar<i32>`
|
||||
- `Bar<u32>`
|
||||
|
||||
error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}`
|
||||
--> $DIR/method-resolution3.rs:18:24
|
||||
|
|
||||
LL | fn foo(x: bool) -> Bar<impl Sized> {
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires type-checking `foo`...
|
||||
--> $DIR/method-resolution3.rs:22:9
|
||||
|
|
||||
LL | x.bar();
|
||||
| ^
|
||||
= note: ...which requires evaluating trait selection obligation `Bar<foo::{opaque#0}>: core::marker::Unpin`...
|
||||
= note: ...which again requires computing type of opaque `foo::{opaque#0}`, completing the cycle
|
||||
note: cycle used when computing type of `foo::{opaque#0}`
|
||||
--> $DIR/method-resolution3.rs:18:24
|
||||
|
|
||||
LL | fn foo(x: bool) -> Bar<impl Sized> {
|
||||
| ^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0391, E0599.
|
||||
For more information about an error, try `rustc --explain E0391`.
|
20
tests/ui/impl-trait/method-resolution3.next.stderr
Normal file
20
tests/ui/impl-trait/method-resolution3.next.stderr
Normal file
@ -0,0 +1,20 @@
|
||||
error[E0034]: multiple applicable items in scope
|
||||
--> $DIR/method-resolution3.rs:22:11
|
||||
|
|
||||
LL | x.bar();
|
||||
| ^^^ multiple `bar` found
|
||||
|
|
||||
note: candidate #1 is defined in an impl for the type `Bar<i32>`
|
||||
--> $DIR/method-resolution3.rs:15:5
|
||||
|
|
||||
LL | fn bar(self) {}
|
||||
| ^^^^^^^^^^^^
|
||||
note: candidate #2 is defined in an impl for the type `Bar<u32>`
|
||||
--> $DIR/method-resolution3.rs:11:5
|
||||
|
|
||||
LL | fn bar(self) {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0034`.
|
29
tests/ui/impl-trait/method-resolution3.rs
Normal file
29
tests/ui/impl-trait/method-resolution3.rs
Normal file
@ -0,0 +1,29 @@
|
||||
//! Check that we consider `Bar<impl Sized>` to successfully unify
|
||||
//! with both `Bar<u32>` and `Bar<i32>` (in isolation), so we bail
|
||||
//! out with ambiguity.
|
||||
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
struct Bar<T>(T);
|
||||
|
||||
impl Bar<u32> {
|
||||
fn bar(self) {}
|
||||
}
|
||||
|
||||
impl Bar<i32> {
|
||||
fn bar(self) {}
|
||||
}
|
||||
|
||||
fn foo(x: bool) -> Bar<impl Sized> {
|
||||
//[current]~^ ERROR: cycle
|
||||
if x {
|
||||
let x = foo(false);
|
||||
x.bar();
|
||||
//[current]~^ ERROR: no method named `bar`
|
||||
//[next]~^^ ERROR: multiple applicable items in scope
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn main() {}
|
22
tests/ui/impl-trait/method-resolution4.next.stderr
Normal file
22
tests/ui/impl-trait/method-resolution4.next.stderr
Normal file
@ -0,0 +1,22 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/method-resolution4.rs:13:9
|
||||
|
|
||||
LL | foo(false).next().unwrap();
|
||||
| ^^^^^^^^^^ cannot infer type
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/method-resolution4.rs:16:5
|
||||
|
|
||||
LL | fn foo(b: bool) -> impl Iterator<Item = ()> {
|
||||
| ------------------------ the expected opaque type
|
||||
...
|
||||
LL | std::iter::empty()
|
||||
| ^^^^^^^^^^^^^^^^^^ types differ
|
||||
|
|
||||
= note: expected opaque type `impl Iterator<Item = ()>`
|
||||
found struct `std::iter::Empty<_>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0282, E0308.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
20
tests/ui/impl-trait/method-resolution4.rs
Normal file
20
tests/ui/impl-trait/method-resolution4.rs
Normal file
@ -0,0 +1,20 @@
|
||||
//! The recursive method call yields the opaque type. The
|
||||
//! `next` method call then constrains the hidden type to `&mut _`
|
||||
//! because `next` takes `&mut self`. We never resolve the inference
|
||||
//! variable, but get a type mismatch when comparing `&mut _` with
|
||||
//! `std::iter::Empty`.
|
||||
|
||||
//@[current] check-pass
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
fn foo(b: bool) -> impl Iterator<Item = ()> {
|
||||
if b {
|
||||
foo(false).next().unwrap();
|
||||
//[next]~^ type annotations needed
|
||||
}
|
||||
std::iter::empty()
|
||||
//[next]~^ mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
42
tests/ui/impl-trait/recursive-parent-trait-method-call.rs
Normal file
42
tests/ui/impl-trait/recursive-parent-trait-method-call.rs
Normal file
@ -0,0 +1,42 @@
|
||||
//! This test checks that we can resolve the `boxed` method call to `FutureExt`,
|
||||
//! because we know that the anonymous future does not implement `StreamExt`.
|
||||
|
||||
//@ edition: 2021
|
||||
//@ check-pass
|
||||
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
||||
trait FutureExt: Future + Sized + Send + 'static {
|
||||
fn boxed(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'static>> {
|
||||
Box::pin(self)
|
||||
}
|
||||
}
|
||||
|
||||
trait StreamExt: Future + Sized + Send + 'static {
|
||||
fn boxed(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'static>> {
|
||||
Box::pin(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Future + Sized + Send + 'static> FutureExt for T {}
|
||||
|
||||
fn go(i: usize) -> impl Future<Output = ()> + Send + 'static {
|
||||
async move {
|
||||
if i != 0 {
|
||||
spawn(async move {
|
||||
let fut = go(i - 1).boxed();
|
||||
fut.await;
|
||||
})
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn<T: Send>(
|
||||
_: impl Future<Output = T> + Send + 'static,
|
||||
) -> impl Future<Output = ()> + Send + 'static {
|
||||
async move { todo!() }
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,15 @@
|
||||
error[E0599]: no method named `bar` found for struct `Bar<u32>` in the current scope
|
||||
--> $DIR/method_resolution.rs:21:14
|
||||
|
|
||||
LL | struct Bar<T>(T);
|
||||
| ------------- method `bar` not found for this struct
|
||||
...
|
||||
LL | self.bar()
|
||||
| ^^^ method not found in `Bar<u32>`
|
||||
|
|
||||
= note: the method was found for
|
||||
- `Bar<Foo>`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
12
tests/ui/type-alias-impl-trait/method_resolution.next.stderr
Normal file
12
tests/ui/type-alias-impl-trait/method_resolution.next.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0599]: no method named `bar` found for struct `Bar<u32>` in the current scope
|
||||
--> $DIR/method_resolution.rs:21:14
|
||||
|
|
||||
LL | struct Bar<T>(T);
|
||||
| ------------- method `bar` not found for this struct
|
||||
...
|
||||
LL | self.bar()
|
||||
| ^^^ method cannot be called on `Bar<u32>` due to unsatisfied trait bounds
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
30
tests/ui/type-alias-impl-trait/method_resolution.rs
Normal file
30
tests/ui/type-alias-impl-trait/method_resolution.rs
Normal file
@ -0,0 +1,30 @@
|
||||
//! `Bar<u32>::foo` is not defining `Foo`, so it cannot rely on the fact that
|
||||
//! `u32` is the hidden type of `Foo` to call `bar`
|
||||
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Foo = impl Sized;
|
||||
|
||||
struct Bar<T>(T);
|
||||
|
||||
impl Bar<Foo> {
|
||||
fn bar(mut self) {
|
||||
self.0 = 42_u32;
|
||||
}
|
||||
}
|
||||
|
||||
impl Bar<u32> {
|
||||
fn foo(self) {
|
||||
self.bar()
|
||||
//~^ ERROR: no method named `bar`
|
||||
}
|
||||
}
|
||||
|
||||
fn foo() -> Foo {
|
||||
42_u32
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,36 @@
|
||||
error[E0599]: no method named `foo` found for struct `Bar<Foo>` in the current scope
|
||||
--> $DIR/method_resolution2.rs:17:14
|
||||
|
|
||||
LL | struct Bar<T>(T);
|
||||
| ------------- method `foo` not found for this struct
|
||||
...
|
||||
LL | self.foo()
|
||||
| ^^^ method not found in `Bar<Foo>`
|
||||
|
|
||||
= note: the method was found for
|
||||
- `Bar<u32>`
|
||||
|
||||
error[E0391]: cycle detected when computing type of opaque `Foo::{opaque#0}`
|
||||
--> $DIR/method_resolution2.rs:10:12
|
||||
|
|
||||
LL | type Foo = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires type-checking `<impl at $DIR/method_resolution2.rs:15:1: 15:14>::bar`...
|
||||
--> $DIR/method_resolution2.rs:17:9
|
||||
|
|
||||
LL | self.foo()
|
||||
| ^^^^
|
||||
= note: ...which requires evaluating trait selection obligation `Bar<Foo>: core::marker::Unpin`...
|
||||
= note: ...which again requires computing type of opaque `Foo::{opaque#0}`, completing the cycle
|
||||
note: cycle used when computing type of `Foo::{opaque#0}`
|
||||
--> $DIR/method_resolution2.rs:10:12
|
||||
|
|
||||
LL | type Foo = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0391, E0599.
|
||||
For more information about an error, try `rustc --explain E0391`.
|
30
tests/ui/type-alias-impl-trait/method_resolution2.rs
Normal file
30
tests/ui/type-alias-impl-trait/method_resolution2.rs
Normal file
@ -0,0 +1,30 @@
|
||||
//! Check that we do not unify `Bar<Foo>` with `Bar<u32>`, even though the
|
||||
//! `foo` method call can be resolved unambiguously by doing so.
|
||||
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[next] check-pass
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Foo = impl Sized;
|
||||
//[current]~^ ERROR: cycle
|
||||
|
||||
struct Bar<T>(T);
|
||||
|
||||
impl Bar<Foo> {
|
||||
fn bar(self) {
|
||||
self.foo()
|
||||
//[current]~^ ERROR: no method named `foo`
|
||||
}
|
||||
}
|
||||
|
||||
impl Bar<u32> {
|
||||
fn foo(self) {}
|
||||
}
|
||||
|
||||
fn foo() -> Foo {
|
||||
42_u32
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,21 @@
|
||||
error[E0307]: invalid `self` parameter type: `Bar<u32>`
|
||||
--> $DIR/method_resolution3.rs:16:18
|
||||
|
|
||||
LL | fn bar(self: Bar<u32>) {
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must be `Self` or a type that dereferences to it
|
||||
= 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[E0307]: invalid `self` parameter type: `&Bar<u32>`
|
||||
--> $DIR/method_resolution3.rs:21:18
|
||||
|
|
||||
LL | fn baz(self: &Bar<u32>) {
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must be `Self` or a type that dereferences to it
|
||||
= 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 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0307`.
|
@ -0,0 +1,15 @@
|
||||
error[E0271]: type mismatch resolving `Foo == u32`
|
||||
--> $DIR/method_resolution3.rs:16:18
|
||||
|
|
||||
LL | fn bar(self: Bar<u32>) {
|
||||
| ^^^^^^^^ types differ
|
||||
|
||||
error[E0271]: type mismatch resolving `Foo == u32`
|
||||
--> $DIR/method_resolution3.rs:21:18
|
||||
|
|
||||
LL | fn baz(self: &Bar<u32>) {
|
||||
| ^^^^^^^^^ types differ
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
36
tests/ui/type-alias-impl-trait/method_resolution3.rs
Normal file
36
tests/ui/type-alias-impl-trait/method_resolution3.rs
Normal file
@ -0,0 +1,36 @@
|
||||
//! Check that one cannot use arbitrary self types where a generic parameter
|
||||
//! mismatches with an opaque type. In theory this could unify with the opaque
|
||||
//! type, registering the generic parameter as the hidden type of the opaque type.
|
||||
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
#![feature(type_alias_impl_trait, arbitrary_self_types)]
|
||||
|
||||
type Foo = impl Copy;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Bar<T>(T);
|
||||
|
||||
impl Bar<Foo> {
|
||||
fn bar(self: Bar<u32>) {
|
||||
//[current]~^ ERROR: invalid `self` parameter
|
||||
//[next]~^^ ERROR: type mismatch resolving `Foo == u32`
|
||||
self.foo()
|
||||
}
|
||||
fn baz(self: &Bar<u32>) {
|
||||
//[current]~^ ERROR: invalid `self` parameter
|
||||
//[next]~^^ ERROR: type mismatch resolving `Foo == u32`
|
||||
self.foo()
|
||||
}
|
||||
}
|
||||
|
||||
impl Bar<u32> {
|
||||
fn foo(self) {}
|
||||
}
|
||||
|
||||
fn foo() -> Foo {
|
||||
42_u32
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,21 @@
|
||||
error[E0307]: invalid `self` parameter type: `Bar<Foo>`
|
||||
--> $DIR/method_resolution4.rs:27:18
|
||||
|
|
||||
LL | fn foo(self: Bar<Foo>) {
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must be `Self` or a type that dereferences to it
|
||||
= 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[E0307]: invalid `self` parameter type: `&Bar<Foo>`
|
||||
--> $DIR/method_resolution4.rs:32:20
|
||||
|
|
||||
LL | fn foomp(self: &Bar<Foo>) {
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must be `Self` or a type that dereferences to it
|
||||
= 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 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0307`.
|
@ -0,0 +1,15 @@
|
||||
error[E0271]: type mismatch resolving `u32 == Foo`
|
||||
--> $DIR/method_resolution4.rs:27:18
|
||||
|
|
||||
LL | fn foo(self: Bar<Foo>) {
|
||||
| ^^^^^^^^ types differ
|
||||
|
||||
error[E0271]: type mismatch resolving `u32 == Foo`
|
||||
--> $DIR/method_resolution4.rs:32:20
|
||||
|
|
||||
LL | fn foomp(self: &Bar<Foo>) {
|
||||
| ^^^^^^^^^ types differ
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
39
tests/ui/type-alias-impl-trait/method_resolution4.rs
Normal file
39
tests/ui/type-alias-impl-trait/method_resolution4.rs
Normal file
@ -0,0 +1,39 @@
|
||||
//! Check that one cannot use arbitrary self types where a generic parameter
|
||||
//! mismatches with an opaque type. In theory this could unify with the opaque
|
||||
//! type, registering the generic parameter as the hidden type of the opaque type.
|
||||
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
#![feature(type_alias_impl_trait, arbitrary_self_types)]
|
||||
|
||||
mod foo {
|
||||
pub type Foo = impl Copy;
|
||||
|
||||
fn foo() -> Foo {
|
||||
42_u32
|
||||
}
|
||||
}
|
||||
use foo::Foo;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Bar<T>(T);
|
||||
|
||||
impl Bar<Foo> {
|
||||
fn bar(self) {}
|
||||
}
|
||||
|
||||
impl Bar<u32> {
|
||||
fn foo(self: Bar<Foo>) {
|
||||
//[current]~^ ERROR: invalid `self` parameter
|
||||
//[next]~^^ ERROR: type mismatch resolving `u32 == Foo`
|
||||
self.bar()
|
||||
}
|
||||
fn foomp(self: &Bar<Foo>) {
|
||||
//[current]~^ ERROR: invalid `self` parameter
|
||||
//[next]~^^ ERROR: type mismatch resolving `u32 == Foo`
|
||||
self.bar()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,15 @@
|
||||
error[E0599]: no method named `bar` found for struct `Bar<u32>` in the current scope
|
||||
--> $DIR/method_resolution5.rs:25:14
|
||||
|
|
||||
LL | struct Bar<T>(T);
|
||||
| ------------- method `bar` not found for this struct
|
||||
...
|
||||
LL | self.bar()
|
||||
| ^^^ method not found in `Bar<u32>`
|
||||
|
|
||||
= note: the method was found for
|
||||
- `Bar<Foo>`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
34
tests/ui/type-alias-impl-trait/method_resolution5.rs
Normal file
34
tests/ui/type-alias-impl-trait/method_resolution5.rs
Normal file
@ -0,0 +1,34 @@
|
||||
//! Even though `Bar<u32>::foo` is defining `Foo`, the old solver does
|
||||
//! not figure out that `u32` is the hidden type of `Foo` to call `bar`.
|
||||
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[next] check-pass
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Foo = impl Sized;
|
||||
|
||||
struct Bar<T>(T);
|
||||
|
||||
impl Bar<Foo> {
|
||||
fn bar(mut self) {
|
||||
self.0 = 42_u32;
|
||||
}
|
||||
}
|
||||
|
||||
impl Bar<u32> {
|
||||
fn foo(self)
|
||||
where
|
||||
Foo:,
|
||||
{
|
||||
self.bar()
|
||||
//[current]~^ ERROR: no method named `bar`
|
||||
}
|
||||
}
|
||||
|
||||
fn foo() -> Foo {
|
||||
42_u32
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,15 @@
|
||||
error: item does not constrain `Tait::{opaque#0}`, but has it in its signature
|
||||
--> $DIR/method_resolution_trait_method_from_opaque.rs:24:8
|
||||
|
|
||||
LL | fn foo(&mut self) {
|
||||
| ^^^
|
||||
|
|
||||
= note: consider moving the opaque type's declaration and defining uses into a separate module
|
||||
note: this opaque type is in the signature
|
||||
--> $DIR/method_resolution_trait_method_from_opaque.rs:17:13
|
||||
|
|
||||
LL | type Tait = impl Iterator<Item = ()>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -0,0 +1,9 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/method_resolution_trait_method_from_opaque.rs:26:9
|
||||
|
|
||||
LL | self.bar.next().unwrap();
|
||||
| ^^^^^^^^ cannot infer type
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
@ -0,0 +1,31 @@
|
||||
//! This test demonstrates how method calls will attempt to unify an opaque type with a reference
|
||||
//! if the method takes `&self` as its argument. This is almost never what is desired, as the user
|
||||
//! would like to have method resolution happen on the opaque type instead of inferring the hidden
|
||||
//! type. Once type-alias-impl-trait requires annotating which functions should constrain the hidden
|
||||
//! type, this won't be as much of a problem, as most functions that do method calls on opaque types
|
||||
//! won't also be the ones defining the hidden type.
|
||||
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
pub struct Foo {
|
||||
bar: Tait,
|
||||
}
|
||||
|
||||
type Tait = impl Iterator<Item = ()>;
|
||||
|
||||
impl Foo {
|
||||
pub fn new() -> Foo {
|
||||
Foo { bar: std::iter::empty() }
|
||||
}
|
||||
|
||||
fn foo(&mut self) {
|
||||
//[current]~^ ERROR: item does not constrain
|
||||
self.bar.next().unwrap();
|
||||
//[next]~^ ERROR: type annotations needed
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user