Skip to content
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
1 change: 1 addition & 0 deletions crates/hir-def/src/expr_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,7 @@ impl ExpressionStore {
visitor.on_pat(target);
visitor.on_expr(value);
}
Expr::IncludeBytes => {}
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/hir-def/src/expr_store/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1748,6 +1748,7 @@ impl<'db> ExprCollector<'db> {
self.alloc_expr(Expr::OffsetOf(OffsetOf { container, fields }), syntax_ptr)
}
ast::Expr::FormatArgsExpr(f) => self.collect_format_args(f, syntax_ptr),
ast::Expr::IncludeBytesExpr(_) => self.alloc_expr(Expr::IncludeBytes, syntax_ptr)
})
}

Expand Down
1 change: 1 addition & 0 deletions crates/hir-def/src/expr_store/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ impl Printer<'_> {
Expr::Missing => w!(self, "�"),
Expr::Underscore => w!(self, "_"),
Expr::InlineAsm(_) => w!(self, "builtin#asm(_)"),
Expr::IncludeBytes => w!(self, "include_bytes!(_)"),
Expr::OffsetOf(offset_of) => {
w!(self, "builtin#offset_of(");
self.print_type_ref(offset_of.container);
Expand Down
4 changes: 3 additions & 1 deletion crates/hir-def/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ pub enum Expr {
Underscore,
OffsetOf(OffsetOf),
InlineAsm(InlineAsm),
IncludeBytes,
}

impl Expr {
Expand All @@ -344,7 +345,8 @@ impl Expr {
| Expr::RecordLit { .. }
| Expr::Tuple { .. }
| Expr::OffsetOf(_)
| Expr::Underscore => ExprPrecedence::Unambiguous,
| Expr::Underscore
| Expr::IncludeBytes => ExprPrecedence::Unambiguous,

Expr::Await { .. }
| Expr::Call { .. }
Expand Down
12 changes: 2 additions & 10 deletions crates/hir-expand/src/builtin/fn_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -852,17 +852,9 @@ fn include_bytes_expand(
span: Span,
) -> ExpandResult<tt::TopSubtree> {
// FIXME: actually read the file here if the user asked for macro expansion
let underscore = sym::underscore;
let zero = tt::Literal {
text_and_suffix: sym::_0_u8,
span,
kind: tt::LitKind::Integer,
suffix_len: 3,
};
// We don't use a real length since we can't know the file length, so we use an underscore
// to infer it.
let pound = mk_pound(span);
let res = quote! {span =>
&[#zero; #underscore]
builtin #pound include_bytes
};
ExpandResult::ok(res)
}
Expand Down
2 changes: 2 additions & 0 deletions crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,8 @@ impl<'a, 'b, 'db, D: Delegate<'db>> ExprUseVisitor<'a, 'b, 'db, D> {
self.consume_expr(rhs)?;
}
}

Expr::IncludeBytes => {}
}
Ok(())
}
Expand Down
8 changes: 7 additions & 1 deletion crates/hir-ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,8 @@ impl<'db> InferenceContext<'_, 'db> {
| Expr::Box { .. }
| Expr::RecordLit { .. }
| Expr::Yeet { .. }
| Expr::Missing => false,
| Expr::Missing
| Expr::IncludeBytes => false,
}
}

Expand Down Expand Up @@ -893,6 +894,11 @@ impl<'db> InferenceContext<'_, 'db> {
self.types.types.unit
}
}
Expr::IncludeBytes => {
let len = self.table.next_const_var(Span::Dummy);
let arr = Ty::new_array_with_const_len(self.interner(), self.types.types.u8, len);
Ty::new_ref(self.interner(), self.types.regions.statik, arr, Mutability::Not)
}
};
let ty = self.insert_type_vars_shallow(ty);
self.write_expr_ty(tgt_expr, ty);
Expand Down
3 changes: 2 additions & 1 deletion crates/hir-ty/src/infer/mutability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ impl<'db> InferenceContext<'_, 'db> {
| Expr::Literal(_)
| Expr::Path(_)
| Expr::Continue { .. }
| Expr::Underscore => (),
| Expr::Underscore
| Expr::IncludeBytes => (),
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/hir-ty/src/mir/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1397,6 +1397,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
Ok(Some(current))
}
Expr::Underscore => Ok(Some(current)),
Expr::IncludeBytes => not_supported!("include_bytes!()"),
}
}

Expand Down
3 changes: 2 additions & 1 deletion crates/ide-db/src/syntax_helpers/node_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,8 @@ pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) {
| ast::Expr::YeetExpr(_)
| ast::Expr::OffsetOfExpr(_)
| ast::Expr::FormatArgsExpr(_)
| ast::Expr::AsmExpr(_) => cb(expr),
| ast::Expr::AsmExpr(_)
| ast::Expr::IncludeBytesExpr(_) => cb(expr),
}
}

Expand Down
13 changes: 13 additions & 0 deletions crates/ide-diagnostics/src/handlers/type_must_be_known.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,19 @@ fn foo<T, U: From<T>>(_: T) -> U {
}
fn bar() {
let _: () = foo(any());
}
"#,
);
}

