Skip to content

Implement builtin # syntax and use it for offset_of!(...) #110694

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 3 commits into from
May 9, 2023
Merged
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 compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
@@ -603,6 +603,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
gate_all!(yeet_expr, "`do yeet` expression is experimental");
gate_all!(dyn_star, "`dyn*` trait objects are experimental");
gate_all!(const_closures, "const closures are experimental");
gate_all!(builtin_syntax, "`builtin #` syntax is unstable");

if !visitor.features.negative_bounds {
for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() {
3 changes: 1 addition & 2 deletions compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
@@ -556,8 +556,7 @@ impl<'a> State<'a> {
self.pclose();
}
ast::ExprKind::OffsetOf(container, fields) => {
// FIXME: This should have its own syntax, distinct from a macro invocation.
self.word("offset_of!");
self.word("builtin # offset_of");
self.popen();
self.rbox(0, Inconsistent);
self.print_type(container);
4 changes: 0 additions & 4 deletions compiler/rustc_builtin_macros/messages.ftl
Original file line number Diff line number Diff line change
@@ -150,10 +150,6 @@ builtin_macros_format_pos_mismatch = {$n} positional {$n ->
*[more] arguments
} in format string, but {$desc}
builtin_macros_offset_of_expected_field = expected field
builtin_macros_offset_of_expected_two_args = expected 2 arguments
builtin_macros_test_case_non_item = `#[test_case]` attribute is only allowed on items
builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests
2 changes: 0 additions & 2 deletions compiler/rustc_builtin_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -44,7 +44,6 @@ mod format;
mod format_foreign;
mod global_allocator;
mod log_syntax;
mod offset_of;
mod source_util;
mod test;
mod trace_macros;
@@ -92,7 +91,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
line: source_util::expand_line,
log_syntax: log_syntax::expand_log_syntax,
module_path: source_util::expand_mod,
offset_of: offset_of::expand_offset_of,
option_env: env::expand_option_env,
core_panic: edition_panic::expand_panic,
std_panic: edition_panic::expand_panic,
99 changes: 0 additions & 99 deletions compiler/rustc_builtin_macros/src/offset_of.rs

This file was deleted.

2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
@@ -313,6 +313,8 @@ declare_features! (
(active, async_closure, "1.37.0", Some(62290), None),
/// Allows async functions to be declared, implemented, and used in traits.
(active, async_fn_in_trait, "1.66.0", Some(91611), None),
/// Allows builtin # foo() syntax
(active, builtin_syntax, "CURRENT_RUSTC_VERSION", Some(110680), None),
/// Allows `c"foo"` literals.
(active, c_str_literals, "CURRENT_RUSTC_VERSION", Some(105723), None),
/// Treat `extern "C"` function as nounwind.
4 changes: 4 additions & 0 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
@@ -257,6 +257,10 @@ parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are inva
.tuple_exception_line_2 = on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access
.tuple_exception_line_3 = see issue #60210 <https://github.com/rust-lang/rust/issues/60210> for more information
parse_expected_builtin_ident = expected identifier after `builtin #`
parse_unknown_builtin_construct = unknown `builtin #` construct `{$name}`
parse_non_string_abi_literal = non-string ABI literal
.suggestion = specify the ABI with a string literal
15 changes: 15 additions & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
@@ -2644,3 +2644,18 @@ pub(crate) struct MalformedCfgAttr {
pub span: Span,
pub sugg: &'static str,
}

#[derive(Diagnostic)]
#[diag(parse_unknown_builtin_construct)]
pub(crate) struct UnknownBuiltinConstruct {
#[primary_span]
pub span: Span,
pub name: Symbol,
}

#[derive(Diagnostic)]
#[diag(parse_expected_builtin_ident)]
pub(crate) struct ExpectedBuiltinIdent {
#[primary_span]
pub span: Span,
}
61 changes: 61 additions & 0 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
@@ -1300,6 +1300,8 @@ impl<'a> Parser<'a> {
})
} else if self.check(&token::OpenDelim(Delimiter::Bracket)) {
self.parse_expr_array_or_repeat(Delimiter::Bracket)
} else if self.is_builtin() {
self.parse_expr_builtin()
} else if self.check_path() {
self.parse_expr_path_start()
} else if self.check_keyword(kw::Move)
@@ -1755,6 +1757,61 @@ impl<'a> Parser<'a> {
self.maybe_recover_from_bad_qpath(expr)
}

/// Parse `builtin # ident(args,*)`.
fn parse_expr_builtin(&mut self) -> PResult<'a, P<Expr>> {
self.parse_builtin(|this, lo, ident| {
if ident.name == sym::offset_of {
return Ok(Some(this.parse_expr_offset_of(lo)?));
}

Ok(None)
})
}

pub(crate) fn parse_builtin<T>(
&mut self,
parse: impl FnOnce(&mut Parser<'a>, Span, Ident) -> PResult<'a, Option<T>>,
) -> PResult<'a, T> {
let lo = self.token.span;

self.bump(); // `builtin`
self.bump(); // `#`

let Some((ident, false)) = self.token.ident() else {
let err = errors::ExpectedBuiltinIdent { span: self.token.span }
.into_diagnostic(&self.sess.span_diagnostic);
return Err(err);
};
self.sess.gated_spans.gate(sym::builtin_syntax, ident.span);
self.bump();

self.expect(&TokenKind::OpenDelim(Delimiter::Parenthesis))?;
let ret = if let Some(res) = parse(self, lo, ident)? {
Ok(res)
} else {
let err = errors::UnknownBuiltinConstruct { span: lo.to(ident.span), name: ident.name }
.into_diagnostic(&self.sess.span_diagnostic);
return Err(err);
};
self.expect(&TokenKind::CloseDelim(Delimiter::Parenthesis))?;

ret
}

pub(crate) fn parse_expr_offset_of(&mut self, lo: Span) -> PResult<'a, P<Expr>> {
let container = self.parse_ty()?;
self.expect(&TokenKind::Comma)?;

let seq_sep = SeqSep { sep: Some(token::Dot), trailing_sep_allowed: false };
let (fields, _trailing, _recovered) = self.parse_seq_to_before_end(
&TokenKind::CloseDelim(Delimiter::Parenthesis),
seq_sep,
Parser::parse_field_name,
)?;
let span = lo.to(self.token.span);
Ok(self.mk_expr(span, ExprKind::OffsetOf(container, fields.to_vec().into())))
}

