Skip to content

Commit 2fdd1ac

Browse files
committed
Auto merge of #14664 - HKalbasi:mir, r=HKalbasi
MIR episode 4 In lowering, it now supports overloaded and arith assignment binary operators, statics. and constants in patterns. There is now 252 functions that we fail to emit mir for them, and the majority of them are due type mismatches or other deep and unrelated issues (but it isn't done yet, for example slice patterns and destructing assignment is not implemented yet). In evaluating, it now can evaluate associated constants in traits (so now typenum's `U5::ToConst` should work), allocator functions, atomic intrinsics, and some more things. It also provides a (hacky) basis for making progress in #14275. I also added a `Interpret` code lens to `Run` and `Debug` when the experimental `interpret tests` is enabled (previously it showed result in hover, which was unusable even for debugging) Changes in unrelated files are: * Changes substitutions of closures, now it includes parent substs ~~before~~ after `sig_ty`. * ~~A salsa input for retrieving the path of a file id, used in emitting stack trace for interpret result.~~ * Normalizing associated types in layout computing
2 parents 001607f + 6312fbf commit 2fdd1ac

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2556
-804
lines changed

crates/base-db/src/change.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ impl fmt::Debug for Change {
3434
}
3535

3636
impl Change {
37-
pub fn new() -> Change {
37+
pub fn new() -> Self {
3838
Change::default()
3939
}
4040

crates/hir-def/src/body/lower.rs

+23-10
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_hash::FxHashMap;
1717
use smallvec::SmallVec;
1818
use syntax::{
1919
ast::{
20-
self, ArrayExprKind, AstChildren, BlockExpr, HasArgList, HasLoopBody, HasName,
20+
self, ArrayExprKind, AstChildren, BlockExpr, HasArgList, HasAttrs, HasLoopBody, HasName,
2121
SlicePatComponents,
2222
},
2323
AstNode, AstPtr, SyntaxNodePtr,
@@ -302,16 +302,29 @@ impl ExprCollector<'_> {
302302
self.alloc_expr(Expr::For { iterable, pat, body, label }, syntax_ptr)
303303
}
304304
ast::Expr::CallExpr(e) => {
305-
let callee = self.collect_expr_opt(e.expr());
306-
let args = if let Some(arg_list) = e.arg_list() {
307-
arg_list.args().filter_map(|e| self.maybe_collect_expr(e)).collect()
308-
} else {
309-
Box::default()
305+
let is_rustc_box = {
306+
let attrs = e.attrs();
307+
attrs.filter_map(|x| x.as_simple_atom()).any(|x| x == "rustc_box")
310308
};
311-
self.alloc_expr(
312-
Expr::Call { callee, args, is_assignee_expr: self.is_lowering_assignee_expr },
313-
syntax_ptr,
314-
)
309+
if is_rustc_box {
310+
let expr = self.collect_expr_opt(e.arg_list().and_then(|x| x.args().next()));
311+
self.alloc_expr(Expr::Box { expr }, syntax_ptr)
312+
} else {
313+
let callee = self.collect_expr_opt(e.expr());
314+
let args = if let Some(arg_list) = e.arg_list() {
315+
arg_list.args().filter_map(|e| self.maybe_collect_expr(e)).collect()
316+
} else {
317+
Box::default()
318+
};
319+
self.alloc_expr(
320+
Expr::Call {
321+
callee,
322+
args,
323+
is_assignee_expr: self.is_lowering_assignee_expr,
324+
},
325+
syntax_ptr,
326+
)
327+
}
315328
}
316329
ast::Expr::MethodCallExpr(e) => {
317330
let receiver = self.collect_expr_opt(e.receiver());

crates/hir-ty/src/builder.rs

+19
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,25 @@ impl TyBuilder<()> {
232232
TyBuilder::new((), params, parent_subst)
233233
}
234234

235+
pub fn subst_for_closure(
236+
db: &dyn HirDatabase,
237+
parent: DefWithBodyId,
238+
sig_ty: Ty,
239+
) -> Substitution {
240+
let sig_ty = sig_ty.cast(Interner);
241+
let self_subst = iter::once(&sig_ty);
242+
let Some(parent) = parent.as_generic_def_id() else {
243+
return Substitution::from_iter(Interner, self_subst);
244+
};
245+
Substitution::from_iter(
246+
Interner,
247+
self_subst
248+
.chain(generics(db.upcast(), parent).placeholder_subst(db).iter(Interner))
249+
.cloned()
250+
.collect::<Vec<_>>(),
251+
)
252+
}
253+
235254
pub fn build(self) -> Substitution {
236255
let ((), subst) = self.build_internal();
237256
subst

crates/hir-ty/src/chalk_db.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::{
2424
method_resolution::{TraitImpls, TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
2525
to_assoc_type_id, to_chalk_trait_id,
2626
traits::ChalkContext,
27-
utils::generics,
27+
utils::{generics, ClosureSubst},
2828
wrap_empty_binders, AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId,
2929
Interner, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef,
3030
TraitRefExt, Ty, TyBuilder, TyExt, TyKind, WhereClause,
@@ -337,7 +337,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
337337
_closure_id: chalk_ir::ClosureId<Interner>,
338338
substs: &chalk_ir::Substitution<Interner>,
339339
) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
340-
let sig_ty = substs.at(Interner, 0).assert_ty_ref(Interner).clone();
340+
let sig_ty = ClosureSubst(substs).sig_ty();
341341
let sig = &sig_ty.callable_sig(self.db).expect("first closure param should be fn ptr");
342342
let io = rust_ir::FnDefInputsAndOutputDatum {
343343
argument_types: sig.params().to_vec(),

crates/hir-ty/src/chalk_ext.rs

+25-11
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
//! Various extensions traits for Chalk types.
22
3-
use chalk_ir::{FloatTy, IntTy, Mutability, Scalar, TyVariableKind, UintTy};
3+
use chalk_ir::{cast::Cast, FloatTy, IntTy, Mutability, Scalar, TyVariableKind, UintTy};
44
use hir_def::{
55
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint},
66
generics::TypeOrConstParamData,
77
lang_item::LangItem,
88
type_ref::Rawness,
9-
FunctionId, GenericDefId, HasModule, ItemContainerId, Lookup, TraitId,
9+
DefWithBodyId, FunctionId, GenericDefId, HasModule, ItemContainerId, Lookup, TraitId,
1010
};
1111

1212
use crate::{
13-
db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
14-
from_placeholder_idx, to_chalk_trait_id, utils::generics, AdtId, AliasEq, AliasTy, Binders,
15-
CallableDefId, CallableSig, ClosureId, DynTy, FnPointer, ImplTraitId, Interner, Lifetime,
16-
ProjectionTy, QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeFlags,
17-
WhereClause,
13+
db::HirDatabase,
14+
from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,
15+
to_chalk_trait_id,
16+
utils::{generics, ClosureSubst},
17+
AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Canonical, CanonicalVarKinds,
18+
ClosureId, DynTy, FnPointer, ImplTraitId, InEnvironment, Interner, Lifetime, ProjectionTy,
19+
QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeFlags, WhereClause,
1820
};
1921

2022
pub trait TyExt {
@@ -46,6 +48,7 @@ pub trait TyExt {
4648

4749
fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>>;
4850
fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId>;
51+
fn is_copy(self, db: &dyn HirDatabase, owner: DefWithBodyId) -> bool;
4952

5053
/// FIXME: Get rid of this, it's not a good abstraction
5154
fn equals_ctor(&self, other: &Ty) -> bool;
@@ -185,10 +188,7 @@ impl TyExt for Ty {
185188
let sig = db.callable_item_signature(callable_def);
186189
Some(sig.substitute(Interner, parameters))
187190
}
188-
TyKind::Closure(.., substs) => {
189-
let sig_param = substs.at(Interner, 0).assert_ty_ref(Interner);
190-
sig_param.callable_sig(db)
191-
}
191+
TyKind::Closure(.., substs) => ClosureSubst(substs).sig_ty().callable_sig(db),
192192
_ => None,
193193
}
194194
}
@@ -327,6 +327,20 @@ impl TyExt for Ty {
327327
}
328328
}
329329

330+
fn is_copy(self, db: &dyn HirDatabase, owner: DefWithBodyId) -> bool {
331+
let crate_id = owner.module(db.upcast()).krate();
332+
let Some(copy_trait) = db.lang_item(crate_id, LangItem::Copy).and_then(|x| x.as_trait()) else {
333+
return false;
334+
};
335+
let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(self).build();
336+
let env = db.trait_environment_for_body(owner);
337+
let goal = Canonical {
338+
value: InEnvironment::new(&env.env, trait_ref.cast(Interner)),
339+
binders: CanonicalVarKinds::empty(Interner),
340+
};
341+
db.trait_solve(crate_id, None, goal).is_some()
342+
}
343+
330344
fn equals_ctor(&self, other: &Ty) -> bool {
331345
match (self.kind(Interner), other.kind(Interner)) {
332346
(TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2,

crates/hir-ty/src/consteval.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use hir_def::{
77
path::Path,
88
resolver::{Resolver, ValueNs},
99
type_ref::ConstRef,
10-
ConstId, EnumVariantId,
10+
DefWithBodyId, EnumVariantId,
1111
};
1212
use la_arena::{Idx, RawIdx};
1313
use stdx::never;
@@ -57,7 +57,7 @@ pub enum ConstEvalError {
5757
impl From<MirLowerError> for ConstEvalError {
5858
fn from(value: MirLowerError) -> Self {
5959
match value {
60-
MirLowerError::ConstEvalError(e) => *e,
60+
MirLowerError::ConstEvalError(_, e) => *e,
6161
_ => ConstEvalError::MirLowerError(value),
6262
}
6363
}
@@ -168,7 +168,7 @@ pub fn try_const_usize(c: &Const) -> Option<u128> {
168168
pub(crate) fn const_eval_recover(
169169
_: &dyn HirDatabase,
170170
_: &[String],
171-
_: &ConstId,
171+
_: &DefWithBodyId,
172172
_: &Substitution,
173173
) -> Result<Const, ConstEvalError> {
174174
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
@@ -184,10 +184,9 @@ pub(crate) fn const_eval_discriminant_recover(
184184

185185
pub(crate) fn const_eval_query(
186186
db: &dyn HirDatabase,
187-
const_id: ConstId,
187+
def: DefWithBodyId,
188188
subst: Substitution,
189189
) -> Result<Const, ConstEvalError> {
190-
let def = const_id.into();
191190
let body = db.mir_body(def)?;
192191
let c = interpret_mir(db, &body, subst, false)?;
193192
Ok(c)

0 commit comments

Comments
 (0)