Skip to content

Commit eaea480

Browse files
committed
add tests, silence type annotations needed errors for opaques
1 parent fccbf16 commit eaea480

13 files changed

+231
-38
lines changed

compiler/rustc_hir_typeck/src/opaque_types.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,21 +117,25 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
117117
)
118118
}
119119
UsageKind::UnconstrainedHiddenType(hidden_type) => {
120-
let infer_var = hidden_type
121-
.ty
122-
.walk()
123-
.filter_map(ty::GenericArg::as_term)
124-
.find(|term| term.is_infer())
125-
.unwrap_or_else(|| hidden_type.ty.into());
126-
self.err_ctxt()
127-
.emit_inference_failure_err(
128-
self.body_id,
129-
hidden_type.span,
130-
infer_var,
131-
TypeAnnotationNeeded::E0282,
132-
false,
133-
)
134-
.emit()
120+
if let Some(guar) = self.tainted_by_errors() {
121+
guar
122+
} else {
123+
let infer_var = hidden_type
124+
.ty
125+
.walk()
126+
.filter_map(ty::GenericArg::as_term)
127+
.find(|term| term.is_infer())
128+
.unwrap_or_else(|| hidden_type.ty.into());
129+
self.err_ctxt()
130+
.emit_inference_failure_err(
131+
self.body_id,
132+
hidden_type.span,
133+
infer_var,
134+
TypeAnnotationNeeded::E0282,
135+
false,
136+
)
137+
.emit()
138+
}
135139
}
136140
UsageKind::HasDefiningUse => continue,
137141
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
error[E0382]: use of moved value: `var`
2+
--> $DIR/call-expr-incorrect-choice-diagnostics.rs:14:9
3+
|
4+
LL | let mut var = item_bound_is_too_weak();
5+
| ------- move occurs because `var` has type `impl FnOnce()`, which does not implement the `Copy` trait
6+
LL | var();
7+
| ----- `var` moved due to this call
8+
LL | var();
9+
| ^^^ value used here after move
10+
|
11+
note: this value implements `FnOnce`, which causes it to be moved when called
12+
--> $DIR/call-expr-incorrect-choice-diagnostics.rs:13:9
13+
|
14+
LL | var();
15+
| ^^^
16+
17+
error[E0618]: expected function, found `impl Sized`
18+
--> $DIR/call-expr-incorrect-choice-diagnostics.rs:24:9
19+
|
20+
LL | fn opaque_type_no_impl_fn() -> impl Sized {
21+
| ----------------------------------------- `opaque_type_no_impl_fn` defined here returns `impl Sized`
22+
LL | if false {
23+
LL | opaque_type_no_impl_fn()();
24+
| ^^^^^^^^^^^^^^^^^^^^^^^^--
25+
| |
26+
| call expression requires function
27+
28+
error[E0618]: expected function, found `impl Sized`
29+
--> $DIR/call-expr-incorrect-choice-diagnostics.rs:34:9
30+
|
31+
LL | fn opaque_type_no_impl_fn_incorrect() -> impl Sized {
32+
| --------------------------------------------------- `opaque_type_no_impl_fn_incorrect` defined here returns `impl Sized`
33+
LL | if false {
34+
LL | opaque_type_no_impl_fn_incorrect()();
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--
36+
| |
37+
| call expression requires function
38+
39+
error[E0618]: expected function, found `impl Deref<Target = impl Sized>`
40+
--> $DIR/call-expr-incorrect-choice-diagnostics.rs:44:9
41+
|
42+
LL | fn opaque_type_deref_no_impl_fn() -> impl Deref<Target = impl Sized> {
43+
| -------------------------------------------------------------------- `opaque_type_deref_no_impl_fn` defined here returns `impl Deref<Target = impl Sized>`
44+
LL | if false {
45+
LL | opaque_type_deref_no_impl_fn()();
46+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--
47+
| |
48+
| call expression requires function
49+
50+
error: aborting due to 4 previous errors
51+
52+
Some errors have detailed explanations: E0382, E0618.
53+
For more information about an error, try `rustc --explain E0382`.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
error[E0382]: use of moved value: `var`
2+
--> $DIR/call-expr-incorrect-choice-diagnostics.rs:14:9
3+
|
4+
LL | let mut var = item_bound_is_too_weak();
5+
| ------- move occurs because `var` has type `{closure@$DIR/call-expr-incorrect-choice-diagnostics.rs:19:5: 19:12}`, which does not implement the `Copy` trait
6+
LL | var();
7+
| ----- `var` moved due to this call
8+
LL | var();
9+
| ^^^ value used here after move
10+
|
11+
note: this value implements `FnOnce`, which causes it to be moved when called
12+
--> $DIR/call-expr-incorrect-choice-diagnostics.rs:13:9
13+
|
14+
LL | var();
15+
| ^^^
16+
help: consider cloning the value if the performance cost is acceptable
17+
|
18+
LL | var.clone()();
19+
| ++++++++
20+
21+
error[E0618]: expected function, found `_`
22+
--> $DIR/call-expr-incorrect-choice-diagnostics.rs:24:9
23+
|
24+
LL | fn opaque_type_no_impl_fn() -> impl Sized {
25+
| ----------------------------------------- `opaque_type_no_impl_fn` defined here returns `_`
26+
LL | if false {
27+
LL | opaque_type_no_impl_fn()();
28+
| ^^^^^^^^^^^^^^^^^^^^^^^^--
29+
| |
30+
| call expression requires function
31+
32+
error[E0618]: expected function, found `_`
33+
--> $DIR/call-expr-incorrect-choice-diagnostics.rs:34:9
34+
|
35+
LL | fn opaque_type_no_impl_fn_incorrect() -> impl Sized {
36+
| --------------------------------------------------- `opaque_type_no_impl_fn_incorrect` defined here returns `_`
37+
LL | if false {
38+
LL | opaque_type_no_impl_fn_incorrect()();
39+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--
40+
| |
41+
| call expression requires function
42+
43+
error[E0618]: expected function, found `_`
44+
--> $DIR/call-expr-incorrect-choice-diagnostics.rs:44:9
45+
|
46+
LL | fn opaque_type_deref_no_impl_fn() -> impl Deref<Target = impl Sized> {
47+
| -------------------------------------------------------------------- `opaque_type_deref_no_impl_fn` defined here returns `_`
48+
LL | if false {
49+
LL | opaque_type_deref_no_impl_fn()();
50+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--
51+
| |
52+
| call expression requires function
53+
54+
error: aborting due to 4 previous errors
55+
56+
Some errors have detailed explanations: E0382, E0618.
57+
For more information about an error, try `rustc --explain E0382`.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//@ revisions: current next
2+
//@[next] compile-flags: -Znext-solver
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
5+
// Testing the errors in case we've made a wrong choice when
6+
// calling an opaque.
7+
8+
use std::ops::Deref;
9+
10+
fn item_bound_is_too_weak() -> impl FnOnce() {
11+
if false {
12+
let mut var = item_bound_is_too_weak();
13+
var();
14+
var();
15+
//~^ ERROR use of moved value: `var`
16+
}
17+
18+
let mut state = String::new();
19+
move || state.push('a')
20+
}
21+
22+
fn opaque_type_no_impl_fn() -> impl Sized {
23+
if false {
24+
opaque_type_no_impl_fn()();
25+
//[current]~^ ERROR expected function, found `impl Sized`
26+
//[next]~^^ ERROR expected function, found `_`
27+
}
28+
29+
1
30+
}
31+
32+
fn opaque_type_no_impl_fn_incorrect() -> impl Sized {
33+
if false {
34+
opaque_type_no_impl_fn_incorrect()();
35+
//[current]~^ ERROR expected function, found `impl Sized`
36+
//[next]~^^ ERROR expected function, found `_`
37+
}
38+
39+
|| ()
40+
}
41+
42+
fn opaque_type_deref_no_impl_fn() -> impl Deref<Target = impl Sized> {
43+
if false {
44+
opaque_type_deref_no_impl_fn()();
45+
//[current]~^ ERROR expected function, found `impl Deref<Target = impl Sized>`
46+
//[next]~^^ ERROR expected function, found `_`
47+
}
48+
49+
&1
50+
}
51+
52+
fn main() {}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0599]: no method named `len` found for struct `Wrapper<T>` in the current scope
2+
--> $DIR/deref-constrains-self-ty.rs:22:32
3+
|
4+
LL | struct Wrapper<T>(T);
5+
| ----------------- method `len` not found for this struct
6+
...
7+
LL | let _ = Wrapper(foo()).len();
8+
| ^^^ method not found in `Wrapper<impl Sized>`
9+
|
10+
= help: items from traits can only be used if the trait is implemented and in scope
11+
= note: the following trait defines an item `len`, perhaps you need to implement it:
12+
candidate #1: `ExactSizeIterator`
13+
14+
error: aborting due to 1 previous error
15+
16+
For more information about this error, try `rustc --explain E0599`.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//@ revisions: current next
2+
//@[next] compile-flags: -Znext-solver
3+
//@ ignore-compare-mode-next-solver (explicit revisions)
4+
//@[next] check-pass
5+
6+
// A test which shows that autoderef can constrain opaque types even
7+
// though it's supposed to treat not-yet-defined opaque types as
8+
// mostly rigid. I don't think this should necessarily compile :shrug:
9+
use std::ops::Deref;
10+
11+
struct Wrapper<T>(T);
12+
13+
impl<T> Deref for Wrapper<Vec<T>> {
14+
type Target = Vec<T>;
15+
fn deref(&self) -> &Self::Target {
16+
&self.0
17+
}
18+
}
19+
20+
fn foo() -> impl Sized {
21+
if false {
22+
let _ = Wrapper(foo()).len();
23+
//[current]~^ ERROR no method named `len` found for struct `Wrapper<T>` in the current scope
24+
}
25+
26+
std::iter::once(1).collect()
27+
}
28+
fn main() {}

tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.current.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0792]: expected generic type parameter, found `impl Foo`
2-
--> $DIR/double-wrap-with-defining-use.rs:12:26
2+
--> $DIR/double-wrap-with-defining-use.rs:11:26
33
|
44
LL | fn a<T: Foo>(x: T) -> impl Foo {
55
| - this generic parameter must be used with a generic type parameter
66
LL | if true { x } else { a(a(x)) }
77
| ^^^^^^^
88

99
error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
10-
--> $DIR/double-wrap-with-defining-use.rs:12:26
10+
--> $DIR/double-wrap-with-defining-use.rs:11:26
1111
|
1212
LL | if true { x } else { a(a(x)) }
1313
| ^^^^^^^

tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Regression test for ICE from issue #140545
22
// The error message is confusing and wrong, but that's a different problem (#139350)
33

4-
//@ edition:2018
54
//@ revisions: current next
65
//@[next] compile-flags: -Znext-solver
76
//@ ignore-compare-mode-next-solver (explicit revisions)

tests/ui/impl-trait/non-defining-uses/ice-issue-146191.current.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | fn create_complex_future() -> impl Future<Output = impl ReturnsSend> {
55
| ^^^^^^^^^^^^^^^^ the trait `ReturnsSend` is not implemented for `()`
66
|
77
help: this trait has no implementations, consider adding one
8-
--> $DIR/ice-issue-146191.rs:14:1
8+
--> $DIR/ice-issue-146191.rs:13:1
99
|
1010
LL | trait ReturnsSend {}
1111
| ^^^^^^^^^^^^^^^^^

tests/ui/impl-trait/non-defining-uses/ice-issue-146191.next.stderr

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,6 @@ error[E0282]: type annotations needed
44
LL | async { create_complex_future().await }
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
66

7-
error[E0282]: type annotations needed
8-
--> $DIR/ice-issue-146191.rs:8:5
9-
|
10-
LL | async { create_complex_future().await }
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
12-
|
13-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
14-
15-
error: aborting due to 2 previous errors
7+
error: aborting due to 1 previous error
168

179
For more information about this error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)