Don't call type_of on TAIT in defining scope in new solver
This commit is contained in:
parent
87c8c83ec7
commit
388c230cf7
6 changed files with 67 additions and 101 deletions
|
@ -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()
|
self.infcx.opaque_type_origin(def_id).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ use rustc_hir::{LangItem, Movability};
|
||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
use rustc_infer::traits::util::supertraits;
|
use rustc_infer::traits::util::supertraits;
|
||||||
use rustc_middle::traits::solve::{CanonicalResponse, Certainty, Goal, QueryResult};
|
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::fast_reject::{DeepRejectCtxt, TreatParams, TreatProjections};
|
||||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
|
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
|
||||||
use rustc_middle::ty::{TraitPredicate, TypeVisitableExt};
|
use rustc_middle::ty::{TraitPredicate, TypeVisitableExt};
|
||||||
|
@ -118,6 +119,32 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||||
return result;
|
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(
|
ecx.probe_and_evaluate_goal_for_constituent_tys(
|
||||||
goal,
|
goal,
|
||||||
structural_traits::instantiate_constituent_tys_for_auto_trait,
|
structural_traits::instantiate_constituent_tys_for_auto_trait,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// compile-flags: -Ztrait-solver=next
|
// compile-flags: -Ztrait-solver=next
|
||||||
// known-bug: #112825
|
// check-pass
|
||||||
|
|
||||||
// Makes sure we don't prepopulate the MIR typeck of `define`
|
// Makes sure we don't prepopulate the MIR typeck of `define`
|
||||||
// with `Foo<T, U> = T`, but instead, `Foo<B, A> = B`, so that
|
// with `Foo<T, U> = T`, but instead, `Foo<B, A> = B`, so that
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
|
|
||||||
--> $DIR/dont-remap-tait-substs.rs:10:24
|
|
||||||
|
|
|
||||||
LL | type Foo<T: Send, U> = impl NeedsSend<T>;
|
|
||||||
| ^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
note: ...which requires borrow-checking `define`...
|
|
||||||
--> $DIR/dont-remap-tait-substs.rs:15:1
|
|
||||||
|
|
|
||||||
LL | fn define<A, B: Send>(a: A, b: B) {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= 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/dont-remap-tait-substs.rs:8:1
|
|
||||||
|
|
|
||||||
LL | / #![feature(type_alias_impl_trait)]
|
|
||||||
LL | |
|
|
||||||
LL | | type Foo<T: Send, U> = impl NeedsSend<T>;
|
|
||||||
LL | |
|
|
||||||
... |
|
|
||||||
LL | |
|
|
||||||
LL | | fn main() {}
|
|
||||||
| |____________^
|
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
|
|
||||||
--> $DIR/dont-remap-tait-substs.rs:10:24
|
|
||||||
|
|
|
||||||
LL | type Foo<T: Send, U> = impl NeedsSend<T>;
|
|
||||||
| ^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
note: ...which requires borrow-checking `define`...
|
|
||||||
--> $DIR/dont-remap-tait-substs.rs:15:1
|
|
||||||
|
|
|
||||||
LL | fn define<A, B: Send>(a: A, b: B) {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= 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/dont-remap-tait-substs.rs:8:1
|
|
||||||
|
|
|
||||||
LL | / #![feature(type_alias_impl_trait)]
|
|
||||||
LL | |
|
|
||||||
LL | | type Foo<T: Send, U> = impl NeedsSend<T>;
|
|
||||||
LL | |
|
|
||||||
... |
|
|
||||||
LL | |
|
|
||||||
LL | | fn main() {}
|
|
||||||
| |____________^
|
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
|
|
||||||
--> $DIR/dont-remap-tait-substs.rs:10:24
|
|
||||||
|
|
|
||||||
LL | type Foo<T: Send, U> = impl NeedsSend<T>;
|
|
||||||
| ^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
note: ...which requires borrow-checking `define`...
|
|
||||||
--> $DIR/dont-remap-tait-substs.rs:15:1
|
|
||||||
|
|
|
||||||
LL | fn define<A, B: Send>(a: A, b: B) {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= 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/dont-remap-tait-substs.rs:8:1
|
|
||||||
|
|
|
||||||
LL | / #![feature(type_alias_impl_trait)]
|
|
||||||
LL | |
|
|
||||||
LL | | type Foo<T: Send, U> = impl NeedsSend<T>;
|
|
||||||
LL | |
|
|
||||||
... |
|
|
||||||
LL | |
|
|
||||||
LL | | fn main() {}
|
|
||||||
| |____________^
|
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
|
|
||||||
--> $DIR/dont-remap-tait-substs.rs:10:24
|
|
||||||
|
|
|
||||||
LL | type Foo<T: Send, U> = impl NeedsSend<T>;
|
|
||||||
| ^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
note: ...which requires borrow-checking `define`...
|
|
||||||
--> $DIR/dont-remap-tait-substs.rs:15:1
|
|
||||||
|
|
|
||||||
LL | fn define<A, B: Send>(a: A, b: B) {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= 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/dont-remap-tait-substs.rs:8:1
|
|
||||||
|
|
|
||||||
LL | / #![feature(type_alias_impl_trait)]
|
|
||||||
LL | |
|
|
||||||
LL | | type Foo<T: Send, U> = impl NeedsSend<T>;
|
|
||||||
LL | |
|
|
||||||
... |
|
|
||||||
LL | |
|
|
||||||
LL | | fn main() {}
|
|
||||||
| |____________^
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0391`.
|
|
|
@ -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`.
|
|
@ -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 = ();
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue