Skip to content

Commit

Permalink
Implement builtin#format_args, using rustc's format_args parser
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Sep 5, 2023
1 parent 3431d58 commit abe8f1e
Show file tree
Hide file tree
Showing 19 changed files with 1,740 additions and 14 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/hir-def/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ triomphe.workspace = true

rustc_abi = { version = "0.0.20221221", package = "hkalbasi-rustc-ap-rustc_abi", default-features = false }
rustc_index = { version = "0.0.20221221", package = "hkalbasi-rustc-ap-rustc_index", default-features = false }
rustc_lexer = { version = "0.1.0", package = "ra-ap-rustc_lexer" }

# local deps
stdx.workspace = true
Expand Down
59 changes: 53 additions & 6 deletions crates/hir-def/src/body/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@ use crate::{
db::DefDatabase,
expander::Expander,
hir::{
dummy_expr_id, Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy,
ClosureKind, Expr, ExprId, InlineAsm, Label, LabelId, Literal, LiteralOrConst, MatchArm,
Movability, OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
dummy_expr_id,
format_args::{
self, FormatArgs, FormatArgument, FormatArgumentKind, FormatArgumentsCollector,
},
Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy, ClosureKind,
Expr, ExprId, InlineAsm, Label, LabelId, Literal, LiteralOrConst, MatchArm, Movability,
OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
},
item_scope::BuiltinShadowMode,
lang_item::LangItem,
Expand Down Expand Up @@ -649,15 +653,58 @@ impl ExprCollector<'_> {
}
ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
ast::Expr::AsmExpr(e) => {
let expr = Expr::InlineAsm(InlineAsm { e: self.collect_expr_opt(e.expr()) });
self.alloc_expr(expr, syntax_ptr)
let e = self.collect_expr_opt(e.expr());
self.alloc_expr(Expr::InlineAsm(InlineAsm { e }), syntax_ptr)
}
ast::Expr::OffsetOfExpr(e) => {
let container = Interned::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
let fields = e.fields().map(|it| it.as_name()).collect();
self.alloc_expr(Expr::OffsetOf(OffsetOf { container, fields }), syntax_ptr)
}
ast::Expr::FormatArgsExpr(_) => self.missing_expr(),
ast::Expr::FormatArgsExpr(f) => {
let mut args = FormatArgumentsCollector::new();
f.args().for_each(|arg| {
args.add(FormatArgument {
kind: match arg.name() {
Some(name) => FormatArgumentKind::Named(name.as_name()),
None => FormatArgumentKind::Normal,
},
expr: self.collect_expr_opt(arg.expr()),
});
});
let template = f.template();
let fmt_snippet = template.as_ref().map(ToString::to_string);
let expr = self.collect_expr_opt(f.template());
if let Expr::Literal(Literal::String(_)) = self.body[expr] {
let source = self.source_map.expr_map_back[expr].clone();
let is_direct_literal = source.file_id == self.expander.current_file_id;
if let ast::Expr::Literal(l) =
source.value.to_node(&self.db.parse_or_expand(source.file_id))
{
if let ast::LiteralKind::String(s) = l.kind() {
return Some(self.alloc_expr(
Expr::FormatArgs(format_args::parse(
expr,
&s,
fmt_snippet,
args,
is_direct_literal,
)),
syntax_ptr,
));
}
}
}

self.alloc_expr(
Expr::FormatArgs(FormatArgs {
template_expr: expr,
template: Default::default(),
arguments: args.finish(),
}),
syntax_ptr,
)
}
})
}

Expand Down
5 changes: 5 additions & 0 deletions crates/hir-def/src/body/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ impl Printer<'_> {
Expr::Missing => w!(self, "�"),
Expr::Underscore => w!(self, "_"),
Expr::InlineAsm(_) => w!(self, "builtin#asm(_)"),
Expr::FormatArgs(_fmt_args) => {
w!(self, "builtin#format_args(");
// FIXME
w!(self, ")");
}
Expr::OffsetOf(offset_of) => {
w!(self, "builtin#offset_of(");
self.print_type_ref(&offset_of.container);
Expand Down
14 changes: 12 additions & 2 deletions crates/hir-def/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//! See also a neighboring `body` module.

pub mod type_ref;
pub mod format_args;

use std::fmt;

Expand All @@ -24,6 +25,7 @@ use syntax::ast;

use crate::{
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
hir::format_args::{FormatArgs, FormatArgumentKind},
path::{GenericArgs, Path},
type_ref::{Mutability, Rawness, TypeRef},
BlockId, ConstBlockId,
Expand Down Expand Up @@ -117,7 +119,6 @@ impl From<ast::LiteralKind> for Literal {
fn from(ast_lit_kind: ast::LiteralKind) -> Self {
use ast::LiteralKind;
match ast_lit_kind {
// FIXME: these should have actual values filled in, but unsure on perf impact
LiteralKind::IntNumber(lit) => {
if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) {
Literal::Float(
Expand Down Expand Up @@ -283,6 +284,7 @@ pub enum Expr {
Underscore,
OffsetOf(OffsetOf),
InlineAsm(InlineAsm),
FormatArgs(FormatArgs),
}

#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -355,7 +357,15 @@ impl Expr {
match self {
Expr::Missing => {}
Expr::Path(_) | Expr::OffsetOf(_) => {}
Expr::InlineAsm(e) => f(e.e),
Expr::InlineAsm(it) => f(it.e),
Expr::FormatArgs(it) => {
f(it.template_expr);
it.arguments
.arguments
.iter()
.filter(|it| !matches!(it.kind, FormatArgumentKind::Captured(_)))
.for_each(|it| f(it.expr));
}
Expr::If { condition, then_branch, else_branch } => {
f(*condition);
f(*then_branch);
Expand Down

0 comments on commit abe8f1e

Please sign in to comment.