Skip to content

Commit bd06def

Browse files
Merge pull request #20785 from ChayimFriedman2/drop-glue
internal: Migrate drop glue handling to new solver
2 parents 2936257 + 2b240c6 commit bd06def

File tree

7 files changed

+113
-128
lines changed

7 files changed

+113
-128
lines changed

crates/hir-ty/src/consteval/tests/intrinsics.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,9 @@ fn overflowing_add() {
354354
fn needs_drop() {
355355
check_number(
356356
r#"
357-
//- minicore: drop, manually_drop, copy, sized
357+
//- minicore: drop, manually_drop, copy, sized, phantom_data
358358
use core::mem::ManuallyDrop;
359+
use core::marker::PhantomData;
359360
extern "rust-intrinsic" {
360361
pub fn needs_drop<T: ?Sized>() -> bool;
361362
}
@@ -380,17 +381,19 @@ fn needs_drop() {
380381
const fn opaque_copy() -> impl Sized + Copy {
381382
|| {}
382383
}
384+
struct RecursiveType(RecursiveType);
383385
trait Everything {}
384386
impl<T> Everything for T {}
385387
const GOAL: bool = !needs_drop::<i32>() && !needs_drop::<X>()
386388
&& needs_drop::<NeedsDrop>() && !needs_drop::<ManuallyDrop<NeedsDrop>>()
387389
&& needs_drop::<[NeedsDrop; 1]>() && !needs_drop::<[NeedsDrop; 0]>()
388-
&& needs_drop::<(X, NeedsDrop)>()
390+
&& needs_drop::<(X, NeedsDrop)>() && !needs_drop::<PhantomData<NeedsDrop>>()
389391
&& needs_drop::<Enum<NeedsDrop>>() && !needs_drop::<Enum<X>>()
390392
&& closure_needs_drop()
391393
&& !val_needs_drop(opaque()) && !val_needs_drop(opaque_copy())
392394
&& needs_drop::<[NeedsDrop]>() && needs_drop::<dyn Everything>()
393-
&& !needs_drop::<&dyn Everything>() && !needs_drop::<str>();
395+
&& !needs_drop::<&dyn Everything>() && !needs_drop::<str>()
396+
&& !needs_drop::<RecursiveType>();
394397
"#,
395398
1,
396399
);

crates/hir-ty/src/db.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use crate::{
1919
Binders, Const, ImplTraitId, ImplTraits, InferenceResult, Substitution, TraitEnvironment, Ty,
2020
TyDefId, ValueTyDefId, chalk_db,
2121
consteval::ConstEvalError,
22-
drop::DropGlue,
2322
dyn_compatibility::DynCompatibilityViolation,
2423
layout::{Layout, LayoutError},
2524
lower::{Diagnostics, GenericDefaults, GenericPredicates},
@@ -334,10 +333,6 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
334333
goal: crate::Canonical<crate::InEnvironment<crate::Goal>>,
335334
) -> NextTraitSolveResult;
336335

337-
#[salsa::invoke(crate::drop::has_drop_glue)]
338-
#[salsa::cycle(cycle_result = crate::drop::has_drop_glue_cycle_result)]
339-
fn has_drop_glue(&self, ty: Ty, env: Arc<TraitEnvironment<'_>>) -> DropGlue;
340-
341336
// next trait solver
342337

343338
#[salsa::invoke(crate::lower_nextsolver::const_param_ty_query)]

crates/hir-ty/src/drop.rs

Lines changed: 85 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
//! Utilities for computing drop info about types.
22
3-
use chalk_ir::cast::Cast;
4-
use hir_def::AdtId;
5-
use hir_def::lang_item::LangItem;
6-
use hir_def::signatures::StructFlags;
3+
use hir_def::{AdtId, lang_item::LangItem, signatures::StructFlags};
4+
use rustc_hash::FxHashSet;
5+
use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike};
76
use stdx::never;
87
use triomphe::Arc;
98

10-
use crate::next_solver::DbInterner;
11-
use crate::next_solver::mapping::{ChalkToNextSolver, NextSolverToChalk};
129
use crate::{
13-
AliasTy, Canonical, CanonicalVarKinds, ConcreteConst, ConstScalar, ConstValue, InEnvironment,
14-
Interner, ProjectionTy, TraitEnvironment, Ty, TyBuilder, TyKind, db::HirDatabase,
10+
TraitEnvironment, consteval_nextsolver,
11+
db::HirDatabase,
1512
method_resolution::TyFingerprint,
13+
next_solver::{
14+
Ty, TyKind,
15+
infer::{InferCtxt, traits::ObligationCause},
16+
obligation_ctxt::ObligationCtxt,
17+
},
1618
};
1719

1820
fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool {
@@ -45,27 +47,52 @@ pub enum DropGlue {
4547
HasDropGlue,
4648
}
4749

48-
pub(crate) fn has_drop_glue(
49-
db: &dyn HirDatabase,
50-
ty: Ty,
51-
env: Arc<TraitEnvironment<'_>>,
50+
pub fn has_drop_glue<'db>(
51+
infcx: &InferCtxt<'db>,
52+
ty: Ty<'db>,
53+
env: Arc<TraitEnvironment<'db>>,
5254
) -> DropGlue {
53-
match ty.kind(Interner) {
54-
TyKind::Adt(adt, subst) => {
55-
if has_destructor(db, adt.0) {
55+
has_drop_glue_impl(infcx, ty, env, &mut FxHashSet::default())
56+
}
57+
58+
fn has_drop_glue_impl<'db>(
59+
infcx: &InferCtxt<'db>,
60+
ty: Ty<'db>,
61+
env: Arc<TraitEnvironment<'db>>,
62+
visited: &mut FxHashSet<Ty<'db>>,
63+
) -> DropGlue {
64+
let mut ocx = ObligationCtxt::new(infcx);
65+
let ty = ocx.structurally_normalize_ty(&ObligationCause::dummy(), env.env, ty).unwrap_or(ty);
66+
67+
if !visited.insert(ty) {
68+
// Recursive type.
69+
return DropGlue::None;
70+
}
71+
72+
let db = infcx.interner.db;
73+
match ty.kind() {
74+
TyKind::Adt(adt_def, subst) => {
75+
let adt_id = adt_def.def_id().0;
76+
if has_destructor(db, adt_id) {
5677
return DropGlue::HasDropGlue;
5778
}
58-
match adt.0 {
79+
match adt_id {
5980
AdtId::StructId(id) => {
60-
if db.struct_signature(id).flags.contains(StructFlags::IS_MANUALLY_DROP) {
81+
if db
82+
.struct_signature(id)
83+
.flags
84+
.intersects(StructFlags::IS_MANUALLY_DROP | StructFlags::IS_PHANTOM_DATA)
85+
{
6186
return DropGlue::None;
6287
}
63-
db.field_types(id.into())
88+
db.field_types_ns(id.into())
6489
.iter()
6590
.map(|(_, field_ty)| {
66-
db.has_drop_glue(
67-
field_ty.clone().substitute(Interner, subst),
91+
has_drop_glue_impl(
92+
infcx,
93+
field_ty.instantiate(infcx.interner, subst),
6894
env.clone(),
95+
visited,
6996
)
7097
})
7198
.max()
@@ -78,12 +105,14 @@ pub(crate) fn has_drop_glue(
78105
.variants
79106
.iter()
80107
.map(|&(variant, _, _)| {
81-
db.field_types(variant.into())
108+
db.field_types_ns(variant.into())
82109
.iter()
83110
.map(|(_, field_ty)| {
84-
db.has_drop_glue(
85-
field_ty.clone().substitute(Interner, subst),
111+
has_drop_glue_impl(
112+
infcx,
113+
field_ty.instantiate(infcx.interner, subst),
86114
env.clone(),
115+
visited,
87116
)
88117
})
89118
.max()
@@ -93,123 +122,70 @@ pub(crate) fn has_drop_glue(
93122
.unwrap_or(DropGlue::None),
94123
}
95124
}
96-
TyKind::Tuple(_, subst) => subst
97-
.iter(Interner)
98-
.map(|ty| ty.assert_ty_ref(Interner))
99-
.map(|ty| db.has_drop_glue(ty.clone(), env.clone()))
125+
TyKind::Tuple(tys) => tys
126+
.iter()
127+
.map(|ty| has_drop_glue_impl(infcx, ty, env.clone(), visited))
100128
.max()
101129
.unwrap_or(DropGlue::None),
102130
TyKind::Array(ty, len) => {
103-
if let ConstValue::Concrete(ConcreteConst { interned: ConstScalar::Bytes(len, _) }) =
104-
&len.data(Interner).value
105-
{
106-
match (&**len).try_into() {
107-
Ok(len) => {
108-
let len = usize::from_le_bytes(len);
109-
if len == 0 {
110-
// Arrays of size 0 don't have drop glue.
111-
return DropGlue::None;
112-
}
113-
}
114-
Err(_) => {
115-
never!("const array size with non-usize len");
116-
}
117-
}
131+
if consteval_nextsolver::try_const_usize(db, len) == Some(0) {
132+
// Arrays of size 0 don't have drop glue.
133+
return DropGlue::None;
118134
}
119-
db.has_drop_glue(ty.clone(), env)
135+
has_drop_glue_impl(infcx, ty, env, visited)
120136
}
121-
TyKind::Slice(ty) => db.has_drop_glue(ty.clone(), env),
137+
TyKind::Slice(ty) => has_drop_glue_impl(infcx, ty, env, visited),
122138
TyKind::Closure(closure_id, subst) => {
123-
let closure_id = (*closure_id).into();
124-
let owner = db.lookup_intern_closure(closure_id).0;
139+
let owner = db.lookup_intern_closure(closure_id.0).0;
125140
let infer = db.infer(owner);
126-
let (captures, _) = infer.closure_info(closure_id);
141+
let (captures, _) = infer.closure_info(closure_id.0);
127142
let env = db.trait_environment_for_body(owner);
128-
let interner = DbInterner::conjure();
129143
captures
130144
.iter()
131145
.map(|capture| {
132-
db.has_drop_glue(
133-
capture.ty(db, subst.to_nextsolver(interner)).to_chalk(interner),
134-
env.clone(),
135-
)
146+
has_drop_glue_impl(infcx, capture.ty(db, subst), env.clone(), visited)
136147
})
137148
.max()
138149
.unwrap_or(DropGlue::None)
139150
}
140151
// FIXME: Handle coroutines.
141-
TyKind::Coroutine(..) | TyKind::CoroutineWitness(..) => DropGlue::None,
152+
TyKind::Coroutine(..) | TyKind::CoroutineWitness(..) | TyKind::CoroutineClosure(..) => {
153+
DropGlue::None
154+
}
142155
TyKind::Ref(..)
143-
| TyKind::Raw(..)
156+
| TyKind::RawPtr(..)
144157
| TyKind::FnDef(..)
145158
| TyKind::Str
146159
| TyKind::Never
147-
| TyKind::Scalar(_)
148-
| TyKind::Function(_)
160+
| TyKind::Bool
161+
| TyKind::Char
162+
| TyKind::Int(_)
163+
| TyKind::Uint(_)
164+
| TyKind::Float(_)
165+
| TyKind::FnPtr(..)
149166
| TyKind::Foreign(_)
150-
| TyKind::Error => DropGlue::None,
151-
TyKind::Dyn(_) => DropGlue::HasDropGlue,
152-
TyKind::AssociatedType(assoc_type_id, subst) => projection_has_drop_glue(
153-
db,
154-
env,
155-
ProjectionTy { associated_ty_id: *assoc_type_id, substitution: subst.clone() },
156-
ty,
157-
),
158-
TyKind::Alias(AliasTy::Projection(projection)) => {
159-
projection_has_drop_glue(db, env, projection.clone(), ty)
160-
}
161-
TyKind::OpaqueType(..) | TyKind::Alias(AliasTy::Opaque(_)) => {
162-
if is_copy(db, ty, env) {
167+
| TyKind::Error(_)
168+
| TyKind::Bound(..)
169+
| TyKind::Placeholder(..) => DropGlue::None,
170+
TyKind::Dynamic(..) => DropGlue::HasDropGlue,
171+
TyKind::Alias(..) => {
172+
if infcx.type_is_copy_modulo_regions(env.env, ty) {
163173
DropGlue::None
164174
} else {
165175
DropGlue::HasDropGlue
166176
}
167177
}
168-
TyKind::Placeholder(_) | TyKind::BoundVar(_) => {
169-
if is_copy(db, ty, env) {
178+
TyKind::Param(_) => {
179+
if infcx.type_is_copy_modulo_regions(env.env, ty) {
170180
DropGlue::None
171181
} else {
172182
DropGlue::DependOnParams
173183
}
174184
}
175-
TyKind::InferenceVar(..) => unreachable!("inference vars shouldn't exist out of inference"),
176-
}
177-
}
178-
179-
fn projection_has_drop_glue(
180-
db: &dyn HirDatabase,
181-
env: Arc<TraitEnvironment<'_>>,
182-
projection: ProjectionTy,
183-
ty: Ty,
184-
) -> DropGlue {
185-
let normalized = db.normalize_projection(projection, env.clone());
186-
match normalized.kind(Interner) {
187-
TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(..) => {
188-
if is_copy(db, ty, env) { DropGlue::None } else { DropGlue::DependOnParams }
185+
TyKind::Infer(..) => unreachable!("inference vars shouldn't exist out of inference"),
186+
TyKind::Pat(..) | TyKind::UnsafeBinder(..) => {
187+
never!("we do not handle pattern and unsafe binder types");
188+
DropGlue::None
189189
}
190-
_ => db.has_drop_glue(normalized, env),
191190
}
192191
}
193-
194-
fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironment<'_>>) -> bool {
195-
let Some(copy_trait) = LangItem::Copy.resolve_trait(db, env.krate) else {
196-
return false;
197-
};
198-
let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(ty).build();
199-
let goal = Canonical {
200-
value: InEnvironment::new(
201-
&env.env.to_chalk(DbInterner::new_with(db, Some(env.krate), env.block)),
202-
trait_ref.cast(Interner),
203-
),
204-
binders: CanonicalVarKinds::empty(Interner),
205-
};
206-
db.trait_solve(env.krate, env.block, goal).certain()
207-
}
208-
209-
pub(crate) fn has_drop_glue_cycle_result(
210-
_db: &dyn HirDatabase,
211-
_ty: Ty,
212-
_env: Arc<TraitEnvironment<'_>>,
213-
) -> DropGlue {
214-
DropGlue::None
215-
}

crates/hir-ty/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ extern crate ra_ap_rustc_next_trait_solver as rustc_next_trait_solver;
2424
mod builder;
2525
mod chalk_db;
2626
mod chalk_ext;
27-
mod drop;
2827
mod infer;
2928
mod inhabitedness;
3029
mod interner;
@@ -42,6 +41,7 @@ pub mod consteval_nextsolver;
4241
pub mod db;
4342
pub mod diagnostics;
4443
pub mod display;
44+
pub mod drop;
4545
pub mod dyn_compatibility;
4646
pub mod generics;
4747
pub mod lang_items;
@@ -94,7 +94,6 @@ use crate::{
9494
pub use autoderef::autoderef;
9595
pub use builder::{ParamKind, TyBuilder};
9696
pub use chalk_ext::*;
97-
pub use drop::DropGlue;
9897
pub use infer::{
9998
Adjust, Adjustment, AutoBorrow, BindingMode, InferenceDiagnostic, InferenceResult,
10099
InferenceTyDiagnosticSource, OverloadedDeref, PointerCast,

crates/hir-ty/src/mir/eval.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ use stdx::never;
3232
use syntax::{SyntaxNodePtr, TextRange};
3333
use triomphe::Arc;
3434

35-
use crate::next_solver::mapping::NextSolverToChalk;
3635
use crate::{
3736
AliasTy, CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstData, ConstScalar, Interner,
3837
MemoryMap, Substitution, ToChalk, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
@@ -44,8 +43,11 @@ use crate::{
4443
layout::{Layout, LayoutError, RustcEnumVariantIdx},
4544
method_resolution::{is_dyn_method, lookup_impl_const},
4645
next_solver::{
47-
DbInterner,
48-
mapping::{ChalkToNextSolver, convert_args_for_result, convert_ty_for_result},
46+
DbInterner, TypingMode,
47+
infer::{DbInternerInferExt, InferCtxt},
48+
mapping::{
49+
ChalkToNextSolver, NextSolverToChalk, convert_args_for_result, convert_ty_for_result,
50+
},
4951
},
5052
static_lifetime,
5153
traits::FnTrait,
@@ -204,6 +206,7 @@ pub struct Evaluator<'a> {
204206
/// Maximum count of bytes that heap and stack can grow
205207
memory_limit: usize,
206208
interner: DbInterner<'a>,
209+
infcx: InferCtxt<'a>,
207210
}
208211

209212
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -690,6 +693,7 @@ impl<'db> Evaluator<'db> {
690693
x.trait_items(db).method_by_name(&Name::new_symbol_root(sym::call_once))
691694
}),
692695
interner,
696+
infcx: interner.infer_ctxt().build(TypingMode::non_body_analysis()),
693697
})
694698
}
695699

0 commit comments

Comments
 (0)