Skip to content

Commit

Permalink
Add some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Jun 13, 2024
1 parent b28221e commit c75f728
Show file tree
Hide file tree
Showing 38 changed files with 998 additions and 0 deletions.
17 changes: 17 additions & 0 deletions tests/ui/impl-trait/call_method_ambiguous.next.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 39 additions & 0 deletions tests/ui/impl-trait/call_method_ambiguous.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 17 additions & 0 deletions tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 25 additions & 0 deletions tests/ui/impl-trait/call_method_on_inherent_impl.rs
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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`.
22 changes: 22 additions & 0 deletions tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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`.
31 changes: 31 additions & 0 deletions tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 35 additions & 0 deletions tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs
Original file line number Diff line number Diff line change
@@ -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() {}
37 changes: 37 additions & 0 deletions tests/ui/impl-trait/call_method_without_import.no_import.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 42 additions & 0 deletions tests/ui/impl-trait/call_method_without_import.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 36 additions & 0 deletions tests/ui/impl-trait/method-resolution.current.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Loading

0 comments on commit c75f728

Please sign in to comment.