Skip to content

Commit 1474ee5

Browse files
committed
Don't try to prove opaque type bounds twice on the same types
1 parent aa8c147 commit 1474ee5

File tree

9 files changed

+69
-41
lines changed

9 files changed

+69
-41
lines changed

compiler/rustc_infer/src/infer/opaque_types.rs

+23-14
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ impl<'tcx> InferCtxt<'tcx> {
508508
) -> InferResult<'tcx, ()> {
509509
let mut obligations = Vec::new();
510510

511-
self.insert_hidden_type(
511+
let already_had_hidden_ty = self.insert_hidden_type(
512512
opaque_type_key,
513513
&cause,
514514
param_env,
@@ -517,14 +517,21 @@ impl<'tcx> InferCtxt<'tcx> {
517517
&mut obligations,
518518
)?;
519519

520-
self.add_item_bounds_for_hidden_type(
521-
opaque_type_key.def_id.to_def_id(),
522-
opaque_type_key.args,
523-
cause,
524-
param_env,
525-
hidden_ty,
526-
&mut obligations,
527-
);
520+
// If we already had a hidden type, that hidden type will
521+
// have already gone through `add_item_bounds_for_hidden_type`.
522+
// Since all the bounds must already hold for the previous hidden type
523+
// and the new hidden type must be equal to the previous hidden type,
524+
// we can conclude that the bounds must already hold.
525+
if !already_had_hidden_ty {
526+
self.add_item_bounds_for_hidden_type(
527+
opaque_type_key.def_id.to_def_id(),
528+
opaque_type_key.args,
529+
cause,
530+
param_env,
531+
hidden_ty,
532+
&mut obligations,
533+
);
534+
}
528535

529536
Ok(InferOk { value: (), obligations })
530537
}
@@ -544,7 +551,7 @@ impl<'tcx> InferCtxt<'tcx> {
544551
hidden_ty: Ty<'tcx>,
545552
a_is_expected: bool,
546553
obligations: &mut Vec<PredicateObligation<'tcx>>,
547-
) -> Result<(), TypeError<'tcx>> {
554+
) -> Result<bool, TypeError<'tcx>> {
548555
// Ideally, we'd get the span where *this specific `ty` came
549556
// from*, but right now we just use the span from the overall
550557
// value being folded. In simple cases like `-> impl Foo`,
@@ -560,7 +567,8 @@ impl<'tcx> InferCtxt<'tcx> {
560567
cause.clone(),
561568
param_env,
562569
ty::PredicateKind::Ambiguous,
563-
))
570+
));
571+
Ok(false)
564572
} else {
565573
let prev = self
566574
.inner
@@ -573,10 +581,11 @@ impl<'tcx> InferCtxt<'tcx> {
573581
.eq_exp(DefineOpaqueTypes::Yes, a_is_expected, prev, hidden_ty)?
574582
.obligations,
575583
);
584+
Ok(true)
585+
} else {
586+
Ok(false)
576587
}
577-
};
578-
579-
Ok(())
588+
}
580589
}
581590

