Merge pull request #20785 from ChayimFriedman2/drop-glue
internal: Migrate drop glue handling to new solver
This commit is contained in:
commit
0580059e43
7 changed files with 113 additions and 128 deletions
|
|
@ -354,8 +354,9 @@ fn overflowing_add() {
|
|||
fn needs_drop() {
|
||||
check_number(
|
||||
r#"
|
||||
//- minicore: drop, manually_drop, copy, sized
|
||||
//- minicore: drop, manually_drop, copy, sized, phantom_data
|
||||
use core::mem::ManuallyDrop;
|
||||
use core::marker::PhantomData;
|
||||
extern "rust-intrinsic" {
|
||||
pub fn needs_drop<T: ?Sized>() -> bool;
|
||||
}
|
||||
|
|
@ -380,17 +381,19 @@ fn needs_drop() {
|
|||
const fn opaque_copy() -> impl Sized + Copy {
|
||||
|| {}
|
||||
}
|
||||
struct RecursiveType(RecursiveType);
|
||||
trait Everything {}
|
||||
impl<T> Everything for T {}
|
||||
const GOAL: bool = !needs_drop::<i32>() && !needs_drop::<X>()
|
||||
&& needs_drop::<NeedsDrop>() && !needs_drop::<ManuallyDrop<NeedsDrop>>()
|
||||
&& needs_drop::<[NeedsDrop; 1]>() && !needs_drop::<[NeedsDrop; 0]>()
|
||||
&& needs_drop::<(X, NeedsDrop)>()
|
||||
&& needs_drop::<(X, NeedsDrop)>() && !needs_drop::<PhantomData<NeedsDrop>>()
|
||||
&& needs_drop::<Enum<NeedsDrop>>() && !needs_drop::<Enum<X>>()
|
||||
&& closure_needs_drop()
|
||||
&& !val_needs_drop(opaque()) && !val_needs_drop(opaque_copy())
|
||||
&& needs_drop::<[NeedsDrop]>() && needs_drop::<dyn Everything>()
|
||||
&& !needs_drop::<&dyn Everything>() && !needs_drop::<str>();
|
||||
&& !needs_drop::<&dyn Everything>() && !needs_drop::<str>()
|
||||
&& !needs_drop::<RecursiveType>();
|
||||
"#,
|
||||
1,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ use crate::{
|
|||
Binders, Const, ImplTraitId, ImplTraits, InferenceResult, Substitution, TraitEnvironment, Ty,
|
||||
TyDefId, ValueTyDefId, chalk_db,
|
||||
consteval::ConstEvalError,
|
||||
drop::DropGlue,
|
||||
dyn_compatibility::DynCompatibilityViolation,
|
||||
layout::{Layout, LayoutError},
|
||||
lower::{Diagnostics, GenericDefaults, GenericPredicates},
|
||||
|
|
@ -334,10 +333,6 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
|||
goal: crate::Canonical<crate::InEnvironment<crate::Goal>>,
|
||||
) -> NextTraitSolveResult;
|
||||
|
||||
#[salsa::invoke(crate::drop::has_drop_glue)]
|
||||
#[salsa::cycle(cycle_result = crate::drop::has_drop_glue_cycle_result)]
|
||||
fn has_drop_glue(&self, ty: Ty, env: Arc<TraitEnvironment<'_>>) -> DropGlue;
|
||||
|
||||
// next trait solver
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::const_param_ty_query)]
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
//! Utilities for computing drop info about types.
|
||||
|
||||
use chalk_ir::cast::Cast;
|
||||
use hir_def::AdtId;
|
||||
use hir_def::lang_item::LangItem;
|
||||
use hir_def::signatures::StructFlags;
|
||||
use hir_def::{AdtId, lang_item::LangItem, signatures::StructFlags};
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike};
|
||||
use stdx::never;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::next_solver::DbInterner;
|
||||
use crate::next_solver::mapping::{ChalkToNextSolver, NextSolverToChalk};
|
||||
use crate::{
|
||||
AliasTy, Canonical, CanonicalVarKinds, ConcreteConst, ConstScalar, ConstValue, InEnvironment,
|
||||
Interner, ProjectionTy, TraitEnvironment, Ty, TyBuilder, TyKind, db::HirDatabase,
|
||||
TraitEnvironment, consteval_nextsolver,
|
||||
db::HirDatabase,
|
||||
method_resolution::TyFingerprint,
|
||||
next_solver::{
|
||||
Ty, TyKind,
|
||||
infer::{InferCtxt, traits::ObligationCause},
|
||||
obligation_ctxt::ObligationCtxt,
|
||||
},
|
||||
};
|
||||
|
||||
fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool {
|
||||
|
|
@ -45,27 +47,52 @@ pub enum DropGlue {
|
|||
HasDropGlue,
|
||||
}
|
||||
|
||||
pub(crate) fn has_drop_glue(
|
||||
db: &dyn HirDatabase,
|
||||
ty: Ty,
|
||||
env: Arc<TraitEnvironment<'_>>,
|
||||
pub fn has_drop_glue<'db>(
|
||||
infcx: &InferCtxt<'db>,
|
||||
ty: Ty<'db>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
) -> DropGlue {
|
||||
match ty.kind(Interner) {
|
||||
TyKind::Adt(adt, subst) => {
|
||||
if has_destructor(db, adt.0) {
|
||||
has_drop_glue_impl(infcx, ty, env, &mut FxHashSet::default())
|
||||
}
|
||||
|
||||
fn has_drop_glue_impl<'db>(
|
||||
infcx: &InferCtxt<'db>,
|
||||
ty: Ty<'db>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
visited: &mut FxHashSet<Ty<'db>>,
|
||||
) -> DropGlue {
|
||||
let mut ocx = ObligationCtxt::new(infcx);
|
||||
let ty = ocx.structurally_normalize_ty(&ObligationCause::dummy(), env.env, ty).unwrap_or(ty);
|
||||
|
||||
if !visited.insert(ty) {
|
||||
// Recursive type.
|
||||
return DropGlue::None;
|
||||
}
|
||||
|
||||
let db = infcx.interner.db;
|
||||
match ty.kind() {
|
||||
TyKind::Adt(adt_def, subst) => {
|
||||
let adt_id = adt_def.def_id().0;
|
||||
if has_destructor(db, adt_id) {
|
||||
return DropGlue::HasDropGlue;
|
||||
}
|
||||
match adt.0 {
|
||||
match adt_id {
|
||||
AdtId::StructId(id) => {
|
||||
if db.struct_signature(id).flags.contains(StructFlags::IS_MANUALLY_DROP) {
|
||||
if db
|
||||
.struct_signature(id)
|
||||
.flags
|
||||
.intersects(StructFlags::IS_MANUALLY_DROP | StructFlags::IS_PHANTOM_DATA)
|
||||
{
|
||||
return DropGlue::None;
|
||||
}
|
||||
db.field_types(id.into())
|
||||
db.field_types_ns(id.into())
|
||||
.iter()
|
||||
.map(|(_, field_ty)| {
|
||||
db.has_drop_glue(
|
||||
field_ty.clone().substitute(Interner, subst),
|
||||
has_drop_glue_impl(
|
||||
infcx,
|
||||
field_ty.instantiate(infcx.interner, subst),
|
||||
env.clone(),
|
||||
visited,
|
||||
)
|
||||
})
|
||||
.max()
|
||||
|
|
@ -78,12 +105,14 @@ pub(crate) fn has_drop_glue(
|
|||
.variants
|
||||
.iter()
|
||||
.map(|&(variant, _, _)| {
|
||||
db.field_types(variant.into())
|
||||
db.field_types_ns(variant.into())
|
||||
.iter()
|
||||
.map(|(_, field_ty)| {
|
||||
db.has_drop_glue(
|
||||
field_ty.clone().substitute(Interner, subst),
|
||||
has_drop_glue_impl(
|
||||
infcx,
|
||||
field_ty.instantiate(infcx.interner, subst),
|
||||
env.clone(),
|
||||
visited,
|
||||
)
|
||||
})
|
||||
.max()
|
||||
|
|
@ -93,123 +122,70 @@ pub(crate) fn has_drop_glue(
|
|||
.unwrap_or(DropGlue::None),
|
||||
}
|
||||
}
|
||||
TyKind::Tuple(_, subst) => subst
|
||||
.iter(Interner)
|
||||
.map(|ty| ty.assert_ty_ref(Interner))
|
||||
.map(|ty| db.has_drop_glue(ty.clone(), env.clone()))
|
||||
TyKind::Tuple(tys) => tys
|
||||
.iter()
|
||||
.map(|ty| has_drop_glue_impl(infcx, ty, env.clone(), visited))
|
||||
.max()
|
||||
.unwrap_or(DropGlue::None),
|
||||
TyKind::Array(ty, len) => {
|
||||
if let ConstValue::Concrete(ConcreteConst { interned: ConstScalar::Bytes(len, _) }) =
|
||||
&len.data(Interner).value
|
||||
{
|
||||
match (&**len).try_into() {
|
||||
Ok(len) => {
|
||||
let len = usize::from_le_bytes(len);
|
||||
if len == 0 {
|
||||
// Arrays of size 0 don't have drop glue.
|
||||
return DropGlue::None;
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
never!("const array size with non-usize len");
|
||||
}
|
||||
}
|
||||
if consteval_nextsolver::try_const_usize(db, len) == Some(0) {
|
||||
// Arrays of size 0 don't have drop glue.
|
||||
return DropGlue::None;
|
||||
}
|
||||
db.has_drop_glue(ty.clone(), env)
|
||||
has_drop_glue_impl(infcx, ty, env, visited)
|
||||
}
|
||||
TyKind::Slice(ty) => db.has_drop_glue(ty.clone(), env),
|
||||
TyKind::Slice(ty) => has_drop_glue_impl(infcx, ty, env, visited),
|
||||
TyKind::Closure(closure_id, subst) => {
|
||||
let closure_id = (*closure_id).into();
|
||||
let owner = db.lookup_intern_closure(closure_id).0;
|
||||
let owner = db.lookup_intern_closure(closure_id.0).0;
|
||||
let infer = db.infer(owner);
|
||||
let (captures, _) = infer.closure_info(closure_id);
|
||||
let (captures, _) = infer.closure_info(closure_id.0);
|
||||
let env = db.trait_environment_for_body(owner);
|
||||
let interner = DbInterner::conjure();
|
||||
captures
|
||||
.iter()
|
||||
.map(|capture| {
|
||||
db.has_drop_glue(
|
||||
capture.ty(db, subst.to_nextsolver(interner)).to_chalk(interner),
|
||||
env.clone(),
|
||||
)
|
||||
has_drop_glue_impl(infcx, capture.ty(db, subst), env.clone(), visited)
|
||||
})
|
||||
.max()
|
||||
.unwrap_or(DropGlue::None)
|
||||
}
|
||||
// FIXME: Handle coroutines.
|
||||
TyKind::Coroutine(..) | TyKind::CoroutineWitness(..) => DropGlue::None,
|
||||
TyKind::Coroutine(..) | TyKind::CoroutineWitness(..) | TyKind::CoroutineClosure(..) => {
|
||||
DropGlue::None
|
||||
}
|
||||
TyKind::Ref(..)
|
||||
| TyKind::Raw(..)
|
||||
| TyKind::RawPtr(..)
|
||||
| TyKind::FnDef(..)
|
||||
| TyKind::Str
|
||||
| TyKind::Never
|
||||
| TyKind::Scalar(_)
|
||||
| TyKind::Function(_)
|
||||
| TyKind::Bool
|
||||
| TyKind::Char
|
||||
| TyKind::Int(_)
|
||||
| TyKind::Uint(_)
|
||||
| TyKind::Float(_)
|
||||
| TyKind::FnPtr(..)
|
||||
| TyKind::Foreign(_)
|
||||
| TyKind::Error => DropGlue::None,
|
||||
TyKind::Dyn(_) => DropGlue::HasDropGlue,
|
||||
TyKind::AssociatedType(assoc_type_id, subst) => projection_has_drop_glue(
|
||||
db,
|
||||
env,
|
||||
ProjectionTy { associated_ty_id: *assoc_type_id, substitution: subst.clone() },
|
||||
ty,
|
||||
),
|
||||
TyKind::Alias(AliasTy::Projection(projection)) => {
|
||||
projection_has_drop_glue(db, env, projection.clone(), ty)
|
||||
}
|
||||
TyKind::OpaqueType(..) | TyKind::Alias(AliasTy::Opaque(_)) => {
|
||||
if is_copy(db, ty, env) {
|
||||
| TyKind::Error(_)
|
||||
| TyKind::Bound(..)
|
||||
| TyKind::Placeholder(..) => DropGlue::None,
|
||||
TyKind::Dynamic(..) => DropGlue::HasDropGlue,
|
||||
TyKind::Alias(..) => {
|
||||
if infcx.type_is_copy_modulo_regions(env.env, ty) {
|
||||
DropGlue::None
|
||||
} else {
|
||||
DropGlue::HasDropGlue
|
||||
}
|
||||
}
|
||||
TyKind::Placeholder(_) | TyKind::BoundVar(_) => {
|
||||
if is_copy(db, ty, env) {
|
||||
TyKind::Param(_) => {
|
||||
if infcx.type_is_copy_modulo_regions(env.env, ty) {
|
||||
DropGlue::None
|
||||
} else {
|
||||
DropGlue::DependOnParams
|
||||
}
|
||||
}
|
||||
TyKind::InferenceVar(..) => unreachable!("inference vars shouldn't exist out of inference"),
|
||||
}
|
||||
}
|
||||
|
||||
fn projection_has_drop_glue(
|
||||
db: &dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment<'_>>,
|
||||
projection: ProjectionTy,
|
||||
ty: Ty,
|
||||
) -> DropGlue {
|
||||
let normalized = db.normalize_projection(projection, env.clone());
|
||||
match normalized.kind(Interner) {
|
||||
TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(..) => {
|
||||
if is_copy(db, ty, env) { DropGlue::None } else { DropGlue::DependOnParams }
|
||||
TyKind::Infer(..) => unreachable!("inference vars shouldn't exist out of inference"),
|
||||
TyKind::Pat(..) | TyKind::UnsafeBinder(..) => {
|
||||
never!("we do not handle pattern and unsafe binder types");
|
||||
DropGlue::None
|
||||
}
|
||||
_ => db.has_drop_glue(normalized, env),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironment<'_>>) -> bool {
|
||||
let Some(copy_trait) = LangItem::Copy.resolve_trait(db, env.krate) else {
|
||||
return false;
|
||||
};
|
||||
let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(ty).build();
|
||||
let goal = Canonical {
|
||||
value: InEnvironment::new(
|
||||
&env.env.to_chalk(DbInterner::new_with(db, Some(env.krate), env.block)),
|
||||
trait_ref.cast(Interner),
|
||||
),
|
||||
binders: CanonicalVarKinds::empty(Interner),
|
||||
};
|
||||
db.trait_solve(env.krate, env.block, goal).certain()
|
||||
}
|
||||
|
||||
pub(crate) fn has_drop_glue_cycle_result(
|
||||
_db: &dyn HirDatabase,
|
||||
_ty: Ty,
|
||||
_env: Arc<TraitEnvironment<'_>>,
|
||||
) -> DropGlue {
|
||||
DropGlue::None
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ extern crate ra_ap_rustc_next_trait_solver as rustc_next_trait_solver;
|
|||
mod builder;
|
||||
mod chalk_db;
|
||||
mod chalk_ext;
|
||||
mod drop;
|
||||
mod infer;
|
||||
mod inhabitedness;
|
||||
mod interner;
|
||||
|
|
@ -42,6 +41,7 @@ pub mod consteval_nextsolver;
|
|||
pub mod db;
|
||||
pub mod diagnostics;
|
||||
pub mod display;
|
||||
pub mod drop;
|
||||
pub mod dyn_compatibility;
|
||||
pub mod generics;
|
||||
pub mod lang_items;
|
||||
|
|
@ -94,7 +94,6 @@ use crate::{
|
|||
pub use autoderef::autoderef;
|
||||
pub use builder::{ParamKind, TyBuilder};
|
||||
pub use chalk_ext::*;
|
||||
pub use drop::DropGlue;
|
||||
pub use infer::{
|
||||
Adjust, Adjustment, AutoBorrow, BindingMode, InferenceDiagnostic, InferenceResult,
|
||||
InferenceTyDiagnosticSource, OverloadedDeref, PointerCast,
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ use stdx::never;
|
|||
use syntax::{SyntaxNodePtr, TextRange};
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::next_solver::mapping::NextSolverToChalk;
|
||||
use crate::{
|
||||
AliasTy, CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstData, ConstScalar, Interner,
|
||||
MemoryMap, Substitution, ToChalk, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
|
||||
|
|
@ -44,8 +43,11 @@ use crate::{
|
|||
layout::{Layout, LayoutError, RustcEnumVariantIdx},
|
||||
method_resolution::{is_dyn_method, lookup_impl_const},
|
||||
next_solver::{
|
||||
DbInterner,
|
||||
mapping::{ChalkToNextSolver, convert_args_for_result, convert_ty_for_result},
|
||||
DbInterner, TypingMode,
|
||||
infer::{DbInternerInferExt, InferCtxt},
|
||||
mapping::{
|
||||
ChalkToNextSolver, NextSolverToChalk, convert_args_for_result, convert_ty_for_result,
|
||||
},
|
||||
},
|
||||
static_lifetime,
|
||||
traits::FnTrait,
|
||||
|
|
@ -204,6 +206,7 @@ pub struct Evaluator<'a> {
|
|||
/// Maximum count of bytes that heap and stack can grow
|
||||
memory_limit: usize,
|
||||
interner: DbInterner<'a>,
|
||||
infcx: InferCtxt<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
|
|
@ -690,6 +693,7 @@ impl<'db> Evaluator<'db> {
|
|||
x.trait_items(db).method_by_name(&Name::new_symbol_root(sym::call_once))
|
||||
}),
|
||||
interner,
|
||||
infcx: interner.infer_ctxt().build(TypingMode::non_body_analysis()),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ use stdx::never;
|
|||
|
||||
use crate::next_solver::mapping::NextSolverToChalk;
|
||||
use crate::{
|
||||
DropGlue,
|
||||
display::DisplayTarget,
|
||||
drop::{DropGlue, has_drop_glue},
|
||||
error_lifetime,
|
||||
mir::eval::{
|
||||
Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule, HirDisplay,
|
||||
|
|
@ -855,7 +855,11 @@ impl<'db> Evaluator<'db> {
|
|||
"size_of generic arg is not provided".into(),
|
||||
));
|
||||
};
|
||||
let result = match self.db.has_drop_glue(ty.clone(), self.trait_env.clone()) {
|
||||
let result = match has_drop_glue(
|
||||
&self.infcx,
|
||||
ty.to_nextsolver(self.interner),
|
||||
self.trait_env.clone(),
|
||||
) {
|
||||
DropGlue::HasDropGlue => true,
|
||||
DropGlue::None => false,
|
||||
DropGlue::DependOnParams => {
|
||||
|
|
|
|||
|
|
@ -82,8 +82,8 @@ use hir_ty::{
|
|||
method_resolution,
|
||||
mir::{MutBorrowKind, interpret_mir},
|
||||
next_solver::{
|
||||
ClauseKind, DbInterner, GenericArgs,
|
||||
infer::InferCtxt,
|
||||
ClauseKind, DbInterner, GenericArgs, TypingMode,
|
||||
infer::{DbInternerInferExt, InferCtxt},
|
||||
mapping::{ChalkToNextSolver, NextSolverToChalk, convert_ty_for_result},
|
||||
},
|
||||
primitive::UintTy,
|
||||
|
|
@ -157,10 +157,11 @@ pub use {
|
|||
tt,
|
||||
},
|
||||
hir_ty::{
|
||||
CastError, DropGlue, FnAbi, PointerCast, Variance, attach_db, attach_db_allow_change,
|
||||
CastError, FnAbi, PointerCast, Variance, attach_db, attach_db_allow_change,
|
||||
consteval::ConstEvalError,
|
||||
diagnostics::UnsafetyReason,
|
||||
display::{ClosureStyle, DisplayTarget, HirDisplay, HirDisplayError, HirWrite},
|
||||
drop::DropGlue,
|
||||
dyn_compatibility::{DynCompatibilityViolation, MethodViolationCode},
|
||||
layout::LayoutError,
|
||||
method_resolution::TyFingerprint,
|
||||
|
|
@ -6043,7 +6044,10 @@ impl<'db> Type<'db> {
|
|||
}
|
||||
|
||||
pub fn drop_glue(&self, db: &'db dyn HirDatabase) -> DropGlue {
|
||||
db.has_drop_glue(self.ty.clone(), self.env.clone())
|
||||
let interner = DbInterner::new_with(db, Some(self.env.krate), self.env.block);
|
||||
// FIXME: This should be `PostAnalysis` I believe.
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
hir_ty::drop::has_drop_glue(&infcx, self.ty.to_nextsolver(interner), self.env.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue