about summary refs log tree commit diff
path: root/src/test/ui/macros
AgeCommit message (Collapse)AuthorLines
2020-12-31Auto merge of #80459 - mark-i-m:or-pat-reg, r=petrochenkovbors-0/+14
Implement edition-based macro :pat feature This PR does two things: 1. Fixes the perf regression from https://github.com/rust-lang/rust/pull/80100#issuecomment-750893149 2. Implements `:pat2018` and `:pat2021` matchers, as described by `@joshtriplett` in https://github.com/rust-lang/rust/issues/54883#issuecomment-745509090 behind the feature gate `edition_macro_pat`. r? `@petrochenkov` cc `@Mark-Simulacrum`
2020-12-30Implement edition-based macro pat featuremark-0/+14
2020-12-29Remove `compile-fail` test suiteVadim Petrochenkov-38/+71
2020-12-22Revert "Promote missing_fragment_specifier to hard error"Wesley Wiser-0/+10
This reverts commit 02eae432e7476a0686633a8c2b7cb1d5aab1bd2c.
2020-12-19implement edition-specific :pat behavior for 2015/18mark-13/+18
2020-12-09Accept arbitrary expressions in key-value attributes at parse timeVadim Petrochenkov-3/+3
2020-12-02Tweak diagnostics on shadowing lifetimes/labelsYuki Okushi-1/+1
2020-11-29Update tests to remove old numeric constantsbstrie-1/+1
Part of #68490. Care has been taken to leave the old consts where appropriate, for testing backcompat regressions, module shadowing, etc. The intrinsics docs were accidentally referring to some methods on f64 as std::f64, which I changed due to being contrary with how we normally disambiguate the shadow module from the primitive. In one other place I changed std::u8 to std::ops since it was just testing path handling in macros. For places which have legitimate uses of the old consts, deprecated attributes have been optimistically inserted. Although currently unnecessary, they exist to emphasize to any future deprecation effort the necessity of these specific symbols and prevent them from being accidentally removed.
2020-11-26Fix new 'unnecessary trailing semicolon' warningsAaron Hill-2/+2
2020-11-23Qualify `panic!` as `core::panic!` in non-built-in `core` macrosCamelid-0/+13
Otherwise code like this #![no_implicit_prelude] fn main() { ::std::todo!(); ::std::unimplemented!(); } will fail to compile, which is unfortunate and presumably unintended. This changes many invocations of `panic!` in a `macro_rules!` definition to invocations of `$crate::panic!`, which makes the invocations hygienic. Note that this does not make the built-in macro `assert!` hygienic.
2020-10-19Ignore panic_fmt lint in macro-comma-behavior-rpass ui test.Mara Bos-0/+1
2020-11-09add regression test for #78892SNCPlay42-0/+14
2020-11-02Treat trailing semicolon as a statement in macro callAaron Hill-0/+27
See https://github.com/rust-lang/rust/issues/61733#issuecomment-716188981 We now preserve the trailing semicolon in a macro invocation, even if the macro expands to nothing. As a result, the following code no longer compiles: ```rust macro_rules! empty { () => { } } fn foo() -> bool { //~ ERROR mismatched { true } //~ ERROR mismatched empty!(); } ``` Previously, `{ true }` would be considered the trailing expression, even though there's a semicolon in `empty!();` This makes macro expansion more token-based.
2020-10-25Rollup merge of #77984 - Aaron1011:fix/macro-mod-weird-parent, r=petrochenkovYuki Okushi-0/+25
Compute proper module parent during resolution Fixes #75982 The direct parent of a module may not be a module (e.g. `const _: () = { #[path = "foo.rs"] mod foo; };`). To find the parent of a module for purposes of resolution, we need to walk up the tree until we hit a module or a crate root.
2020-10-24Rollup merge of #78327 - petrochenkov:inconsist, r=Aaron1011Jonas Schievink-0/+25
resolve: Relax macro resolution consistency check to account for any errors The check was previously omitted only when ambiguity errors or `Res::Err` were encountered, but the "macro-expanded `extern crate` items cannot shadow..." error (at least) can cause same inconsistencies as well. Fixes https://github.com/rust-lang/rust/issues/78325
2020-10-24Compute proper module parent during resolutionAaron Hill-0/+25
Fixes #75982 The direct parent of a module may not be a module (e.g. `const _: () = { #[path = "foo.rs"] mod foo; };`). To find the parent of a module for purposes of resolution, we need to walk up the tree until we hit a module or a crate root.
2020-10-24resolve: Relax macro resolution consistency check to account for any errorsVadim Petrochenkov-0/+25
2020-10-24Rollup merge of #78264 - JohnTitor:macro-test, r=petrochenkovJonas Schievink-0/+10
Add regression test for issue-77475 Closes #77475
2020-10-23Auto merge of #77015 - davidtwco:check-attr-variant-closure-expr, r=lcnrbors-17/+1
passes: `check_attr` on more targets This PR modifies `check_attr` so that: - Enum variants are now checked (some attributes would not have been prohibited on variants previously). - `check_expr_attributes` and `check_stmt_attributes` are removed as `check_attributes` can perform the same checks. This means that codegen attribute errors aren't shown if there are other errors first (e.g. from other attributes, as shown in `src/test/ui/macros/issue-68060.rs` changes below).
2020-10-23Add regression test for issue-77475Yuki Okushi-0/+10
2020-09-30Re-run tests with --blessTemirkhan Myrzamadi-0/+3
2020-09-28passes: `check_attr` on more targetsDavid Wood-17/+1
This commit modifies `check_attr` so that: - Enum variants are now checked (some attributes would not have been prohibited on variants previously). - `check_expr_attributes` and `check_stmt_attributes` are removed as `check_attributes` can perform the same checks. Signed-off-by: David Wood <david@davidtw.co>
2020-09-21Record `tcx.def_span` instead of `item.span` in crate metadataAaron Hill-8/+4
This was missed in PR #75465. As a result, a few places have been using the full body span of functions, instead of just the header span.
2020-09-12Auto merge of #73461 - calebzulawski:validate-attribute-placement, ↵bors-11/+9
r=matthewjasper Validate built-in attribute placement Closes #54584, closes #47725, closes #54044. I've changed silently ignoring some incorrectly placed attributes to errors. I'm not sure what the policy is since this can theoretically break code (should they be warnings instead? does it warrant a crater run?).
2020-09-09Rollup merge of #75984 - kornelski:typeormodule, r=matthewjasperTyler Mandry-14/+14
Improve unresolved use error message "use of undeclared type or module `foo`" doesn't mention that it could be a crate. This error can happen when users forget to add a dependency to `Cargo.toml`, so I think it's important to mention that it could be a missing crate. I've used a heuristic based on Rust's naming conventions. It complains about an unknown type if the ident starts with an upper-case letter, and crate or module otherwise. It seems to work very well. The expanded error help covers both an unknown type and a missing crate case.
2020-09-08Update testsGuillaume Gomez-1/+2
2020-09-05Allow #[cold], #[track_caller] on closures. Fix whitespace in error messages.Caleb Zulawski-15/+3
2020-09-05Emit warnings for misplaced attributes used by some cratesCaleb Zulawski-1/+4
2020-09-05Check placement of more attributesCaleb Zulawski-11/+18
2020-09-02Auto merge of #76160 - scileo:format-recovery, r=petrochenkovbors-2/+2
Improve recovery on malformed format call The token following a format expression should be a comma. However, when it is replaced with a similar token (such as a dot), then the corresponding error is emitted, but the token is treated as a comma, and the parsing step continues. r? @petrochenkov
2020-09-02Improve recovery on malformed format callSasha-2/+2
If a comma in a format call is replaced with a similar token, then we emit an error and continue parsing, instead of stopping at this point.
2020-09-01Clarify message about unresolved useKornel-14/+14
2020-09-01Give a better error message for duplicate built-in macrosJoshua Nelson-3/+48
Previously, this would say no such macro existed, but this was misleading, since the macro _did_ exist, it was just already seen. - Say where the macro was previously defined - Add long-form error message
2020-08-27Abort when catch_unwind catches a foreign exceptionAmanieu d'Antras-17/+18
2020-08-18Promote missing_fragment_specifier to hard errorAleksey Kladov-10/+0
It has been deny_by_default since 2017 (and warned for some time before that), so it seems reasonable to promote it. The specific technical motivation to do this now is to remove a field from `ParseSess` -- it is a global state, and global state makes extracting libraries annoying. Closes #40107
2020-08-18Move macro test to ui/macrosAleksey Kladov-0/+19
2020-08-02Auto merge of #74785 - euclio:deprecation-kinds, r=petrochenkovbors-8/+8
report kind of deprecated item in message This is important for fields, which are incorrectly referred to as "items".
2020-07-27mv std libs to library/mark-3/+3
2020-07-26report kind of deprecated item in messageAndy Russell-8/+8
This is important for fields, which are incorrectly referred to as "items".
2020-07-01Rollup merge of #73569 - Aaron1011:fix/macro-rules-group, r=petrochenkovManish Goregaokar-0/+25
Handle `macro_rules!` tokens consistently across crates When we serialize a `macro_rules!` macro, we used a 'lowered' `TokenStream` for its body, which has all `Nonterminal`s expanded in-place via `nt_to_tokenstream`. This matters when an 'outer' `macro_rules!` macro expands to an 'inner' `macro_rules!` macro - the inner macro may use tokens captured from the 'outer' macro in its definition. This means that invoking a foreign `macro_rules!` macro may use a different body `TokenStream` than when the same `macro_rules!` macro is invoked in the same crate. This difference is observable by proc-macros invoked by a `macro_rules!` macro - a `None`-delimited group will be seen in the same-crate case (inserted when convering `Nonterminal`s to the `proc_macro` crate's structs), but no `None`-delimited group in the cross-crate case. To fix this inconsistency, we now insert `None`-delimited groups when 'lowering' a `Nonterminal` `macro_rules!` body, just as we do in `proc_macro_server`. Additionally, we no longer print extra spaces for `None`-delimited groups - as far as pretty-printing is concerned, they don't exist (only their contents do). This ensures that `Display` output of a `TokenStream` does not depend on which crate a `macro_rules!` macro was invoked from. This PR is necessary in order to patch the `solana-genesis-programs` for the upcoming hygiene serialization breakage (https://github.com/rust-lang/rust/pull/72121#issuecomment-646924847). The `solana-genesis-programs` crate will need to use a proc macro to re-span certain tokens in a nested `macro_rules!`, which requires us to consistently use a `None`-delimited group. See `src/test/ui/proc-macro/nested-macro-rules.rs` for an example of the kind of nested `macro_rules!` affected by this crate.
2020-07-01Insert NoDelim groups around nonterminals when lowering macro_rulesAaron Hill-0/+25
2020-06-30Stabilize `#[track_caller]`.Adam Perry-5/+3
Does not yet make its constness stable, though. Use of `Location::caller` in const contexts is still gated by `#![feature(const_caller_location)]`.
2020-05-26expand `env!` with def-site contextAndy Russell-0/+2
2020-05-19Auto merge of #69171 - Amanieu:new-asm, r=nagisa,nikomatsakisbors-17/+24
Implement new asm! syntax from RFC 2850 This PR implements the new `asm!` syntax proposed in https://github.com/rust-lang/rfcs/pull/2850. # Design A large part of this PR revolves around taking an `asm!` macro invocation and plumbing it through all of the compiler layers down to LLVM codegen. Throughout the various stages, an `InlineAsm` generally consists of 3 components: - The template string, which is stored as an array of `InlineAsmTemplatePiece`. Each piece represents either a literal or a placeholder for an operand (just like format strings). ```rust pub enum InlineAsmTemplatePiece { String(String), Placeholder { operand_idx: usize, modifier: Option<char>, span: Span }, } ``` - The list of operands to the `asm!` (`in`, `[late]out`, `in[late]out`, `sym`, `const`). These are represented differently at each stage of lowering, but follow a common pattern: - `in`, `out` and `inout` all have an associated register class (`reg`) or explicit register (`"eax"`). - `inout` has 2 forms: one with a single expression that is both read from and written to, and one with two separate expressions for the input and output parts. - `out` and `inout` have a `late` flag (`lateout` / `inlateout`) to indicate that the register allocator is allowed to reuse an input register for this output. - `out` and the split variant of `inout` allow `_` to be specified for an output, which means that the output is discarded. This is used to allocate scratch registers for assembly code. - `sym` is a bit special since it only accepts a path expression, which must point to a `static` or a `fn`. - The options set at the end of the `asm!` macro. The only one that is particularly of interest to rustc is `NORETURN` which makes `asm!` return `!` instead of `()`. ```rust bitflags::bitflags! { pub struct InlineAsmOptions: u8 { const PURE = 1 << 0; const NOMEM = 1 << 1; const READONLY = 1 << 2; const PRESERVES_FLAGS = 1 << 3; const NORETURN = 1 << 4; const NOSTACK = 1 << 5; } } ``` ## AST `InlineAsm` is represented as an expression in the AST: ```rust pub struct InlineAsm { pub template: Vec<InlineAsmTemplatePiece>, pub operands: Vec<(InlineAsmOperand, Span)>, pub options: InlineAsmOptions, } pub enum InlineAsmRegOrRegClass { Reg(Symbol), RegClass(Symbol), } pub enum InlineAsmOperand { In { reg: InlineAsmRegOrRegClass, expr: P<Expr>, }, Out { reg: InlineAsmRegOrRegClass, late: bool, expr: Option<P<Expr>>, }, InOut { reg: InlineAsmRegOrRegClass, late: bool, expr: P<Expr>, }, SplitInOut { reg: InlineAsmRegOrRegClass, late: bool, in_expr: P<Expr>, out_expr: Option<P<Expr>>, }, Const { expr: P<Expr>, }, Sym { expr: P<Expr>, }, } ``` The `asm!` macro is implemented in librustc_builtin_macros and outputs an `InlineAsm` AST node. The template string is parsed using libfmt_macros, positional and named operands are resolved to explicit operand indicies. Since target information is not available to macro invocations, validation of the registers and register classes is deferred to AST lowering. ## HIR `InlineAsm` is represented as an expression in the HIR: ```rust pub struct InlineAsm<'hir> { pub template: &'hir [InlineAsmTemplatePiece], pub operands: &'hir [InlineAsmOperand<'hir>], pub options: InlineAsmOptions, } pub enum InlineAsmRegOrRegClass { Reg(InlineAsmReg), RegClass(InlineAsmRegClass), } pub enum InlineAsmOperand<'hir> { In { reg: InlineAsmRegOrRegClass, expr: Expr<'hir>, }, Out { reg: InlineAsmRegOrRegClass, late: bool, expr: Option<Expr<'hir>>, }, InOut { reg: InlineAsmRegOrRegClass, late: bool, expr: Expr<'hir>, }, SplitInOut { reg: InlineAsmRegOrRegClass, late: bool, in_expr: Expr<'hir>, out_expr: Option<Expr<'hir>>, }, Const { expr: Expr<'hir>, }, Sym { expr: Expr<'hir>, }, } ``` AST lowering is where `InlineAsmRegOrRegClass` is converted from `Symbol`s to an actual register or register class. If any modifiers are specified for a template string placeholder, these are validated against the set allowed for that operand type. Finally, explicit registers for inputs and outputs are checked for conflicts (same register used for different operands). ## Type checking Each register class has a whitelist of types that it may be used with. After the types of all operands have been determined, the `intrinsicck` pass will check that these types are in the whitelist. It also checks that split `inout` operands have compatible types and that `const` operands are integers or floats. Suggestions are emitted where needed if a template modifier should be used for an operand based on the type that was passed into it. ## HAIR `InlineAsm` is represented as an expression in the HAIR: ```rust crate enum ExprKind<'tcx> { // [..] InlineAsm { template: &'tcx [InlineAsmTemplatePiece], operands: Vec<InlineAsmOperand<'tcx>>, options: InlineAsmOptions, }, } crate enum InlineAsmOperand<'tcx> { In { reg: InlineAsmRegOrRegClass, expr: ExprRef<'tcx>, }, Out { reg: InlineAsmRegOrRegClass, late: bool, expr: Option<ExprRef<'tcx>>, }, InOut { reg: InlineAsmRegOrRegClass, late: bool, expr: ExprRef<'tcx>, }, SplitInOut { reg: InlineAsmRegOrRegClass, late: bool, in_expr: ExprRef<'tcx>, out_expr: Option<ExprRef<'tcx>>, }, Const { expr: ExprRef<'tcx>, }, SymFn { expr: ExprRef<'tcx>, }, SymStatic { expr: ExprRef<'tcx>, }, } ``` The only significant change compared to HIR is that `Sym` has been lowered to either a `SymFn` whose `expr` is a `Literal` ZST of the `fn`, or a `SymStatic` whose `expr` is a `StaticRef`. ## MIR `InlineAsm` is represented as a `Terminator` in the MIR: ```rust pub enum TerminatorKind<'tcx> { // [..] /// Block ends with an inline assembly block. This is a terminator since /// inline assembly is allowed to diverge. InlineAsm { /// The template for the inline assembly, with placeholders. template: &'tcx [InlineAsmTemplatePiece], /// The operands for the inline assembly, as `Operand`s or `Place`s. operands: Vec<InlineAsmOperand<'tcx>>, /// Miscellaneous options for the inline assembly. options: InlineAsmOptions, /// Destination block after the inline assembly returns, unless it is /// diverging (InlineAsmOptions::NORETURN). destination: Option<BasicBlock>, }, } pub enum InlineAsmOperand<'tcx> { In { reg: InlineAsmRegOrRegClass, value: Operand<'tcx>, }, Out { reg: InlineAsmRegOrRegClass, late: bool, place: Option<Place<'tcx>>, }, InOut { reg: InlineAsmRegOrRegClass, late: bool, in_value: Operand<'tcx>, out_place: Option<Place<'tcx>>, }, Const { value: Operand<'tcx>, }, SymFn { value: Box<Constant<'tcx>>, }, SymStatic { value: Box<Constant<'tcx>>, }, } ``` As part of HAIR lowering, `InOut` and `SplitInOut` operands are lowered to a split form with a separate `in_value` and `out_place`. Semantically, the `InlineAsm` terminator is similar to the `Call` terminator except that it has multiple output places where a `Call` only has a single return place output. The constant promotion pass is used to ensure that `const` operands are actually constants (using the same logic as `#[rustc_args_required_const]`). ## Codegen Operands are lowered one more time before being passed to LLVM codegen: ```rust pub enum InlineAsmOperandRef<'tcx, B: BackendTypes + ?Sized> { In { reg: InlineAsmRegOrRegClass, value: OperandRef<'tcx, B::Value>, }, Out { reg: InlineAsmRegOrRegClass, late: bool, place: Option<PlaceRef<'tcx, B::Value>>, }, InOut { reg: InlineAsmRegOrRegClass, late: bool, in_value: OperandRef<'tcx, B::Value>, out_place: Option<PlaceRef<'tcx, B::Value>>, }, Const { string: String, }, SymFn { instance: Instance<'tcx>, }, SymStatic { def_id: DefId, }, } ``` The operands are lowered to LLVM operands and constraint codes as follow: - `out` and the output part of `inout` operands are added first, as required by LLVM. Late output operands have a `=` prefix added to their constraint code, non-late output operands have a `=&` prefix added to their constraint code. - `in` operands are added normally. - `inout` operands are tied to the matching output operand. - `sym` operands are passed as function pointers or pointers, using the `"s"` constraint. - `const` operands are formatted to a string and directly inserted in the template string. The template string is converted to LLVM form: - `$` characters are escaped as `$$`. - `const` operands are converted to strings and inserted directly. - Placeholders are formatted as `${X:M}` where `X` is the operand index and `M` is the modifier character. Modifiers are converted from the Rust form to the LLVM form. The various options are converted to clobber constraints or LLVM attributes, refer to the [RFC](https://github.com/Amanieu/rfcs/blob/inline-asm/text/0000-inline-asm.md#mapping-to-llvm-ir) for more details. Note that LLVM is sometimes rather picky about what types it accepts for certain constraint codes so we sometimes need to insert conversions to/from a supported type. See the target-specific ISelLowering.cpp files in LLVM for details. # Adding support for new architectures Adding inline assembly support to an architecture is mostly a matter of defining the registers and register classes for that architecture. All the definitions for register classes are located in `src/librustc_target/asm/`. Additionally you will need to implement lowering of these register classes to LLVM constraint codes in `src/librustc_codegen_llvm/asm.rs`.
2020-05-19Auto merge of #68717 - petrochenkov:stabexpat, r=varkorbors-1/+1
Stabilize fn-like proc macros in expression, pattern and statement positions I.e. all the positions in which stable `macro_rules` macros are supported. Depends on https://github.com/rust-lang/rust/pull/68716 ("Stabilize `Span::mixed_site`"). cc https://github.com/rust-lang/rust/issues/54727 cc https://github.com/rust-lang/rust/issues/54727#issuecomment-580647446 Stabilization report: https://github.com/rust-lang/rust/pull/68717#issuecomment-623197503.
2020-05-18Add tests for asm!Amanieu d'Antras-17/+24
2020-05-09Rollup merge of #71185 - JohnTitor:run-fail, r=petrochenkovRalf Jung-0/+113
Move tests from `test/run-fail` to UI Fixes #65440 cc #65865 #65506 r? @nikomatsakis
2020-05-08Skip tests on emscriptenYuki Okushi-0/+15
2020-05-07reword "possible candidate" import suggestionAndy Russell-1/+1
2020-05-06Move tests from `test/run-fail` to UIYuki Okushi-0/+98