582591
pub fn add_item_bounds_for_hidden_type(

src/tools/clippy/tests/ui/new_ret_no_self_overflow.stderr

+17-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
1-
error[E0275]: overflow evaluating the requirement `<i32 as std::ops::Add>::Output == issue10041::X`
2-
--> $DIR/new_ret_no_self_overflow.rs:20:25
1+
error: methods called `new` usually return `Self`
2+
--> $DIR/new_ret_no_self_overflow.rs:9:9
33
|
4-
LL | pub fn new() -> X {
5-
| ^
4+
LL | / pub fn new() -> impl PartialOrd {
5+
LL | | 0i32
6+
LL | | }
7+
| |_________^
8+
|
9+
= note: `-D clippy::new-ret-no-self` implied by `-D warnings`
10+
11+
error: methods called `new` usually return `Self`
12+
--> $DIR/new_ret_no_self_overflow.rs:20:9
13+
|
14+
LL | / pub fn new() -> X {
15+
LL | | 0i32
16+
LL | | }
17+
| |_________^
618

7-
error: aborting due to previous error
19+
error: aborting due to 2 previous errors
820

9-
For more information about this error, try `rustc --explain E0275`.

tests/ui/async-await/suggest-missing-await.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ LL | take_u32(x.await)
2424
error[E0308]: mismatched types
2525
--> $DIR/suggest-missing-await.rs:22:5
2626
|
27+
LL | async fn suggest_await_in_async_fn_return() {
28+
| - expected `()` because of return type
2729
LL | dummy()
2830
| ^^^^^^^ expected `()`, found future
2931
|

tests/ui/parser/expr-as-stmt.stderr

+10-3
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,16 @@ error[E0308]: mismatched types
8181
--> $DIR/expr-as-stmt.rs:64:7
8282
|
8383
LL | { foo() } || { true }
84-
| ^^^^^- help: consider using a semicolon here: `;`
85-
| |
86-
| expected `()`, found `i32`
84+
| ^^^^^ expected `()`, found `i32`
85+
|
86+
help: consider using a semicolon here
87+
|
88+
LL | { foo(); } || { true }
89+
| +
90+
help: you might have meant to return this value
91+
|
92+
LL | { return foo(); } || { true }
93+
| ++++++ +
8794

8895
error[E0308]: mismatched types
8996
--> $DIR/expr-as-stmt.rs:8:6

tests/ui/type-alias-impl-trait/issue-63279.rs

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ fn c() -> Closure {
77
|| -> Closure { || () }
88
//~^ ERROR: mismatched types
99
//~| ERROR: mismatched types
10-
//~| ERROR: expected a `FnOnce<()>` closure, found `()`
1110
}
1211

1312
fn main() {}

tests/ui/type-alias-impl-trait/issue-63279.stderr

+4-10
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,6 @@ LL | fn c() -> Closure {
77
= help: the trait `FnOnce<()>` is not implemented for `()`
88
= note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
99

10-
error[E0277]: expected a `FnOnce<()>` closure, found `()`
11-
--> $DIR/issue-63279.rs:7:11
12-
|
13-
LL | || -> Closure { || () }
14-
| ^^^^^^^ expected an `FnOnce<()>` closure, found `()`
15-
|
16-
= help: the trait `FnOnce<()>` is not implemented for `()`
17-
= note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
18-
1910
error[E0308]: mismatched types
2011
--> $DIR/issue-63279.rs:7:21
2112
|
@@ -32,6 +23,9 @@ LL | || -> Closure { (|| ())() }
3223
error[E0308]: mismatched types
3324
--> $DIR/issue-63279.rs:7:5
3425
|
26+
LL | fn c() -> Closure {
27+
| ------- expected `()` because of return type
28+
LL |
3529
LL | || -> Closure { || () }
3630
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found closure
3731
|
@@ -42,7 +36,7 @@ help: use parentheses to call this closure
4236
LL | (|| -> Closure { || () })()
4337
| + +++
4438

45-
error: aborting due to 4 previous errors
39+
error: aborting due to 3 previous errors
4640

4741
Some errors have detailed explanations: E0277, E0308.
4842
For more information about an error, try `rustc --explain E0277`.

tests/ui/type-alias-impl-trait/self-referential-in-fn-trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#![feature(type_alias_impl_trait)]
22

33
type Foo<'a> = impl Fn() -> Foo<'a>;
4+
//~^ ERROR: unconstrained opaque type
45

56
fn crash<'a>(_: &'a (), x: Foo<'a>) -> Foo<'a> {
6-
//~^ ERROR: overflow evaluating the requirement `<Foo<'a> as FnOnce<()>>::Output == Foo<'a>
77
x
88
}
99

tests/ui/type-alias-impl-trait/self-referential-in-fn-trait.stderr

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
error[E0275]: overflow evaluating the requirement `<Foo<'a> as FnOnce<()>>::Output == Foo<'a>`
2-
--> $DIR/self-referential-in-fn-trait.rs:5:40
1+
error: unconstrained opaque type
2+
--> $DIR/self-referential-in-fn-trait.rs:3:16
33
|
4-
LL | fn crash<'a>(_: &'a (), x: Foo<'a>) -> Foo<'a> {
5-
| ^^^^^^^
4+
LL | type Foo<'a> = impl Fn() -> Foo<'a>;
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `Foo` must be used in combination with a concrete type within the same module
68

79
error: aborting due to previous error
810

9-
For more information about this error, try `rustc --explain E0275`.

tests/ui/typeck/issue-90027-async-fn-return-suggestion.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,18 @@ error[E0308]: mismatched types
1010
--> $DIR/issue-90027-async-fn-return-suggestion.rs:9:5
1111
|
1212
LL | async fn world() -> () {
13-
| -- expected `()` because of return type
13+
| --
14+
| |
15+
| expected `()` because of return type
16+
| expected `()` because of return type
1417
LL | 0
1518
| ^ expected `()`, found integer
1619

1720
error[E0308]: mismatched types
1821
--> $DIR/issue-90027-async-fn-return-suggestion.rs:14:5
1922
|
23+
LL | async fn suggest_await_in_async_fn_return() {
24+
| - expected `()` because of return type
2025
LL | hello()
2126
| ^^^^^^^ expected `()`, found future
2227
|

0 commit comments

Comments
 (0)