Skip to content

Commit

Permalink
Auto merge of #15557 - Veykril:builtin-syntax, r=Veykril
Browse files Browse the repository at this point in the history
Parse builtin# syntax and add typechecking for builtin#offset_of expression

Also removes box syntax, fixes #14504

cc rust-lang/compiler-team#580 #15082
  • Loading branch information
bors committed Sep 5, 2023
2 parents 2df30e1 + 3431d58 commit caeea45
Show file tree
Hide file tree
Showing 30 changed files with 465 additions and 265 deletions.
20 changes: 13 additions & 7 deletions crates/hir-def/src/body/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ use crate::{
expander::Expander,
hir::{
dummy_expr_id, Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy,
ClosureKind, Expr, ExprId, Label, LabelId, Literal, LiteralOrConst, MatchArm, Movability,
Pat, PatId, RecordFieldPat, RecordLitField, Statement,
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 @@ -579,11 +579,6 @@ impl ExprCollector<'_> {
syntax_ptr,
)
}
ast::Expr::BoxExpr(e) => {
let expr = self.collect_expr_opt(e.expr());
self.alloc_expr(Expr::Box { expr }, syntax_ptr)
}

ast::Expr::ArrayExpr(e) => {
let kind = e.kind();

Expand Down Expand Up @@ -653,6 +648,16 @@ 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)
}
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(),
})
}

Expand All @@ -663,6 +668,7 @@ impl ExprCollector<'_> {
let result_expr_id = self.alloc_expr(Expr::Missing, syntax_ptr);
let prev_binding_owner = self.current_binding_owner.take();
self.current_binding_owner = Some(result_expr_id);

(result_expr_id, prev_binding_owner)
}

Expand Down
11 changes: 11 additions & 0 deletions crates/hir-def/src/body/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use std::fmt::{self, Write};

use hir_expand::db::ExpandDatabase;
use itertools::Itertools;
use syntax::ast::HasName;

