Skip to content

Commit

Permalink
Don't call type_of on TAIT in defining scope in new solver
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jul 6, 2023
1 parent 87c8c83 commit 388c230
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 101 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
}
}

pub(super) fn can_define_opaque_ty(&mut self, def_id: LocalDefId) -> bool {
pub(super) fn can_define_opaque_ty(&self, def_id: LocalDefId) -> bool {
self.infcx.opaque_type_origin(def_id).is_some()
}

Expand Down
27 changes: 27 additions & 0 deletions compiler/rustc_trait_selection/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rustc_hir::{LangItem, Movability};
use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::util::supertraits;
use rustc_middle::traits::solve::{CanonicalResponse, Certainty, Goal, QueryResult};
use rustc_middle::traits::Reveal;
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, TreatProjections};
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
use rustc_middle::ty::{TraitPredicate, TypeVisitableExt};
Expand Down Expand Up @@ -118,6 +119,32 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
return result;
}

// Don't call `type_of` on a local TAIT that's in the defining scope,
// since that may require calling `typeck` on the same item we're
// currently type checking, which will result in a fatal cycle that
// ideally we want to avoid, since we can make progress on this goal
// via an alias bound or a locally-inferred hidden type instead.
//
// Also, don't call `type_of` on a TAIT in `Reveal::All` mode, since
// we already normalize the self type in
// `assemble_candidates_after_normalizing_self_ty`, and we'd
// just be registering an identical candidate here.
//
// Returning `Err(NoSolution)` here is ok in `SolverMode::Coherence`
// since we'll always be registering an ambiguous candidate in
// `assemble_candidates_after_normalizing_self_ty` due to normalizing
// the TAIT.
if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() {
if matches!(goal.param_env.reveal(), Reveal::All)
|| opaque_ty
.def_id
.as_local()
.is_some_and(|def_id| ecx.can_define_opaque_ty(def_id))
{
return Err(NoSolution);
}
}

ecx.probe_and_evaluate_goal_for_constituent_tys(
goal,
structural_traits::instantiate_constituent_tys_for_auto_trait,
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/traits/new-solver/dont-remap-tait-substs.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// compile-flags: -Ztrait-solver=next
// known-bug: #112825
// check-pass

// Makes sure we don't prepopulate the MIR typeck of `define`
// with `Foo<T, U> = T`, but instead, `Foo<B, A> = B`, so that
Expand Down
99 changes: 0 additions & 99 deletions tests/ui/traits/new-solver/dont-remap-tait-substs.stderr

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error[E0283]: type annotations needed: cannot satisfy `Foo: Send`
--> $DIR/dont-type_of-tait-in-defining-scope.rs:16:5
|
LL | needs_send::<Foo>();
| ^^^^^^^^^^^^^^^^^
|
= note: cannot satisfy `Foo: Send`
note: required by a bound in `needs_send`
--> $DIR/dont-type_of-tait-in-defining-scope.rs:13:18
|
LL | fn needs_send<T: Send>() {}
| ^^^^ required by this bound in `needs_send`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0283`.
22 changes: 22 additions & 0 deletions tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// revisions: is_send not_send
// compile-flags: -Ztrait-solver=next
//[is_send] check-pass

#![feature(type_alias_impl_trait)]

#[cfg(is_send)]
type Foo = impl Send;

#[cfg(not_send)]
type Foo = impl Sized;

fn needs_send<T: Send>() {}

fn test() {
needs_send::<Foo>();
//[not_send]~^ ERROR type annotations needed: cannot satisfy `Foo: Send`
}

fn main() {
let _: Foo = ();
}

0 comments on commit 388c230

Please sign in to comment.