#[test]
fn include_bytes() {
check_diagnostics(
r#"
//- minicore: include_bytes

fn foo() {
include_bytes!("./foo.txt");
}
"#,
);
Expand Down
4 changes: 4 additions & 0 deletions crates/parser/src/grammar/expressions/atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,10 @@ fn builtin_expr(p: &mut Parser<'_>) -> Option<CompletedMarker> {
// builtin#naked_asm("");
// }
parse_asm_expr(p, m)
} else if p.eat_contextual_kw(T![include_bytes]) {
// test include_bytes
// fn foo() { builtin # include_bytes }
Some(m.complete(p, INCLUDE_BYTES_EXPR))
} else {
m.abandon(p);
None
Expand Down
8 changes: 8 additions & 0 deletions crates/parser/src/syntax_kind/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ pub enum SyntaxKind {
FORMAT_ARGS_KW,
GEN_KW,
GLOBAL_ASM_KW,
INCLUDE_BYTES_KW,
INLATEOUT_KW,
INOUT_KW,
IS_KW,
Expand Down Expand Up @@ -225,6 +226,7 @@ pub enum SyntaxKind {
IMPL,
IMPL_RESTRICTION,
IMPL_TRAIT_TYPE,
INCLUDE_BYTES_EXPR,
INDEX_EXPR,
INFER_TYPE,
ITEM_LIST,
Expand Down Expand Up @@ -412,6 +414,7 @@ impl SyntaxKind {
| IMPL
| IMPL_RESTRICTION
| IMPL_TRAIT_TYPE
| INCLUDE_BYTES_EXPR
| INDEX_EXPR
| INFER_TYPE
| ITEM_LIST
Expand Down Expand Up @@ -641,6 +644,7 @@ impl SyntaxKind {
DYN_KW => "dyn",
FORMAT_ARGS_KW => "format_args",
GLOBAL_ASM_KW => "global_asm",
INCLUDE_BYTES_KW => "include_bytes",
INLATEOUT_KW => "inlateout",
INOUT_KW => "inout",
IS_KW => "is",
Expand Down Expand Up @@ -750,6 +754,7 @@ impl SyntaxKind {
DYN_KW if edition < Edition::Edition2018 => true,
FORMAT_ARGS_KW => true,
GLOBAL_ASM_KW => true,
INCLUDE_BYTES_KW => true,
INLATEOUT_KW => true,
INOUT_KW => true,
IS_KW => true,
Expand Down Expand Up @@ -847,6 +852,7 @@ impl SyntaxKind {
DYN_KW if edition < Edition::Edition2018 => true,
FORMAT_ARGS_KW => true,
GLOBAL_ASM_KW => true,
INCLUDE_BYTES_KW => true,
INLATEOUT_KW => true,
INOUT_KW => true,
IS_KW => true,
Expand Down Expand Up @@ -1007,6 +1013,7 @@ impl SyntaxKind {
"dyn" if edition < Edition::Edition2018 => DYN_KW,
"format_args" => FORMAT_ARGS_KW,
"global_asm" => GLOBAL_ASM_KW,
"include_bytes" => INCLUDE_BYTES_KW,
"inlateout" => INLATEOUT_KW,
"inout" => INOUT_KW,
"is" => IS_KW,
Expand Down Expand Up @@ -1185,6 +1192,7 @@ macro_rules ! T_ {
[dyn] => { $ crate :: SyntaxKind :: DYN_KW };
[format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW };
[global_asm] => { $ crate :: SyntaxKind :: GLOBAL_ASM_KW };
[include_bytes] => { $ crate :: SyntaxKind :: INCLUDE_BYTES_KW };
[inlateout] => { $ crate :: SyntaxKind :: INLATEOUT_KW };
[inout] => { $ crate :: SyntaxKind :: INOUT_KW };
[is] => { $ crate :: SyntaxKind :: IS_KW };
Expand Down
2 changes: 2 additions & 0 deletions crates/parser/test_data/generated/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@ mod ok {
run_and_expect_no_errors("test_data/parser/inline/ok/impl_type_params.rs");
}
#[test]
fn include_bytes() { run_and_expect_no_errors("test_data/parser/inline/ok/include_bytes.rs"); }
#[test]
fn index_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/index_expr.rs"); }
#[test]
fn label() { run_and_expect_no_errors("test_data/parser/inline/ok/label.rs"); }
Expand Down
23 changes: 23 additions & 0 deletions crates/parser/test_data/parser/inline/ok/include_bytes.rast
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
SOURCE_FILE
FN
FN_KW "fn"
WHITESPACE " "
NAME
IDENT "foo"
PARAM_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
WHITESPACE " "
INCLUDE_BYTES_EXPR
BUILTIN_KW "builtin"
WHITESPACE " "
POUND "#"
WHITESPACE " "
INCLUDE_BYTES_KW "include_bytes"
WHITESPACE " "
R_CURLY "}"
WHITESPACE "\n"
1 change: 1 addition & 0 deletions crates/parser/test_data/parser/inline/ok/include_bytes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fn foo() { builtin # include_bytes }
6 changes: 6 additions & 0 deletions crates/syntax/rust.ungram
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,12 @@ Expr =
| YeetExpr
| LetExpr
| UnderscoreExpr
| IncludeBytesExpr

// We need a special expression for this because we don't have access to the file,
// and emitting a specific array will have problems with the length.
IncludeBytesExpr =
'builtin' '#' 'include_bytes'

OffsetOfExpr =
Attr* 'builtin' '#' 'offset_of' '(' Type ',' fields:(NameRef ('.' NameRef)* ) ')'
Expand Down
58 changes: 58 additions & 0 deletions crates/syntax/src/ast/generated/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,19 @@ impl ImplTraitType {
#[inline]
pub fn impl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![impl]) }
}
pub struct IncludeBytesExpr {
pub(crate) syntax: SyntaxNode,
}
impl IncludeBytesExpr {
#[inline]
pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
#[inline]
pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) }
#[inline]
pub fn include_bytes_token(&self) -> Option<SyntaxToken> {
support::token(&self.syntax, T![include_bytes])
}
}
pub struct IndexExpr {
pub(crate) syntax: SyntaxNode,
}
Expand Down Expand Up @@ -2212,6 +2225,7 @@ pub enum Expr {
ForExpr(ForExpr),
FormatArgsExpr(FormatArgsExpr),
IfExpr(IfExpr),
IncludeBytesExpr(IncludeBytesExpr),
IndexExpr(IndexExpr),
LetExpr(LetExpr),
Literal(Literal),
Expand Down Expand Up @@ -4373,6 +4387,38 @@ impl fmt::Debug for ImplTraitType {
f.debug_struct("ImplTraitType").field("syntax", &self.syntax).finish()
}
}
impl AstNode for IncludeBytesExpr {
#[inline]
fn kind() -> SyntaxKind
where
Self: Sized,
{
INCLUDE_BYTES_EXPR
}
#[inline]
fn can_cast(kind: SyntaxKind) -> bool { kind == INCLUDE_BYTES_EXPR }
#[inline]
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
}
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl hash::Hash for IncludeBytesExpr {
fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); }
}
impl Eq for IncludeBytesExpr {}
impl PartialEq for IncludeBytesExpr {
fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax }
}
impl Clone for IncludeBytesExpr {
fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } }
}
impl fmt::Debug for IncludeBytesExpr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("IncludeBytesExpr").field("syntax", &self.syntax).finish()
}
}
impl AstNode for IndexExpr {
#[inline]
fn kind() -> SyntaxKind
Expand Down Expand Up @@ -8101,6 +8147,10 @@ impl From<IfExpr> for Expr {
#[inline]
fn from(node: IfExpr) -> Expr { Expr::IfExpr(node) }
}
impl From<IncludeBytesExpr> for Expr {
#[inline]
fn from(node: IncludeBytesExpr) -> Expr { Expr::IncludeBytesExpr(node) }
}
impl From<IndexExpr> for Expr {
#[inline]
fn from(node: IndexExpr) -> Expr { Expr::IndexExpr(node) }
Expand Down Expand Up @@ -8205,6 +8255,7 @@ impl AstNode for Expr {
| FOR_EXPR
| FORMAT_ARGS_EXPR
| IF_EXPR
| INCLUDE_BYTES_EXPR
| INDEX_EXPR
| LET_EXPR
| LITERAL
Expand Down Expand Up @@ -8246,6 +8297,7 @@ impl AstNode for Expr {
FOR_EXPR => Expr::ForExpr(ForExpr { syntax }),
FORMAT_ARGS_EXPR => Expr::FormatArgsExpr(FormatArgsExpr { syntax }),
IF_EXPR => Expr::IfExpr(IfExpr { syntax }),
INCLUDE_BYTES_EXPR => Expr::IncludeBytesExpr(IncludeBytesExpr { syntax }),
INDEX_EXPR => Expr::IndexExpr(IndexExpr { syntax }),
LET_EXPR => Expr::LetExpr(LetExpr { syntax }),
LITERAL => Expr::Literal(Literal { syntax }),
Expand Down Expand Up @@ -8289,6 +8341,7 @@ impl AstNode for Expr {
Expr::ForExpr(it) => &it.syntax,
Expr::FormatArgsExpr(it) => &it.syntax,
Expr::IfExpr(it) => &it.syntax,
Expr::IncludeBytesExpr(it) => &it.syntax,
Expr::IndexExpr(it) => &it.syntax,
Expr::LetExpr(it) => &it.syntax,
Expr::Literal(it) => &it.syntax,
Expand Down Expand Up @@ -10405,6 +10458,11 @@ impl std::fmt::Display for ImplTraitType {
std::fmt::Display::fmt(self.syntax(), f)
}
}
impl std::fmt::Display for IncludeBytesExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
}
}
impl std::fmt::Display for IndexExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
Expand Down
Loading