Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,16 @@ where
// this is the defining scope, and otherwise treat it as rigid.
// However, in `ErasedNotcoherence` we *always* treat it as rigid.
// This is the same as other modes if def_id is None, but wrong if we do have a DefId.
// So, if we have one, we register in the EvalCtxt that we may need that defid.
// We might then decide to rerun in the correct typing mode.
if let Some(def_id) = def_id.as_local() {
self.opaque_accesses.rerun_if_opaque_in_opaque_type_storage(
RerunReason::NormalizeOpaqueType,
def_id,
)?;
// Thus we should rerun if the opaque is in the defining scope. And we should do
// so immediately, otherwise we might continue evaluating with rigid opaques that
// should be revealed and trigger query cycle when leaking it for auto trait.
// See `tests/ui/traits/next-solver/normalize/always-rerun-normalizing-opaques.rs`.
//
// FIXME: verify that we can get away with not rerunning immediately when
// normalizing foreign opaques. Currently we don't do so because that would greatly
// worsen the compilation time of `wg-grammar`.
if def_id.as_local().is_some() {
match self.opaque_accesses.rerun_always(RerunReason::NormalizeOpaqueType)? {}
} else {
self.opaque_accesses
.rerun_if_in_post_analysis(RerunReason::NormalizeOpaqueTypeRemoteCrate)?;
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,6 @@ where
goal.predicate.self_ty().kind()
{
debug_assert!(is_rigid == ty::IsRigid::Yes);
if ecx.opaque_accesses.might_rerun() {
match ecx.opaque_accesses.rerun_always(RerunReason::AutoTraitLeakage)? {}
}

for item_bound in cx.item_self_bounds(def_id.into()).skip_binder() {
if item_bound
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_type_ir/src/infer_ctxt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ pub enum TypingMode<I: Interner, S: TypingModeErasedStatus = MayBeErased> {
/// we bail out, setting a field on `EvalCtxt` that indicates the canonicalization must be
/// rerun in the original typing mode.
Comment thread
adwinwhite marked this conversation as resolved.
///
/// Specifically, we always reveal auto traits for rigid aliases and thus we don't allow
/// incorrectly marked rigid local opaques. We ensure this by immediately bailing out
/// when normalizing local opaques.
///
/// `TypingMode::Coherence` is not replaced by this and is always kept as-is.
ErasedNotCoherence(S),
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_type_ir/src/ty_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ impl<I: Interner> AliasTyKind<I> {
/// if the param env is the same, e.g., `Typeck/PostTypeckUntilBorrowck` and
/// `PostAnalysis/Codegen`.
///
/// We always reveal auto traits for rigid aliases and this can cause query cycle in
/// `TypingMode::ErasedNotCoherence`. Thus we don't allow incorrectly marked rigid local
/// opaques. We achieve this by immediately bailing out when normalizing local opaques.
///
/// FIXME(#155345): Alias handling is currently still in flux for the new trait
/// solver and this is currently somewhat messy. Please reach out on
/// #t-types/trait-system-refactor-initiative if you encounter this and it isn't
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//@ edition: 2024
//@ compile-flags: -Znext-solver
//@ check-pass

// Previously we update the rerun flag when we normalize opaques and don't immedidately bail.
// We normalize goals when adding them which is separate from their evaluation.
// So we don't have the `might_rerun` flag when evaluating them.
// This leads to query cycle in code where we need to leak opaque types for auto traits.

fn is_send<T: Send>(_: T) {}

fn inner() -> impl Sized {
is_send(outer());
}

fn outer() -> impl Sized {
inner()
}

// From #135062 which was fixed but broken again.
async fn foo() {
is_send(bar())
}

async fn bar() {
foo().await;
}

fn main() {}
Loading