/// Returns a string literal if the next token is a string literal.
/// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
/// and returns `None` if the next token is not literal at all.
@@ -2824,6 +2881,10 @@ impl<'a> Parser<'a> {
})
}

pub(crate) fn is_builtin(&self) -> bool {
self.token.is_keyword(kw::Builtin) && self.look_ahead(1, |t| *t == token::Pound)
}

/// Parses a `try {...}` expression (`try` token already eaten).
fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, P<Expr>> {
let (attrs, body) = self.parse_inner_attrs_and_block()?;
8 changes: 8 additions & 0 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
@@ -265,6 +265,9 @@ impl<'a> Parser<'a> {
// UNION ITEM
self.bump(); // `union`
self.parse_item_union()?
} else if self.is_builtin() {
// BUILTIN# ITEM
return self.parse_item_builtin();
} else if self.eat_keyword(kw::Macro) {
// MACROS 2.0 ITEM
self.parse_item_decl_macro(lo)?
@@ -434,6 +437,11 @@ impl<'a> Parser<'a> {
}
}

fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemInfo>> {
// To be expanded
return Ok(None);
}

/// Parses an item macro, e.g., `item!();`.
fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
let path = self.parse_path(PathStyle::Mod)?; // `foo::bar`
6 changes: 5 additions & 1 deletion compiler/rustc_parse/src/parser/stmt.rs
Original file line number Diff line number Diff line change
@@ -90,7 +90,11 @@ impl<'a> Parser<'a> {
attrs,
errors::InvalidVariableDeclarationSub::UseLetNotVar,
)?
} else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() {
} else if self.check_path()
&& !self.token.is_qpath_start()
&& !self.is_path_start_item()
&& !self.is_builtin()
{
// We have avoided contextual keywords like `union`, items with `crate` visibility,
// or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something
// that starts like a path (1 token), but it fact not a path.
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
@@ -95,6 +95,7 @@ symbols! {

// Weak keywords, have special meaning only in specific contexts.
Auto: "auto",
Builtin: "builtin",
Catch: "catch",
Default: "default",
MacroRules: "macro_rules",
@@ -440,6 +441,7 @@ symbols! {
breakpoint,
bridge,
bswap,
builtin_syntax,
c_str,
c_str_literals,
c_unwind,
6 changes: 3 additions & 3 deletions library/core/src/mem/mod.rs
Original file line number Diff line number Diff line change
@@ -1315,9 +1315,9 @@ impl<T> SizedTypeProperties for T {}
///
/// assert_eq!(mem::offset_of!(NestedA, b.0), 0);
/// ```
#[unstable(feature = "offset_of", issue = "106655")]
#[rustc_builtin_macro]
#[cfg(not(bootstrap))]
#[unstable(feature = "offset_of", issue = "106655")]
#[allow_internal_unstable(builtin_syntax)]
pub macro offset_of($Container:ty, $($fields:tt).+ $(,)?) {
/* compiler built-in */
builtin # offset_of($Container, $($fields).+)
}
16 changes: 8 additions & 8 deletions tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff
Original file line number Diff line number Diff line change
@@ -22,17 +22,17 @@

bb0: {
StorageLive(_1); // scope 0 at $DIR/offset_of.rs:+1:9: +1:10
- _1 = OffsetOf(Alpha, [0]); // scope 0 at $DIR/offset_of.rs:+1:13: +1:33
+ _1 = const 4_usize; // scope 0 at $DIR/offset_of.rs:+1:13: +1:33
- _1 = OffsetOf(Alpha, [0]); // scope 0 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ _1 = const 4_usize; // scope 0 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
StorageLive(_2); // scope 1 at $DIR/offset_of.rs:+2:9: +2:10
- _2 = OffsetOf(Alpha, [1]); // scope 1 at $DIR/offset_of.rs:+2:13: +2:33
+ _2 = const 0_usize; // scope 1 at $DIR/offset_of.rs:+2:13: +2:33
- _2 = OffsetOf(Alpha, [1]); // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ _2 = const 0_usize; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
StorageLive(_3); // scope 2 at $DIR/offset_of.rs:+3:9: +3:11
- _3 = OffsetOf(Alpha, [2, 0]); // scope 2 at $DIR/offset_of.rs:+3:14: +3:36
+ _3 = const 2_usize; // scope 2 at $DIR/offset_of.rs:+3:14: +3:36
- _3 = OffsetOf(Alpha, [2, 0]); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ _3 = const 2_usize; // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
StorageLive(_4); // scope 3 at $DIR/offset_of.rs:+4:9: +4:11
- _4 = OffsetOf(Alpha, [2, 1]); // scope 3 at $DIR/offset_of.rs:+4:14: +4:36
+ _4 = const 3_usize; // scope 3 at $DIR/offset_of.rs:+4:14: +4:36
- _4 = OffsetOf(Alpha, [2, 1]); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ _4 = const 3_usize; // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
_0 = const (); // scope 0 at $DIR/offset_of.rs:+0:15: +5:2
StorageDead(_4); // scope 3 at $DIR/offset_of.rs:+5:1: +5:2
StorageDead(_3); // scope 2 at $DIR/offset_of.rs:+5:1: +5:2
8 changes: 4 additions & 4 deletions tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff
Original file line number Diff line number Diff line change
@@ -22,13 +22,13 @@

bb0: {
StorageLive(_1); // scope 0 at $DIR/offset_of.rs:+1:9: +1:11
_1 = OffsetOf(Gamma<T>, [0]); // scope 0 at $DIR/offset_of.rs:+1:14: +1:37
_1 = OffsetOf(Gamma<T>, [0]); // scope 0 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
StorageLive(_2); // scope 1 at $DIR/offset_of.rs:+2:9: +2:11
_2 = OffsetOf(Gamma<T>, [1]); // scope 1 at $DIR/offset_of.rs:+2:14: +2:37
_2 = OffsetOf(Gamma<T>, [1]); // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
StorageLive(_3); // scope 2 at $DIR/offset_of.rs:+3:9: +3:11
_3 = OffsetOf(Delta<T>, [1]); // scope 2 at $DIR/offset_of.rs:+3:14: +3:37
_3 = OffsetOf(Delta<T>, [1]); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
StorageLive(_4); // scope 3 at $DIR/offset_of.rs:+4:9: +4:11
_4 = OffsetOf(Delta<T>, [2]); // scope 3 at $DIR/offset_of.rs:+4:14: +4:37
_4 = OffsetOf(Delta<T>, [2]); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
_0 = const (); // scope 0 at $DIR/offset_of.rs:+0:17: +5:2
StorageDead(_4); // scope 3 at $DIR/offset_of.rs:+5:1: +5:2
StorageDead(_3); // scope 2 at $DIR/offset_of.rs:+5:1: +5:2
7 changes: 7 additions & 0 deletions tests/ui/feature-gates/feature-gate-builtin_syntax.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
struct Foo {
v: u8,
w: u8,
}
fn main() {
builtin # offset_of(Foo, v); //~ ERROR `builtin #` syntax is unstable
}
12 changes: 12 additions & 0 deletions tests/ui/feature-gates/feature-gate-builtin_syntax.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0658]: `builtin #` syntax is unstable
--> $DIR/feature-gate-builtin_syntax.rs:6:15
|
LL | builtin # offset_of(Foo, v);
| ^^^^^^^^^
|
= note: see issue #110680 <https://github.com/rust-lang/rust/issues/110680> for more information
= help: add `#![feature(builtin_syntax)]` to the crate attributes to enable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0658`.
14 changes: 11 additions & 3 deletions tests/ui/offset-of/offset-of-arg-count.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,15 @@
use std::mem::offset_of;

fn main() {
offset_of!(NotEnoughArguments); //~ ERROR expected one of
offset_of!(NotEnoughArgumentsWithAComma, ); //~ ERROR expected 2 arguments
offset_of!(Container, field, too many arguments); //~ ERROR expected 2 arguments
offset_of!(NotEnoughArguments); //~ ERROR unexpected end of macro invocation
offset_of!(NotEnoughArgumentsWithAComma, ); //~ ERROR unexpected end of macro invocation
offset_of!(Container, field, too many arguments); //~ ERROR no rules expected the token `too`
offset_of!(S, f); // compiles fine
offset_of!(S, f,); // also compiles fine
offset_of!(S, f.); //~ ERROR unexpected end of macro invocation
offset_of!(S, f.,); //~ ERROR expected identifier
offset_of!(S, f..); //~ ERROR no rules expected the token
offset_of!(S, f..,); //~ ERROR no rules expected the token
}

struct S { f: u8, }
59 changes: 49 additions & 10 deletions tests/ui/offset-of/offset-of-arg-count.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,59 @@
error: expected one of `!`, `(`, `+`, `,`, `::`, or `<`, found `<eof>`
--> $DIR/offset-of-arg-count.rs:6:16
error: unexpected end of macro invocation
--> $DIR/offset-of-arg-count.rs:6:34
|
LL | offset_of!(NotEnoughArguments);
| ^^^^^^^^^^^^^^^^^^ expected one of `!`, `(`, `+`, `,`, `::`, or `<`
| ^ missing tokens in macro arguments
|
note: while trying to match `,`
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL

error: expected 2 arguments
--> $DIR/offset-of-arg-count.rs:7:5
error: unexpected end of macro invocation
--> $DIR/offset-of-arg-count.rs:7:45
|
LL | offset_of!(NotEnoughArgumentsWithAComma, );
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^ missing tokens in macro arguments
|
note: while trying to match meta-variable `$fields:tt`
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL

error: expected 2 arguments
--> $DIR/offset-of-arg-count.rs:8:5
error: no rules expected the token `too`
--> $DIR/offset-of-arg-count.rs:8:34
|
LL | offset_of!(Container, field, too many arguments);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^ no rules expected this token in macro call
|
= note: while trying to match sequence end

error: unexpected end of macro invocation
--> $DIR/offset-of-arg-count.rs:11:21
|
LL | offset_of!(S, f.);
| ^ missing tokens in macro arguments
|
note: while trying to match meta-variable `$fields:tt`
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL

error: expected identifier, found `,`
--> $DIR/offset-of-arg-count.rs:12:21
|
LL | offset_of!(S, f.,);
| ^ expected identifier

error: no rules expected the token `..`
--> $DIR/offset-of-arg-count.rs:13:20
|
LL | offset_of!(S, f..);
| ^^ no rules expected this token in macro call
|
= note: while trying to match sequence start

error: no rules expected the token `..`
--> $DIR/offset-of-arg-count.rs:14:20
|
LL | offset_of!(S, f..,);
| ^^ no rules expected this token in macro call
|
= note: while trying to match sequence start

error: aborting due to 3 previous errors
error: aborting due to 7 previous errors

44 changes: 44 additions & 0 deletions tests/ui/offset-of/offset-of-builtin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#![feature(builtin_syntax)]

// For the exposed macro we already test these errors in the other files,
// but this test helps to make sure the builtin construct also errors.
// This has the same examples as offset-of-arg-count.rs

fn main() {
builtin # offset_of(NotEnoughArguments); //~ ERROR expected one of
}
fn t1() {
// Already errored upon at the macro level. Yielding an error would require
// extra effort.
builtin # offset_of(NotEnoughArgumentsWithAComma, );
}
fn t2() {
builtin # offset_of(Container, field, too many arguments); //~ ERROR expected identifier, found
//~| ERROR found `,`
//~| ERROR found `many`
//~| ERROR found `arguments`
}
fn t3() {
builtin # offset_of(S, f); // compiles fine
}
fn t4() {
// Already errored upon at the macro level. Yielding an error would require
// extra effort.
builtin # offset_of(S, f);
}
fn t5() {
builtin # offset_of(S, f.); //~ ERROR expected identifier
}
fn t6() {
builtin # offset_of(S, f.,); //~ ERROR expected identifier
}
fn t7() {
builtin # offset_of(S, f..); //~ ERROR expected one of
}
fn t8() {
// Already errored upon at the macro level. Yielding an error would require
// extra effort.
builtin # offset_of(S, f..,);
}

struct S { f: u8, }
65 changes: 65 additions & 0 deletions tests/ui/offset-of/offset-of-builtin.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
error: expected one of `!`, `(`, `+`, `,`, `::`, or `<`, found `)`
--> $DIR/offset-of-builtin.rs:8:43
|
LL | builtin # offset_of(NotEnoughArguments);
| ^ expected one of `!`, `(`, `+`, `,`, `::`, or `<`

error: expected identifier, found `,`
--> $DIR/offset-of-builtin.rs:16:41
|
LL | builtin # offset_of(Container, field, too many arguments);
| ^
| |
| expected identifier
| help: remove this comma

error: expected one of `)` or `.`, found `,`
--> $DIR/offset-of-builtin.rs:16:41
|
LL | builtin # offset_of(Container, field, too many arguments);
| ^
| |
| expected one of `)` or `.`
| help: missing `.`

error: expected one of `)` or `.`, found `many`
--> $DIR/offset-of-builtin.rs:16:47
|
LL | builtin # offset_of(Container, field, too many arguments);
| -^^^^ expected one of `)` or `.`
| |
| help: missing `.`

error: expected one of `)` or `.`, found `arguments`
--> $DIR/offset-of-builtin.rs:16:52
|
LL | builtin # offset_of(Container, field, too many arguments);
| -^^^^^^^^^ expected one of `)` or `.`
| |
| help: missing `.`

error: expected identifier, found `)`
--> $DIR/offset-of-builtin.rs:30:30
|
LL | builtin # offset_of(S, f.);
| ^ expected identifier

error: expected identifier, found `,`
--> $DIR/offset-of-builtin.rs:33:30
|
LL | builtin # offset_of(S, f.,);
| ^ expected identifier

error: expected one of `)` or `.`, found `..`
--> $DIR/offset-of-builtin.rs:36:29
|
LL | builtin # offset_of(S, f..);
| ^^ expected one of `)` or `.`
|
help: if you meant to bind the contents of the rest of the array pattern into `f`, use `@`
|
LL | builtin # offset_of(S, f @ ..);
| +

error: aborting due to 8 previous errors

3 changes: 3 additions & 0 deletions tests/ui/offset-of/offset-of-dst-field.stderr
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ LL | offset_of!(Alpha, z);
| ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
--> $DIR/offset-of-dst-field.rs:31:5
@@ -13,6 +14,7 @@ LL | offset_of!(Beta, z);
| ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn Trait + 'static)`
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the size for values of type `Extern` cannot be known at compilation time
--> $DIR/offset-of-dst-field.rs:32:5
@@ -21,6 +23,7 @@ LL | offset_of!(Gamma, z);
| ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `Extern`
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 3 previous errors

