mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 22:54:58 +00:00
MIR episode 5
This commit is contained in:
parent
9b3387454d
commit
cbcafd3539
36 changed files with 1532 additions and 362 deletions
|
@ -165,7 +165,7 @@ impl Body {
|
|||
};
|
||||
let expander = Expander::new(db, file_id, module);
|
||||
let (mut body, source_map) =
|
||||
Body::new(db, expander, params, body, module.krate, is_async_fn);
|
||||
Body::new(db, def, expander, params, body, module.krate, is_async_fn);
|
||||
body.shrink_to_fit();
|
||||
|
||||
(Arc::new(body), Arc::new(source_map))
|
||||
|
@ -189,13 +189,14 @@ impl Body {
|
|||
|
||||
fn new(
|
||||
db: &dyn DefDatabase,
|
||||
owner: DefWithBodyId,
|
||||
expander: Expander,
|
||||
params: Option<(ast::ParamList, impl Iterator<Item = bool>)>,
|
||||
body: Option<ast::Expr>,
|
||||
krate: CrateId,
|
||||
is_async_fn: bool,
|
||||
) -> (Body, BodySourceMap) {
|
||||
lower::lower(db, expander, params, body, krate, is_async_fn)
|
||||
lower::lower(db, owner, expander, params, body, krate, is_async_fn)
|
||||
}
|
||||
|
||||
fn shrink_to_fit(&mut self) {
|
||||
|
|
|
@ -40,11 +40,12 @@ use crate::{
|
|||
nameres::{DefMap, MacroSubNs},
|
||||
path::{GenericArgs, Path},
|
||||
type_ref::{Mutability, Rawness, TypeRef},
|
||||
AdtId, BlockId, BlockLoc, ModuleDefId, UnresolvedMacro,
|
||||
AdtId, BlockId, BlockLoc, DefWithBodyId, ModuleDefId, UnresolvedMacro,
|
||||
};
|
||||
|
||||
pub(super) fn lower(
|
||||
db: &dyn DefDatabase,
|
||||
owner: DefWithBodyId,
|
||||
expander: Expander,
|
||||
params: Option<(ast::ParamList, impl Iterator<Item = bool>)>,
|
||||
body: Option<ast::Expr>,
|
||||
|
@ -53,6 +54,7 @@ pub(super) fn lower(
|
|||
) -> (Body, BodySourceMap) {
|
||||
ExprCollector {
|
||||
db,
|
||||
owner,
|
||||
krate,
|
||||
def_map: expander.module.def_map(db),
|
||||
source_map: BodySourceMap::default(),
|
||||
|
@ -80,6 +82,7 @@ pub(super) fn lower(
|
|||
struct ExprCollector<'a> {
|
||||
db: &'a dyn DefDatabase,
|
||||
expander: Expander,
|
||||
owner: DefWithBodyId,
|
||||
def_map: Arc<DefMap>,
|
||||
ast_id_map: Arc<AstIdMap>,
|
||||
krate: CrateId,
|
||||
|
@ -269,16 +272,13 @@ impl ExprCollector<'_> {
|
|||
}
|
||||
Some(ast::BlockModifier::Const(_)) => {
|
||||
self.with_label_rib(RibKind::Constant, |this| {
|
||||
this.collect_as_a_binding_owner_bad(
|
||||
|this| {
|
||||
this.collect_block_(e, |id, statements, tail| Expr::Const {
|
||||
id,
|
||||
statements,
|
||||
tail,
|
||||
})
|
||||
},
|
||||
syntax_ptr,
|
||||
)
|
||||
let (result_expr_id, prev_binding_owner) =
|
||||
this.initialize_binding_owner(syntax_ptr);
|
||||
let inner_expr = this.collect_block(e);
|
||||
let x = this.db.intern_anonymous_const((this.owner, inner_expr));
|
||||
this.body.exprs[result_expr_id] = Expr::Const(x);
|
||||
this.current_binding_owner = prev_binding_owner;
|
||||
result_expr_id
|
||||
})
|
||||
}
|
||||
None => self.collect_block(e),
|
||||
|
|
|
@ -436,8 +436,8 @@ impl<'a> Printer<'a> {
|
|||
Expr::Async { id: _, statements, tail } => {
|
||||
self.print_block(Some("async "), statements, tail);
|
||||
}
|
||||
Expr::Const { id: _, statements, tail } => {
|
||||
self.print_block(Some("const "), statements, tail);
|
||||
Expr::Const(id) => {
|
||||
w!(self, "const {{ /* {id:?} */ }}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -218,9 +218,10 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope
|
|||
scopes.set_scope(expr, scope);
|
||||
compute_block_scopes(statements, *tail, body, scopes, &mut scope);
|
||||
}
|
||||
Expr::Unsafe { id, statements, tail }
|
||||
| Expr::Async { id, statements, tail }
|
||||
| Expr::Const { id, statements, tail } => {
|
||||
Expr::Const(_) => {
|
||||
// FIXME: This is broken.
|
||||
}
|
||||
Expr::Unsafe { id, statements, tail } | Expr::Async { id, statements, tail } => {
|
||||
let mut scope = scopes.new_block_scope(*scope, *id, None);
|
||||
// Overwrite the old scope for the block expr, so that every block scope can be found
|
||||
// via the block itself (important for blocks that only contain items, no expressions).
|
||||
|
|
|
@ -16,16 +16,17 @@ use crate::{
|
|||
TraitAliasData, TraitData, TypeAliasData,
|
||||
},
|
||||
generics::GenericParams,
|
||||
hir::ExprId,
|
||||
import_map::ImportMap,
|
||||
item_tree::{AttrOwner, ItemTree},
|
||||
lang_item::{LangItem, LangItemTarget, LangItems},
|
||||
nameres::{diagnostics::DefDiagnostic, DefMap},
|
||||
visibility::{self, Visibility},
|
||||
AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId,
|
||||
ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId,
|
||||
LocalFieldId, Macro2Id, Macro2Loc, MacroRulesId, MacroRulesLoc, ProcMacroId, ProcMacroLoc,
|
||||
StaticId, StaticLoc, StructId, StructLoc, TraitAliasId, TraitAliasLoc, TraitId, TraitLoc,
|
||||
TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, VariantId,
|
||||
AnonymousConstId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId,
|
||||
EnumLoc, ExternBlockId, ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc,
|
||||
LocalEnumVariantId, LocalFieldId, Macro2Id, Macro2Loc, MacroRulesId, MacroRulesLoc,
|
||||
ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitAliasId,
|
||||
TraitAliasLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, VariantId,
|
||||
};
|
||||
|
||||
#[salsa::query_group(InternDatabaseStorage)]
|
||||
|
@ -60,6 +61,8 @@ pub trait InternDatabase: SourceDatabase {
|
|||
fn intern_proc_macro(&self, loc: ProcMacroLoc) -> ProcMacroId;
|
||||
#[salsa::interned]
|
||||
fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId;
|
||||
#[salsa::interned]
|
||||
fn intern_anonymous_const(&self, id: (DefWithBodyId, ExprId)) -> AnonymousConstId;
|
||||
}
|
||||
|
||||
#[salsa::query_group(DefDatabaseStorage)]
|
||||
|
|
|
@ -26,7 +26,7 @@ use crate::{
|
|||
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
|
||||
path::{GenericArgs, Path},
|
||||
type_ref::{Mutability, Rawness, TypeRef},
|
||||
BlockId,
|
||||
AnonymousConstId, BlockId,
|
||||
};
|
||||
|
||||
pub use syntax::ast::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp};
|
||||
|
@ -169,11 +169,7 @@ pub enum Expr {
|
|||
statements: Box<[Statement]>,
|
||||
tail: Option<ExprId>,
|
||||
},
|
||||
Const {
|
||||
id: Option<BlockId>,
|
||||
statements: Box<[Statement]>,
|
||||
tail: Option<ExprId>,
|
||||
},
|
||||
Const(AnonymousConstId),
|
||||
Unsafe {
|
||||
id: Option<BlockId>,
|
||||
statements: Box<[Statement]>,
|
||||
|
@ -355,10 +351,10 @@ impl Expr {
|
|||
Expr::Let { expr, .. } => {
|
||||
f(*expr);
|
||||
}
|
||||
Expr::Const(_) => (),
|
||||
Expr::Block { statements, tail, .. }
|
||||
| Expr::Unsafe { statements, tail, .. }
|
||||
| Expr::Async { statements, tail, .. }
|
||||
| Expr::Const { statements, tail, .. } => {
|
||||
| Expr::Async { statements, tail, .. } => {
|
||||
for stmt in statements.iter() {
|
||||
match stmt {
|
||||
Statement::Let { initializer, else_branch, .. } => {
|
||||
|
|
|
@ -59,7 +59,11 @@ mod pretty;
|
|||
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use base_db::{impl_intern_key, salsa, CrateId, ProcMacroKind};
|
||||
use base_db::{
|
||||
impl_intern_key,
|
||||
salsa::{self, InternId},
|
||||
CrateId, ProcMacroKind,
|
||||
};
|
||||
use hir_expand::{
|
||||
ast_id_map::FileAstId,
|
||||
attrs::{Attr, AttrId, AttrInput},
|
||||
|
@ -472,6 +476,46 @@ impl_from!(
|
|||
for ModuleDefId
|
||||
);
|
||||
|
||||
// FIXME: make this a DefWithBodyId
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
pub struct AnonymousConstId(InternId);
|
||||
impl_intern_key!(AnonymousConstId);
|
||||
|
||||
/// A constant, which might appears as a const item, an annonymous const block in expressions
|
||||
/// or patterns, or as a constant in types with const generics.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum GeneralConstId {
|
||||
ConstId(ConstId),
|
||||
AnonymousConstId(AnonymousConstId),
|
||||
}
|
||||
|
||||
impl_from!(ConstId, AnonymousConstId for GeneralConstId);
|
||||
|
||||
impl GeneralConstId {
|
||||
pub fn generic_def(self, db: &dyn db::DefDatabase) -> Option<GenericDefId> {
|
||||
match self {
|
||||
GeneralConstId::ConstId(x) => Some(x.into()),
|
||||
GeneralConstId::AnonymousConstId(x) => {
|
||||
let (parent, _) = db.lookup_intern_anonymous_const(x);
|
||||
parent.as_generic_def_id()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(self, db: &dyn db::DefDatabase) -> String {
|
||||
match self {
|
||||
GeneralConstId::ConstId(const_id) => db
|
||||
.const_data(const_id)
|
||||
.name
|
||||
.as_ref()
|
||||
.and_then(|x| x.as_str())
|
||||
.unwrap_or("_")
|
||||
.to_owned(),
|
||||
GeneralConstId::AnonymousConstId(id) => format!("{{anonymous const {id:?}}}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The defs which have a body.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum DefWithBodyId {
|
||||
|
|
|
@ -12,6 +12,9 @@ use crate::{
|
|||
};
|
||||
|
||||
pub(crate) fn print_path(path: &Path, buf: &mut dyn Write) -> fmt::Result {
|
||||
if let Path::LangItem(x) = path {
|
||||
return write!(buf, "$lang_item::{x:?}");
|
||||
}
|
||||
match path.type_anchor() {
|
||||
Some(anchor) => {
|
||||
write!(buf, "<")?;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue