Merge pull request #20446 from lcnr/kinda-unhelpful-3

next-solver fun time
This commit is contained in:
Lukas Wirth 2025-08-13 10:17:53 +00:00 committed by GitHub
commit 7af2dd9704
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 88 additions and 81 deletions

View File

@ -182,7 +182,7 @@ pub fn layout_of_ty_ns_query<'db>(
}; };
let dl = &*target; let dl = &*target;
let cx = LayoutCx::new(dl); let cx = LayoutCx::new(dl);
let infer_ctxt = interner.infer_ctxt().build(TypingMode::non_body_analysis()); let infer_ctxt = interner.infer_ctxt().build(TypingMode::PostAnalysis);
let cause = ObligationCause::dummy(); let cause = ObligationCause::dummy();
let ty = deeply_normalize(infer_ctxt.at(&cause, ParamEnv::empty()), ty).unwrap_or(ty); let ty = deeply_normalize(infer_ctxt.at(&cause, ParamEnv::empty()), ty).unwrap_or(ty);
let result = match ty.kind() { let result = match ty.kind() {
@ -335,27 +335,6 @@ pub fn layout_of_ty_ns_query<'db>(
ptr.valid_range_mut().start = 1; ptr.valid_range_mut().start = 1;
Layout::scalar(dl, ptr) Layout::scalar(dl, ptr)
} }
TyKind::Alias(_, ty) => match ty.def_id {
SolverDefId::TypeAliasId(_) => {
return Err(LayoutError::HasPlaceholder);
}
SolverDefId::InternedOpaqueTyId(opaque) => {
let impl_trait_id = db.lookup_intern_impl_trait_id(opaque);
match impl_trait_id {
crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
let infer = db.infer(func.into());
return db.layout_of_ty(infer.type_of_rpit[idx].clone(), trait_env);
}
crate::ImplTraitId::TypeAliasImplTrait(..) => {
return Err(LayoutError::NotImplemented);
}
crate::ImplTraitId::AsyncBlockTypeImplTrait(_, _) => {
return Err(LayoutError::NotImplemented);
}
}
}
_ => unreachable!(),
},
TyKind::Closure(c, args) => { TyKind::Closure(c, args) => {
let id = match c { let id = match c {
SolverDefId::InternedClosureId(id) => id, SolverDefId::InternedClosureId(id) => id,
@ -389,7 +368,11 @@ pub fn layout_of_ty_ns_query<'db>(
} }
TyKind::Error(_) => return Err(LayoutError::HasErrorType), TyKind::Error(_) => return Err(LayoutError::HasErrorType),
TyKind::Placeholder(_) | TyKind::Bound(..) | TyKind::Infer(..) | TyKind::Param(..) => { TyKind::Placeholder(_)
| TyKind::Bound(..)
| TyKind::Infer(..)
| TyKind::Param(..)
| TyKind::Alias(..) => {
return Err(LayoutError::HasPlaceholder); return Err(LayoutError::HasPlaceholder);
} }
}; };

View File