5 changes: 5 additions & 0 deletions tests/ui/offset-of/offset-of-unstable.stderr
Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@ LL | | );
| |_____^
|
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0658]: use of unstable library feature 'unstable_test_feature'
--> $DIR/offset-of-unstable.rs:18:5
@@ -41,6 +42,7 @@ LL | offset_of!(StableWithUnstableField, unstable);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0658]: use of unstable library feature 'unstable_test_feature'
--> $DIR/offset-of-unstable.rs:20:5
@@ -49,6 +51,7 @@ LL | offset_of!(StableWithUnstableFieldType, stable.unstable);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0658]: use of unstable library feature 'unstable_test_feature'
--> $DIR/offset-of-unstable.rs:21:5
@@ -61,6 +64,7 @@ LL | | );
| |_____^
|
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0658]: use of unstable library feature 'unstable_test_feature'
--> $DIR/offset-of-unstable.rs:26:5
@@ -73,6 +77,7 @@ LL | | );
| |_____^
|
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
= note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 8 previous errors

9 changes: 9 additions & 0 deletions tests/ui/parser/builtin-syntax.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#![feature(builtin_syntax)]

fn main() {
builtin # foobar(); //~ ERROR unknown `builtin #` construct
}

fn not_identifier() {
builtin # {}(); //~ ERROR expected identifier after
}
14 changes: 14 additions & 0 deletions tests/ui/parser/builtin-syntax.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: unknown `builtin #` construct `foobar`
--> $DIR/builtin-syntax.rs:4:5
|
LL | builtin # foobar();
| ^^^^^^^^^^^^^^^^

error: expected identifier after `builtin #`
--> $DIR/builtin-syntax.rs:8:15
|
LL | builtin # {}();
| ^

error: aborting due to 2 previous errors