Commit Graph

120726 Commits

Author SHA1 Message Date
Dylan MacKenzie
fc964c5317 Clean up generator live locals analysis
Instead of using a bespoke dataflow analysis, `MaybeRequiresStorage`,
for computing locals that need to be stored across yield points and that
have conflicting storage, use a combination of simple, generally
applicable dataflow analyses. In this case, the formula for locals
that are live at a yield point is:

    live_across_yield := (live & init) | (!movable & borrowed)

and the formula for locals that require storage (and thus may conflict
with others) at a given point is:

    requires_storage := init | borrowed

`init` is `MaybeInitializedLocals`, a direct equivalent of
`MaybeInitializedPlaces` that works only on whole `Local`s. `borrowed`
and `live` are the pre-existing `MaybeBorrowedLocals` and
`MaybeLiveLocals` analyses respectively.
2020-05-19 17:50:05 -07:00
Dylan MacKenzie
daea09cf91 Add MaybeInitializedLocals dataflow analysis 2020-05-19 17:50:05 -07:00
Nicholas Nethercote
9eb0399a9d Adjust the zero check in RawVec::grow.
This was supposed to land as part of #72227. (I wish `git push` would
abort when you have uncommited changes.)
2020-05-20 09:57:14 +10:00
Aaron Hill
4a8ccdcc0b
Use a fixed-point iteration when breaking tokens
Some tokens need to be broken in a loop until we reach
'unbreakable' tokens.
2020-05-19 19:47:23 -04:00
Matthias Schiffer
a114a23723 Document #[ffi_const] and #[ffi_pure] function attributes in unstable book
Based on the work of gnzlbg <gonzalobg88@gmail.com>.
2020-05-20 01:16:11 +02:00
Matthias Schiffer
a7d7f0bbe9 Add tests for #[ffi_const] and #[ffi_pure] function attributes
Based on the work of gnzlbg <gonzalobg88@gmail.com>.
2020-05-20 01:16:11 +02:00
Matthias Schiffer
abc236414b Implement #[ffi_const] and #[ffi_pure] function attributes
Introduce function attribute corresponding to the `const`/`pure`
attributes supported by GCC, clang and other compilers.

Based on the work of gnzlbg <gonzalobg88@gmail.com>.
2020-05-20 01:16:11 +02:00
marmeladema
fdc4522f80 Remove unused StableHashingContext::node_to_hir_id method 2020-05-20 00:11:05 +01:00
Aaron Hill
9b2b8a5afa
Break tokens before checking if they are 'probably equal'
Fixes #68489

When checking two `TokenStreams` to see if they are 'probably equal',
we ignore the `IsJoint` information associated with each `TokenTree`.
However, the `IsJoint` information determines whether adjacent tokens
will be 'glued' (if possible) when construction the `TokenStream` - e.g.
`[Gt Gt]` can be 'glued' to `BinOp(Shr)`.

Since we are ignoring the `IsJoint` information, 'glued' and 'unglued'
tokens are equivalent for determining if two `TokenStreams` are
'probably equal'. Therefore, we need to 'unglue' all tokens in the
stream to avoid false negatives (which cause us to throw out the cached
tokens, losing span information).
2020-05-19 18:48:26 -04:00
Jeremy Fitzhardinge
508e3f2bdc Remove unused dependencies 2020-05-19 14:34:23 -07:00
mibac138
aaeea7ffc3 Alter wording for use foo::self help 2020-05-19 22:12:41 +02:00
Pyry Kontio
46159b3610 split_inclusive: add tracking issue number (72360) 2020-05-20 04:22:37 +09:00
mibac138
d190e10f74 Add error recovery for use foo::self 2020-05-19 20:40:47 +02:00
mibac138
84a44218ad Suggest fixes for use foo::self 2020-05-19 20:40:46 +02:00
Tamir Duberstein
2bf6833d37
Remove dangling COPYRIGHT references
Missed in 2a663555dd.
2020-05-19 14:34:30 -04:00
bors
3a7dfda40a Auto merge of #69171 - Amanieu:new-asm, r=nagisa,nikomatsakis
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-19 18:32:40 +00:00
Amanieu d'Antras
1cfdc7ed0c Update dlmalloc dependency to 0.1.4 2020-05-19 18:25:41 +01:00
Nadrieril
d7e1d5f0c2 Make caveat more precise 2020-05-19 17:02:31 +01:00
bors
672b272077 Auto merge of #72227 - nnethercote:tiny-vecs-are-dumb, r=Amanieu
Tiny Vecs are dumb.

Currently, if you repeatedly push to an empty vector, the capacity
growth sequence is 0, 1, 2, 4, 8, 16, etc. This commit changes the
relevant code (the "amortized" growth strategy) to skip 1 and 2, instead
using 0, 4, 8, 16, etc. (You can still get a capacity of 1 or 2 using
the "exact" growth strategy, e.g. via `reserve_exact()`.)

