Skip to content

Commit 824334c

Browse files
committed
MIR episode 4
1 parent 797c2f1 commit 824334c

Some content is hidden

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

52 files changed

+2438
-721
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/base-db/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ pub const DEFAULT_PARSE_LRU_CAP: usize = 128;
5858
pub trait FileLoader {
5959
/// Text of the file.
6060
fn file_text(&self, file_id: FileId) -> Arc<str>;
61+
fn file_path_for_display(&self, file_id: FileId) -> Arc<str>;
6162
fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId>;
6263
fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>>;
6364
}
@@ -91,6 +92,10 @@ fn parse_query(db: &dyn SourceDatabase, file_id: FileId) -> Parse<ast::SourceFil
9192
pub trait SourceDatabaseExt: SourceDatabase {
9293
#[salsa::input]
9394
fn file_text(&self, file_id: FileId) -> Arc<str>;
95+
/// This is only intended to be used in displaying things like stack traces to the user. You should
96+
/// use `SourceRoot` for working with structure of directories and file system.
97+
#[salsa::input]
98+
fn file_path_for_display(&self, file_id: FileId) -> Arc<str>;
9499
/// Path to a file, relative to the root of its source root.
95100
/// Source root of the file.
96101
#[salsa::input]
@@ -121,6 +126,9 @@ impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> {
121126
fn file_text(&self, file_id: FileId) -> Arc<str> {
122127
SourceDatabaseExt::file_text(self.0, file_id)
123128
}
129+
fn file_path_for_display(&self, file_id: FileId) -> Arc<str> {
130+
SourceDatabaseExt::file_path_for_display(self.0, file_id)
131+
}
124132
fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> {
125133
// FIXME: this *somehow* should be platform agnostic...
126134
let source_root = self.0.file_source_root(path.anchor);

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

+27-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,33 @@ 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+
if let Some(arg) = e.arg_list().into_iter().flat_map(|x| x.args()).next() {
311+
let expr = self.collect_expr(arg);
312+
self.alloc_expr(Expr::Box { expr }, syntax_ptr)
313+
} else {
314+
self.alloc_expr(Expr::Missing, syntax_ptr)
315+
}
316+
} else {
317+
let callee = self.collect_expr_opt(e.expr());
318+
let args = if let Some(arg_list) = e.arg_list() {
319+
arg_list.args().filter_map(|e| self.maybe_collect_expr(e)).collect()
320+
} else {
321+
Box::default()
322+
};
323+
self.alloc_expr(
324+
Expr::Call {
325+
callee,
326+
args,
327+
is_assignee_expr: self.is_lowering_assignee_expr,
328+
},
329+
syntax_ptr,
330+
)
331+
}
315332
}
316333
ast::Expr::MethodCallExpr(e) => {
317334
let receiver = self.collect_expr_opt(e.receiver());

crates/hir-def/src/test_db.rs

+3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ impl FileLoader for TestDB {
7474
fn file_text(&self, file_id: FileId) -> Arc<str> {
7575
FileLoaderDelegate(self).file_text(file_id)
7676
}
77+
fn file_path_for_display(&self, file_id: FileId) -> Arc<str> {
78+
FileLoaderDelegate(self).file_path_for_display(file_id)
79+
}
7780
fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> {
7881
FileLoaderDelegate(self).resolve_path(path)
7982
}

crates/hir-ty/src/builder.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use chalk_ir::{
66
cast::{Cast, CastTo, Caster},
77
fold::TypeFoldable,
88
interner::HasInterner,
9-
AdtId, DebruijnIndex, Scalar,
9+
AdtId, DebruijnIndex, GenericArgData, Scalar,
1010
};
1111
use hir_def::{
1212
builtin_type::BuiltinType, generics::TypeOrConstParamData, ConstParamId, DefWithBodyId,
@@ -232,6 +232,28 @@ 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+
Substitution::from_iter(
241+
Interner,
242+
parent
243+
.as_generic_def_id()
244+
.map(|p| {
245+
generics(db.upcast(), p)
246+
.placeholder_subst(db)
247+
.iter(Interner)
248+
.chain(iter::once(&GenericArgData::Ty(sig_ty).intern(Interner)))
249+
.cloned()
250+
.collect::<Vec<_>>()
251+
})
252+
.into_iter()
253+
.flatten(),
254+
)
255+
}
256+
235257
pub fn build(self) -> Substitution {
236258
let ((), subst) = self.build_internal();
237259
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)