Skip to content

Commit b105e2a

Browse files
committed
Actually prevent cycle errors
1 parent 6e354fb commit b105e2a

19 files changed

+73
-138
lines changed

compiler/rustc_hir_analysis/src/collect/type_of.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
44
use rustc_hir::intravisit;
55
use rustc_hir::intravisit::Visitor;
66
use rustc_hir::{HirId, Node};
7+
use rustc_infer::infer::opaque_types::may_define_opaque_type;
78
use rustc_middle::hir::nested_filter;
89
use rustc_middle::ty::print::with_forced_trimmed_paths;
910
use rustc_middle::ty::subst::InternalSubsts;
@@ -589,6 +590,12 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
589590
debug!("no constraint: no typeck results");
590591
return;
591592
}
593+
594+
if !may_define_opaque_type(self.tcx, item_def_id, self.def_id) {
595+
debug!("no constraint: does not have TAIT in signature");
596+
return;
597+
}
598+
592599
// Calling `mir_borrowck` can lead to cycle errors through
593600
// const-checking, avoid calling it if we don't have to.
594601
// ```rust

compiler/rustc_infer/src/infer/opaque_types.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,11 +638,19 @@ impl<'tcx> InferCtxt<'tcx> {
638638
/// and `opaque_hir_id` is the `HirId` of the definition of the opaque type `Baz`.
639639
/// For the above example, this function returns `true` for `f1` and `false` for `f2`.
640640
#[instrument(skip(tcx), level = "trace", ret)]
641-
fn may_define_opaque_type<'tcx>(
641+
pub fn may_define_opaque_type<'tcx>(
642642
tcx: TyCtxt<'tcx>,
643643
def_id: LocalDefId,
644644
opaque_def_id: LocalDefId,
645645
) -> bool {
646+
if tcx.is_closure(def_id.to_def_id()) {
647+
return may_define_opaque_type(
648+
tcx,
649+
tcx.parent(def_id.to_def_id()).expect_local(),
650+
opaque_def_id,
651+
);
652+
}
653+
646654
let param_env = tcx.param_env(def_id);
647655
let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(opaque_def_id);
648656
let mut hir_id = tcx.hir().local_def_id_to_hir_id(def_id);

tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
#![feature(type_alias_impl_trait)]
22
#![allow(dead_code)]
33

4-
// FIXME This should compile, but it currently doesn't
4+
// check-pass
55

66
mod m {
77
type Foo = impl std::fmt::Debug;
8-
//~^ ERROR: cycle detected when computing type of `m::Foo::{opaque#0}` [E0391]
98

109
pub fn foo() -> Foo {
1110
22_u32

tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr

Lines changed: 0 additions & 22 deletions
This file was deleted.

tests/ui/type-alias-impl-trait/defining-scopes-cycle-prevention.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#![feature(type_alias_impl_trait)]
22

3+
// check-pass
4+
35
// Check that, even within the defining scope, we can get the
46
// `Send` or `Sync` bound of a TAIT, as long as the current function
57
// doesn't mention those TAITs in the signature
68
type Foo = impl std::fmt::Debug;
7-
//~^ ERROR cycle detected
89

910
fn is_send<T: Send>() {}
1011

tests/ui/type-alias-impl-trait/defining-scopes-cycle-prevention.stderr

Lines changed: 0 additions & 28 deletions
This file was deleted.

tests/ui/type-alias-impl-trait/defining-scopes-syntactic.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ type DropType<T> = ();
77
//~^ ERROR type parameter `T` is unused
88

99
type Foo = impl std::fmt::Debug;
10+
//~^ ERROR unconstrained opaque type
11+
1012
// Check that, even though `Foo` is not part
1113
// of the actual type, we do allow this to be a defining scope
1214
fn g() -> DropType<Foo> {

tests/ui/type-alias-impl-trait/defining-scopes-syntactic.stderr

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,16 @@ error[E0091]: type parameter `T` is unused
44
LL | type DropType<T> = ();
55
| ^ unused type parameter
66

7+
error: unconstrained opaque type
8+
--> $DIR/defining-scopes-syntactic.rs:9:12
9+
|
10+
LL | type Foo = impl std::fmt::Debug;
11+
| ^^^^^^^^^^^^^^^^^^^^
12+
|
13+
= note: `Foo` must be used in combination with a concrete type within the same module
14+
715
error[E0308]: mismatched types
8-
--> $DIR/defining-scopes-syntactic.rs:13:18
16+
--> $DIR/defining-scopes-syntactic.rs:15:18
917
|
1018
LL | type Foo = impl std::fmt::Debug;
1119
| -------------------- the expected opaque type
@@ -18,7 +26,7 @@ LL | let _: Foo = 42;
1826
= note: expected opaque type `Foo`
1927
found type `{integer}`
2028

21-
error: aborting due to 2 previous errors
29+
error: aborting due to 3 previous errors
2230

2331
Some errors have detailed explanations: E0091, E0308.
2432
For more information about an error, try `rustc --explain E0091`.

tests/ui/type-alias-impl-trait/defining-scopes.stderr

Lines changed: 0 additions & 17 deletions
This file was deleted.

tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@
33
use std::fmt::Debug;
44

55
type Foo = impl Debug;
6-
pub trait Yay { }
7-
impl Yay for Foo { }
6+
pub trait Yay {}
7+
impl Yay for Foo {}
88

9-
fn foo() {
10-
is_yay::<u32>(); //~ ERROR: the trait bound `u32: Yay` is not satisfied
9+
fn foo()
10+
where
11+
Foo: Debug,
12+
{
13+
is_yay::<u32>(); //~ ERROR: the trait bound `u32: Yay` is not satisfied
1114
is_debug::<u32>(); // OK
12-
is_yay::<Foo>(); // OK
15+
is_yay::<Foo>(); // OK
1316
is_debug::<Foo>(); // OK
1417
}
1518

16-
fn is_yay<T: Yay>() { }
17-
fn is_debug<T: Debug>() { }
19+
fn is_yay<T: Yay>() {}
20+
fn is_debug<T: Debug>() {}
1821

1922
fn main() {}

0 commit comments

Comments
 (0)