Skip to content

Commit ee76b04

Browse files
committed
MIR episode 4
1 parent 797c2f1 commit ee76b04

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

+2557
-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)