@ -22,8 +22,8 @@ use rustc_type_ir::inherent::{
use rustc_type_ir::lang_items::TraitSolverLangItem; use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::solve::SizedTraitKind;
use rustc_type_ir::{ use rustc_type_ir::{
AliasTerm, AliasTermKind, AliasTy, EarlyBinder, FlagComputation, Flags, ImplPolarity, InferTy, AliasTerm, AliasTermKind, AliasTy, AliasTyKind, EarlyBinder, FlagComputation, Flags,
ProjectionPredicate, TraitPredicate, TraitRef, Upcast, ImplPolarity, InferTy, ProjectionPredicate, TraitPredicate, TraitRef, Upcast,
}; };
use salsa::plumbing::AsId; use salsa::plumbing::AsId;
use smallvec::{SmallVec, smallvec}; use smallvec::{SmallVec, smallvec};
@ -626,12 +626,7 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
fn struct_tail_ty( fn struct_tail_ty(
self, self,
interner: DbInterner<'db>, interner: DbInterner<'db>,
) -> Option< ) -> Option<EarlyBinder<DbInterner<'db>, Ty<'db>>> {
rustc_type_ir::EarlyBinder<
DbInterner<'db>,
<DbInterner<'db> as rustc_type_ir::Interner>::Ty,
>,
> {
let db = interner.db(); let db = interner.db();
let hir_def::AdtId::StructId(struct_id) = self.inner().id else { let hir_def::AdtId::StructId(struct_id) = self.inner().id else {
return None; return None;
@ -645,10 +640,7 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
fn all_field_tys( fn all_field_tys(
self, self,
interner: DbInterner<'db>, interner: DbInterner<'db>,
) -> rustc_type_ir::EarlyBinder< ) -> EarlyBinder<DbInterner<'db>, impl IntoIterator<Item = Ty<'db>>> {
DbInterner<'db>,
impl IntoIterator<Item = <DbInterner<'db> as rustc_type_ir::Interner>::Ty>,
> {
let db = interner.db(); let db = interner.db();
// FIXME: this is disabled just to match the behavior with chalk right now // FIXME: this is disabled just to match the behavior with chalk right now
let field_tys = |id: VariantId| { let field_tys = |id: VariantId| {
@ -679,19 +671,14 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
.collect(), .collect(),
}; };
rustc_type_ir::EarlyBinder::bind(tys) EarlyBinder::bind(tys)
} }
fn sizedness_constraint( fn sizedness_constraint(
self, self,
interner: DbInterner<'db>, interner: DbInterner<'db>,
sizedness: SizedTraitKind, sizedness: SizedTraitKind,
) -> Option< ) -> Option<EarlyBinder<DbInterner<'db>, Ty<'db>>> {
rustc_type_ir::EarlyBinder<
DbInterner<'db>,
<DbInterner<'db> as rustc_type_ir::Interner>::Ty,
>,
> {
if self.is_struct() { if self.is_struct() {
let tail_ty = self.all_field_tys(interner).skip_binder().into_iter().last()?; let tail_ty = self.all_field_tys(interner).skip_binder().into_iter().last()?;
@ -1024,8 +1011,8 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
false false
} }
fn expand_abstract_consts<T: rustc_type_ir::TypeFoldable<Self>>(self, t: T) -> T { fn expand_abstract_consts<T: rustc_type_ir::TypeFoldable<Self>>(self, _: T) -> T {
t unreachable!("only used by the old trait solver in rustc");
} }
fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf { fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf {
@ -1054,6 +1041,9 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
), ),
SolverDefId::InternedOpaqueTyId(_def_id) => { SolverDefId::InternedOpaqueTyId(_def_id) => {
// FIXME(next-solver): track variances // FIXME(next-solver): track variances
//
// We compute them based on the only `Ty` level info in rustc,
// move `variances_of_opaque` into `rustc_next_trait_solver` for reuse.
VariancesOf::new_from_iter( VariancesOf::new_from_iter(
self, self,
(0..self.generics_of(def_id).count()).map(|_| Variance::Invariant), (0..self.generics_of(def_id).count()).map(|_| Variance::Invariant),
@ -1063,7 +1053,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
} }
} }
fn type_of(self, def_id: Self::DefId) -> rustc_type_ir::EarlyBinder<Self, Self::Ty> { fn type_of(self, def_id: Self::DefId) -> EarlyBinder<Self, Self::Ty> {
let def_id = match def_id { let def_id = match def_id {
SolverDefId::TypeAliasId(id) => { SolverDefId::TypeAliasId(id) => {
use hir_def::Lookup; use hir_def::Lookup;
@ -1074,6 +1064,13 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
crate::TyDefId::TypeAliasId(id) crate::TyDefId::TypeAliasId(id)
} }
SolverDefId::AdtId(id) => crate::TyDefId::AdtId(id), SolverDefId::AdtId(id) => crate::TyDefId::AdtId(id),
// FIXME(next-solver): This uses the types of `query mir_borrowck` in rustc.
//
// We currently always use the type from HIR typeck which ignores regions. This
// should be fine.
SolverDefId::InternedOpaqueTyId(_) => {
return self.type_of_opaque_hir_typeck(def_id);
}
_ => panic!("Unexpected def_id `{def_id:?}` provided for `type_of`"), _ => panic!("Unexpected def_id `{def_id:?}` provided for `type_of`"),
}; };
self.db().ty_ns(def_id) self.db().ty_ns(def_id)
@ -1087,9 +1084,12 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
AdtDef::new(def_id, self) AdtDef::new(def_id, self)
} }
fn alias_ty_kind(self, alias: rustc_type_ir::AliasTy<Self>) -> rustc_type_ir::AliasTyKind { fn alias_ty_kind(self, alias: rustc_type_ir::AliasTy<Self>) -> AliasTyKind {
// FIXME: not currently creating any others match alias.def_id {
rustc_type_ir::AliasTyKind::Projection SolverDefId::InternedOpaqueTyId(_) => AliasTyKind::Opaque,
SolverDefId::TypeAliasId(_) => AliasTyKind::Projection,
_ => unimplemented!("Unexpected alias: {:?}", alias.def_id),
}
} }
fn alias_term_kind( fn alias_term_kind(
@ -1100,7 +1100,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
SolverDefId::InternedOpaqueTyId(_) => AliasTermKind::OpaqueTy, SolverDefId::InternedOpaqueTyId(_) => AliasTermKind::OpaqueTy,
SolverDefId::TypeAliasId(_) => AliasTermKind::ProjectionTy, SolverDefId::TypeAliasId(_) => AliasTermKind::ProjectionTy,
SolverDefId::ConstId(_) => AliasTermKind::UnevaluatedConst, SolverDefId::ConstId(_) => AliasTermKind::UnevaluatedConst,
_ => unreachable!("Unexpected alias: {:?}", alias.def_id), _ => unimplemented!("Unexpected alias: {:?}", alias.def_id),
} }
} }
@ -1194,8 +1194,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn fn_sig( fn fn_sig(
self, self,
def_id: Self::DefId, def_id: Self::DefId,
) -> rustc_type_ir::EarlyBinder<Self, rustc_type_ir::Binder<Self, rustc_type_ir::FnSig<Self>>> ) -> EarlyBinder<Self, rustc_type_ir::Binder<Self, rustc_type_ir::FnSig<Self>>> {
{
let id = match def_id { let id = match def_id {
SolverDefId::FunctionId(id) => CallableDefId::FunctionId(id), SolverDefId::FunctionId(id) => CallableDefId::FunctionId(id),
SolverDefId::Ctor(ctor) => match ctor { SolverDefId::Ctor(ctor) => match ctor {
@ -1248,7 +1247,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn item_bounds( fn item_bounds(
self, self,
def_id: Self::DefId, def_id: Self::DefId,
) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
explicit_item_bounds(self, def_id).map_bound(|bounds| { explicit_item_bounds(self, def_id).map_bound(|bounds| {
Clauses::new_from_iter(self, elaborate(self, bounds).collect::<Vec<_>>()) Clauses::new_from_iter(self, elaborate(self, bounds).collect::<Vec<_>>())
}) })
@ -1258,7 +1257,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn item_self_bounds( fn item_self_bounds(
self, self,
def_id: Self::DefId, def_id: Self::DefId,
) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
explicit_item_bounds(self, def_id).map_bound(|bounds| { explicit_item_bounds(self, def_id).map_bound(|bounds| {
Clauses::new_from_iter( Clauses::new_from_iter(
self, self,
@ -1270,7 +1269,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn item_non_self_bounds( fn item_non_self_bounds(
self, self,
def_id: Self::DefId, def_id: Self::DefId,
) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
let all_bounds: FxHashSet<_> = self.item_bounds(def_id).skip_binder().into_iter().collect(); let all_bounds: FxHashSet<_> = self.item_bounds(def_id).skip_binder().into_iter().collect();
let own_bounds: FxHashSet<_> = let own_bounds: FxHashSet<_> =
self.item_self_bounds(def_id).skip_binder().into_iter().collect(); self.item_self_bounds(def_id).skip_binder().into_iter().collect();
@ -1288,7 +1287,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn predicates_of( fn predicates_of(
self, self,
def_id: Self::DefId, def_id: Self::DefId,
) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
let predicates = self.db().generic_predicates_ns(def_id.try_into().unwrap()); let predicates = self.db().generic_predicates_ns(def_id.try_into().unwrap());
let predicates: Vec<_> = predicates.iter().cloned().collect(); let predicates: Vec<_> = predicates.iter().cloned().collect();
EarlyBinder::bind(predicates.into_iter()) EarlyBinder::bind(predicates.into_iter())
@ -1298,7 +1297,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn own_predicates_of( fn own_predicates_of(
self, self,
def_id: Self::DefId, def_id: Self::DefId,
) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
let predicates = self.db().generic_predicates_without_parent_ns(def_id.try_into().unwrap()); let predicates = self.db().generic_predicates_without_parent_ns(def_id.try_into().unwrap());
let predicates: Vec<_> = predicates.iter().cloned().collect(); let predicates: Vec<_> = predicates.iter().cloned().collect();
EarlyBinder::bind(predicates.into_iter()) EarlyBinder::bind(predicates.into_iter())
@ -1308,8 +1307,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn explicit_super_predicates_of( fn explicit_super_predicates_of(
self, self,
def_id: Self::DefId, def_id: Self::DefId,
) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> {
{
let predicates: Vec<(Clause<'db>, Span)> = self let predicates: Vec<(Clause<'db>, Span)> = self
.db() .db()
.generic_predicates_ns(def_id.try_into().unwrap()) .generic_predicates_ns(def_id.try_into().unwrap())
@ -1317,15 +1315,14 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
.cloned() .cloned()
.map(|p| (p, Span::dummy())) .map(|p| (p, Span::dummy()))
.collect(); .collect();
rustc_type_ir::EarlyBinder::bind(predicates) EarlyBinder::bind(predicates)
} }
#[tracing::instrument(skip(self), ret)] #[tracing::instrument(skip(self), ret)]
fn explicit_implied_predicates_of( fn explicit_implied_predicates_of(
self, self,
def_id: Self::DefId, def_id: Self::DefId,
) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> {
{
let predicates: Vec<(Clause<'db>, Span)> = self let predicates: Vec<(Clause<'db>, Span)> = self
.db() .db()
.generic_predicates_ns(def_id.try_into().unwrap()) .generic_predicates_ns(def_id.try_into().unwrap())
@ -1333,13 +1330,13 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
.cloned() .cloned()
.map(|p| (p, Span::dummy())) .map(|p| (p, Span::dummy()))
.collect(); .collect();
rustc_type_ir::EarlyBinder::bind(predicates) EarlyBinder::bind(predicates)
} }
fn impl_super_outlives( fn impl_super_outlives(
self, self,
impl_def_id: Self::DefId, impl_def_id: Self::DefId,
) -> rustc_type_ir::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> { ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
let impl_id = match impl_def_id { let impl_id = match impl_def_id {
SolverDefId::ImplId(id) => id, SolverDefId::ImplId(id) => id,
_ => unreachable!(), _ => unreachable!(),
@ -1362,11 +1359,11 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn const_conditions( fn const_conditions(
self, self,
def_id: Self::DefId, def_id: Self::DefId,
) -> rustc_type_ir::EarlyBinder< ) -> EarlyBinder<
Self, Self,
impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>, impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>,
> { > {
rustc_type_ir::EarlyBinder::bind([unimplemented!()]) EarlyBinder::bind([unimplemented!()])
} }
fn has_target_features(self, def_id: Self::DefId) -> bool { fn has_target_features(self, def_id: Self::DefId) -> bool {
@ -1740,7 +1737,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
} }
fn has_item_definition(self, def_id: Self::DefId) -> bool { fn has_item_definition(self, def_id: Self::DefId) -> bool {
// FIXME: should check if has value // FIXME(next-solver): should check if the associated item has a value.
true true
} }
@ -1753,7 +1750,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn impl_trait_ref( fn impl_trait_ref(
self, self,
impl_def_id: Self::DefId, impl_def_id: Self::DefId,
) -> rustc_type_ir::EarlyBinder<Self, rustc_type_ir::TraitRef<Self>> { ) -> EarlyBinder<Self, rustc_type_ir::TraitRef<Self>> {
let impl_id = match impl_def_id { let impl_id = match impl_def_id {
SolverDefId::ImplId(id) => id, SolverDefId::ImplId(id) => id,
_ => panic!("Unexpected SolverDefId in impl_trait_ref"), _ => panic!("Unexpected SolverDefId in impl_trait_ref"),
@ -1815,7 +1812,8 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
} }
fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool { fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool {
// FIXME(next-solver) // FIXME(next-solver): should check the `TraitFlags` for
// the `#[rustc_do_not_implement_via_object]` flag
true true
} }
@ -1954,12 +1952,12 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
fn explicit_implied_const_bounds( fn explicit_implied_const_bounds(
self, self,
def_id: Self::DefId, def_id: Self::DefId,
) -> rustc_type_ir::EarlyBinder< ) -> EarlyBinder<
Self, Self,
impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>, impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>,
> { > {
// FIXME(next-solver) // FIXME(next-solver)
rustc_type_ir::EarlyBinder::bind([]) EarlyBinder::bind([])
} }
fn fn_is_const(self, def_id: Self::DefId) -> bool { fn fn_is_const(self, def_id: Self::DefId) -> bool {
@ -1982,21 +1980,31 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
None None
} }
fn type_of_opaque_hir_typeck( fn type_of_opaque_hir_typeck(self, def_id: Self::LocalDefId) -> EarlyBinder<Self, Self::Ty> {
self, match def_id {
def_id: Self::LocalDefId, SolverDefId::InternedOpaqueTyId(opaque) => {
) -> rustc_type_ir::EarlyBinder<Self, Self::Ty> { let impl_trait_id = self.db().lookup_intern_impl_trait_id(opaque);
// FIXME(next-solver) match impl_trait_id {
unimplemented!() crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
let infer = self.db().infer(func.into());
EarlyBinder::bind(infer.type_of_rpit[idx].to_nextsolver(self))
}
crate::ImplTraitId::TypeAliasImplTrait(..)
| crate::ImplTraitId::AsyncBlockTypeImplTrait(_, _) => {
// FIXME(next-solver)
EarlyBinder::bind(Ty::new_error(self, ErrorGuaranteed))
}
}
}
_ => panic!("Unexpected SolverDefId in type_of_opaque_hir_typeck"),
}
} }
fn coroutine_hidden_types( fn coroutine_hidden_types(
self, self,
def_id: Self::DefId, def_id: Self::DefId,
) -> rustc_type_ir::EarlyBinder< ) -> EarlyBinder<Self, rustc_type_ir::Binder<Self, rustc_type_ir::CoroutineWitnessTypes<Self>>>
Self, {
rustc_type_ir::Binder<Self, rustc_type_ir::CoroutineWitnessTypes<Self>>,
> {
// FIXME(next-solver) // FIXME(next-solver)
unimplemented!() unimplemented!()
} }

View File

@ -6,12 +6,12 @@ mod incremental;
mod macros; mod macros;
mod method_resolution; mod method_resolution;
mod never_type; mod never_type;
mod opaque_types;
mod patterns; mod patterns;
mod regression; mod regression;
mod simple; mod simple;
mod trait_aliases; mod trait_aliases;
mod traits; mod traits;
mod type_alias_impl_traits;
use base_db::{Crate, SourceDatabase}; use base_db::{Crate, SourceDatabase};
use expect_test::Expect; use expect_test::Expect;

View File

@ -159,3 +159,19 @@ static ALIAS: i32 = {
"#]], "#]],
) )
} }
#[test]
fn leak_auto_traits() {
check_no_mismatches(
r#"
//- minicore: send
fn foo() -> impl Sized {}
fn is_send<T: Send>(_: T) {}
fn main() {
is_send(foo());
}
"#,
);
}