This idea (along with the phrase "tiny Vecs are dumb") comes from the
"doubling" growth strategy that was removed from `RawVec` in #72013.
That strategy was barely ever used -- only when a `VecDeque` was grown,
oddly enough -- which is why it was removed in #72013.

(Fun fact: until just a few days ago, I thought the "doubling" strategy
was used for repeated push case. In other words, this commit makes
`Vec`s behave the way I always thought they behaved.)

This change reduces the number of allocations done by rustc itself by
10% or more. It speeds up rustc, and will also speed up any other Rust
program that uses `Vec`s a lot.

In theory, the change could increase memory usage, but in practice it
doesn't. It would be an unusual program where very small `Vec`s having a
capacity of 4 rather than 1 or 2 would make a difference. You'd need a
*lot* of very small `Vec`s, and/or some very small `Vec`s with very
large elements.

r? @Amanieu
2020-05-19 15:12:12 +00:00
Guillaume Gomez
ed8478036c Fix going back in history to a search result page on firefox 2020-05-19 16:48:21 +02:00
Tymoteusz Jankowski
fc4c9a6c7f
Make intra-link resolve links for both trait and impl items 2020-05-19 14:32:17 +02:00
bors
42acd9086f Auto merge of #72346 - Dylan-DPC:rollup-vp418xs, r=Dylan-DPC
Rollup of 5 pull requests

Successful merges:

 - #71886 (Stabilize saturating_abs and saturating_neg)
 - #72066 (correctly handle uninferred consts)
 - #72068 (Ignore arguments when looking for `IndexMut` for subsequent `mut` obligation)
 - #72338 (Fix ICE in -Zsave-analysis)
 - #72344 (Assert doc wording)

Failed merges:

r? @ghost
2020-05-19 11:54:40 +00:00
Dylan DPC
745ca2afae
Rollup merge of #72344 - kornelski:assertdoc, r=Mark-Simulacrum
Assert doc wording

The current wording implies unsafe code is dependent on assert:

https://users.rust-lang.org/t/are-assert-statements-included-in-unsafe-blocks/42865
2020-05-19 13:53:47 +02:00
Dylan DPC
817880842c
Rollup merge of #72338 - doctorn:trait-object-ice, r=ecstatic-morse
Fix ICE in -Zsave-analysis

Puts a short-circuit in to avoid an ICE in `-Zsave-analysis`.

r? @ecstatic-morse

Resolves #72267
2020-05-19 13:53:45 +02:00
Dylan DPC
79ac73a3fc
Rollup merge of #72068 - estebank:mut-deref-hack, r=oli-obk
Ignore arguments when looking for `IndexMut` for subsequent `mut` obligation

Given code like `v[&field].boo();` where `field: String` and
`.boo(&mut self)`, typeck will have decided that `v` is accessed using
`Index`, but when `boo` adds a new `mut` obligation,
`convert_place_op_to_mutable` is called. When this happens, for *some
reason* the arguments' dereference adjustments are completely ignored
causing an error saying that `IndexMut` is not satisfied:

```
error[E0596]: cannot borrow data in an index of `Indexable` as mutable
  --> src/main.rs:30:5
   |
30 |     v[&field].boo();
   |     ^^^^^^^^^ cannot borrow as mutable
   |
   = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `Indexable`
```

This is not true, but by changing `try_overloaded_place_op` to retry
when given `Needs::MutPlace` without passing the argument types, the
example successfully compiles.

I believe there might be more appropriate ways to deal with this.

Fix #72002.
2020-05-19 13:53:43 +02:00
Dylan DPC
12040cf665
Rollup merge of #72066 - lcnr:const-type-info-err, r=varkor
correctly handle uninferred consts

fixes the ICE mentioned in https://github.com/rust-lang/rust/issues/70507#issuecomment-615268893

I originally tried to generalize `need_type_info_err` to also work with consts which was not as much fun as I hoped 😅

It might be easier to have some duplication here and handle consts separately.

r? @varkor
2020-05-19 13:53:41 +02:00
Dylan DPC
4c48f5ab69
Rollup merge of #71886 - t-rapp:tr-saturating-funcs, r=dtolnay
Stabilize saturating_abs and saturating_neg

Stabilizes the following signed integer functions with saturation mechanics:
 * saturating_abs()
 * saturating_neg()

