Auto merge of #99098 - Mark-Simulacrum:beta-next, r=Mark-Simulacrum

[beta] backport rollup

*  Return a FxIndexSet in is_late_bound query. #98959
*  rustdoc: filter '_ lifetimes from ty::PolyTraitRef #98727
* don't succeed evaluate_obligation query if new opaque types were registered #98614
*  Update llvm-project #98567

There's a few more as-yet-unapproved/unmerged PRs that'll land later, but creating a partial rollup for now so that we can include at least some PRs in the first crater run.

r? `@Mark-Simulacrum`
This commit is contained in:
bors 2022-07-10 01:19:06 +00:00
commit 93ef0cd7fd
29 changed files with 163 additions and 192 deletions

View file

@ -891,6 +891,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
.region_constraints_added_in_snapshot(&snapshot.undo_snapshot)
}
pub fn opaque_types_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'a, 'tcx>) -> bool {
self.inner.borrow().undo_log.opaque_types_in_snapshot(&snapshot.undo_snapshot)
}
pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) {
self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup);
}

View file

@ -103,7 +103,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
ty::Opaque(def_id, substs) => {
ty::Opaque(def_id, substs) if def_id.is_local() => {
let origin = if self.defining_use_anchor.is_some() {
// Check that this is `impl Trait` type is
// declared by `parent_def_id` -- i.e., one whose

View file

@ -185,6 +185,10 @@ impl<'tcx> InferCtxtUndoLogs<'tcx> {
})
}
pub(crate) fn opaque_types_in_snapshot(&self, s: &Snapshot<'tcx>) -> bool {
self.logs[s.undo_len..].iter().any(|log| matches!(log, UndoLog::OpaqueTypes(..)))
}
pub(crate) fn region_constraints(
&self,
) -> impl Iterator<Item = &'_ region_constraints::UndoLog<'tcx>> + Clone {

View file

@ -203,7 +203,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> {
Some(&ProjectionCacheEntry::NormalizedTy { ref ty, complete: _ }) => {
info!("ProjectionCacheEntry::complete({:?}) - completing {:?}", key, ty);
let mut ty = ty.clone();
if result == EvaluationResult::EvaluatedToOk {
if result.must_apply_considering_regions() {
ty.obligations = vec![];
}
map.insert(key, ProjectionCacheEntry::NormalizedTy { ty, complete: Some(result) });

View file

@ -96,6 +96,7 @@ macro_rules! arena_types {
// (during lowering) and the `librustc_middle` arena (for decoding MIR)
[decode] asm_template: rustc_ast::InlineAsmTemplatePiece,
[decode] used_trait_imports: rustc_data_structures::fx::FxHashSet<rustc_hir::def_id::LocalDefId>,
[decode] is_late_bound_map: rustc_data_structures::fx::FxIndexSet<rustc_hir::def_id::LocalDefId>,
[decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>,
[] dep_kind: rustc_middle::dep_graph::DepKindStruct,

View file

@ -1572,7 +1572,7 @@ rustc_queries! {
Option<&'tcx FxHashMap<ItemLocalId, Region>> {
desc { "looking up a named region" }
}
query is_late_bound_map(_: LocalDefId) -> Option<&'tcx FxHashSet<LocalDefId>> {
query is_late_bound_map(_: LocalDefId) -> Option<&'tcx FxIndexSet<LocalDefId>> {
desc { "testing if a region is late bound" }
}
/// For a given item (like a struct), gets the default lifetimes to be used

View file

@ -176,6 +176,10 @@ pub enum EvaluationResult {
EvaluatedToOk,
/// Evaluation successful, but there were unevaluated region obligations.
EvaluatedToOkModuloRegions,
/// Evaluation successful, but need to rerun because opaque types got
/// hidden types assigned without it being known whether the opaque types
/// are within their defining scope
EvaluatedToOkModuloOpaqueTypes,
/// Evaluation is known to be ambiguous -- it *might* hold for some
/// assignment of inference variables, but it might not.
///
@ -252,9 +256,11 @@ impl EvaluationResult {
pub fn may_apply(self) -> bool {
match self {
EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToUnknown => {
true
}
EvaluatedToOkModuloOpaqueTypes
| EvaluatedToOk
| EvaluatedToOkModuloRegions
| EvaluatedToAmbig
| EvaluatedToUnknown => true,
EvaluatedToErr | EvaluatedToRecur => false,
}
@ -264,7 +270,11 @@ impl EvaluationResult {
match self {
EvaluatedToUnknown | EvaluatedToRecur => true,
EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToErr => false,
EvaluatedToOkModuloOpaqueTypes
| EvaluatedToOk
| EvaluatedToOkModuloRegions
| EvaluatedToAmbig
| EvaluatedToErr => false,
}
}
}

View file

@ -1105,6 +1105,7 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
Lift
)]
pub struct OpaqueTypeKey<'tcx> {
// FIXME(oli-obk): make this a LocalDefId
pub def_id: DefId,
pub substs: SubstsRef<'tcx>,
}

View file

@ -2539,12 +2539,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
/// "Constrained" basically means that it appears in any type but
/// not amongst the inputs to a projection. In other words, `<&'a
/// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`.
fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxHashSet<LocalDefId>> {
fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<LocalDefId>> {
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
let decl = tcx.hir().fn_decl_by_hir_id(hir_id)?;
let generics = tcx.hir().get_generics(def_id)?;
let mut late_bound = FxHashSet::default();
let mut late_bound = FxIndexSet::default();
let mut constrained_by_input = ConstrainedCollector::default();
for arg_ty in decl.inputs {

View file

@ -777,6 +777,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
Ok(
EvaluationResult::EvaluatedToOk
| EvaluationResult::EvaluatedToOkModuloRegions
| EvaluationResult::EvaluatedToOkModuloOpaqueTypes
| EvaluationResult::EvaluatedToAmbig,
) => {}
_ => return false,

View file

@ -394,6 +394,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
Err(_) => return Ok(EvaluatedToErr),
}
if self.infcx.opaque_types_added_in_snapshot(snapshot) {
return Ok(result.max(EvaluatedToOkModuloOpaqueTypes));
}
match self.infcx.region_constraints_added_in_snapshot(snapshot) {
None => Ok(result),
Some(_) => Ok(result.max(EvaluatedToOkModuloRegions)),

View file

@ -203,14 +203,6 @@ bitflags! {
| TypeFlags::HAS_CT_INFER.bits
| TypeFlags::HAS_TY_PLACEHOLDER.bits
| TypeFlags::HAS_CT_PLACEHOLDER.bits
// The `evaluate_obligation` query does not return further
// obligations. If it evaluates an obligation with an opaque
// type, that opaque type may get compared to another type,
// constraining it. We would lose this information.
// FIXME: differentiate between crate-local opaque types
// and opaque types from other crates, as only opaque types
// from the local crate can possibly be a local name
| TypeFlags::HAS_TY_OPAQUE.bits
// We consider 'freshened' types and constants
// to depend on a particular fn.
// The freshening process throws away information,

View file

@ -167,7 +167,7 @@ fn clean_poly_trait_ref_with_bindings<'tcx>(
.collect_referenced_late_bound_regions(&poly_trait_ref)
.into_iter()
.filter_map(|br| match br {
ty::BrNamed(_, name) => Some(GenericParamDef {
ty::BrNamed(_, name) if name != kw::UnderscoreLifetime => Some(GenericParamDef {
name,
kind: GenericParamDefKind::Lifetime { outlives: vec![] },
}),

@ -1 +1 @@
Subproject commit c9e2e89ed3aa5a3be77143aa0c86906b4138374a
Subproject commit d8eb9fc4db91c4955002bf3b118de428efb67493

View file

@ -0,0 +1,19 @@
// revisions: rpass1 rpass2
// edition:2021
// See https://github.com/rust-lang/rust/issues/98890
#![allow(unused)]
struct Foo;
impl Foo {
async fn f(&self, _: &&()) -> &() {
&()
}
}
#[cfg(rpass2)]
enum Bar {}
fn main() {}

View file

@ -0,0 +1,9 @@
/// When reexporting this function, make sure the anonymous lifetimes are not rendered.
///
/// https://github.com/rust-lang/rust/issues/98697
pub fn repro<F>()
where
F: Fn(&str),
{
unimplemented!()
}

View file

@ -0,0 +1,13 @@
// aux-build:issue-98697-reexport-with-anonymous-lifetime.rs
// ignore-cross-compile
// When reexporting a function with a HRTB with anonymous lifetimes,
// make sure the anonymous lifetimes are not rendered.
//
// https://github.com/rust-lang/rust/issues/98697
extern crate issue_98697_reexport_with_anonymous_lifetime;
// @has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'fn repro<F>() where F: Fn(&str)'
// @!has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'for<'
pub use issue_98697_reexport_with_anonymous_lifetime::repro;

View file

@ -11,7 +11,6 @@ fn main() {
// return type, which can't depend on the obligation.
fn cycle1() -> impl Clone {
//~^ ERROR cycle detected
//~| ERROR cycle detected
send(cycle2().clone());
Rc::new(Cell::new(5))

View file

@ -30,45 +30,47 @@ note: ...which requires building MIR for `cycle1`...
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
--> $DIR/auto-trait-leak.rs:14:5
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | send(cycle2().clone());
| ^^^^
= note: ...which requires evaluating trait selection obligation `impl core::clone::Clone: core::marker::Send`...
note: ...which requires computing type of `cycle2::{opaque#0}`...
--> $DIR/auto-trait-leak.rs:20:16
--> $DIR/auto-trait-leak.rs:19:16
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^
note: ...which requires borrow-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:20:1
--> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `cycle2`...
--> $DIR/auto-trait-leak.rs:20:1
--> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `cycle2`...
--> $DIR/auto-trait-leak.rs:20:1
--> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires unsafety-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:20:1
--> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires building MIR for `cycle2`...
--> $DIR/auto-trait-leak.rs:20:1
--> $DIR/auto-trait-leak.rs:19:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:20:1
--> $DIR/auto-trait-leak.rs:20:5
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | send(cycle1().clone());
| ^^^^
= note: ...which requires evaluating trait selection obligation `impl core::clone::Clone: core::marker::Send`...
= note: ...which again requires computing type of `cycle1::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
--> $DIR/auto-trait-leak.rs:1:1
@ -82,90 +84,6 @@ LL | | Rc::new(String::from("foo"))
LL | | }
| |_^
error[E0391]: cycle detected when computing type of `cycle1::{opaque#0}`
--> $DIR/auto-trait-leak.rs:12:16
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^
|
note: ...which requires borrow-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires unsafety-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires building MIR for `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires computing type of `cycle2::{opaque#0}`...
--> $DIR/auto-trait-leak.rs:20:16
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^
note: ...which requires borrow-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:20:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `cycle2`...
--> $DIR/auto-trait-leak.rs:20:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `cycle2`...
--> $DIR/auto-trait-leak.rs:20:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires unsafety-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:20:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires building MIR for `cycle2`...
--> $DIR/auto-trait-leak.rs:20:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:20:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires computing type of `cycle1::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
--> $DIR/auto-trait-leak.rs:1:1
|
LL | / use std::cell::Cell;
LL | | use std::rc::Rc;
LL | |
LL | | fn send<T: Send>(_: T) {}
... |
LL | | Rc::new(String::from("foo"))
LL | | }
| |_^
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0391`.

View file

@ -6,7 +6,6 @@
mod m {
type Foo = impl std::fmt::Debug;
//~^ ERROR: cycle detected when computing type of `m::Foo::{opaque#0}` [E0391]
//~| ERROR: cycle detected when computing type of `m::Foo::{opaque#0}` [E0391]
pub fn foo() -> Foo {
22_u32

View file

@ -5,10 +5,11 @@ LL | type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `m::bar`...
--> $DIR/auto-trait-leakage3.rs:15:5
--> $DIR/auto-trait-leakage3.rs:15:9
|
LL | pub fn bar() {
| ^^^^^^^^^^^^
LL | is_send(foo());
| ^^^^^^^
= note: ...which requires evaluating trait selection obligation `m::Foo: core::marker::Send`...
= note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle
note: cycle used when checking item types in module `m`
--> $DIR/auto-trait-leakage3.rs:6:1
@ -16,24 +17,6 @@ note: cycle used when checking item types in module `m`
LL | mod m {
| ^^^^^
error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}`
--> $DIR/auto-trait-leakage3.rs:7:16
|
LL | type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `m::bar`...
--> $DIR/auto-trait-leakage3.rs:15:5
|
LL | pub fn bar() {
| ^^^^^^^^^^^^
= note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle
note: cycle used when checking item types in module `m`
--> $DIR/auto-trait-leakage3.rs:6:1
|
LL | mod m {
| ^^^^^
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0391`.

View file

@ -4,7 +4,6 @@
mod m {
type Foo = impl std::fmt::Debug;
//~^ ERROR cycle detected
//~| ERROR cycle detected
// Cycle: error today, but it'd be nice if it eventually worked

View file

@ -5,10 +5,11 @@ LL | type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `m::bar`...
--> $DIR/inference-cycle.rs:15:5
--> $DIR/inference-cycle.rs:15:9
|
LL | pub fn bar() {
| ^^^^^^^^^^^^
LL | is_send(foo()); // Today: error
| ^^^^^^^
= note: ...which requires evaluating trait selection obligation `m::Foo: core::marker::Send`...
= note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle
note: cycle used when checking item types in module `m`
--> $DIR/inference-cycle.rs:4:1
@ -16,24 +17,6 @@ note: cycle used when checking item types in module `m`
LL | mod m {
| ^^^^^
error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}`
--> $DIR/inference-cycle.rs:5:16
|
LL | type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `m::bar`...
--> $DIR/inference-cycle.rs:15:5
|
LL | pub fn bar() {
| ^^^^^^^^^^^^
= note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle
note: cycle used when checking item types in module `m`
--> $DIR/inference-cycle.rs:4:1
|
LL | mod m {
| ^^^^^
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0391`.

View file

@ -0,0 +1,13 @@
// edition:2018
type AsyncFnPtr = Box<
dyn Fn() -> std::pin::Pin<Box<dyn std::future::Future<Output = ()>>>,
>;
async fn test() {}
#[allow(unused_must_use)]
fn main() {
Box::new(test) as AsyncFnPtr;
//~^ ERROR type mismatch
}

View file

@ -0,0 +1,18 @@
error[E0271]: type mismatch resolving `<fn() -> impl Future<Output = ()> {test} as FnOnce<()>>::Output == Pin<Box<(dyn Future<Output = ()> + 'static)>>`
--> $DIR/issue-98604.rs:11:5
|
LL | Box::new(test) as AsyncFnPtr;
| ^^^^^^^^^^^^^^ expected struct `Pin`, found opaque type
|
note: while checking the return type of the `async fn`
--> $DIR/issue-98604.rs:7:17
|
LL | async fn test() {}
| ^ checked the `Output` of this `async fn`, found opaque type
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
found opaque type `impl Future<Output = ()>`
= note: required for the cast to the object type `dyn Fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0271`.

View file

@ -0,0 +1,9 @@
fn hi() -> impl Sized { std::ptr::null::<u8>() }
fn main() {
let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi);
//~^ ERROR type mismatch resolving `<fn() -> impl Sized {hi} as FnOnce<()>>::Output == Box<u8>`
let boxed = b();
let null = *boxed;
println!("{null:?}");
}

View file

@ -0,0 +1,16 @@
error[E0271]: type mismatch resolving `<fn() -> impl Sized {hi} as FnOnce<()>>::Output == Box<u8>`
--> $DIR/issue-98608.rs:4:39
|
LL | fn hi() -> impl Sized { std::ptr::null::<u8>() }
| ---------- the found opaque type
...
LL | let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi);
| ^^^^^^^^^^^^ expected struct `Box`, found opaque type
|
= note: expected struct `Box<u8>`
found opaque type `impl Sized`
= note: required for the cast to the object type `dyn Fn() -> Box<u8>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0271`.

View file

@ -4,7 +4,6 @@ use std::fmt::Debug;
type Foo = impl Debug;
//~^ ERROR cycle detected
//~| ERROR cycle detected
fn is_send<T: Send>() { }

View file

@ -5,10 +5,11 @@ LL | type Foo = impl Debug;
| ^^^^^^^^^^
|
note: ...which requires type-checking `not_good`...
--> $DIR/reveal_local.rs:11:1
--> $DIR/reveal_local.rs:13:5
|
LL | fn not_good() {
| ^^^^^^^^^^^^^
LL | is_send::<Foo>();
| ^^^^^^^^^^^^^^
= note: ...which requires evaluating trait selection obligation `Foo: core::marker::Send`...
= note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
--> $DIR/reveal_local.rs:1:1
@ -22,30 +23,6 @@ LL | |
LL | | fn main() {}
| |____________^
error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
--> $DIR/reveal_local.rs:5:12
|
LL | type Foo = impl Debug;
| ^^^^^^^^^^
|
note: ...which requires type-checking `not_gooder`...
--> $DIR/reveal_local.rs:17:1
|
LL | fn not_gooder() {
| ^^^^^^^^^^^^^^^
= note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
--> $DIR/reveal_local.rs:1:1
|
LL | / #![feature(type_alias_impl_trait)]
LL | |
LL | | use std::fmt::Debug;
LL | |
... |
LL | |
LL | | fn main() {}
| |____________^
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0391`.