Rollup merge of #113320 - oli-obk:eval_obligation_query, r=petrochenkov,BoxyUwU

Add some extra information to opaque type cycle errors

Plus a bunch of cleanups.

This should help users debug query cycles due to auto trait checking. We'll probably want to fix cycle errors in most (or all?) cases by looking at the current item's hidden types (new solver does this), and by delaying the auto trait checks to after typeck.
This commit is contained in:
Michael Goulet 2023-07-05 08:45:44 -07:00 committed by GitHub
commit 0334b64cbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 443 additions and 55 deletions

View File

@ -588,6 +588,10 @@ pub enum SelectionError<'tcx> {
/// Signaling that an error has already been emitted, to avoid
/// multiple errors being shown.
ErrorReporting,
/// Computing an opaque type's hidden type caused an error (e.g. a cycle error).
/// We can thus not know whether the hidden type implements an auto trait, so
/// we should not presume anything about it.
OpaqueTypeAutoTraitLeakageUnknown(DefId),
}
#[derive(Clone, Debug, TypeVisitable, Lift)]

View File

@ -126,18 +126,13 @@ struct JobOwner<'tcx, K, D: DepKind>
#[cold]
#[inline(never)]
fn mk_cycle<Q, Qcx>(
query: Q,
qcx: Qcx,
cycle_error: CycleError<Qcx::DepKind>,
handler: HandleCycleError,
) -> Q::Value
fn mk_cycle<Q, Qcx>(query: Q, qcx: Qcx, cycle_error: CycleError<Qcx::DepKind>) -> Q::Value
where
Q: QueryConfig<Qcx>,
Qcx: QueryContext,
{
let error = report_cycle(qcx.dep_context().sess(), &cycle_error);
handle_cycle_error(query, qcx, &cycle_error, error, handler)
handle_cycle_error(query, qcx, &cycle_error, error)
}
fn handle_cycle_error<Q, Qcx>(
@ -145,14 +140,13 @@ fn handle_cycle_error<Q, Qcx>(
qcx: Qcx,
cycle_error: &CycleError<Qcx::DepKind>,
mut error: DiagnosticBuilder<'_, ErrorGuaranteed>,
handler: HandleCycleError,
) -> Q::Value
where
Q: QueryConfig<Qcx>,
Qcx: QueryContext,
{
use HandleCycleError::*;
match handler {
match query.handle_cycle_error() {
Error => {
error.emit();
query.value_from_cycle_error(*qcx.dep_context(), &cycle_error.cycle)
@ -277,7 +271,7 @@ fn cycle_error<Q, Qcx>(
&qcx.current_query_job(),
span,
);
(mk_cycle(query, qcx, error, query.handle_cycle_error()), None)
(mk_cycle(query, qcx, error), None)
}
#[inline(always)]
@ -314,7 +308,7 @@ fn wait_for_query<Q, Qcx>(
(v, Some(index))
}
Err(cycle) => (mk_cycle(query, qcx, cycle, query.handle_cycle_error()), None),
Err(cycle) => (mk_cycle(query, qcx, cycle), None),
}
}

View File

@ -6,10 +6,13 @@ pub trait Value<Tcx: DepContext, D: DepKind>: Sized {
}
impl<Tcx: DepContext, T, D: DepKind> Value<Tcx, D> for T {
default fn from_cycle_error(tcx: Tcx, _: &[QueryInfo<D>]) -> T {
default fn from_cycle_error(tcx: Tcx, cycle: &[QueryInfo<D>]) -> T {
tcx.sess().abort_if_errors();
// Ideally we would use `bug!` here. But bug! is only defined in rustc_middle, and it's
// non-trivial to define it earlier.
panic!("Value::from_cycle_error called without errors");
panic!(
"<{} as Value>::from_cycle_error called without errors: {cycle:#?}",
std::any::type_name::<T>()
);
}
}

View File

@ -30,7 +30,7 @@
use rustc_infer::infer::{InferOk, TypeTrace};
use rustc_middle::traits::select::OverflowError;
use rustc_middle::traits::solve::Goal;
use rustc_middle::traits::SelectionOutputTypeParameterMismatch;
use rustc_middle::traits::{DefiningAnchor, SelectionOutputTypeParameterMismatch};
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
@ -1152,6 +1152,11 @@ fn report_selection_error(
}
}
SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id) => self.report_opaque_type_auto_trait_leakage(
&obligation,
def_id,
),
TraitNotObjectSafe(did) => {
let violations = self.tcx.object_safety_violations(did);
report_object_safety_error(self.tcx, span, did, violations)
@ -1170,16 +1175,10 @@ fn report_selection_error(
}
// Already reported in the query.
SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(_)) => {
// FIXME(eddyb) remove this once `ErrorGuaranteed` becomes a proof token.
self.tcx.sess.delay_span_bug(span, "`ErrorGuaranteed` without an error");
return;
}
SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(_)) |
// Already reported.
Overflow(OverflowError::Error(_)) => {
self.tcx.sess.delay_span_bug(span, "`OverflowError` has been reported");
return;
}
Overflow(OverflowError::Error(_)) => return,
Overflow(_) => {
bug!("overflow should be handled before the `report_selection_error` path");
}
@ -1471,6 +1470,12 @@ fn report_type_parameter_mismatch_cyclic_type_error(
terr: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
fn report_opaque_type_auto_trait_leakage(
&self,
obligation: &PredicateObligation<'tcx>,
def_id: DefId,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
fn report_type_parameter_mismatch_error(
&self,
obligation: &PredicateObligation<'tcx>,
@ -3192,6 +3197,39 @@ fn report_type_parameter_mismatch_cyclic_type_error(
)
}
fn report_opaque_type_auto_trait_leakage(
&self,
obligation: &PredicateObligation<'tcx>,
def_id: DefId,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let name = match self.tcx.opaque_type_origin(def_id.expect_local()) {
hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => {
format!("opaque type")
}
hir::OpaqueTyOrigin::TyAlias { .. } => {
format!("`{}`", self.tcx.def_path_debug_str(def_id))
}
};
let mut err = self.tcx.sess.struct_span_err(
obligation.cause.span,
format!("cannot check whether the hidden type of {name} satisfies auto traits"),
);
err.span_note(self.tcx.def_span(def_id), "opaque type is declared here");
match self.defining_use_anchor {
DefiningAnchor::Bubble | DefiningAnchor::Error => {}
DefiningAnchor::Bind(bind) => {
err.span_note(
self.tcx.def_ident_span(bind).unwrap_or_else(|| self.tcx.def_span(bind)),
"this item depends on auto traits of the hidden type, \
but may also be registering the hidden type. \
This is not supported right now. \
You can try moving the opaque type and the item that actually registers a hidden type into a new submodule".to_string(),
);
}
};
err
}
fn report_type_parameter_mismatch_error(
&self,
obligation: &PredicateObligation<'tcx>,

View File

@ -67,7 +67,7 @@ pub(super) fn confirm_candidate(
}
AutoImplCandidate => {
let data = self.confirm_auto_impl_candidate(obligation);
let data = self.confirm_auto_impl_candidate(obligation)?;
ImplSource::Builtin(data)
}
@ -376,12 +376,12 @@ fn flatten_answer_tree<'tcx>(
fn confirm_auto_impl_candidate(
&mut self,
obligation: &TraitObligation<'tcx>,
) -> Vec<PredicateObligation<'tcx>> {
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
debug!(?obligation, "confirm_auto_impl_candidate");
let self_ty = self.infcx.shallow_resolve(obligation.predicate.self_ty());
let types = self.constituent_types_for_ty(self_ty);
self.vtable_auto_impl(obligation, obligation.predicate.def_id(), types)
let types = self.constituent_types_for_ty(self_ty)?;
Ok(self.vtable_auto_impl(obligation, obligation.predicate.def_id(), types))
}
/// See `confirm_auto_impl_candidate`.

View File

@ -2271,8 +2271,8 @@ fn copy_clone_conditions(
fn constituent_types_for_ty(
&self,
t: ty::Binder<'tcx, Ty<'tcx>>,
) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
match *t.skip_binder().kind() {
) -> Result<ty::Binder<'tcx, Vec<Ty<'tcx>>>, SelectionError<'tcx>> {
Ok(match *t.skip_binder().kind() {
ty::Uint(_)
| ty::Int(_)
| ty::Bool
@ -2336,12 +2336,16 @@ fn constituent_types_for_ty(
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
let ty = self.tcx().type_of(def_id);
if ty.skip_binder().references_error() {
return Err(SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id));
}
// We can resolve the `impl Trait` to its concrete type,
// which enforces a DAG between the functions requiring
// the auto trait bounds in question.
t.rebind(vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)])
t.rebind(vec![ty.subst(self.tcx(), substs)])
}
}
})
}
fn collect_predicates_for_types(

View File

@ -24,5 +24,6 @@ async fn cb() {
type F = impl Future;
// Check that statics are inhabited computes they layout.
static POOL: Task<F> = Task::new();
//~^ ERROR: cannot check whether the hidden type of `layout_error[b009]::main::F::{opaque#0}` satisfies auto traits
Task::spawn(&POOL, || cb());
}

View File

@ -4,6 +4,24 @@ error[E0425]: cannot find value `Foo` in this scope
LL | let a = Foo;
| ^^^ not found in this scope
error: aborting due to previous error
error: cannot check whether the hidden type of `layout_error[b009]::main::F::{opaque#0}` satisfies auto traits
--> $DIR/layout-error.rs:26:18
|
LL | static POOL: Task<F> = Task::new();
| ^^^^^^^
|
note: opaque type is declared here
--> $DIR/layout-error.rs:24:14
|
LL | type F = impl Future;
| ^^^^^^^^^^^
note: required because it appears within the type `Task<F>`
--> $DIR/layout-error.rs:9:12
|
LL | pub struct Task<F: Future>(F);
| ^^^^
= note: shared static variables must have a type that implements `Sync`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0425`.

View File

@ -3,21 +3,23 @@
fn send<T: Send>(_: T) {}
fn main() {
}
fn main() {}
// Cycles should work as the deferred obligations are
// independently resolved and only require the concrete
// return type, which can't depend on the obligation.
fn cycle1() -> impl Clone {
//~^ ERROR cycle detected
//~| ERROR cycle detected
send(cycle2().clone());
//~^ ERROR: cannot check whether the hidden type of opaque type satisfies auto traits
Rc::new(Cell::new(5))
}
fn cycle2() -> impl Clone {
send(cycle1().clone());
//~^ ERROR: cannot check whether the hidden type of opaque type satisfies auto traits
Rc::new(String::from("foo"))
}

View File

@ -1,5 +1,5 @@
error[E0391]: cycle detected when computing type of `cycle1::{opaque#0}`
--> $DIR/auto-trait-leak.rs:12:16
--> $DIR/auto-trait-leak.rs:11:16
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^
@ -11,12 +11,12 @@ LL | send(cycle2().clone());
| ^^^^
= note: ...which requires evaluating trait selection obligation `cycle2::{opaque#0}: core::marker::Send`...
note: ...which requires computing type of `cycle2::{opaque#0}`...
--> $DIR/auto-trait-leak.rs:19:16
--> $DIR/auto-trait-leak.rs:20:16
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^
note: ...which requires type-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:20:5
--> $DIR/auto-trait-leak.rs:21:5
|
LL | send(cycle1().clone());
| ^^^^
@ -34,6 +34,89 @@ LL | | Rc::new(String::from("foo"))
LL | | }
| |_^
error: aborting due to previous error
error[E0391]: cycle detected when computing type of `cycle1::{opaque#0}`
--> $DIR/auto-trait-leak.rs:11:16
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^
|
note: ...which requires type-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:14:5
|
LL | send(cycle2().clone());
| ^^^^
= note: ...which requires evaluating trait selection obligation `cycle2::{opaque#0}: core::marker::Send`...
note: ...which requires computing type of `cycle2::{opaque#0}`...
--> $DIR/auto-trait-leak.rs:20:16
|
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: cannot check whether the hidden type of opaque type satisfies auto traits
--> $DIR/auto-trait-leak.rs:21:10
|
LL | send(cycle1().clone());
| ---- ^^^^^^^^^^^^^^^^
| |
| required by a bound introduced by this call
|
note: opaque type is declared here
--> $DIR/auto-trait-leak.rs:11:16
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^
note: this item depends on auto traits of the hidden type, but may also be registering the hidden type. This is not supported right now. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
--> $DIR/auto-trait-leak.rs:20:4
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^
note: required by a bound in `send`
--> $DIR/auto-trait-leak.rs:4:12
|
LL | fn send<T: Send>(_: T) {}
| ^^^^ required by this bound in `send`
error: cannot check whether the hidden type of opaque type satisfies auto traits
--> $DIR/auto-trait-leak.rs:14:10
|
LL | send(cycle2().clone());
| ---- ^^^^^^^^^^^^^^^^
| |
| required by a bound introduced by this call
|
note: opaque type is declared here
--> $DIR/auto-trait-leak.rs:20:16
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^
note: this item depends on auto traits of the hidden type, but may also be registering the hidden type. This is not supported right now. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
--> $DIR/auto-trait-leak.rs:11:4
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^
note: required by a bound in `send`
--> $DIR/auto-trait-leak.rs:4:12
|
LL | fn send<T: Send>(_: T) {}
| ^^^^ required by this bound in `send`
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0391`.

View File

@ -24,6 +24,8 @@ async fn iceice<A, B>()
B: Send, // <- a second bound
{
normalize(broken_fut(), ());
//~^ ERROR: cannot check whether the hidden type of opaque type satisfies auto traits
//~| ERROR: cannot check whether the hidden type of opaque type satisfies auto traits
}
fn main() {}

View File

@ -4,6 +4,61 @@ error[E0425]: cannot find value `ident_error` in this scope
LL | ident_error;
| ^^^^^^^^^^^ not found in this scope
error: aborting due to previous error
error: cannot check whether the hidden type of opaque type satisfies auto traits
--> $DIR/issue-103181-2.rs:26:15
|
LL | normalize(broken_fut(), ());
| --------- ^^^^^^^^^^^^
| |
| required by a bound introduced by this call
|
note: opaque type is declared here
--> $DIR/issue-103181-2.rs:11:23
|
LL | async fn broken_fut() {
| ^
note: this item depends on auto traits of the hidden type, but may also be registering the hidden type. This is not supported right now. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
--> $DIR/issue-103181-2.rs:20:10
|
LL | async fn iceice<A, B>()
| ^^^^^^
note: required for `impl Future<Output = ()>` to implement `SendFuture`
--> $DIR/issue-103181-2.rs:7:17
|
LL | impl<Fut: Send> SendFuture for Fut {
| ---- ^^^^^^^^^^ ^^^
| |
| unsatisfied trait bound introduced here
note: required by a bound in `normalize`
--> $DIR/issue-103181-2.rs:18:19
|
LL | fn normalize<Fut: SendFuture>(_: Fut, _: Fut::Output) {}
| ^^^^^^^^^^ required by this bound in `normalize`
error: cannot check whether the hidden type of opaque type satisfies auto traits
--> $DIR/issue-103181-2.rs:26:5
|
LL | normalize(broken_fut(), ());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: opaque type is declared here
--> $DIR/issue-103181-2.rs:11:23
|
LL | async fn broken_fut() {
| ^
note: this item depends on auto traits of the hidden type, but may also be registering the hidden type. This is not supported right now. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
--> $DIR/issue-103181-2.rs:20:10
|
LL | async fn iceice<A, B>()
| ^^^^^^
note: required for `impl Future<Output = ()>` to implement `SendFuture`
--> $DIR/issue-103181-2.rs:7:17
|
LL | impl<Fut: Send> SendFuture for Fut {
| ---- ^^^^^^^^^^ ^^^
| |
| unsatisfied trait bound introduced here
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0425`.

View File

@ -4,8 +4,9 @@
// FIXME This should compile, but it currently doesn't
mod m {
type Foo = impl std::fmt::Debug;
pub 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
@ -13,6 +14,7 @@ pub fn foo() -> Foo {
pub fn bar() {
is_send(foo());
//~^ ERROR: cannot check whether the hidden type of `auto_trait_leakage3[211d]::m::Foo::{opaque#0}
}
fn is_send<T: Send>(_: T) {}

View File

@ -1,11 +1,11 @@
error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}`
--> $DIR/auto-trait-leakage3.rs:7:16
--> $DIR/auto-trait-leakage3.rs:7:20
|
LL | type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `m::bar`...
--> $DIR/auto-trait-leakage3.rs:15:9
--> $DIR/auto-trait-leakage3.rs:16:9
|
LL | is_send(foo());
| ^^^^^^^
@ -17,6 +17,48 @@ note: cycle used when checking item types in module `m`
LL | mod m {
| ^^^^^
error: aborting due to previous error
error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}`
--> $DIR/auto-trait-leakage3.rs:7:20
|
LL | pub 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: cannot check whether the hidden type of `auto_trait_leakage3[211d]::m::Foo::{opaque#0}` satisfies auto traits
--> $DIR/auto-trait-leakage3.rs:16:17
|
LL | is_send(foo());
| ------- ^^^^^
| |
| required by a bound introduced by this call
|
note: opaque type is declared here
--> $DIR/auto-trait-leakage3.rs:7:20
|
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
note: this item depends on auto traits of the hidden type, but may also be registering the hidden type. This is not supported right now. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
--> $DIR/auto-trait-leakage3.rs:15:12
|
LL | pub fn bar() {
| ^^^
note: required by a bound in `is_send`
--> $DIR/auto-trait-leakage3.rs:20:19
|
LL | fn is_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `is_send`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0391`.

View File

@ -2,8 +2,9 @@
#![allow(dead_code)]
mod m {
type Foo = impl std::fmt::Debug;
pub type Foo = impl std::fmt::Debug;
//~^ ERROR cycle detected
//~| ERROR cycle detected
// Cycle: error today, but it'd be nice if it eventually worked
@ -13,10 +14,11 @@ pub fn foo() -> Foo {
pub fn bar() {
is_send(foo()); // Today: error
//~^ ERROR: cannot check whether the hidden type of `inference_cycle[4ecc]::m::Foo::{opaque#0}` satisfies auto traits
}
fn baz() {
let f: Foo = 22_u32;
let f: Foo = ();
}
fn is_send<T: Send>(_: T) {}

View File

@ -1,11 +1,11 @@
error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}`
--> $DIR/inference-cycle.rs:5:16
--> $DIR/inference-cycle.rs:5:20
|
LL | type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `m::bar`...
--> $DIR/inference-cycle.rs:15:9
--> $DIR/inference-cycle.rs:16:9
|
LL | is_send(foo()); // Today: error
| ^^^^^^^
@ -17,6 +17,48 @@ note: cycle used when checking item types in module `m`
LL | mod m {
| ^^^^^
error: aborting due to previous error
error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}`
--> $DIR/inference-cycle.rs:5:20
|
LL | pub 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: cannot check whether the hidden type of `inference_cycle[4ecc]::m::Foo::{opaque#0}` satisfies auto traits
--> $DIR/inference-cycle.rs:16:17
|
LL | is_send(foo()); // Today: error
| ------- ^^^^^
| |
| required by a bound introduced by this call
|
note: opaque type is declared here
--> $DIR/inference-cycle.rs:5:20
|
LL | pub type Foo = impl std::fmt::Debug;
| ^^^^^^^^^^^^^^^^^^^^
note: this item depends on auto traits of the hidden type, but may also be registering the hidden type. This is not supported right now. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
--> $DIR/inference-cycle.rs:15:12
|
LL | pub fn bar() {
| ^^^
note: required by a bound in `is_send`
--> $DIR/inference-cycle.rs:24:19
|
LL | fn is_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `is_send`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0391`.

View File

@ -4,13 +4,16 @@
type Foo = impl Debug;
//~^ ERROR cycle detected
//~| ERROR cycle detected
//~| ERROR cycle detected
fn is_send<T: Send>() { }
fn is_send<T: Send>() {}
fn not_good() {
// Error: this function does not constrain `Foo` to any particular
// hidden type, so it cannot rely on `Send` being true.
is_send::<Foo>();
//~^ ERROR: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits
}
fn not_gooder() {
@ -20,6 +23,7 @@ fn not_gooder() {
// while we could know this from the hidden type, it would
// need extra roundabout logic to support it.
is_send::<Foo>();
//~^ ERROR: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits
}
fn main() {}

View File

@ -5,7 +5,7 @@ LL | type Foo = impl Debug;
| ^^^^^^^^^^
|
note: ...which requires type-checking `not_good`...
--> $DIR/reveal_local.rs:13:5
--> $DIR/reveal_local.rs:15:5
|
LL | is_send::<Foo>();
| ^^^^^^^^^^^^^^
@ -23,6 +23,98 @@ LL | |
LL | | fn main() {}
| |____________^
error: aborting due to previous error
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_good`...
--> $DIR/reveal_local.rs:12:1
|
LL | fn not_good() {
| ^^^^^^^^^^^^^
= 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: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits
--> $DIR/reveal_local.rs:15:15
|
LL | is_send::<Foo>();
| ^^^
|
note: opaque type is declared here
--> $DIR/reveal_local.rs:5:12
|
LL | type Foo = impl Debug;
| ^^^^^^^^^^
note: this item depends on auto traits of the hidden type, but may also be registering the hidden type. This is not supported right now. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
--> $DIR/reveal_local.rs:12:4
|
LL | fn not_good() {
| ^^^^^^^^
note: required by a bound in `is_send`
--> $DIR/reveal_local.rs:10:15
|
LL | fn is_send<T: Send>() {}
| ^^^^ required by this bound in `is_send`
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:19: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: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits
--> $DIR/reveal_local.rs:25:15
|
LL | is_send::<Foo>();
| ^^^
|
note: opaque type is declared here
--> $DIR/reveal_local.rs:5:12
|
LL | type Foo = impl Debug;
| ^^^^^^^^^^
note: this item depends on auto traits of the hidden type, but may also be registering the hidden type. This is not supported right now. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
--> $DIR/reveal_local.rs:19:4
|
LL | fn not_gooder() {
| ^^^^^^^^^^
note: required by a bound in `is_send`
--> $DIR/reveal_local.rs:10:15
|
LL | fn is_send<T: Send>() {}
| ^^^^ required by this bound in `is_send`
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0391`.