mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #153581 - nnethercote:rm-cycle_stash, r=oli-obk
Simplify `type_of_opaque`. There is a bunch of complexity supporting the "cannot check whether the hidden type of opaque type satisfies auto traits" error that shows up in `tests/ui/impl-trait/auto-trait-leak.rs`. This is an obscure error that shows up in a single test. If we are willing to downgrade that error message to a cycle error, we can do the following. - Simplify the `type_of_opaque` return value. - Remove the `cycle_stash` query modifier. - Remove the `CyclePlaceholder` type. - Remove the `SelectionError::OpaqueTypeAutoTraitLeakageUnknown` variant. - Remove a `FromCycleError` impl. - Remove `report_opaque_type_auto_trait_leakage`. - Remove the `StashKey::Cycle` variant. - Remove the `CycleErrorHandling::Stash` variant. That's a lot! I think this is a worthwhile trade-off. r? @oli-obk
This commit is contained in:
@@ -371,8 +371,6 @@ pub enum StashKey {
|
||||
MaybeFruTypo,
|
||||
CallAssocMethod,
|
||||
AssociatedTypeSuggestion,
|
||||
/// Query cycle detected, stashing in favor of a better error.
|
||||
Cycle,
|
||||
UndeterminedMacroResolution,
|
||||
/// Used by `Parser::maybe_recover_trailing_expr`
|
||||
ExprInPat,
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::VisitorExt;
|
||||
use rustc_hir::{self as hir, AmbigArg, HirId};
|
||||
use rustc_middle::query::plumbing::CyclePlaceholder;
|
||||
use rustc_middle::ty::print::with_forced_trimmed_paths;
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_middle::ty::{self, DefiningScopeKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
||||
@@ -183,10 +182,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
|
||||
}
|
||||
},
|
||||
|
||||
Node::OpaqueTy(..) => tcx.type_of_opaque(def_id).map_or_else(
|
||||
|CyclePlaceholder(guar)| Ty::new_error(tcx, guar),
|
||||
|ty| ty.instantiate_identity(),
|
||||
),
|
||||
Node::OpaqueTy(..) => tcx.type_of_opaque(def_id).instantiate_identity(),
|
||||
|
||||
Node::ForeignItem(foreign_item) => match foreign_item.kind {
|
||||
ForeignItemKind::Fn(..) => {
|
||||
@@ -249,12 +245,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn type_of_opaque(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: DefId,
|
||||
) -> Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
|
||||
pub(super) fn type_of_opaque(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<'_, Ty<'_>> {
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
Ok(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
|
||||
match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
|
||||
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
|
||||
opaque::find_opaque_ty_constraints_for_tait(
|
||||
tcx,
|
||||
@@ -287,11 +280,11 @@ pub(super) fn type_of_opaque(
|
||||
DefiningScopeKind::MirBorrowck,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// Foreign opaque type will go through the foreign provider
|
||||
// and load the type from metadata.
|
||||
Ok(tcx.type_of(def_id))
|
||||
tcx.type_of(def_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,6 @@ struct QueryModifiers {
|
||||
arena_cache: Option<Ident>,
|
||||
cache_on_disk_if: Option<CacheOnDiskIf>,
|
||||
cycle_delay_bug: Option<Ident>,
|
||||
cycle_stash: Option<Ident>,
|
||||
depth_limit: Option<Ident>,
|
||||
desc: Desc,
|
||||
eval_always: Option<Ident>,
|
||||
@@ -159,7 +158,6 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
|
||||
let mut cache_on_disk_if = None;
|
||||
let mut desc = None;
|
||||
let mut cycle_delay_bug = None;
|
||||
let mut cycle_stash = None;
|
||||
let mut no_hash = None;
|
||||
let mut anon = None;
|
||||
let mut eval_always = None;
|
||||
@@ -195,8 +193,6 @@ macro_rules! try_insert {
|
||||
try_insert!(arena_cache = modifier);
|
||||
} else if modifier == "cycle_delay_bug" {
|
||||
try_insert!(cycle_delay_bug = modifier);
|
||||
} else if modifier == "cycle_stash" {
|
||||
try_insert!(cycle_stash = modifier);
|
||||
} else if modifier == "no_hash" {
|
||||
try_insert!(no_hash = modifier);
|
||||
} else if modifier == "anon" {
|
||||
@@ -221,7 +217,6 @@ macro_rules! try_insert {
|
||||
cache_on_disk_if,
|
||||
desc,
|
||||
cycle_delay_bug,
|
||||
cycle_stash,
|
||||
no_hash,
|
||||
anon,
|
||||
eval_always,
|
||||
@@ -257,7 +252,6 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream {
|
||||
arena_cache,
|
||||
cache_on_disk_if,
|
||||
cycle_delay_bug,
|
||||
cycle_stash,
|
||||
depth_limit,
|
||||
desc: _,
|
||||
eval_always,
|
||||
@@ -273,8 +267,6 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream {
|
||||
|
||||
let cycle_error_handling = if cycle_delay_bug.is_some() {
|
||||
quote! { DelayBug }
|
||||
} else if cycle_stash.is_some() {
|
||||
quote! { Stash }
|
||||
} else {
|
||||
quote! { Error }
|
||||
};
|
||||
@@ -411,7 +403,6 @@ macro_rules! doc_link {
|
||||
doc_link!(
|
||||
arena_cache,
|
||||
cycle_delay_bug,
|
||||
cycle_stash,
|
||||
no_hash,
|
||||
anon,
|
||||
eval_always,
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
//! - `cache_on_disk_if { ... }`: Cache the query result to disk if the provided block evaluates to
|
||||
//! true. The query key identifier is available for use within the block, as is `tcx`.
|
||||
//! - `cycle_delay_bug`: If a dependency cycle is detected, emit a delayed bug instead of aborting immediately.
|
||||
//! - `cycle_stash`: If a dependency cycle is detected, stash the error for later handling.
|
||||
//! - `no_hash`: Do not hash the query result for incremental compilation; just mark as dirty if recomputed.
|
||||
//! - `anon`: Make the query anonymous in the dependency graph (no dep node is created).
|
||||
//! - `eval_always`: Always evaluate the query, ignoring its dependencies and cached results.
|
||||
@@ -118,7 +117,6 @@
|
||||
CodegenUnit, CollectionMode, MonoItem, MonoItemPartitions, NormalizationErrorInMono,
|
||||
};
|
||||
use crate::query::describe_as_module;
|
||||
use crate::query::plumbing::CyclePlaceholder;
|
||||
use crate::traits::query::{
|
||||
CanonicalAliasGoal, CanonicalDropckOutlivesGoal, CanonicalImpliedOutlivesBoundsGoal,
|
||||
CanonicalMethodAutoderefStepsGoal, CanonicalPredicateGoal, CanonicalTypeOpAscribeUserTypeGoal,
|
||||
@@ -339,22 +337,16 @@
|
||||
feedable
|
||||
}
|
||||
|
||||
/// Returns the *hidden type* of the opaque type given by `DefId` unless a cycle occurred.
|
||||
///
|
||||
/// This is a specialized instance of [`Self::type_of`] that detects query cycles.
|
||||
/// Unless `CyclePlaceholder` needs to be handled separately, call [`Self::type_of`] instead.
|
||||
/// This is used to improve the error message in cases where revealing the hidden type
|
||||
/// for auto-trait leakage cycles.
|
||||
/// Returns the *hidden type* of the opaque type given by `DefId`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This query will panic if the given definition is not an opaque type.
|
||||
query type_of_opaque(key: DefId) -> Result<ty::EarlyBinder<'tcx, Ty<'tcx>>, CyclePlaceholder> {
|
||||
query type_of_opaque(key: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
|
||||
desc {
|
||||
"computing type of opaque `{path}`",
|
||||
path = tcx.def_path_str(key),
|
||||
}
|
||||
cycle_stash
|
||||
}
|
||||
query type_of_opaque_hir_typeck(key: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
|
||||
desc {
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
use crate::mir::interpret::EvalToValTreeResult;
|
||||
use crate::mir::mono::{MonoItem, NormalizationErrorInMono};
|
||||
use crate::query::plumbing::CyclePlaceholder;
|
||||
use crate::traits::solve;
|
||||
use crate::ty::adjustment::CoerceUnsizedInfo;
|
||||
use crate::ty::{self, Ty, TyCtxt};
|
||||
@@ -212,10 +211,6 @@ impl Erasable for Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop> {
|
||||
[u8; size_of::<Result<&'static ty::List<Ty<'static>>, ty::util::AlwaysRequiresDrop>>()];
|
||||
}
|
||||
|
||||
impl Erasable for Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
|
||||
type Storage = [u8; size_of::<Result<ty::EarlyBinder<'static, Ty<'_>>, CyclePlaceholder>>()];
|
||||
}
|
||||
|
||||
impl Erasable
|
||||
for Result<(&'_ [Spanned<MonoItem<'_>>], &'_ [Spanned<MonoItem<'_>>]), NormalizationErrorInMono>
|
||||
{
|
||||
|
||||
@@ -28,11 +28,6 @@
|
||||
/// A cycle error results in a delay_bug call
|
||||
pub(crate) struct cycle_delay_bug;
|
||||
|
||||
/// # `cycle_stash` query modifier
|
||||
///
|
||||
/// A cycle error results in a stashed cycle error that can be unstashed and canceled later
|
||||
pub(crate) struct cycle_stash;
|
||||
|
||||
/// # `depth_limit` query modifier
|
||||
///
|
||||
/// Whether the query has a call depth limit
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
use rustc_data_structures::sync::{AtomicU64, WorkerLocal};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::hir_id::OwnerId;
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
pub use sealed::IntoQueryParam;
|
||||
|
||||
@@ -58,7 +57,6 @@ pub enum ActiveKeyStatus<'tcx> {
|
||||
pub enum CycleErrorHandling {
|
||||
Error,
|
||||
DelayBug,
|
||||
Stash,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -651,9 +649,6 @@ fn into_query_param(self) -> LocalDefId {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, HashStable)]
|
||||
pub struct CyclePlaceholder(pub ErrorGuaranteed);
|
||||
|
||||
#[cold]
|
||||
pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
|
||||
bug!(
|
||||
|
||||
@@ -633,10 +633,6 @@ pub enum SelectionError<'tcx> {
|
||||
NotConstEvaluatable(NotConstEvaluatable),
|
||||
/// Exceeded the recursion depth during type projection.
|
||||
Overflow(OverflowError),
|
||||
/// 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),
|
||||
/// Error for a `ConstArgHasType` goal
|
||||
ConstArgHasWrongType { ct: ty::Const<'tcx>, ct_ty: Ty<'tcx>, expected_ty: Ty<'tcx> },
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_data_structures::sync::{DynSend, DynSync};
|
||||
use rustc_data_structures::{outline, sharded, sync};
|
||||
use rustc_errors::{FatalError, StashKey};
|
||||
use rustc_errors::FatalError;
|
||||
use rustc_middle::dep_graph::{DepGraphData, DepNodeKey, SerializedDepNodeIndex};
|
||||
use rustc_middle::query::plumbing::QueryVTable;
|
||||
use rustc_middle::query::{
|
||||
@@ -110,16 +110,6 @@ fn mk_cycle<'tcx, C: QueryCache>(
|
||||
let guar = error.delay_as_bug();
|
||||
(query.value_from_cycle_error)(tcx, cycle_error, guar)
|
||||
}
|
||||
CycleErrorHandling::Stash => {
|
||||
let guar = if let Some(root) = cycle_error.cycle.first()
|
||||
&& let Some(span) = root.frame.info.span
|
||||
{
|
||||
error.stash(span, StashKey::Cycle).unwrap()
|
||||
} else {
|
||||
error.emit()
|
||||
};
|
||||
(query.value_from_cycle_error)(tcx, cycle_error, guar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
use rustc_middle::queries::QueryVTables;
|
||||
use rustc_middle::query::CycleError;
|
||||
use rustc_middle::query::erase::erase_val;
|
||||
use rustc_middle::query::plumbing::CyclePlaceholder;
|
||||
use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
@@ -31,9 +30,6 @@ pub(crate) fn specialize_query_vtables<'tcx>(vtables: &mut QueryVTables<'tcx>) {
|
||||
vtables.erase_and_anonymize_regions_ty.value_from_cycle_error =
|
||||
|tcx, _, guar| erase_val(Ty::new_error(tcx, guar));
|
||||
|
||||
vtables.type_of_opaque.value_from_cycle_error =
|
||||
|_, _, guar| erase_val(Err(CyclePlaceholder(guar)));
|
||||
|
||||
vtables.fn_sig.value_from_cycle_error = |tcx, cycle, guar| erase_val(fn_sig(tcx, cycle, guar));
|
||||
|
||||
vtables.check_representability.value_from_cycle_error =
|
||||
|
||||
@@ -756,11 +756,6 @@ pub fn report_selection_error(
|
||||
}
|
||||
}
|
||||
|
||||
SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id) => return self.report_opaque_type_auto_trait_leakage(
|
||||
&obligation,
|
||||
def_id,
|
||||
),
|
||||
|
||||
SelectionError::TraitDynIncompatible(did) => {
|
||||
let violations = self.tcx.dyn_compatibility_violations(did);
|
||||
report_dyn_incompatibility(self.tcx, span, None, did, violations)
|
||||
@@ -3331,34 +3326,6 @@ fn report_cyclic_signature_error(
|
||||
)
|
||||
}
|
||||
|
||||
fn report_opaque_type_auto_trait_leakage(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
def_id: DefId,
|
||||
) -> ErrorGuaranteed {
|
||||
let name = match self.tcx.local_opaque_ty_origin(def_id.expect_local()) {
|
||||
hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } => {
|
||||
"opaque type".to_string()
|
||||
}
|
||||
hir::OpaqueTyOrigin::TyAlias { .. } => {
|
||||
format!("`{}`", self.tcx.def_path_debug_str(def_id))
|
||||
}
|
||||
};
|
||||
let mut err = self.dcx().struct_span_err(
|
||||
obligation.cause.span,
|
||||
format!("cannot check whether the hidden type of {name} satisfies auto traits"),
|
||||
);
|
||||
|
||||
err.note(
|
||||
"fetching the hidden types of an opaque inside of the defining scope is not supported. \
|
||||
You can try moving the opaque type and the item that actually registers a hidden type into a new submodule",
|
||||
);
|
||||
err.span_note(self.tcx.def_span(def_id), "opaque type is declared here");
|
||||
|
||||
self.note_obligation_cause(&mut err, &obligation);
|
||||
self.dcx().try_steal_replace_and_emit_err(self.tcx.def_span(def_id), StashKey::Cycle, err)
|
||||
}
|
||||
|
||||
fn report_signature_mismatch_error(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
|
||||
@@ -2404,15 +2404,11 @@ fn constituent_types_for_auto_trait(
|
||||
// We can resolve the opaque type to its hidden type,
|
||||
// which enforces a DAG between the functions requiring
|
||||
// the auto trait bounds in question.
|
||||
match self.tcx().type_of_opaque(def_id) {
|
||||
Ok(ty) => ty::Binder::dummy(AutoImplConstituents {
|
||||
types: vec![ty.instantiate(self.tcx(), args)],
|
||||
assumptions: vec![],
|
||||
}),
|
||||
Err(_) => {
|
||||
return Err(SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id));
|
||||
}
|
||||
}
|
||||
let ty = self.tcx().type_of_opaque(def_id);
|
||||
ty::Binder::dummy(AutoImplConstituents {
|
||||
types: vec![ty.instantiate(self.tcx(), args)],
|
||||
assumptions: vec![],
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -8,7 +8,7 @@ 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 {
|
||||
fn cycle1() -> impl Clone { //~ ERROR: cycle detected
|
||||
send(cycle2().clone());
|
||||
|
||||
Rc::new(Cell::new(5))
|
||||
@@ -16,7 +16,6 @@ fn cycle1() -> impl Clone {
|
||||
|
||||
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"))
|
||||
}
|
||||
|
||||
@@ -1,22 +1,84 @@
|
||||
error: cannot check whether the hidden type of opaque type satisfies auto traits
|
||||
--> $DIR/auto-trait-leak.rs:18:10
|
||||
|
|
||||
LL | send(cycle1().clone());
|
||||
| ---- ^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
|
||||
note: opaque type is declared here
|
||||
error[E0391]: cycle detected when computing type of opaque `cycle1::{opaque#0}`
|
||||
--> $DIR/auto-trait-leak.rs:11:16
|
||||
|
|
||||
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`
|
||||
note: ...which requires borrow-checking `cycle1`...
|
||||
--> $DIR/auto-trait-leak.rs:11:1
|
||||
|
|
||||
LL | fn cycle1() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires promoting constants in MIR for `cycle1`...
|
||||
--> $DIR/auto-trait-leak.rs:11:1
|
||||
|
|
||||
LL | fn cycle1() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires checking if `cycle1` contains FFI-unwind calls...
|
||||
--> $DIR/auto-trait-leak.rs:11:1
|
||||
|
|
||||
LL | fn cycle1() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires building MIR for `cycle1`...
|
||||
--> $DIR/auto-trait-leak.rs:11:1
|
||||
|
|
||||
LL | fn cycle1() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires match-checking `cycle1`...
|
||||
--> $DIR/auto-trait-leak.rs:11:1
|
||||
|
|
||||
LL | fn cycle1() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires type-checking `cycle1`...
|
||||
--> $DIR/auto-trait-leak.rs:12:5
|
||||
|
|
||||
LL | send(cycle2().clone());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which requires evaluating trait selection obligation `cycle2::{opaque#0}: core::marker::Send`...
|
||||
note: ...which requires computing type of opaque `cycle2::{opaque#0}`...
|
||||
--> $DIR/auto-trait-leak.rs:17:16
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^
|
||||
note: ...which requires borrow-checking `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:17:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires promoting constants in MIR for `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:17:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires checking if `cycle2` contains FFI-unwind calls...
|
||||
--> $DIR/auto-trait-leak.rs:17:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires building MIR for `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:17:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires match-checking `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:17:1
|
||||
|
|
||||
LL | fn cycle2() -> impl Clone {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires type-checking `cycle2`...
|
||||
--> $DIR/auto-trait-leak.rs:18:5
|
||||
|
|
||||
LL | send(cycle1().clone());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which requires evaluating trait selection obligation `cycle1::{opaque#0}: core::marker::Send`...
|
||||
= note: ...which again requires computing type of opaque `cycle1::{opaque#0}`, completing the cycle
|
||||
note: cycle used when computing type of `cycle1::{opaque#0}`
|
||||
--> $DIR/auto-trait-leak.rs:11:16
|
||||
|
|
||||
LL | fn cycle1() -> impl Clone {
|
||||
| ^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0391`.
|
||||
|
||||
@@ -11,7 +11,6 @@ fn foo() -> Bar
|
||||
Bar: Send,
|
||||
{
|
||||
[0; 1 + 2]
|
||||
//~^ ERROR: type annotations needed: cannot satisfy `Bar: Send`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
error[E0283]: type annotations needed: cannot satisfy `Bar: Send`
|
||||
--> $DIR/in-where-clause.rs:13:9
|
||||
|
|
||||
LL | [0; 1 + 2]
|
||||
| ^^^^^
|
||||
|
|
||||
= note: cannot satisfy `Bar: Send`
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/in-where-clause.rs:11:10
|
||||
|
|
||||
LL | fn foo() -> Bar
|
||||
| --- required by a bound in this function
|
||||
LL | where
|
||||
LL | Bar: Send,
|
||||
| ^^^^ required by this bound in `foo`
|
||||
|
||||
error[E0391]: cycle detected when computing type of opaque `Bar::{opaque#0}`
|
||||
--> $DIR/in-where-clause.rs:5:12
|
||||
|
|
||||
@@ -77,7 +61,6 @@ LL | type Bar = impl Sized;
|
||||
= note: cycle used when evaluating trait selection obligation `Bar: core::marker::Send`
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Some errors have detailed explanations: E0283, E0391.
|
||||
For more information about an error, try `rustc --explain E0283`.
|
||||
For more information about this error, try `rustc --explain E0391`.
|
||||
|
||||
Reference in New Issue
Block a user