Skip to content

feat: MIR episode 4 #14664

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/base-db/src/change.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl fmt::Debug for Change {
}

impl Change {
pub fn new() -> Change {
pub fn new() -> Self {
Change::default()
}

Expand Down
33 changes: 23 additions & 10 deletions crates/hir-def/src/body/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use syntax::{
ast::{
self, ArrayExprKind, AstChildren, BlockExpr, HasArgList, HasLoopBody, HasName,
self, ArrayExprKind, AstChildren, BlockExpr, HasArgList, HasAttrs, HasLoopBody, HasName,
SlicePatComponents,
},
AstNode, AstPtr, SyntaxNodePtr,
Expand Down Expand Up @@ -302,16 +302,29 @@ impl ExprCollector<'_> {
self.alloc_expr(Expr::For { iterable, pat, body, label }, syntax_ptr)
}
ast::Expr::CallExpr(e) => {
let callee = self.collect_expr_opt(e.expr());
let args = if let Some(arg_list) = e.arg_list() {
arg_list.args().filter_map(|e| self.maybe_collect_expr(e)).collect()
} else {
Box::default()
let is_rustc_box = {
let attrs = e.attrs();
attrs.filter_map(|x| x.as_simple_atom()).any(|x| x == "rustc_box")
};
self.alloc_expr(
Expr::Call { callee, args, is_assignee_expr: self.is_lowering_assignee_expr },
syntax_ptr,
)
if is_rustc_box {
let expr = self.collect_expr_opt(e.arg_list().and_then(|x| x.args().next()));
self.alloc_expr(Expr::Box { expr }, syntax_ptr)
} else {
let callee = self.collect_expr_opt(e.expr());
let args = if let Some(arg_list) = e.arg_list() {
arg_list.args().filter_map(|e| self.maybe_collect_expr(e)).collect()
} else {
Box::default()
};
self.alloc_expr(
Expr::Call {
callee,
args,
is_assignee_expr: self.is_lowering_assignee_expr,
},
syntax_ptr,
)
}
}
ast::Expr::MethodCallExpr(e) => {
let receiver = self.collect_expr_opt(e.receiver());
Expand Down
19 changes: 19 additions & 0 deletions crates/hir-ty/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,25 @@ impl TyBuilder<()> {
TyBuilder::new((), params, parent_subst)
}

pub fn subst_for_closure(
db: &dyn HirDatabase,
parent: DefWithBodyId,
sig_ty: Ty,
) -> Substitution {
let sig_ty = sig_ty.cast(Interner);
let self_subst = iter::once(&sig_ty);
let Some(parent) = parent.as_generic_def_id() else {
return Substitution::from_iter(Interner, self_subst);
};
Substitution::from_iter(
Interner,
self_subst
.chain(generics(db.upcast(), parent).placeholder_subst(db).iter(Interner))
.cloned()
.collect::<Vec<_>>(),
)
}

pub fn build(self) -> Substitution {
let ((), subst) = self.build_internal();
subst
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-ty/src/chalk_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::{
method_resolution::{TraitImpls, TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
to_assoc_type_id, to_chalk_trait_id,
traits::ChalkContext,
utils::generics,
utils::{generics, ClosureSubst},
wrap_empty_binders, AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId,
Interner, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef,
TraitRefExt, Ty, TyBuilder, TyExt, TyKind, WhereClause,
Expand Down Expand Up @@ -337,7 +337,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
_closure_id: chalk_ir::ClosureId<Interner>,
substs: &chalk_ir::Substitution<Interner>,
) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
let sig_ty = substs.at(Interner, 0).assert_ty_ref(Interner).clone();
let sig_ty = ClosureSubst(substs).sig_ty();
let sig = &sig_ty.callable_sig(self.db).expect("first closure param should be fn ptr");
let io = rust_ir::FnDefInputsAndOutputDatum {
argument_types: sig.params().to_vec(),
Expand Down
36 changes: 25 additions & 11 deletions crates/hir-ty/src/chalk_ext.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
//! Various extensions traits for Chalk types.

use chalk_ir::{FloatTy, IntTy, Mutability, Scalar, TyVariableKind, UintTy};
use chalk_ir::{cast::Cast, FloatTy, IntTy, Mutability, Scalar, TyVariableKind, UintTy};
use hir_def::{
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint},
generics::TypeOrConstParamData,
lang_item::LangItem,
type_ref::Rawness,
FunctionId, GenericDefId, HasModule, ItemContainerId, Lookup, TraitId,
DefWithBodyId, FunctionId, GenericDefId, HasModule, ItemContainerId, Lookup, TraitId,
};

use crate::{
db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
from_placeholder_idx, to_chalk_trait_id, utils::generics, AdtId, AliasEq, AliasTy, Binders,
CallableDefId, CallableSig, ClosureId, DynTy, FnPointer, ImplTraitId, Interner, Lifetime,
ProjectionTy, QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeFlags,
WhereClause,
db::HirDatabase,
from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,
to_chalk_trait_id,
utils::{generics, ClosureSubst},
AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Canonical, CanonicalVarKinds,
ClosureId, DynTy, FnPointer, ImplTraitId, InEnvironment, Interner, Lifetime, ProjectionTy,
QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeFlags, WhereClause,
};

pub trait TyExt {
Expand Down Expand Up @@ -46,6 +48,7 @@ pub trait TyExt {

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

/// FIXME: Get rid of this, it's not a good abstraction
fn equals_ctor(&self, other: &Ty) -> bool;
Expand Down Expand Up @@ -185,10 +188,7 @@ impl TyExt for Ty {
let sig = db.callable_item_signature(callable_def);
Some(sig.substitute(Interner, parameters))
}
TyKind::Closure(.., substs) => {
let sig_param = substs.at(Interner, 0).assert_ty_ref(Interner);
sig_param.callable_sig(db)
}
TyKind::Closure(.., substs) => ClosureSubst(substs).sig_ty().callable_sig(db),
_ => None,
}
}
Expand Down Expand Up @@ -327,6 +327,20 @@ impl TyExt for Ty {
}
}

fn is_copy(self, db: &dyn HirDatabase, owner: DefWithBodyId) -> bool {
let crate_id = owner.module(db.upcast()).krate();
let Some(copy_trait) = db.lang_item(crate_id, LangItem::Copy).and_then(|x| x.as_trait()) else {
return false;
};
let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(self).build();
let env = db.trait_environment_for_body(owner);
let goal = Canonical {
value: InEnvironment::new(&env.env, trait_ref.cast(Interner)),
binders: CanonicalVarKinds::empty(Interner),
};
db.trait_solve(crate_id, None, goal).is_some()
}

fn equals_ctor(&self, other: &Ty) -> bool {
match (self.kind(Interner), other.kind(Interner)) {
(TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2,
Expand Down
9 changes: 4 additions & 5 deletions crates/hir-ty/src/consteval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use hir_def::{
path::Path,
resolver::{Resolver, ValueNs},
type_ref::ConstRef,
ConstId, EnumVariantId,
DefWithBodyId, EnumVariantId,
};
use la_arena::{Idx, RawIdx};
use stdx::never;
Expand Down Expand Up @@ -57,7 +57,7 @@ pub enum ConstEvalError {
impl From<MirLowerError> for ConstEvalError {
fn from(value: MirLowerError) -> Self {
match value {
MirLowerError::ConstEvalError(e) => *e,
MirLowerError::ConstEvalError(_, e) => *e,
_ => ConstEvalError::MirLowerError(value),
}
}
Expand Down Expand Up @@ -168,7 +168,7 @@ pub fn try_const_usize(c: &Const) -> Option<u128> {
pub(crate) fn const_eval_recover(
_: &dyn HirDatabase,
_: &[String],
_: &ConstId,
_: &DefWithBodyId,
_: &Substitution,
) -> Result<Const, ConstEvalError> {
Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
Expand All @@ -184,10 +184,9 @@ pub(crate) fn const_eval_discriminant_recover(

pub(crate) fn const_eval_query(
db: &dyn HirDatabase,
const_id: ConstId,
def: DefWithBodyId,
subst: Substitution,
) -> Result<Const, ConstEvalError> {
let def = const_id.into();
let body = db.mir_body(def)?;
let c = interpret_mir(db, &body, subst, false)?;
Ok(c)
Expand Down
Loading