Closes #59983
2020-05-19 13:53:36 +02:00
Guillaume Gomez
56c494a148 Clean up E0593 explanation 2020-05-19 13:20:33 +02:00
Kornel
5b65c0f9a5 Assert doc wording 2020-05-19 11:22:03 +01:00
Bastian Kauschke
08b9b97c53 add test for repr(128) enum derives 2020-05-19 10:55:12 +02:00
Bastian Kauschke
d6cb5405dd add tests for enum discriminants 2020-05-19 10:55:12 +02:00
Bastian Kauschke
ff2940a9f4 update discriminant_value usage in tests 2020-05-19 10:55:12 +02:00
Bastian Kauschke
3188ca7dd9 update discriminant_value usage in the compiler 2020-05-19 10:25:13 +02:00
Bastian Kauschke
25930e47ba update codegen of discriminant_value 2020-05-19 10:25:13 +02:00
Bastian Kauschke
b6975bf22f auto implDiscriminantKind for every type 2020-05-19 10:25:13 +02:00
Bastian Kauschke
9f7c5a80a3 update libcore, add discriminant_kind lang-item 2020-05-19 10:12:35 +02:00
Bastian Kauschke
aab144f6d1 update select docs 2020-05-19 10:12:35 +02:00
bors
914adf04af Auto merge of #71447 - cuviper:unsized_cow, r=dtolnay
impl From<Cow> for Box, Rc, and Arc

These forward `Borrowed`/`Owned` values to existing `From` impls.

- `Box<T>` is a fundamental type, so it would be a breaking change to add a blanket impl. Therefore, `From<Cow>` is only implemented for `[T]`, `str`, `CStr`, `OsStr`, and `Path`.
- For `Rc<T>` and `Arc<T>`, `From<Cow>` is implemented for everything that implements `From` the borrowed and owned types separately.
2020-05-19 08:08:48 +00:00
bors
5943351d0e Auto merge of #68717 - petrochenkov:stabexpat, r=varkor
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-19 03:11:32 +00:00
bors
89988fe727 Auto merge of #72330 - Dylan-DPC:rollup-yuxadv8, r=Dylan-DPC
Rollup of 5 pull requests

Successful merges:

 - #71599 (Support coercion between (FnDef | Closure) and (FnDef | Closure))
 - #71973 (Lazy normalization of constants (Reprise))
 - #72283 (Drop Elaboration Elaboration)
 - #72290 (Add newer rust versions to linker-plugin-lto.md)
 - #72318 (Add help text for remote-test-client)

Failed merges:

r? @ghost
2020-05-18 22:50:40 +00:00
Eric Huss
c8443bb33a Update cargo 2020-05-18 15:41:57 -07:00
Nathan Corbyn
ef3f2c0a7c Fix ICE in -Zsave-analysis 2020-05-18 22:55:04 +01:00
Simon Sapin
861dfaa855 Apply suggestions from code review
Co-authored-by: kennytm <kennytm@gmail.com>
2020-05-18 21:29:43 +02:00
Simon Sapin
49d5f5a977 Add len and slice_from_raw_parts to NonNull<[T]>
This follows the precedent of the recently-added `<*const [T]>::len`
(adding to its tracking issue https://github.com/rust-lang/rust/issues/71146)
and `ptr::slice_from_raw_parts`.
2020-05-18 21:29:43 +02:00
Nadrieril
159f48cdc2 Don't mention function pointers
See https://github.com/rust-lang/rust/pull/71930#discussion_r426762889
2020-05-18 20:14:38 +01:00
bors
d8878868c8 Auto merge of #72332 - mati865:ci-fix, r=pietroalbini
CI: Workaround MSYS2 issue
2020-05-18 18:40:07 +00:00
Mateusz Mikuła
081daf609c Update pacman first 2020-05-18 20:38:59 +02:00
Bastian Kauschke
5da74304d5 correctly handle uninferred consts 2020-05-18 20:36:18 +02:00
Dylan DPC
256ce18dcb
Rollup merge of #72318 - tblah:remote-test-client-doc, r=nikomatsakis
Add help text for remote-test-client

Add help text describing the usage of remote-test-client
2020-05-18 19:04:08 +02:00
Dylan DPC
0b63bc7b51
Rollup merge of #72290 - elichai:2020-doc-lto, r=wesleywiser
Add newer rust versions to linker-plugin-lto.md

Hi,
This doc got a bit out of date,
it's hosted here: https://doc.rust-lang.org/rustc/linker-plugin-lto.html
you can check the versions I've added via:
```bash
$ rustup install 1.38.0
$ rustc +1.38.0 -vV
rustc 1.38.0 (625451e37 2019-09-23)
binary: rustc
commit-hash: 625451e376bb2e5283fc4741caa0a3e8a2ca4d54
commit-date: 2019-09-23
host: x86_64-unknown-linux-gnu
release: 1.38.0
LLVM version: 9.0

$ rustup install 1.43.1
$ rustc +1.43.1 -vV
rustc 1.43.1 (8d69840ab 2020-05-04)
binary: rustc
commit-hash: 8d69840ab92ea7f4d323420088dd8c9775f180cd
commit-date: 2020-05-04
host: x86_64-unknown-linux-gnu
release: 1.43.1
LLVM version: 9.0
```
2020-05-18 19:04:06 +02:00