use crate::{
Expand Down Expand Up @@ -154,6 +155,16 @@ impl Printer<'_> {
match expr {
Expr::Missing => w!(self, "�"),
Expr::Underscore => w!(self, "_"),
Expr::InlineAsm(_) => w!(self, "builtin#asm(_)"),
Expr::OffsetOf(offset_of) => {
w!(self, "builtin#offset_of(");
self.print_type_ref(&offset_of.container);
w!(
self,
", {})",
offset_of.fields.iter().format_with(".", |field, f| f(&field.display(self.db)))
);
}
Expr::Path(path) => self.print_path(path),
Expr::If { condition, then_branch, else_branch } => {
w!(self, "if ");
Expand Down
16 changes: 15 additions & 1 deletion crates/hir-def/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,19 @@ pub enum Expr {
Array(Array),
Literal(Literal),
Underscore,
OffsetOf(OffsetOf),
InlineAsm(InlineAsm),
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OffsetOf {
pub container: Interned<TypeRef>,
pub fields: Box<[Name]>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InlineAsm {
pub e: ExprId,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down Expand Up @@ -341,7 +354,8 @@ impl Expr {
pub fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) {
match self {
Expr::Missing => {}
Expr::Path(_) => {}
Expr::Path(_) | Expr::OffsetOf(_) => {}
Expr::InlineAsm(e) => f(e.e),
Expr::If { condition, then_branch, else_branch } => {
f(*condition);
f(*then_branch);
Expand Down
39 changes: 39 additions & 0 deletions crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,45 @@ fn main() { 0 as u32; }
);
}

#[test]
fn test_asm_expand() {
check(
r#"
#[rustc_builtin_macro]
macro_rules! asm {() => {}}
fn main() {
let i: u64 = 3;
let o: u64;
unsafe {
asm!(
"mov {0}, {1}",
"add {0}, 5",
out(reg) o,
in(reg) i,
);
}
}
"#,
expect![[r##"
#[rustc_builtin_macro]
macro_rules! asm {() => {}}
fn main() {
let i: u64 = 3;
let o: u64;
unsafe {
builtin #asm ( {
$crate::format_args!("mov {0}, {1}");
$crate::format_args!("add {0}, 5");
}
);
}
}
"##]],
);
}

#[test]
fn test_line_expand() {
check(
Expand Down
12 changes: 8 additions & 4 deletions crates/hir-expand/src/builtin_fn_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ fn asm_expand(
_id: MacroCallId,
tt: &tt::Subtree,
) -> ExpandResult<tt::Subtree> {
// FIXME: parse asm here

// We expand all assembly snippets to `format_args!` invocations to get format syntax
// highlighting for them.

Expand All @@ -415,10 +417,12 @@ fn asm_expand(
}
}

let expanded = quote! {{
##literals
loop {}
}};
let pound = quote! {@PUNCT '#'};
let expanded = quote! {
builtin #pound asm (
{##literals}
)
};
ExpandResult::ok(expanded)
}

Expand Down
3 changes: 3 additions & 0 deletions crates/hir-ty/src/infer/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@ impl InferenceContext<'_> {

fn walk_expr_without_adjust(&mut self, tgt_expr: ExprId) {
match &self.body[tgt_expr] {
Expr::OffsetOf(_) => (),
Expr::InlineAsm(e) => self.walk_expr_without_adjust(e.e),
Expr::If { condition, then_branch, else_branch } => {
self.consume_expr(*condition);
self.consume_expr(*then_branch);
Expand Down Expand Up @@ -620,6 +622,7 @@ impl InferenceContext<'_> {
| Expr::Tuple { exprs, is_assignee_expr: _ } => {
self.consume_exprs(exprs.iter().copied())
}

Expr::Missing
| Expr::Continue { .. }
| Expr::Path(_)
Expand Down
5 changes: 5 additions & 0 deletions crates/hir-ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,11 @@ impl InferenceContext<'_> {
});
expected
}
Expr::OffsetOf(_) => TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner),
Expr::InlineAsm(it) => {
self.infer_expr_no_expect(it.e);
self.result.standard_types.unit.clone()
}
};
// use a new type variable if we got unknown here
let ty = self.insert_type_vars_shallow(ty);
Expand Down
2 changes: 2 additions & 0 deletions crates/hir-ty/src/infer/mutability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ impl InferenceContext<'_> {
fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutability) {
match &self.body[tgt_expr] {
Expr::Missing => (),
Expr::InlineAsm(e) => self.infer_mut_expr_without_adjust(e.e, Mutability::Not),
Expr::OffsetOf(_) => (),
&Expr::If { condition, then_branch, else_branch } => {
self.infer_mut_expr(condition, Mutability::Not);
self.infer_mut_expr(then_branch, Mutability::Not);
Expand Down
6 changes: 6 additions & 0 deletions crates/hir-ty/src/mir/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
mut current: BasicBlockId,
) -> Result<Option<BasicBlockId>> {
match &self.body.exprs[expr_id] {
Expr::OffsetOf(_) => {
not_supported!("builtin#offset_of")
}
Expr::InlineAsm(_) => {
not_supported!("builtin#asm")
}
Expr::Missing => {
if let DefWithBodyId::FunctionId(f) = self.owner {
let assoc = f.lookup(self.db.upcast());
Expand Down
89 changes: 26 additions & 63 deletions crates/hir-ty/src/tests/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,6 @@ use expect_test::expect;

use super::{check, check_infer, check_no_mismatches, check_types};

#[test]
fn infer_box() {
check_types(
r#"
//- /main.rs crate:main deps:std
fn test() {
let x = box 1;
let t = (x, box x, box &1, box [1]);
t;
} //^ (Box<i32>, Box<Box<i32>>, Box<&i32>, Box<[i32; 1]>)
//- /std.rs crate:std
#[prelude_import] use prelude::*;
mod prelude {}
mod boxed {
#[lang = "owned_box"]
pub struct Box<T: ?Sized> {
inner: *mut T,
}
}
"#,
);
}

#[test]
fn infer_box_with_allocator() {
check_types(
r#"
//- /main.rs crate:main deps:std
fn test() {
let x = box 1;
let t = (x, box x, box &1, box [1]);
t;
} //^ (Box<i32, {unknown}>, Box<Box<i32, {unknown}>, {unknown}>, Box<&i32, {unknown}>, Box<[i32; 1], {unknown}>)
//- /std.rs crate:std
#[prelude_import] use prelude::*;
mod boxed {
#[lang = "owned_box"]
pub struct Box<T: ?Sized, A: Allocator> {
inner: *mut T,
allocator: A,
}
}
"#,
);
}

#[test]
fn infer_adt_self() {
check_types(
Expand Down Expand Up @@ -2763,8 +2714,8 @@ impl<T> [T] {
}
fn test() {
let vec = <[_]>::into_vec(box [1i32]);
let v: Vec<Box<dyn B>> = <[_]> :: into_vec(box [box Astruct]);
let vec = <[_]>::into_vec(#[rustc_box] Box::new([1i32]));
let v: Vec<Box<dyn B>> = <[_]> :: into_vec(#[rustc_box] Box::new([#[rustc_box] Box::new(Astruct)]));
}
trait B{}
Expand All @@ -2774,20 +2725,20 @@ impl B for Astruct {}
expect![[r#"
604..608 'self': Box<[T], A>
637..669 '{ ... }': Vec<T, A>
683..796 '{ ...t]); }': ()
683..853 '{ ...])); }': ()
693..696 'vec': Vec<i32, Global>
699..714 '<[_]>::into_vec': fn into_vec<i32, Global>(Box<[i32], Global>) -> Vec<i32, Global>
699..726 '<[_]>:...1i32])': Vec<i32, Global>
715..725 'box [1i32]': Box<[i32; 1], Global>
719..725 '[1i32]': [i32; 1]
720..724 '1i32': i32
736..737 'v': Vec<Box<dyn B, Global>, Global>
757..774 '<[_]> ...to_vec': fn into_vec<Box<dyn B, Global>, Global>(Box<[Box<dyn B, Global>], Global>) -> Vec<Box<dyn B, Global>, Global>
757..793 '<[_]> ...ruct])': Vec<Box<dyn B, Global>, Global>
775..792 'box [b...truct]': Box<[Box<dyn B, Global>; 1], Global>
779..792 '[box Astruct]': [Box<dyn B, Global>; 1]
780..791 'box Astruct': Box<Astruct, Global>
784..791 'Astruct': Astruct
699..745 '<[_]>:...i32]))': Vec<i32, Global>
715..744 '#[rust...1i32])': Box<[i32; 1], Global>
737..743 '[1i32]': [i32; 1]
738..742 '1i32': i32
755..756 'v': Vec<Box<dyn B, Global>, Global>
776..793 '<[_]> ...to_vec': fn into_vec<Box<dyn B, Global>, Global>(Box<[Box<dyn B, Global>], Global>) -> Vec<Box<dyn B, Global>, Global>
776..850 '<[_]> ...ct)]))': Vec<Box<dyn B, Global>, Global>
794..849 '#[rust...uct)])': Box<[Box<dyn B, Global>; 1], Global>
816..848 '[#[rus...ruct)]': [Box<dyn B, Global>; 1]
817..847 '#[rust...truct)': Box<Astruct, Global>
839..846 'Astruct': Astruct
"#]],
)
}
Expand Down Expand Up @@ -3649,3 +3600,15 @@ fn main() {
"#,
);
}

#[test]
fn offset_of() {
check_types(
r#"
fn main() {
builtin#offset_of((,), 0);
// ^^^^^^^^^^^^^^^^^^^^^^^^^ usize
}
"#,
);
}
Loading

0 comments on commit caeea45

Please sign in to comment.