Fix miscompilation of inline assembly with outputs in cases where we emit an invoke instead of call instruction.
We ran into this bug where rustc would segfault while trying to compile certain uses of inline assembly.
Here is a simple repro that demonstrates the issue:
```rust
#![feature(asm_unwind)]
fn main() {
let _x = String::from("string here just cause we need something with a non-trivial drop");
let foo: u64;
unsafe {
std::arch::asm!(
"mov {}, 1",
out(reg) foo,
options(may_unwind)
);
}
println!("{}", foo);
}
```
([playground link](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=7d6641e83370d2536a07234aca2498ff))
But crucially `feature(asm_unwind)` is not actually needed and this can be triggered on stable as a result of the way async functions/generators are handled in the compiler. e.g.:
```rust
extern crate futures; // 0.3.21
async fn bar() {
let foo: u64;
unsafe {
std::arch::asm!(
"mov {}, 1",
out(reg) foo,
);
}
println!("{}", foo);
}
fn main() {
futures::executor::block_on(bar());
}
```
([playground link](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1c7781c34dd4a3e80ae4bd936a0c82fc))
An example of the incorrect LLVM generated:
```llvm
bb1: ; preds = %start
%1 = invoke i64 asm sideeffect alignstack inteldialect unwind "mov ${0:q}, 1", "=&r,~{dirflag},~{fpsr},~{flags},~{memory}"()
to label %bb2 unwind label %cleanup, !srcloc !9
store i64 %1, i64* %foo, align 8
bb2:
[...snip...]
```
The store should not be placed after the asm invoke but rather should be in the normal control flow basic block (`bb2` in this case).
[Here](https://gist.github.com/luqmana/be1af5b64d2cda5a533e3e23a7830b44) is a writeup of the investigation that lead to finding this.
[`let_chains`] Forbid `let` inside parentheses
Parenthesizes are mostly a no-op in let chains, in other words, they are mostly ignored.
```rust
let opt = Some(Some(1i32));
if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
println!("`b` is declared inside but used outside");
}
```
As seen above, such behavior can lead to confusion.
A proper fix or nested encapsulation would probably require research, time and a modified MIR graph so in this PR I simply denied any `let` inside parentheses. Non-let stuff are still allowed.
```rust
fn main() {
let fun = || true;
if let true = (true && fun()) && (true) {
println!("Allowed");
}
}
```
It is worth noting that `let ...` is not an expression and the RFC did not mention this specific situation.
cc `@matthewjasper`
Rollup of 7 pull requests
Successful merges:
- #95743 (Update binary_search example to instead redirect to partition_point)
- #95771 (Update linker-plugin-lto.md to 1.60)
- #95861 (Note that CI tests Windows 10)
- #95875 (bootstrap: show available paths help text for aliased subcommands)
- #95876 (Add a note for unsatisfied `~const Drop` bounds)
- #95907 (address fixme for diagnostic variable name)
- #95917 (thin_box test: import from std, not alloc)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Only suggest removing semicolon when expression is compatible with `impl Trait`
https://github.com/rust-lang/rust/issues/54771#issuecomment-476423690
> It still needs checking that the last statement's expr can actually conform to the trait, but the naïve behavior is there.
Only suggest removing a semicolon when the type behind the semicolon actually implements the trait in an RPIT `-> impl Trait`. Also upgrade the label that suggests removing the semicolon to a suggestion (should it be verbose?).
cc #54771
When a `macro_rules! foo { ... }` invocation is compiled the name used
is `foo`, not `macro_rules!`. This is different to all other macro
invocations, and confused me when I was inserted debugging println
statements for macro evaluation.
This commit changes it to `macro_rules` (or just `macro`), which is what
I expected. There are no externally visible changes.
Rollup of 7 pull requests
Successful merges:
- #95566 (Avoid duplication of doc comments in `std::char` constants and functions)
- #95784 (Suggest replacing `typeof(...)` with an actual type)
- #95807 (Suggest adding a local for vector to fix borrowck errors)
- #95849 (Check for git submodules in non-git source tree.)
- #95852 (Fix missing space in lossy provenance cast lint)
- #95857 (Allow multiple derefs to be splitted in deref_separator)
- #95868 (rustdoc: Reduce allocations in a `html::markdown` function)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Allow multiple derefs to be splitted in deref_separator
Previously in #95649 only a single deref within projection was supported and multiple derefs caused a bunch of issues, this PR fixes those issues.
```@oli-obk``` helped a ton again ❤️
Suggest replacing `typeof(...)` with an actual type
This PR adds suggestion to replace `typeof(...)` with an actual type of `...`, for example in case of `typeof(1)` we suggest replacing it with `i32`.
If the expression
1. Is not const (`{ let a = 1; let _: typeof(a); }`)
2. Can't be found (`let _: typeof(this_variable_does_not_exist)`)
3. Or has non-suggestable type (closure, generator, error, etc)
we don't suggest anything.
The 1 one is sad, but it's not clear how to support non-consts expressions for `typeof`.
_This PR is inspired by [this tweet]._
[this tweet]: https://twitter.com/compiler_errors/status/1511945354752638976
Make def names and HIR names consistent.
The name in the `DefKey` is interned to create the `DefId`, so it does not
require any query to access. This can be leveraged to avoid a few useless
HIR accesses for names.
~In order to achieve that, generic parameters created from universal
impl-trait are given the pretty-printed ast as a name, instead of
`{{opaque}}`.~
~Drive-by: the `TyCtxt::opt_item_name` used a dummy span for non-local
definitions. We have access to `def_ident_span`, so we use it.~
We may sometimes emit an `invoke` instead of a `call` for inline
assembly during the MIR -> LLVM IR lowering. But we failed to update
the IR builder's current basic block before writing the results to the
outputs. This would result in invalid IR because the basic block would
end in a `store` instruction, which isn't a valid terminator.
expand: Remove `ParseSess::missing_fragment_specifiers`
It was used for deduplicating some errors for legacy code which are mostly deduplicated even without that, but at cost of global mutable state, which is not a good tradeoff.
cc https://github.com/rust-lang/rust/pull/95747#issuecomment-1091619403
r? ``@nnethercote``
Left overs of #95761
These are just nits. Feel free to close this PR if all modifications are not worth merging.
* `#![feature(decl_macro)]` is not needed anymore in `rustc_expand`
* `tuple_impls` does not require `$Tuple:ident`. I guess it is there to enhance readability?
r? ```@petrochenkov```
refactor: simplify few string related interactions
Few small optimizations:
check_doc_keyword: don't alloc string for emptiness check
check_doc_alias_value: get argument as Symbol to prevent needless string convertions
check_doc_attrs: don't alloc vec, iterate over slice.
replace as_str() check with symbol check
get_single_str_from_tts: don't prealloc string
trivial string to str replace
LifetimeScopeForPath::NonElided use Vec<Symbol> instead of Vec<String>
AssertModuleSource use FxHashSet<Symbol> instead of BTreeSet<String>
CrateInfo.crate_name replace FxHashMap<CrateNum, String> with FxHashMap<CrateNum, Symbol>
It was used for deduplicating some errors for legacy code which are mostly deduplicated even without that, but at cost of global mutable state, which is not a good tradeoff.
interpret: err instead of ICE on size mismatches in to_bits_or_ptr_internal
We did this a while ago already for `to_i32()` and friends, but missed this one. That became quite annoying when I was debugging an ICE caused by `read_pointer` in a Miri shim where the code was passing an argument at the wrong type.
Having `scalar_to_ptr` be fallible is consistent with all the other `Scalar::to_*` methods being fallible. I added `unwrap` only in code outside the interpreter, which is no worse off than before now in terms of panics.
r? ````@oli-obk````
Remove explicit delimiter token trees from `Delimited`.
They were introduced by the final commit in #95159 and gave a
performance win. But since the introduction of `MatcherLoc` they are no
longer needed. This commit reverts that change, making the code a bit
simpler.
r? `@petrochenkov`
Strict provenance lints
See #95488.
This PR introduces two unstable (allow by default) lints to which lint on int2ptr and ptr2int casts, as the former is not possible in the strict provenance model and the latter can be written nicer using the `.addr()` API.
Based on an initial version of the lint by ```@Gankra``` in #95199.
Cached stable hash cleanups
r? `@nnethercote`
Add a sanity assertion in debug mode to check that the cached hashes are actually the ones we get if we compute the hash each time.
Add a new data structure that bundles all the hash-caching work to make it easier to re-use it for different interned data structures
They were introduced by the final commit in #95159 and gave a
performance win. But since the introduction of `MatcherLoc` they are no
longer needed. This commit reverts that change, making the code a bit
simpler.
Enforce well formedness for type alias impl trait's hidden type
fixes#84657
This was not an issue with return-position-impl-trait because the generic bounds of the function are the same as those of the opaque type, and the hidden type must already be well formed within the function.
With type-alias-impl-trait the hidden type could be defined in a function that has *more* lifetime bounds than the type alias. This is fine, but the hidden type must still be well formed without those additional bounds.
- Create hir_crate_items query which traverses tcx.hir_crate(()).owners to return a hir::ModuleItems
- use tcx.hir_crate_items in tcx.hir().items() to return an iterator of hir::ItemId
- add par_items(impl Fn(hir::ItemId)) to traverse all items in parallel
Signed-off-by: Miguel Guarniz <mi9uel9@gmail.com>
* split `fuzzy_provenance_casts` into a ptr2int and a int2ptr lint
* feature gate both lints
* update documentation to be more realistic short term
* add tests for these lints
check_doc_alias_value: get argument as Symbol to prevent needless string convertions
check_doc_attrs: don't alloc vec, iterate over slice. Vec introduced in #83149, but no perf run posted on merge
replace as_str() check with symbol check
get_single_str_from_tts: don't prealloc string
trivial string to str replace
LifetimeScopeForPath::NonElided use Vec<Symbol> instead of Vec<String>
AssertModuleSource use BTreeSet<Symbol> instead of BTreeSet<String>
CrateInfo.crate_name replace FxHashMap<CrateNum, String> with FxHashMap<CrateNum, Symbol>
This commit suggests replacing typeof(...) with an actual type of "...",
for example in case of `typeof(1)` we suggest replacing it with `i32`.
If the expression
- Is not const (`{ let a = 1; let _: typeof(a); }`)
- Can't be found (`let _: typeof(this_variable_does_not_exist)`)
- Or has non-suggestable type (closure, generator, error, etc)
we don't suggest anything.
Report opaque type mismatches directly during borrowck of the function instead of within the `type_of` query.
This allows us to only store a single hidden type per opaque type instead of having to store one per set of substitutions.
r? `@compiler-errors`
This does not affect diagnostics, because the diagnostic messages are exactly the same.
This allows profiling costly arguments to be recorded only when `-Zself-profile-events=args` is on: using a closure that takes an `EventArgRecorder` and call its `record_arg` or `record_args` methods.
Use gender neutral terms
#95508 was not executed well, but it did find a couple of legitimate issues: some uses of unnecessarily gendered language, and some typos. This PR fixes (properly) the legitimate issues it found.
Stop flagging unexpected inner attributes as outer ones in certain diagnostics
Fixes#94340.
In the issue to-be-fixed I write that the general message _an inner attribute is not permitted in this context_ should be more specific noting that the “context” is the `include` macro. This, however, cannot be achieved without touching a lot of things and passing a flag to the `parse_expr` and `parse_item` calls in `expand_include`. This seems rather hacky to me. That's why I left it as it. `Span::from_expansion` does not apply either AFAIK.
`@rustbot` label A-diagnostics T-compiler
Bump bootstrap compiler to 1.61.0 beta
This PR bumps the bootstrap compiler to the 1.61.0 beta. The first commit changes the stage0 compiler, the second commit applies the "mechanical" changes and the third and fourth commits apply changes explained in the relevant comments.
r? `@Mark-Simulacrum`
By heap allocating the argument within `NtPath`, `NtVis`, and `NtStmt`.
This slightly reduces cumulative and peak allocation amounts, most
notably on `deep-vector`.
Check that all hidden types are the same and then deduplicate them.
fixes#95538
This used to trigger a sanity check. Now we accept that there may be multiple places where a hidden type is constrained and we merge all of these at the end.
Ideally we'd merge eagerly, but that is a larger refactoring that I don't want to put into a backport
New mir-opt deref_separator
This adds a new mir-opt that split certain derefs into this form:
`let x = (*a.b).c;` to => `tmp = a.b; let x = (*tmp).c;`
Huge thanks to ``@oli-obk`` for his patient mentoring.
interp/validity: enforce Scalar::Initialized
This is a follow-up to https://github.com/rust-lang/rust/pull/94527, to also account for the new kind of `Scalar` layout inside the validity checker.
r? `@oli-obk`
enhance `ConstGoto` mir-opt by moving up `StorageDead` statements
From the `FIXME` in the implementation of `ConstGoto` miropt. We can move `StorageDead` statements up to the predecessor. This can expand the scope of application of this opt.
interp: pass TyCtxt to Machine methods that do not take InterpCx
This just seems like something you might need, so let's consistently have it.
One day we might have to add `ParamEnv` as well, though that seems less likely (and in Miri you can always use `reveal_all` anyway). It might make sense to have a type that packages `TyCtxt` and `ParamEnv`, this pairing occurs quite frequently in rustc...
r? `@oli-obk`
Currently it's called in `parse_tt` every time a match rule is invoked.
This commit moves it so it's called instead once per match rule, in
`compile_declarative_macro. This is a performance win.
The commit also moves `compute_locs` out of `TtParser`, because there's
no longer any reason for it to be in there.
Let CTFE to handle partially uninitialized unions without marking the entire value as uninitialized.
follow up to #94411
To fix https://github.com/rust-lang/rust/issues/69488 and by extension fix https://github.com/rust-lang/rust/issues/94371, we should stop treating types like `MaybeUninit<usize>` as something that the `Scalar` type in the interpreter engine can represent. So we add a new field to `abi::Primitive` that records whether the primitive is nested in a union
cc `@RalfJung`
r? `@ghost`
Use the proc-macro descr to track their individual expansions with
self-profiling events. This will help diagnose performance issues
with slow proc-macros.
Note invariance reason for FnDef types
Fixes#95272. Is it worthwhile even printing a variance explanation here? Or should I try to track down which function parameter is responsible for the invariance?
r? ``@Aaron1011`` since you wrote #89336
diagnostics: translation infrastructure
An implementation of the infrastructure required to have translatable diagnostic messages.
- Introduces a `DiagnosticMessage` type which can represent both the current non-translatable messages and identifiers for [Fluent](https://projectfluent.org/).
- Modifies current diagnostic API so that existing calls still work but `DiagnosticMessage`s can be provided too.
- Adds support for always loading a "fallback bundle" containing the English diagnostic messages, which are used when a `DiagnosticMessage::FluentIdentifier` is used in a diagnostic being emitted.
- Adds support for loading a "primary bundle" which contains the user's preferred language translation, and is used preferentially when it contains a diagnostic message being emitted. Primary bundles are loaded either from the path provided to `-Ztranslate-alternate-ftl` (for testing), or from the sysroot at `$sysroot/locale/$locale/*.ftl` given a locale with `-Ztranslate-lang` (which is parsed as a language identifier).
- Adds "diagnostic args" which enable normally-interpolated variables to be made available as variables for Fluent messages to use.
- Updates `#[derive(SessionDiagnostic)]` so that it can only be used for translatable diagnostics and update the handful of diagnostics which used the derive to be translatable.
For example, the following diagnostic...
```rust
#[derive(SessionDiagnostic)]
#[error = "E0195"]
pub struct LifetimesOrBoundsMismatchOnTrait {
#[message = "lifetime parameters or bounds on {item_kind} `{ident}` do not match the trait declaration"]
#[label = "lifetimes do not match {item_kind} in trait"]
pub span: Span,
#[label = "lifetimes in impl do not match this {item_kind} in trait"]
pub generics_span: Option<Span>,
pub item_kind: &'static str,
pub ident: Ident,
}
```
...becomes...
```rust
#[derive(SessionDiagnostic)]
#[error(code = "E0195", slug = "typeck-lifetimes-or-bounds-mismatch-on-trait")]
pub struct LifetimesOrBoundsMismatchOnTrait {
#[primary_span]
#[label]
pub span: Span,
#[label = "generics-label"]
pub generics_span: Option<Span>,
pub item_kind: &'static str,
pub ident: Ident,
}
```
```fluent
typeck-lifetimes-or-bounds-mismatch-on-trait =
lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
.label = lifetimes do not match {$item_kind} in trait
.generics-label = lifetimes in impl do not match this {$item_kind} in trait
```
r? `@estebank`
cc `@oli-obk` `@Manishearth`
In #95555 this was moved out of `parse_tt_inner` and `nameize` into
`compute_locs`. But the next commit will be moving `compute_locs`
outwards to a place that isn't suitable for the missing fragment
identifier checking. So this reinstates the old checking.
Conditional on the parallel compiler being enabled, use a different
`IntlLangMemoizer` which supports being sent between threads in
`FluentBundle`.
Signed-off-by: David Wood <david.wood@huawei.com>
`FluentId` is the type alias that is used everywhere else so it should
be used here too so that this doesn't need updated if the alias changes.
Signed-off-by: David Wood <david.wood@huawei.com>
Add an option for enabling and disabling Fluent's directionality
isolation markers in output. Disabled by default as these can render in
some terminals and applications.
Signed-off-by: David Wood <david.wood@huawei.com>
Add some links to the Fluent documentation to
`DiagnosticMessage::FluentIdentifier` which explain what a Fluent
message and attribute are.
Signed-off-by: David Wood <david.wood@huawei.com>
Removes `expected_pluralize` parameter from diagnostic struct which is
no longer necessary as the Fluent message can determine the correct
pluralization.
Signed-off-by: David Wood <david.wood@huawei.com>
If the user requests a diagnostic locale of "en-US" then it doesn't make
sense to try and load that from the `$sysroot` because it is just the
default built-in locale.
Signed-off-by: David Wood <david.wood@huawei.com>
Extends support for generating `DiagnosticMessage::FluentIdentifier`
messages from `SessionDiagnostic` derive to `#[suggestion]`.
Signed-off-by: David Wood <david.wood@huawei.com>
Extends support for generating `DiagnosticMessage::FluentIdentifier`
messages from `SessionDiagnostic` derive to `#[label]`.
Signed-off-by: David Wood <david.wood@huawei.com>
In an effort to make it easier to port diagnostics to
`SessionDiagnostic` (for translation) and since translation slugs could
replace error codes, make error codes optional in the
`SessionDiagnostic` derive.
Signed-off-by: David Wood <david.wood@huawei.com>
A call to `set_arg` is generated for every field of a
`SessionDiagnostic` struct without attributes, but not all types support
being an argument, so `#[no_arg]` is introduced to skip these fields.
Signed-off-by: David Wood <david.wood@huawei.com>
Small commit renaming `#[message]` to `#[primary_span]` as this more
accurately reflects what it does now.
Signed-off-by: David Wood <david.wood@huawei.com>
Small commit adding backticks around types and annotations in the error
messages from the session diagnostic derive.
Signed-off-by: David Wood <david.wood@huawei.com>
Fluent diagnostics can insert directionality isolation markers around
interpolated variables indicating that there may be a shift from
right-to-left to left-to-right text (or vice-versa). These are disabled
because they are sometimes visible in the error output, but may be worth
investigating in future (for example: if type names are left-to-right
and the surrounding diagnostic messages are right-to-left, then these
might be helpful).
Signed-off-by: David Wood <david.wood@huawei.com>
Non-subdiagnostic fields (i.e. those that don't have `#[label]`
attributes or similar and are just additional context) have to be added
as arguments for Fluent messages to refer them. This commit extends the
`SessionDiagnostic` derive to do this for all fields that do not have
attributes and introduces an `IntoDiagnosticArg` trait that is
implemented on all types that can be converted to a argument for Fluent.
Signed-off-by: David Wood <david.wood@huawei.com>
Move the handling of `Span` or `(Span, Applicability)` types in
`#[suggestion]` attributes to its own function.
Signed-off-by: David Wood <david.wood@huawei.com>
Various small changes to comments, like wrapping code in backticks,
changing comments to doc comments and adding newlines.
Signed-off-by: David Wood <david.wood@huawei.com>
Extend loading of Fluent bundles so that bundles can be loaded from the
sysroot based on the language requested by the user, or using a nightly
flag.
Sysroot bundles are loaded from `$sysroot/share/locale/$locale/*.ftl`.
Signed-off-by: David Wood <david.wood@huawei.com>
This commit updates the signatures of all diagnostic functions to accept
types that can be converted into a `DiagnosticMessage`. This enables
existing diagnostic calls to continue to work as before and Fluent
identifiers to be provided. The `SessionDiagnostic` derive just
generates normal diagnostic calls, so these APIs had to be modified to
accept Fluent identifiers.
In addition, loading of the "fallback" Fluent bundle, which contains the
built-in English messages, has been implemented.
Each diagnostic now has "arguments" which correspond to variables in the
Fluent messages (necessary to render a Fluent message) but no API for
adding arguments has been added yet. Therefore, diagnostics (that do not
require interpolation) can be converted to use Fluent identifiers and
will be output as before.
`MultiSpan` contains labels, which are more complicated with the
introduction of diagnostic translation and will use types from
`rustc_errors` - however, `rustc_errors` depends on `rustc_span` so
`rustc_span` cannot use types like `DiagnosticMessage` without
dependency cycles. Introduce a new `rustc_error_messages` crate that can
contain `DiagnosticMessage` and `MultiSpan`.
Signed-off-by: David Wood <david.wood@huawei.com>
Introduce a `DiagnosticMessage` type that will enable diagnostic
messages to be simple strings or Fluent identifiers.
`DiagnosticMessage` is now used in the implementation of the standard
`DiagnosticBuilder` APIs.
Signed-off-by: David Wood <david.wood@huawei.com>
rustdoc: Fix resolution of `crate`-relative paths in doc links
Resolve `crate::foo` paths transparently to rustdoc, so their resolution no longer affects diagnostics and modules used for determining traits in scope.
The proper solution is to account for the current `module_id`/`parent_scope` in `fn resolve_crate_root`, but it's a slightly larger compiler changes. This PR moves the code closer to it, but keeps it rustdoc-specific.
Fixes https://github.com/rust-lang/rust/issues/78696
Fixes https://github.com/rust-lang/rust/issues/94924
Fix late-bound ICE in `dyn` return type suggestion
This fixes the root-cause of the attached issues -- the root problem is that we're using the return type from a signature with late-bound instead of early-bound regions. The change on line 1087 (`let Some(liberated_sig) = typeck_results.liberated_fn_sigs().get(fn_hir_id) else { return false; };`) makes sure we're grabbing the _right_ return type for this suggestion to check the `dyn` predicates with.
Fixes#91801Fixes#91803
This fix also includes some drive-by changes, specifically:
1. Don't suggest boxing when we have `-> dyn Trait` and are already returning `Box<T>` where `T: Trait` (before we always boxed the value).
2. Suggestion applies even when the return type is a type alias (e.g. `type Foo = dyn Trait`). This does cause the suggestion to expand to the aliased type, but I think it's still beneficial.
3. Split up the multipart suggestion because there's a 6-line max in the printed output...
I am open to splitting out the above changes, if we just want to fix the ICE first.
cc: ```@terrarier2111``` and #92289
Mention implementers of unsatisfied trait
When encountering an unsatisfied trait bound, if there are no other
suggestions, mention all the types that *do* implement that trait:
```
error[E0277]: the trait bound `f32: Foo` is not satisfied
--> $DIR/impl_wf.rs:22:6
|
LL | impl Baz<f32> for f32 { }
| ^^^^^^^^ the trait `Foo` is not implemented for `f32`
|
= help: the trait `Foo` is implemented for `i32`
note: required by a bound in `Baz`
--> $DIR/impl_wf.rs:18:31
|
LL | trait Baz<U: ?Sized> where U: Foo { }
| ^^^ required by this bound in `Baz`
```
```
error[E0277]: the trait bound `u32: Foo` is not satisfied
--> $DIR/associated-types-path-2.rs:29:5
|
LL | f1(2u32, 4u32);
| ^^ the trait `Foo` is not implemented for `u32`
|
= help: the trait `Foo` is implemented for `i32`
note: required by a bound in `f1`
--> $DIR/associated-types-path-2.rs:13:14
|
LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
| ^^^ required by this bound in `f1`
```
Suggest dereferencing in more cases.
Fix#87437, fix#90970.
When encountering an unsatisfied trait bound, if there are no other
suggestions, mention all the types that *do* implement that trait:
```
error[E0277]: the trait bound `f32: Foo` is not satisfied
--> $DIR/impl_wf.rs:22:6
|
LL | impl Baz<f32> for f32 { }
| ^^^^^^^^ the trait `Foo` is not implemented for `f32`
|
= help: the following other types implement trait `Foo`:
Option<T>
i32
str
note: required by a bound in `Baz`
--> $DIR/impl_wf.rs:18:31
|
LL | trait Baz<U: ?Sized> where U: Foo { }
| ^^^ required by this bound in `Baz`
```
Mention implementers of traits in `ImplObligation`s.
Do not mention other `impl`s for closures, ranges and `?`.
Suggest borrowing when trying to coerce unsized type into `dyn Trait`
A helpful error in response to #95598, since we can't coerce e.g. `&str` into `&dyn Display`, but we can coerce `&&str` into `&dyn Display` :)
Not sure if the suggestion message needs some help. Let me know, and I can refine this PR.
Reduce unnecessary escaping in proc_macro::Literal::character/string
I noticed that https://doc.rust-lang.org/proc_macro/struct.Literal.html#method.character is producing unreadable literals that make macro-expanded code unnecessarily hard to read. Since the proc macro server was using `escape_unicode()`, every char is escaped using `\u{…}` regardless of whether there is any need to do so. For example `Literal::character('=')` would previously produce `'\u{3d}'` which unnecessarily obscures the meaning when reading the macro-expanded code.
I've changed Literal::string also in this PR because `str`'s `Debug` impl is also smarter than just calling `escape_debug` on every char. For example `Literal::string("ferris's")` would previously produce `"ferris\'s"` but will now produce `"ferris's"`.
A new matcher representation for use in `parse_tt`
By transforming the matcher into a different form, `parse_tt` can run faster and be easier to understand.
r? `@petrochenkov`
Improve method name suggestions
Attempts to improve method name suggestions when a matching method name
is not found. The approach taken is use the Levenshtein distance and
account for substrings having a high distance but can sometimes be very
close to the intended method (eg. empty vs is_empty).
resolves#94747
`parse_tt` currently traverses a `&[TokenTree]` to do matching. But this
is a bad representation for the traversal.
- `TokenTree` is nested, and there's a bunch of expensive and fiddly
state required to handle entering and exiting nested submatchers.
- There are three positions (sequence separators, sequence Kleene ops,
and end of the matcher) that are represented by an index that exceeds
the end of the `&[TokenTree]`, which is clumsy and error-prone.
This commit introduces a new representation called `MatcherLoc` that is
designed specifically for matching. It fixes all the above problems,
making the code much easier to read. A `&[TokenTree]` is converted to a
`&[MatcherLoc]` before matching begins. Despite the cost of the
conversion, it's still a net performance win, because various pieces of
traversal state are computed once up-front, rather than having to be
recomputed repeatedly during the macro matching.
Some improvements worth noting.
- `parse_tt_inner` is *much* easier to read. No more having to compare
`idx` against `len` and read comments to understand what the result
means.
- The handling of `Delimited` in `parse_tt_inner` is now trivial.
- The three end-of-sequence cases in `parse_tt_inner` are now handled in
three separate match arms, and the control flow is much simpler.
- `nameize` is no longer recursive.
- There were two places that issued "missing fragment specifier" errors:
one in `parse_tt_inner()`, and one in `nameize()`. Presumably the
latter was never executed. There's now a single place issuing these
errors, in `compute_locs()`.
- The number of heap allocations done for a `check full` build of
`async-std-1.10.0` (an extreme example of heavy macro use) drops from
11.8M to 2.6M, and most of these occur outside of macro matching.
- The size of `MatcherPos` drops from 64 bytes to 16 bytes. Small enough
that it no longer needs boxing, which partly accounts for the
reduction in allocations.
- The rest of the drop in allocations is due to the removal of
`MatcherKind`, because we no longer need to record anything for the
parent matcher when entering a submatcher.
- Overall it reduces code size by 45 lines.
Do not use `ParamEnv::and` when building a cache key from a param-env and trait eval candidate
Do not use `ParamEnv::and` to cache a param-env with a selection/evaluation candidate.
This is because if the param-env is `RevealAll` mode, and the candidate looks global (i.e. it has erased regions, which can show up when we normalize a projection type under a binder<sup>1</sup>), then when we use `ParamEnv::and` to pair the candidate and the param-env for use as a cache key, we will throw away the param-env's caller bounds, and we'll end up caching a candidate that we inferred from the param-env with a empty param-env, which may cause cache-hit later when we have an empty param-env, and possibly mess with normalization like we see in the referenced issue during codegen.
Not sure how to trigger this with a more structured test, but changing `check-pass` to `build-pass` triggers the case that https://github.com/rust-lang/rust/issues/94903 detected.
<sup>1.</sup> That is, we will replace the late-bound region with a placeholder, which gets canonicalized and turned into an infererence variable, which gets erased during region freshening right before we cache the result. Sorry, it's quite a few steps.
Fixes#94903
r? `@Aaron1011` (or reassign as you see fit)
Don't emit non-asm contents error for naked function composed of errors
## Motivation
For naked functions an error is emitted when they are composed of anything other than a single asm!() block. However, this error triggers in a couple situations in which it adds no additional information or is actively misleading.
One example is if you do have an asm!() block but simply one with a syntax error:
```rust
#[naked]
unsafe extern "C" fn compiler_errors() {
asm!(invalid_syntax)
}
```
This results in two errors, one for the syntax error itself and another telling you that you need an asm block in your function:
```rust
error[E0787]: naked functions must contain a single asm block
--> src/main.rs:6:1
|
6 | / unsafe extern "C" fn naked_compile_error() {
7 | | asm!(blah)
8 | | }
| |_^
```
This issue also comes up when [utilizing `compile_error!()` for improving your diagnostics](https://twitter.com/steveklabnik/status/1509538243020218372), such as raising a compiler error when compiling for an unsupported target.
## Implementation
The rules this PR implements are as follows:
1. If any non-erroneous non-asm statement is included, an error will still occur
2. If multiple asm statements are included, an error will still occur
3. If 0 or 1 asm statements are present, as well as any non-zero number of erroneous statements, then this error will *not* be raised as it is likely either redundant or incorrect
The rule of thumb is effectively "if an error is present and its correction could change things, don't raise an error".
Reduce the cost of loading all built-ins targets
This PR started by measuring the exact slowdown of checking of well known conditional values.
Than this PR implemented some technics to reduce the cost of loading all built-ins targets.
cf. https://github.com/rust-lang/rust/issues/82450#issuecomment-1073992323
Add debug assertions to some unsafe functions
As suggested by https://github.com/rust-lang/rust/issues/51713
~~Some similar code calls `abort()` instead of `panic!()` but aborting doesn't work in a `const fn`, and the intrinsic for doing dispatch based on whether execution is in a const is unstable.~~
This picked up some invalid uses of `get_unchecked` in the compiler, and fixes them.
I can confirm that they do in fact pick up invalid uses of `get_unchecked` in the wild, though the user experience is less-than-awesome:
```
Running unittests (target/x86_64-unknown-linux-gnu/debug/deps/rle_decode_fast-04b7918da2001b50)
running 6 tests
error: test failed, to rerun pass '--lib'
Caused by:
process didn't exit successfully: `/home/ben/rle-decode-helper/target/x86_64-unknown-linux-gnu/debug/deps/rle_decode_fast-04b7918da2001b50` (signal: 4, SIGILL: illegal instruction)
```
~~As best I can tell these changes produce a 6% regression in the runtime of `./x.py test` when `[rust] debug = true` is set.~~
Latest commit (6894d559bd) brings the additional overhead from this PR down to 0.5%, while also adding a few more assertions. I think this actually covers all the places in `core` that it is reasonable to check for safety requirements at runtime.
Thoughts?
Attempts to improve method name suggestions when a matching method name
is not found. The approach taken is use the Levenshtein distance and
account for substrings having a high distance but can sometimes be very
close to the intended method (eg. empty vs is_empty).
make memcmp return a value of c_int_width instead of i32
This is an attempt to fix#32610 and #78022, namely, that `memcmp` always returns an `i32` regardless of the platform. I'm running into some issues and was hoping I could get some help.
Here's what I've been attempting so far:
1. Build the stage0 compiler with all the changes _expect_ for the changes in `library/core/src/slice/cmp.rs` and `compiler/rustc_codegen_llvm/src/context.rs`; this is because `target_c_int_width` isn't passed through and recognized as a valid config option yet. I'm building with `./x.py build --stage 0 library/core library/proc_macro compiler/rustc`
2. Next I add in the `#[cfg(c_int_width = ...)]` params to `cmp.rs` and `context.rs` and build the stage 1 compiler by running `./x.py build --keep-stage 0 --stage 1 library/core library/proc_macro compiler/rustc`. This step now runs successfully.
3. Lastly, I try to build the test program for AVR mentioned in #78022 with `RUSTFLAGS="--emit llvm-ir" cargo build --release`, and look at the resulting llvm IR, which still shows:
```
...
%11 = call addrspace(1) i32 `@memcmp(i8*` nonnull %5, i8* nonnull %10, i16 5) #7, !dbg !1191 %.not = icmp eq i32 %11, 0, !dbg !1191
...
; Function Attrs: nounwind optsize declare i32 `@memcmp(i8*,` i8*, i16) local_unnamed_addr addrspace(1) #4
```
Any ideas what I'm missing here? Alternately, if this is totally the wrong approach I'm open to other suggestions.
cc `@Rahix`
Use DefPathHash instead of HirId to break inlining cycles.
The `DefPathHash` is stable across incremental compilation sessions, so provides a total order on `LocalDefId`. Using it instead of `HirId` ensures the MIR inliner has the same behaviour for incremental and non-incremental compilation.
A downside is that the cycle tie break is not as predictable is with `HirId`.
Suggest `i += 1` when we see `i++` or `++i`
Closes#83502 (for `i++` and `++i`; `--i` should be covered by #82987, and `i--`
is tricky to handle).
This is a continuation of #83536.
r? `@estebank`
Fix multiline attributes handling in doctests
Fixes#55713.
I needed to have access to the `unclosed_delims` field in order to check that the attribute was completely parsed and didn't have missing parts, so I created a getter for it.
r? `@notriddle`
Rollup of 4 pull requests
Successful merges:
- #95587 (Remove need for associated_type_bounds in std.)
- #95589 (Include a header in .rlink files)
- #95593 (diagnostics: add test case for bogus T:Sized suggestion)
- #95597 (Refer to u8 by absolute path in expansion of thread_local)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Include a header in .rlink files
I couldn't find the right place where to put tests. Is there some location that tests `.rlink` creation and loading?
I only found `src/test/run-make-fulldeps/separate-link/Makefile`, but I'm not sure how to check the error message in the Makefile.
Fixes: https://github.com/rust-lang/rust/issues/95297
r? `@bjorn3`
Make GATs object safe under generic_associated_types_extended feature
Based on #94869
Let's say we have
```rust
trait StreamingIterator {
type Item<'a> where Self: 'a;
}
```
And `dyn for<'a> StreamingIterator<Item<'a> = &'a i32>`.
If we ask `(dyn for<'a> StreamingIterator<Item<'a> = &'a i32>): StreamingIterator`, then we have to prove that `for<'x> (&'x i32): Sized`. So, we generate *new* bound vars to subst for the GAT generics.
Importantly, this doesn't fully verify that these are usable and sound.
r? `@nikomatsakis`
Add error message suggestion for missing noreturn in naked function
I had to google the syntax for inline asm's `noreturn` option when I got this error earlier today, so I figured I'd save others the trouble and add the syntax/fix as a suggestion in the error.
Handle rustc_const_stable attribute in library feature collector
The library feature collector in [compiler/rustc_passes/src/lib_features.rs](551b4fa395/compiler/rustc_passes/src/lib_features.rs) has only been looking at `#[stable(…)]`, `#[unstable(…)]`, and `#[rustc_const_unstable(…)]` attributes, while ignoring `#[rustc_const_stable(…)]`. The consequences of this were:
- When any const feature got stabilized (changing one or more `rustc_const_unstable` to `rustc_const_stable`), users who had previously enabled that unstable feature using `#![feature(…)]` would get told "unknown feature", rather than rustc's nicer "the feature … has been stable since … and no longer requires an attribute to enable".
This can be seen in the way that https://github.com/rust-lang/rust/pull/93957#issuecomment-1079794660 failed after rebase:
```console
error[E0635]: unknown feature `const_ptr_offset`
--> $DIR/offset_from_ub.rs:1:35
|
LL | #![feature(const_ptr_offset_from, const_ptr_offset)]
| ^^^^^^^^^^^^^^^^
```
- We weren't enforcing that a particular feature is either stable everywhere or unstable everywhere, and that a feature that has been stabilized has the same stabilization version everywhere, both of which we enforce for the other stability attributes.
This PR updates the library feature collector to handle `rustc_const_stable`, and fixes places in the standard library and test suite where `rustc_const_stable` was being used in a way that does not meet the rules for a stability attribute.
Rollup of 6 pull requests
Successful merges:
- #95032 (Clean up, categorize and sort unstable features in std.)
- #95260 (Better suggestions for `Fn`-family trait selection errors)
- #95293 (suggest wrapping single-expr blocks in square brackets)
- #95344 (Make `impl Debug for rustdoc::clean::Item` easier to read)
- #95388 (interpret: make isize::MAX the limit for dynamic value sizes)
- #95530 (rustdoc: do not show primitives and keywords as private)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
interpret: make isize::MAX the limit for dynamic value sizes
We are currently enforcing `data_layout.obj_size_bound()` as the maximal dynamic size of a Rust value (including for `size_of_val_raw`), but that does not match the docs.
In particular, Miri currently falsely says that this code has UB:
```rust
#![feature(layout_for_ptr)]
fn main() {
let size = isize::MAX as usize;
// Creating a raw slice of size isize::MAX and asking for its size is okay.
let s = std::ptr::slice_from_raw_parts(1usize as *const u8, size);
assert_eq!(size, unsafe { std::mem::size_of_val_raw(s) });
}
```
Better suggestions for `Fn`-family trait selection errors
1. Suppress suggestions to add `std::ops::Fn{,Mut,Once}` bounds when a type already implements `Fn{,Mut,Once}`
2. Add a note that points out that a type does in fact implement `Fn{,Mut,Once}`, but the arguments vary (either by number or by actual arguments)
3. Add a note that points out that a type does in fact implement `Fn{,Mut,Once}`, but not the right one (e.g. implements `FnMut`, but `Fn` is required).
Fixes#95147
A more robust solution to finding where to place use suggestions was added.
The algorithm uses the AST to find the span for the suggestion so we pass this span
down to the HIR during lowering and use it.
Signed-off-by: Miguel Guarniz <mi9uel9@gmail.com>
Specialize infinite-type "insert some indirection" suggestion for Option
Suggest `Option<Box<_>>` instead of `Box<Option<_>>` for infinitely-recursive members of a struct.
Not sure if I can get the span of the generic subty of the Option so I can make this a `+++`-style suggestion. The current output is a tiny bit less fancy looking than the original suggestion.
Should I limit the specialization to just `Option<Box<TheOuterStruct>>`? Because right now it applies to all `Option` members in the struct that are returned by `Representability::SelfRecursive`.
Fixes#91402
r? `@estebank`
(since you wrote the original suggestion and are definitely most familiar with it!)
Make lowering pull-based
~Based on https://github.com/rust-lang/rust/pull/90451~
Part of https://github.com/rust-lang/rust/pull/88186
The current lowering code visits all the item-likes in the AST in order, and lowers them one by one.
This PR changes it to index the AST and then proceed to lowering on-demand. This is closer to the logic of query-based lowering.
allow large Size again
This basically reverts most of https://github.com/rust-lang/rust/pull/80042, and instead does the panic in `bits()` with a `#[cold]` function to make sure it does not get inlined.
https://github.com/rust-lang/rust/pull/80042 added a comment about an invariant ("The top 3 bits are ALWAYS zero") that is not actually enforced, and if it were enforced that would be a problem for https://github.com/rust-lang/rust/pull/95388. So I think we should not have that invariant, and I adjusted the code accordingly.
r? `@oli-obk` Cc `@sivadeilra`
It's only used in one place, and there we clone and then make a bunch of
modifications. It's clearer if we duplicate more explicitly, and there's
a symmetry now between `sequence()` and `empty_sequence()`.
`parse_tt` needs a way to get from within submatchers make to the
enclosing submatchers. Currently it has two distinct mechanisms for
this:
- `Delimited` submatchers use `MatcherPos::stack` to record stuff about
the parent (and further back ancestors).
- `Sequence` submatchers use `MatcherPosSequence::parent` to point to
the parent matcher position.
Having two mechanisms is really confusing, and it took me a long time to
understand all this.
This commit eliminates `MatcherPos::stack`, and changes `Delimited`
submatchers to use the same mechanism as sequence submatchers. That
mechanism is also changed a bit: instead of storing the entire parent
`MatcherPos`, we now only store the necessary parts from the parent
`MatcherPos`.
Overall this is a small performance win, with the positives outweighing
the negatives, but it's mostly for clarity.
Spellchecking compiler comments
This PR cleans up the rest of the spelling mistakes in the compiler comments. This PR does not change any literal or code spelling issues.
Don't ICE when opaque types get their hidden type constrained again.
Contrary to popular belief, `codegen_fulfill_obligation` does not get used solely in codegen, so we cannot rely on `param_env` being set to RevealAll and thus revealing the hidden types instead of constraining them.
Fixes#89312 (for real this time)
Restore `impl Future<Output = Type>` to async blocks
I was sad when I undid some of the code I wrote in #91096 in the PR #95225, so I fixed it here to not print `[async output]`.
This PR "manually" normalizes the associated type `<[generator] as Generator>::Return` type which appears very frequently in `impl Future` types that result from async block desugaring.
Currently, we detect an exit from a `Delimited` submatcher when `idx`
exceeds the bounds of the current submatcher *and* there is a `stack`
entry.
This commit changes it to something simpler: just look for a
`CloseDelim` token.
Rollup of 6 pull requests
Successful merges:
- #93901 (Stabilize native library modifier syntax and the `whole-archive` modifier specifically)
- #94806 (Fix `cargo run tidy`)
- #94869 (Add the generic_associated_types_extended feature)
- #95011 (async: Give predictable name to binding generated from .await expressions.)
- #95251 (Reduce max hash in raw strings from u16 to u8)
- #95298 (Fix double drop of allocator in IntoIter impl of Vec)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
async: Give predictable name to binding generated from .await expressions.
This name makes it to debuginfo and allows debuggers to identify such bindings and their captured versions in suspended async fns.
This will be useful for async stack traces, as discussed in https://internals.rust-lang.org/t/async-debugging-logical-stack-traces-setting-goals-collecting-examples/15547.
I don't know if this needs some discussion by ````@rust-lang/compiler,```` e.g. about the name of the binding (`__awaitee`) or about the fact that this PR introduces a (soft) guarantee about a compiler generated name. Although, regarding the later, I think the same reasoning applies here as it does for debuginfo in general.
r? ````@tmandry````
Add the generic_associated_types_extended feature
Right now, this only ignore obligations that reference new placeholders in `poly_project_and_unify_type`. In the future, this might do other things, like allowing object-safe GATs.
**This feature is *incomplete* and quite likely unsound. This is mostly just for testing out potential future APIs using a "relaxed" set of rules until we figure out *proper* rules.**
Also drive by cleanup of adding a `ProjectAndUnifyResult` enum instead of using a `Result<Result<Option>>`.
r? `@nikomatsakis`
Remember mutability in `DefKind::Static`.
This allows to compute the `BodyOwnerKind` from `DefKind` only, and
removes a direct dependency of some MIR queries onto HIR.
As a side effect, it also simplifies metadata, since we don't need 4
flavours of `EntryKind::*Static` any more.
Yet more `parse_tt` improvements
Including lots of comment improvements, and an overhaul of how `matches` work that gives big speedups.
r? `@petrochenkov`
Contrary to popular belief, `codegen_fulfill_obligation` does not get used solely in codegen, so we cannot rely on `param_env` being set to RevealAll and thus revealing the hidden types instead of constraining them.
allow arbitrary inherent impls for builtin types in core
Part of https://github.com/rust-lang/compiler-team/issues/487. Slightly adjusted after some talks with `@m-ou-se` about the requirements of `t-libs-api`.
This adds a crate attribute `#![rustc_coherence_is_core]` which allows arbitrary impls for builtin types in core.
For other library crates impls for builtin types should be avoided if possible. We do have to allow the existing stable impls however. To prevent us from accidentally adding more of these in the future, there is a second attribute `#[rustc_allow_incoherent_impl]` which has to be added to **all impl items**. This only supports impls for builtin types but can easily be extended to additional types in a future PR.
This implementation does not check for overlaps in these impls. Perfectly checking that requires us to check the coherence of these incoherent impls in every crate, as two distinct dependencies may add overlapping methods. It should be easy enough to detect if it goes wrong and the attribute is only intended for use inside of std.
The first two commits are mostly unrelated cleanups.
Strict Provenance MVP
This patch series examines the question: how bad would it be if we adopted
an extremely strict pointer provenance model that completely banished all
int<->ptr casts.
The key insight to making this approach even *vaguely* pallatable is the
ptr.with_addr(addr) -> ptr
function, which takes a pointer and an address and creates a new pointer
with that address and the provenance of the input pointer. In this way
the "chain of custody" is completely and dynamically restored, making the
model suitable even for dynamic checkers like CHERI and Miri.
This is not a formal model, but lots of the docs discussing the model
have been updated to try to the *concept* of this design in the hopes
that it can be iterated on.
See #95228
Rollup of 5 pull requests
Successful merges:
- #95294 (Document Linux kernel handoff in std::io::copy and std::fs::copy)
- #95443 (Clarify how `src/tools/x` searches for python)
- #95452 (fix since field version for termination stabilization)
- #95460 (Spellchecking compiler code)
- #95461 (Spellchecking some comments)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Lazy type-alias-impl-trait take two
### user visible change 1: RPIT inference from recursive call sites
Lazy TAIT has an insta-stable change. The following snippet now compiles, because opaque types can now have their hidden type set from wherever the opaque type is mentioned.
```rust
fn bar(b: bool) -> impl std::fmt::Debug {
if b {
return 42
}
let x: u32 = bar(false); // this errors on stable
99
}
```
The return type of `bar` stays opaque, you can't do `bar(false) + 42`, you need to actually mention the hidden type.
### user visible change 2: divergence between RPIT and TAIT in return statements
Note that `return` statements and the trailing return expression are special with RPIT (but not TAIT). So
```rust
#![feature(type_alias_impl_trait)]
type Foo = impl std::fmt::Debug;
fn foo(b: bool) -> Foo {
if b {
return vec![42];
}
std::iter::empty().collect() //~ ERROR `Foo` cannot be built from an iterator
}
fn bar(b: bool) -> impl std::fmt::Debug {
if b {
return vec![42]
}
std::iter::empty().collect() // Works, magic (accidentally stabilized, not intended)
}
```
But when we are working with the return value of a recursive call, the behavior of RPIT and TAIT is the same:
```rust
type Foo = impl std::fmt::Debug;
fn foo(b: bool) -> Foo {
if b {
return vec![];
}
let mut x = foo(false);
x = std::iter::empty().collect(); //~ ERROR `Foo` cannot be built from an iterator
vec![]
}
fn bar(b: bool) -> impl std::fmt::Debug {
if b {
return vec![];
}
let mut x = bar(false);
x = std::iter::empty().collect(); //~ ERROR `impl Debug` cannot be built from an iterator
vec![]
}
```
### user visible change 3: TAIT does not merge types across branches
In contrast to RPIT, TAIT does not merge types across branches, so the following does not compile.
```rust
type Foo = impl std::fmt::Debug;
fn foo(b: bool) -> Foo {
if b {
vec![42_i32]
} else {
std::iter::empty().collect()
//~^ ERROR `Foo` cannot be built from an iterator over elements of type `_`
}
}
```
It is easy to support, but we should make an explicit decision to include the additional complexity in the implementation (it's not much, see a721052457cf513487fb4266e3ade65c29b272d2 which needs to be reverted to enable this).
### PR formalities
previous attempt: #92007
This PR also includes #92306 and #93783, as they were reverted along with #92007 in #93893fixes#93411fixes#88236fixes#89312fixes#87340fixes#86800fixes#86719fixes#84073fixes#83919fixes#82139fixes#77987fixes#74282fixes#67830fixes#62742fixes#54895
Currently, matches within a sequence are recorded in a new empty
`matches` vector. Then when the sequence finishes the matches are merged
into the `matches` vector of the parent.
This commit changes things so that a sequence mp inherits the matches
made so far. This means that additional matches from the sequence don't
need to be merged into the parent. `push_match` becomes more
complicated, and the current sequence depth needs to be tracked. But
it's a sizeable performance win because it avoids one or more
`push_match` calls on every iteration of a sequence.
The commit also removes `match_hi`, which is no longer necessary.
Suggest wrapping patterns in enum variants
Structured suggestion to wrap a pattern in a single-field enum or struct:
```diff
struct A;
enum B {
A(A),
}
fn main(b: B) {
match b {
- A => {}
+ B::A(A) => {}
}
}
```
Half of #94942, the other half I'm not exactly sure how to fix.
Also includes two drive-by changes (that I am open to splitting out into another PR, but thought they could be rolled up into this one):
- 07776c111f: Makes sure not to suggest wrapping if it doesn't have tuple field constructor (i.e. has named fields)
- 8f2bbb18fd53e5008bb488302dbd354577698ede: Also suggest wrapping expressions in a tuple struct (not just enum variants)
This allows to compute the `BodyOwnerKind` from `DefKind` only, and
removes a direct dependency of some MIR queries onto HIR.
As a side effect, it also simplifies metadata, since we don't need 4
flavours of `EntryKind::*Static` any more.
These debug assertions are all implemented only at runtime using
`const_eval_select`, and in the error path they execute
`intrinsics::abort` instead of being a normal debug assertion to
minimize the impact of these assertions on code size, when enabled.
Of all these changes, the bounds checks for unchecked indexing are
expected to be most impactful (case in point, they found a problem in
rustc).
When printing the whole DepNode, the output file is simply too massive to
be actually useful for profiling.
This trimmed down version mixes a lot of information together, but it also
allows to ask questions such that "why does this query ever access HIR?".
Fix yet another Box<T, A> ICE
Fixes#95036.
This widens the special case from #94414 to make sure that boxes with a custom allocator are never directly dereferenced.
parallel_compiler: hide dependencies behind feature
Separate dependencies for `parallel_compiler` feature, so they will not be compiled if feature not selected, reducing number of compiled crates from 238 to 224.
Ignore doc comments in a declarative macro matcher.
Fixes#95267. Reverts to the old behaviour before #95159 introduced a
regression.
r? `@petrochenkov`
resolve: Simplify some diagnostic code to avoid an ICE
No need to resolve those paths, they are already resolved, we just need to take the results from `partial_res_map`.
Fixes https://github.com/rust-lang/rust/issues/95327
Tell users that `||` operators are not currently supported in let chain expressions
Tells that `||` operators are not currently supported instead of not allowed. See https://github.com/rust-lang/rust/issues/53667#issuecomment-1066075876
In other words, this PR is pretty much trivial.
Remove `Nonterminal::NtTT`.
It's only needed for macro expansion, not as a general element in the
AST. This commit removes it, adds `NtOrTt` for the parser and macro
expansion cases, and renames the variants in `NamedMatch` to better
match the new type.
r? `@petrochenkov`
Make fatal DiagnosticBuilder yield `!`
Fatal errors should really be fatal, so emitting them should cause us to exit at the same time.
Fine with just throwing away these changes if they're not worthwhile. Also, maybe we want to use an uninhabited enum instead of `!`.
r? `@eddyb` who has been working on `DiagnosticBuilder` stuff, feel free to reassign.
Skip needless bitset for debuginfo
Found this while digging around looking at the inlining logic.
Seemed obvious enough so I decided to try to take care of it.
Is this what you had in mind, `@eddyb?`
It's only needed for macro expansion, not as a general element in the
AST. This commit removes it, adds `NtOrTt` for the parser and macro
expansion cases, and renames the variants in `NamedMatch` to better
match the new type.
Provide suggestion for missing `>` in a type parameter list
When encountering an inproperly terminated type parameter list, provide
a suggestion to close it after the last non-constraint type parameter
that was successfully parsed.
Fix#94058.
Rollup of 5 pull requests
Successful merges:
- #91981 (Recover suggestions and useful information lost in previous PR)
- #93469 (Skip pointing out ambiguous impls in alloc/std crates too in inference errors)
- #95335 (Move resolve_path to rustc_builtin_macros and make it private)
- #95340 (interpret: with enforce_number_validity, ensure integers are truly Scalar::Int (i.e., no pointers))
- #95341 (ARMv6K Horizon OS has_thread_local support)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
ARMv6K Horizon OS has_thread_local support
cc. ```@ian-h-chamberlain```
cc. ```@AzureMarker```
Being an ARM target, it has always had built-in support for `#[thread_local]`. This PR comes in just now because we were testing `std::thread` support with `thread_local_dtor`s. This will hopefully be the last PR for the target specification, unless anymore features will be needed as time goes on.
interpret: with enforce_number_validity, ensure integers are truly Scalar::Int (i.e., no pointers)
This is required for https://github.com/rust-lang/miri/pull/2040
r? ```@oli-obk```
Skip pointing out ambiguous impls in alloc/std crates too in inference errors
This generalizes the logic in `annotate_source_of_ambiguity` to skip printing ambiguity errors traits in `alloc` and `std` as well, not just `core`.
While this does spot-fix the issue mentioned below, it would be nicer to generalize this logic, for example to detect when the trait predicate's `self_ty` has any numerical inference variables. Is it worthwhile to scrap this solution for one like that?
Fixes#93450
r? `@estebank`
feel free to reassign
When encountering an inproperly terminated type parameter list, provide
a suggestion to close it after the last non-constraint type parameter
that was successfully parsed.
Fix#94058.
Remove `Session::one_time_diagnostic`
This is untracked mutable state, which modified the behaviour of queries.
It was used for 2 things: some full-blown errors, but mostly for lint declaration notes ("the lint level is defined here" notes).
It is replaced by the diagnostic deduplication infra which already exists in the diagnostic emitter.
A new diagnostic level `OnceNote` is introduced specifically for lint notes, to deduplicate subdiagnostics.
As a drive-by, diagnostic emission takes a `&mut` to allow dropping the `SubDiagnostic`s.
incr. comp.: Let compiler retry finalizing session directory a few times.
In my local testing this fixed issue https://github.com/rust-lang/rust/issues/86929. I wasn't able to come up with a regression test for it though.
Swap DtorckConstraint to DropckConstraint
This change was made as per suspicion that this struct was never renamed after consistent use of DropCk.
This also clarifies the meaning behind the name of this structure.
Fixes https://github.com/rust-lang/rust/issues/94310
resolve: Do not build expensive suggestions if they are not actually used
And remove a bunch of (conditionally) unused parameters from path resolution functions.
This helps with performance issues in https://github.com/rust-lang/rust/pull/94857, and should be helpful in general even without that.
Currently it copies a `KleeneOp` and a `Token` out of a
`SequenceRepetition`. It's better to store a reference to the
`SequenceRepetition`, which is now possible due to #95159 having changed
the lifetimes.
The `Lrc` is only relevant within `transcribe()`. There, the `Lrc` is
helpful for the non-`NtTT` cases, because the entire nonterminal is
cloned. But for the `NtTT` cases the inner token tree is cloned (a full
clone) and so the `Lrc` is of no help.
This commit splits the `NtTT` and non-`NtTT` cases, avoiding the useless
`Lrc` in the former case, for the following effect on macro-heavy
crates.
- It reduces the total number of allocations a lot.
- It increases the size of some of the remaining allocations.
- It doesn't affect *peak* memory usage, because the larger allocations
are short-lived.
This overall gives a speed win.
add diagnostic items for clippy's `trim_split_whitespace`
Adding the following diagnostic items:
* str_split_whitespace,
* str_trim,
* str_trim_start,
* str_trim_end
They are needed for https://github.com/rust-lang/rust-clippy/pull/8575
r? `@flip1995`
debuginfo: Fix debuginfo for Box<T> where T is unsized.
Before this fix, the debuginfo for the fields was generated from the struct defintion of Box<T>, but (at least at the moment) the compiler pretends that Box<T> is just a (fat) pointer, so the fields need to be `pointer` and `vtable` instead of `__0: Unique<T>` and `__1: Allocator`.
This is meant as a temporary mitigation until we can make sure that simply treating Box as a regular struct in debuginfo does not cause too much breakage in the ecosystem.
r? ````@wesleywiser````
Clarify which kinds of MIR are allowed during which phases.
This enhances documentation with these details and extends the validator to check these requirements more thoroughly. Most of these conditions were already being checked.
There was also some disagreement between the `MirPhase` docs and validator as to what it meant for the `body.phase` field to have a certain value. This PR resolves those disagreements in favor of the `MirPhase` docs (which is what the pass manager implemented), adjusting the validator accordingly. The result is now that the `DropLowering` phase begins with the end of the elaborate drops pass, and lasts until the beginning of the generator lowring pass. This doesn't feel entirely natural to me, but as long as it's documented accurately it should be ok.
r? rust-lang/mir-opt
Also remove a redundant parameter from `fn resolve_path(_with_ribs)`, `crate_lint: CrateLint` is a more detailed version of `record_used: bool` with `CrateLint::No` meaning `false` and anything else meaning `true`.
Separate const prop lints from optimizations
r? `@oli-obk`
Separates lints and optimizations during const prop by moving the lints into their own file and checking them during post borrowck cleanup.
Thanks to `@oli-obk` for mentoring me.
This change was made as per suspicion that this struct was never renamed after consistent use of DropCk.
This also clarifies the meaning behind the name of this structure.
Change Thir to lazily create constants
To allow `AbstractConst`s to work with the previous thir changes we made and those we want to make, i.e. to avoid problems due to `ValTree` and `ConstValue` conversions, we instead switch to a thir representation for constants that allows us to lazily create constants.
r? `@oli-obk`
Properly track `ImplObligations`
Instead of probing for all possible `impl`s that could have caused an
`ImplObligation`, keep track of its `DefId` and obligation spans for
accurate error reporting.
Follow to #89580. Addresses #89418.
Before this fix, the debuginfo for the fields was generated from the
struct defintion of Box<T>, but (at least at the moment) the compiler
pretends that Box<T> is just a (fat) pointer, so the fields need to be
`pointer` and `vtable` instead of `__0: Unique<T>` and `__1: Allocator`.
This is meant as a temporary mitigation until we can make sure that
simply treating Box as a regular struct in debuginfo does not cause too
much breakage in the ecosystem.
`run-rustfix` applies all suggestions regardless of their Applicability.
There's a flag, `rustfix-only-machine-applicable`, that does what it
says, but then the produced `.fixed` file would have invalid code from
the suggestions that weren't applied. So, I moved the cases of postfix
increment, in which case multiple suggestions are given, to the
`-notfixed` test, which does not run rustfix.
I also changed the Applicability to Unspecified since MaybeIncorrect
requires that the code be valid, even if it's incorrect.
Instead of probing for all possible impls that could have caused an
`ImplObligation`, keep track of its `DefId` and obligation spans for
accurate error reporting.
Follow up to #89580. Addresses #89418.
Remove some unnecessary clones.
Tweak output for auto trait impl obligations.
This enhances documentation with these details and extends the validator to check these requirements
more thoroughly. As a part of this, we add a new `Deaggregated` phase, and rename other phases so
that their names more naturally correspond to what they represent.
interpret/memory: simplify check_and_deref_ptr
*Finally* I saw a way to make this code simpler. The odd preprocessing in `let ptr_or_addr =` has bothered me since forever, but it actually became unnecessary in the last provenance refactoring. :)
This also leads to slightly more explicit error messages as a nice side-effect. 🎉
r? `@oli-obk`
Better errors when a Copy impl on a Struct is not self-consistent
As discovered in a Zulip thread with `@nnethercote` and `@Mark-Simulacrum,` it's not immediately obvious why a field on an ADT doesn't implement `Copy`. This PR attempts to give slightly more detailed information by spinning up a fulfillment context to try to dig down and discover transitive fulfillment errors that cause `is_copy_modulo_regions` to fail on a ADT field.
The error message still kinda sucks, but should only show up in the case that an existing error message was totally missing... so I think it's a good compromise for now?
diagnostics: do not suggest `fn foo({ <body> }`
Instead of suggesting that the body always replace the last character on the line, presuming it must be a semicolon, the parser should instead check what the last character is, and append the body if it is anything else.
Fixes#83104
Rename `~const Drop` to `~const Destruct`
r? `@oli-obk`
Completely switching to `~const Destructible` would be rather complicated, so it seems best to add it for now and wait for it to be backported to beta in the next release.
The rationale is to prevent complications such as #92149 and #94803 by introducing an entirely new trait. And `~const Destructible` reads a bit better than `~const Drop`. Name Bikesheddable.
interpret/validity: improve clarity
I was confused by my own (ancient) comment in `validity.rs` so I figured I'd clarify. (And I don't think ZST-ness is relevant at all inside that branch, no idea where that comment comes from.)
Also `extend` seems more clear than `clone_from`.
Fold aarch64 feature +fp into +neon
Arm's FEAT_FP and Feat_AdvSIMD describe the same thing on AArch64:
The Neon unit, which handles both floating point and SIMD instructions.
Moreover, a configuration for AArch64 must include both or neither.
Arm says "entirely proprietary" toolchains may omit floating point:
https://developer.arm.com/documentation/102374/0101/Data-processing---floating-point
In the Programmer's Guide for Armv8-A, Arm says AArch64 can have
both FP and Neon or neither in custom implementations:
https://developer.arm.com/documentation/den0024/a/AArch64-Floating-point-and-NEON
In "Bare metal boot code for Armv8-A", enabling Neon and FP
is just disabling the same trap flag:
https://developer.arm.com/documentation/dai0527/a
In an unlikely future where "Neon and FP" become unrelated,
we can add "[+-]fp" as its own feature flag.
Until then, we can simplify programming with Rust on AArch64 by
folding both into "[+-]neon", which is valid as it supersets both.
"[+-]neon" is retained for niche uses such as firmware, kernels,
"I just hate floats", and so on.
I am... pretty sure no one is relying on this.
An argument could be made that, as we are not an "entirely proprietary" toolchain, we should not support AArch64 without floats at all. I think that's a bit excessive. However, I want to recognize the intent: programming for AArch64 should be simplified where possible. For x86-64, programmers regularly set up illegal feature configurations because it's hard to understand them, see https://github.com/rust-lang/rust/issues/89586. And per the above notes, plus the discussion in https://github.com/rust-lang/rust/issues/86941, there should be no real use cases for leaving these features split: the two should in fact always go together.
- Fixesrust-lang/rust#95002.
- Fixesrust-lang/rust#95064.
- Fixesrust-lang/rust#95122.
Instead of suggesting that the body always replace the last character on the
line, presuming it must be a semicolon, the parser should instead check what
the last character is, and append the body if it is anything else.
Fixes#83104
Arm's FEAT_FP and Feat_AdvSIMD describe the same thing on AArch64:
The Neon unit, which handles both floating point and SIMD instructions.
Moreover, a configuration for AArch64 must include both or neither.
Arm says "entirely proprietary" toolchains may omit floating point:
https://developer.arm.com/documentation/102374/0101/Data-processing---floating-point
In the Programmer's Guide for Armv8-A, Arm says AArch64 can have
both FP and Neon or neither in custom implementations:
https://developer.arm.com/documentation/den0024/a/AArch64-Floating-point-and-NEON
In "Bare metal boot code for Armv8-A", enabling Neon and FP
is just disabling the same trap flag:
https://developer.arm.com/documentation/dai0527/a
In an unlikely future where "Neon and FP" become unrelated,
we can add "[+-]fp" as its own feature flag.
Until then, we can simplify programming with Rust on AArch64 by
folding both into "[+-]neon", which is valid as it supersets both.
"[+-]neon" is retained for niche uses such as firmware, kernels,
"I just hate floats", and so on.
Introduce `TtParser`
These commits make a number of changes to declarative macro expansion, resulting in code that is shorter, simpler, and faster.
Best reviewed one commit at a time.
r? `@petrochenkov`
As its name suggests, `TokenTreeOrTokenTreeSlice` is either a single
`TokenTree` or a slice of them. It has methods `len` and `get_tt` that
let it be treated much like an ordinary slice. The reason it isn't an
ordinary slice is that for `TokenTree::Delimited` the open and close
delimiters are represented implicitly, and when they are needed they are
constructed on the fly with `Delimited::{open,close}_tt`, rather than
being present in memory.
This commit changes `Delimited` so the open and close delimiters are
represented explicitly. As a result, `TokenTreeOrTokenTreeSlice` is no
longer needed and `MatcherPos` and `MatcherTtFrame` can just use an
ordinary slice. `TokenTree::{len,get_tt}` are also removed, because they
were only needed to support `TokenTreeOrTokenTreeSlice`.
The change makes the code shorter and a little bit faster on benchmarks
that use macro expansion heavily, partly because `MatcherPos` is a lot
smaller (less data to `memcpy`) and partly because ordinary slice
operations are faster than `TokenTreeOrTokenTreeSlice::{len,get_tt}`.
Suggest constraining param for unary ops when missing trait impl
This PR adds a suggestion of constraining param for unary ops `-` and `!` when the corresponding trait implementation
is missing.
Fixs #94543.
BTW, this is my first time to touch rustc, please correct me if I did anything wrong.
rename LocalState::Uninitialized to Unallocated
This is to avoid confusion with `Uninit` as in `ScalarMaybeUninit`, which is very different.
r? `@oli-obk`
Inline some parser functions
Some crates that do a lot of complex declarative macro expansion spend a lot of time parsing (and reparsing) tokens. These commits inline some functions for some minor speed wins.
r? `@ghost`
Disable almost certainly unsound early otherwise branch MIR opt
Originally thought this was just an MIR semantics issue, but it's not.
r? rust-lang/mir-opt
The call site within `Parser::bump` is hot.
Also add an inline annotation to `Parser::next_tok`. It was already
being inlined by the compiler; this just makes sure that continues.
Return err instead of ICE
Having `escaping_bound_vars` results in ICE when trying to create `ty::Binder::dummy`, to avoid it we return err like the line above. I think this requires a more sophisticated fix, I would love to investigate if mentorship is available 🤓Fixes#95023 and #85350
suggest removing type ascription in bad parsing position
Not sure how to test this with the non-nightly suggestion. Didn't add a new UI test because it already manifests in an existing UI test.
Fixes#95014
By putting them in `TtParser`, we can reuse them for every rule in a
macro. With that done, they can be `SmallVec` instead of `Vec`, and this
is a performance win because these vectors are hot and `SmallVec`
operations are a bit slower due to always needing an "inline or heap?"
check.
This type was a small performance win for `html5ever`, which uses a
macro with hundreds of very simple rules that don't contain any
metavariables. But this type is complicated (extra lifetimes) and
perf-neutral for macros that do have metavariables.
This commit removes `MatcherPosHandle`, simplifying things a lot. This
increases the allocation rate for `html5ever` and similar cases a bit,
but makes things easier for follow-up changes that will improve
performance more than what we lost here.
Give more details in `Display` for `hir::Target`
Made because I was making a code change and got a very confusing "should be applied to a method, not a method" error.
```
error[E0718]: `into_try_type` language item must be applied to a method
--> library\core\src\ops\try_trait.rs:352:32
|
352 | #[cfg_attr(not(bootstrap), lang = "into_try_type")]
| ^^^^^^^^^^^^^^^^^^^^^^ attribute should be applied to a method, not a method
```
With this change the error is more actionable
```
error[E0718]: `into_try_type` language item must be applied to a required trait method
--> library\core\src\ops\try_trait.rs:352:32
|
352 | #[cfg_attr(not(bootstrap), lang = "into_try_type")]
| ^^^^^^^^^^^^^^^^^^^^^^ attribute should be applied to a required trait method, not a provided trait method
```
Made because I was making a code change and got a very confusing "should be applied to a method, not a method" error.
```
error[E0718]: `into_try_type` language item must be applied to a method
--> library\core\src\ops\try_trait.rs:352:32
|
352 | #[cfg_attr(not(bootstrap), lang = "into_try_type")]
| ^^^^^^^^^^^^^^^^^^^^^^ attribute should be applied to a method, not a method
```
Always evaluate all cfg predicate in all() and any()
This pull-request adjust the handling of the `all()` and `any()` to always evaluate every cfg predicate because not doing so result in accepting incorrect `cfg`:
```rust
#[cfg(any(unix, foo::bar))] // Should error on foo::bar, but does not on unix platform (but does on non unix platform)
fn foo1() {}
#[cfg(all(foo, foo::bar))] // Should error on foo::bar, but does not
fn foo2() {}
#[cfg(all(foo::bar, foo))] // Correctly error on foo::bar
fn foo3() {}
#[cfg(any(foo::bar, foo))] // Correctly error on foo::bar
fn foo4() {}
```
This pull-request take the side to directly turn it into a hard error instead of having a future incompatibility lint because the combination to get this incorrect behavior is unusual and highly probable that some code have this without noticing.
A [search](https://cs.github.com/?scopeName=All+repos&scope=&q=lang%3Arust+%2Fany%5C%28%5Ba-zA-Z%5D%2C+%5Ba-zA-Z%5D%2B%3A%3A%5Ba-zA-Z%5D%2B%2F) on Github reveal no such instance nevertheless a Crater run should probably be done before merging this.
This was discover in https://github.com/rust-lang/rust/pull/94175 when trying to lint on the second predicate. Also note that this seems to have being introduce with Rust 1.27.0: https://rust.godbolt.org/z/KnfqKv15f.
r? `@petrochenkov`
It currently has no state, just the three methods `parse_tt`,
`parse_tt_inner`, and `bb_items_ambiguity_error`.
This commit is large but trivial, and mostly consists of changes to the
indentation of those methods. Subsequent commits will do more.
Rollup of 4 pull requests
Successful merges:
- #95013 (Update browser-ui-test version to 0.8.2)
- #95039 (Make negative coherence work when there's impl negative on super predicates)
- #95047 (Refactor: remove an unnecessary pattern for ignoring all parts)
- #95048 (update Miri)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Implement -Z oom=panic
This PR removes the `#[rustc_allocator_nounwind]` attribute on `alloc_error_handler` which allows it to unwind with a panic instead of always aborting. This is then used to implement `-Z oom=panic` as per RFC 2116 (tracking issue #43596).
Perf and binary size tests show negligible impact.
Rollup of 10 pull requests
Successful merges:
- #91133 (Improve `unsafe` diagnostic)
- #93222 (Make ErrorReported impossible to construct outside `rustc_errors`)
- #93745 (Stabilize ADX target feature)
- #94309 ([generator_interior] Be more precise with scopes of borrowed places)
- #94698 (Remove redundant code from copy-suggestions)
- #94731 (Suggest adding `{ .. }` around a const function call with arguments)
- #94960 (Fix many spelling mistakes)
- #94982 (Add deprecated_safe feature gate and attribute, cc #94978)
- #94997 (debuginfo: Fix ICE when generating name for type that produces a layout error.)
- #95000 (Fixed wrong type name in comment)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Remove redundant code from copy-suggestions
Follow up to #94375, just remove some code that is not necessary anymore. This may make the perf of such suggestions a little bit worse, but I don't think this is significant.
r? `@estebank`
[generator_interior] Be more precise with scopes of borrowed places
Previously the generator interior type checking analysis would use the nearest temporary scope as the scope of a borrowed value. This ends up being overly broad for cases such as:
```rust
fn status(_client_status: &Client) -> i16 {
200
}
fn main() {
let client = Client;
let g = move || match status(&client) {
_status => yield,
};
assert_send(g);
}
```
In this case, the borrow `&client` could be considered in scope for the entirety of the `match` expression, meaning it would be viewed as live across the `yield`, therefore making the generator not `Send`.
In most cases, we want to use the enclosing expression as the scope for a borrowed value which will be less than or equal to the nearest temporary scope. This PR changes the analysis to use the enclosing expression as the scope for most borrows, with the exception of borrowed RValues which are true temporary values that should have the temporary scope. There's one further exception where borrows of a copy such as happens in autoref cases also should be ignored despite being RValues.
Joint work with `@nikomatsakis`
Fixes#57017
r? `@tmandry`
Stabilize ADX target feature
This is a continuation of #60109, which noted that while the ADX intrinsics were stabilized, the corresponding target feature never was.
This PR follows the same general structure and stabilizes the ADX target feature.
See also https://github.com/rust-lang/rust/issues/44839 - tracking issue for target feature
Make ErrorReported impossible to construct outside `rustc_errors`
There are a few places were we have to construct it, though, and a few
places that are more invasive to change. To do this, we create a
constructor with a long obvious name.
cc #69426 `@varkor` `@eddyb` `@estebank`
I actually didn't see that I was assigned to this issue until now...
There are a few places were we have to construct it, though, and a few
places that are more invasive to change. To do this, we create a
constructor with a long obvious name.
These features include:
- V for vector extension
- Zfinx, Zdinx, Zhinx and Zhinxmin float in integer register extensions
- Zfh, Zfhmin 16-bit float pointer extensions
- Zbkb, Zkbc, Zbkc, Zk* cryptography extensions
It matches name in LLVM feature and is_riscv_feature_detected!.
Extend the irrefutable_let_patterns lint to let chains
Implements the suggestion from https://github.com/rust-lang/rust/pull/94927#issuecomment-1067078300
We only look for complete suffixes or prefixes of irrefutable let patterns, so
that an irrefutable let pattern in a chain surrounded by refutable ones is
not linted, as it is an useful pattern that has no low-cost replacement (unlike suffixes or prefixes which can just be copied outside of the `if`: either into the `if`'s block, or the block surrounding the `if`).
If all patterns in a let chain are irrefutable, we lint as well.
Depends on #94958 ~~so I included it into the PR for now~~ *which has been merged since*.
r? `@estebank`
cc `@joshtriplett` `@c410-f3r`
Only look for complete suffixes or prefixes of irrefutable let patterns, so
that an irrefutable let pattern in a chain surrounded by refutable ones is
not linted, as it is an useful pattern.
fix typos
Rework of #94603 which got closed as I was trying to unmerge and repush. This is a subset of changes from the original pr as I sed'd whatever typos I remembered from the original PR
thanks to `@cuishuang` for the original PR
debuginfo: Fix bug in type name generation for dyn types with associated types but no other generic arguments.
For types like `&dyn Future<Output=bool>` the compiler currently emits invalid types names in debuginfo. This PR fixes this.
Before:
```txt
// DWARF
&dyn core::future::future::Future, Output=bool>
// CodeView
ref$<dyn$<core::future::future::Future,assoc$<Output,bool> > > >
```
After:
```txt
// DWARF
&dyn core::future::future::Future<Output=bool>
// CodeView
ref$<dyn$<core::future::future::Future<assoc$<Output,bool> > > >
```
These syntactically incorrect type names can cause downstream tools (e.g. debugger extensions) crash when trying to parse them.
r? `@wesleywiser`
debuginfo: Refactor debuginfo generation for types
This PR implements the refactoring of the `rustc_codegen_llvm::debuginfo::metadata` module as described in MCP https://github.com/rust-lang/compiler-team/issues/482.
In particular it
- changes names to use `di_node` instead of `metadata`
- uniformly names all functions that build new debuginfo nodes `build_xyz_di_node`
- renames `CrateDebugContext` to `CodegenUnitDebugContext` (which is more accurate)
- removes outdated parts from `compiler/rustc_codegen_llvm/src/debuginfo/doc.md`
- moves `TypeMap` and functions that work directly work with it to a new `type_map` module
- moves enum related builder functions to a new `enums` module
- splits enum debuginfo building for the native and cpp-like cases, since they are mostly separate
- uses `SmallVec` instead of `Vec` in many places
- removes the old infrastructure for dealing with recursion cycles (`create_and_register_recursive_type_forward_declaration()`, `RecursiveTypeDescription`, `set_members_of_composite_type()`, `MemberDescription`, `MemberDescriptionFactory`, `prepare_xyz_metadata()`, etc)
- adds `type_map::build_type_with_children()` as a replacement for dealing with recursion cycles
- adds many (doc-)comments explaining what's going on
- changes cpp-like naming for C-Style enums so they don't get a `enum$<...>` name (because the NatVis visualizer does not apply to them)
- fixes detection of what is a C-style enum because some enums where classified as C-style even though they have fields
- changes cpp-like naming for generator enums so that NatVis works for them
- changes the position of discriminant debuginfo node so it is consistently nested inside the top-level union instead of, sometimes, next to it
The following could be done in subsequent PRs:
- add caching for `closure_saved_names_of_captured_variables`
- add caching for `generator_layout_and_saved_local_names`
- fix inconsistent handling of what is considered a C-style enum wrt to debuginfo
- rename `metadata` module to `types`
- move common generator fields to front instead of appending them
This PR is based on https://github.com/rust-lang/rust/pull/93644 which is not merged yet.
Right now, the changes are all done in one big commit. They could be split into smaller commits but hopefully the list of changes above makes it tractable to review them as a single commit too.
For now: r? `@ghost` (let's see if this affects compile times)
More robust fallback for `use` suggestion
Our old way to suggest where to add `use`s would first look for pre-existing `use`s in the relevant crate/module, and if there are *no* uses, it would fallback on trying to use another item as the basis for the suggestion.
But this was fragile, as illustrated in issue #87613
This PR instead identifies span of the first token after any inner attributes, and uses *that* as the fallback for the `use` suggestion.
Fix#87613
check ~Projection~ all supertrait bounds when confirming dyn candidate
I'm pretty sure Projection is the only other PredicateKind that we care about enforcing here.
Fixes#80800
This is a continuation of #60109, which noted that while the ADX
intrinsics were stabilized, the corresponding target feature never was.
This PR follows the same general structure and stabilizes the ADX target
feature.
Improve `expect` impl and handle `#[expect(unfulfilled_lint_expectations)]` (RFC 2383)
This PR updates unstable `ExpectationIds` in stashed diagnostics and adds some asserts to ensure that the stored expectations are really empty in the end. Additionally, it handles the `#[expect(unfulfilled_lint_expectations)]` case.
According to the [Errors and lints docs](https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-levels) the `error` level should only be used _"when the compiler detects a problem that makes it unable to compile the program"_. As this isn't the case with `#[expect(unfulfilled_lint_expectations)]` I decided to only create a warning. To avoid adding a new lint only for this case, I simply emit a `unfulfilled_lint_expectations` diagnostic with an additional note.
---
r? `@wesleywiser` I'm requesting a review from you since you reviewed the previous PR https://github.com/rust-lang/rust/pull/87835. You are welcome to reassign it if you're busy 🙃
rfc: [RFC-2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html)
tracking issue: https://github.com/rust-lang/rust/issues/85549
cc: `@flip1995` In case you're also interested in this :)
Type params and assoc types have unit metadata if they are sized
Extend the logic in `Pointee` projection to ensure that we can satisfy `<T as Pointee>::Metadata = ()` if `T: Sized`.
cc: `@SimonSapin` and #93959
This commit
- changes names to use di_node instead of metadata
- uniformly names all functions that build new debuginfo nodes build_xyz_di_node
- renames CrateDebugContext to CodegenUnitDebugContext (which is more accurate)
- moves TypeMap and functions that work directly work with it to a new type_map module
- moves and reimplements enum related builder functions to a new enums module
- splits enum debuginfo building for the native and cpp-like cases, since they are mostly separate
- uses SmallVec instead of Vec in many places
- removes the old infrastructure for dealing with recursion cycles (create_and_register_recursive_type_forward_declaration(), RecursiveTypeDescription, set_members_of_composite_type(), MemberDescription, MemberDescriptionFactory, prepare_xyz_metadata(), etc)
- adds type_map::build_type_with_children() as a replacement for dealing with recursion cycles
- adds many (doc-)comments explaining what's going on
- changes cpp-like naming for C-Style enums so they don't get a enum$<...> name (because the NatVis visualizer does not apply to them)
- fixes detection of what is a C-style enum because some enums where classified as C-style even though they have fields
- changes the position of discriminant debuginfo node so it is consistently nested inside the top-level union instead of, sometimes, next to it
Add riscv32im-unknown-none-elf built-in target triple.
* Add built-in target `riscv32im-unknown-none-elf`.
* Update `platform-support.md` to list it as a Tier 3 target.
Below are details on how this target meets the requirements for tier 3:
> A tier 3 target must have a designated developer or developers (the "target maintainers") on record to be CCed when issues arise regarding the target. (The mechanism to track and CC such developers may evolve over time.)
I would be willing to be a target maintainer, though I would appreciate if others with more experience around RISC-V volunteered to help with that as well.
> Targets must use naming consistent with any existing targets; for instance, a target for the same CPU or OS as an existing Rust target should use the same name for that CPU or OS. Targets should normally use the same names and naming conventions as used elsewhere in the broader ecosystem beyond Rust (such as in other toolchains), unless they have a very good reason to diverge. Changing the name of a target can be highly disruptive, especially once the target reaches a higher tier, so getting the name right is important even for a tier 3 target.
Uses the same naming as the LLVM target, and the same convention as many other bare-metal targets.
> Target names should not introduce undue confusion or ambiguity unless absolutely necessary to maintain ecosystem compatibility. For example, if the name of the target makes people extremely likely to form incorrect beliefs about what it targets, the name should be changed or augmented to disambiguate it.
I don't believe there is any ambiguity here.
> Tier 3 targets may have unusual requirements to build or use, but must not create legal issues or impose onerous legal terms for the Rust project or for Rust developers or users.
I don't see any legal issues here.
> The target must not introduce license incompatibilities.
> Anything added to the Rust repository must be under the standard Rust license (MIT OR Apache-2.0).
> The target must not cause the Rust tools or libraries built for any other host (even when supporting cross-compilation to the target) to depend on any new dependency less permissive than the Rust licensing policy. This applies whether the dependency is a Rust crate that would require adding new license exceptions (as specified by the tidy tool in the rust-lang/rust repository), or whether the dependency is a native library or binary. In other words, the introduction of the target must not cause a user installing or running a version of Rust or the Rust tools to be subject to any new license requirements.
> If the target supports building host tools (such as rustc or cargo), those host tools must not depend on proprietary (non-FOSS) libraries, other than ordinary runtime libraries supplied by the platform and commonly used by other binaries built for the target. For instance, rustc built for the target may depend on a common proprietary C runtime library or console output library, but must not depend on a proprietary code generation library or code optimization library. Rust's license permits such combinations, but the Rust project has no interest in maintaining such combinations within the scope of Rust itself, even at tier 3.
> Targets should not require proprietary (non-FOSS) components to link a functional binary or library.
> "onerous" here is an intentionally subjective term. At a minimum, "onerous" legal/licensing terms include but are not limited to: non-disclosure requirements, non-compete requirements, contributor license agreements (CLAs) or equivalent, "non-commercial"/"research-only"/etc terms, requirements conditional on the employer or employment of any particular Rust developers, revocable terms, any requirements that create liability for the Rust project or its developers or users, or any requirements that adversely affect the livelihood or prospects of the Rust project or its developers or users.
I see no issues with any of the above.
> Neither this policy nor any decisions made regarding targets shall create any binding agreement or estoppel by any party. If any member of an approving Rust team serves as one of the maintainers of a target, or has any legal or employment requirement (explicit or implicit) that might affect their decisions regarding a target, they must recuse themselves from any approval decisions regarding the target's tier status, though they may otherwise participate in discussions.
> This requirement does not prevent part or all of this policy from being cited in an explicit contract or work agreement (e.g. to implement or maintain support for a target). This requirement exists to ensure that a developer or team responsible for reviewing and approving a target does not face any legal threats or obligations that would prevent them from freely exercising their judgment in such approval, even if such judgment involves subjective matters or goes beyond the letter of these requirements.
Only relevant to those making approval decisions.
> Tier 3 targets should attempt to implement as much of the standard libraries as possible and appropriate (core for most targets, alloc for targets that can support dynamic memory allocation, std for targets with an operating system or equivalent layer of system-provided functionality), but may leave some code unimplemented (either unavailable or stubbed out as appropriate), whether because the target makes it impossible to implement or challenging to implement. The authors of pull requests are not obligated to avoid calling any portions of the standard library on the basis of a tier 3 target not implementing those portions.
`core` and `alloc` can be used. `std` cannot be used as this is a bare-metal target.
> The target must provide documentation for the Rust community explaining how to build for the target, using cross-compilation if possible. If the target supports running tests (even if they do not pass), the documentation must explain how to run tests for the target, using emulation if possible or dedicated hardware if necessary.
Use `--target=x86_64-unknown-none-elf` option to cross compile, just like any target. The target does not support running tests.
> Tier 3 targets must not impose burden on the authors of pull requests, or other developers in the community, to maintain the target. In particular, do not post comments (automated or manual) on a PR that derail or suggest a block on the PR based on a tier 3 target. Do not send automated messages or notifications (via any medium, including via `@)` to a PR author or others involved with a PR regarding a tier 3 target, unless they have opted into such messages.
> Backlinks such as those generated by the issue/PR tracker when linking to an issue or PR are not considered a violation of this policy, within reason. However, such messages (even on a separate repository) must not generate notifications to anyone involved with a PR who has not requested such notifications.
I don't foresee this being a problem.
> Patches adding or updating tier 3 targets must not break any existing tier 2 or tier 1 target, and must not knowingly break another tier 3 target without approval of either the compiler team or the maintainers of the other tier 3 target.
> In particular, this may come up when working on closely related targets, such as variations of the same architecture with different features. Avoid introducing unconditional uses of features that another variation of the target may not have; use conditional compilation or runtime detection, as appropriate, to let each target run code supported by that target.
No other targets should be affected by the pull request.
Identify anonymous lifetimes by their DefId in HIR.
`ParamName::Fresh` currently identifies anonymous lifetimes by an `usize` index computed from the number of lifetimes in scope. This makes the behaviour of lowering dependent on the contents of the surrounding item in unpredictable ways.
This PR replaces this index by the `LocalDefId` of the synthetized generic lifetime parameter. This makes obvious which parameter the lifetime corresponds to.
Fix exposing fields marked unstable or doc hidden
Closes https://github.com/rust-lang/rust/issues/89837
Work towards https://github.com/rust-lang/rust/issues/89554
Filter fields that are marked `doc(hidden)` or are unstable with that feature turned off. This brings structs and enums into alignment behavior-wise when emitting warning/errors about pattern exhaustiveness/reachability.
cc `@Nadrieril`
Return early to fix ICE
This fixes#94627, ICE happens because compiler tries to suggest constraining type parameter but the only constraint is implicit `std::Sized` one, so it gets removed and there is nothing to suggest resulting in ICE.
diagnostics: do not spurriously claim something is "not an iterator"
Fixes a minor regression caused by #94746, where `iter::Filter` is spurriously declared "not an iterator."
Improve `AdtDef` interning.
This commit makes `AdtDef` use `Interned`. Much of the commit is tedious
changes to introduce getter functions. The interesting changes are in
`compiler/rustc_middle/src/ty/adt.rs`.
r? `@fee1-dead`
CTFE/Miri: detect out-of-bounds pointers in offset_from
Also I became uneasy with aggressively doing `try_to_int` here -- this will always succeed on Miri, leading to the wrong codepath being taken. We should rather try to convert them both to pointers, and use the integer path as a fallback, so that's what I implemented now.
Hiding whitespaces helps with the diff.
Fixes https://github.com/rust-lang/miri/issues/1950
r? ``@oli-obk``
Change several HashMaps to IndexMap to improve incremental hashing performance
Stable hashing hash maps in incremental mode takes a lot of time, especially for some benchmarks like `clap`. As noted by `@Mark-Simulacrum` [here](https://github.com/rust-lang/rust/pull/89404#issuecomment-950043892), this cost could be reduced by replacing some hash maps by indexmaps.
I gathered some statistics and found several hash maps that took a lot of time to hash and replaced them by indexmaps. However, in order for this to work, we need to make sure that these indexmaps have deterministic insertion order. These three are used only in visitors as far as I can see, which seems deterministic. Can we enforce this somehow? Or should some explaining comment be included for these maps?
The current structure makes it hard to tell that there are just four
distinct code paths, depending on how many items there are in `bb_items`
and `next_items`. This commit introduces a `match` that clarifies
things.
This commit makes `AdtDef` use `Interned`. Much the commit is tedious
changes to introduce getter functions. The interesting changes are in
`compiler/rustc_middle/src/ty/adt.rs`.
mir-opt: Replace clone on primitives with copy
We can't do it for everything, but it would be nice to at least stop making calls to clone methods in debug from things like derived-clones.
r? `@ghost`
Only emit pointer-like metadata for `Box<T, A>` when `A` is ZST
Basically copy the change in #94043, but for debuginfo.
r? ``@michaelwoerister``
Fixes#94725
[1/2] Implement macro meta-variable expressions
See https://github.com/rust-lang/rust/pull/93545#issuecomment-1050963295
The logic behind `length`, `index` and `count` was removed but the parsing code is still present, i.e., everything is simply ignored like `ignored`.
r? ``@petrochenkov``
Treat unstable lints as unknown
This change causes unstable lints to be ignored if the `unknown_lints`
lint is allowed. To achieve this, it also changes lints to apply as soon
as they are processed. Previously, lints in the same set were processed
as a batch and then all simultaneously applied.
Implementation of https://github.com/rust-lang/compiler-team/issues/469
Use modern formatting for format! macros
This updates the standard library's documentation to use the new format_args syntax.
The documentation is worthwhile to update as it should be more idiomatic
(particularly for features like this, which are nice for users to get acquainted
with). The general codebase is likely more hassle than benefit to update: it'll
hurt git blame, and generally updates can be done by folks updating the code if
(and when) that makes things more readable with the new format.
A few places in the compiler and library code are updated (mostly just due to
already having been done when this commit was first authored).
`eprintln!("{}", e)` becomes `eprintln!("{e}")`, but `eprintln!("{}", e.kind())` remains untouched.
RustWrapper: add missing include
This is required after LLVM change 3c4410dfcaaf (aka
https://reviews.llvm.org/D121168) did some includes cleanup.
r? nikic
Better error for normalization errors from parent crates that use `#![feature(generic_const_exprs)]`
This PR implements a somewhat rudimentary heuristic to suggest using `#![feature(generic_const_exprs)]` in a child crate when a function from a foreign crate (that may have used `#![feature(generic_const_exprs)]`) fails to normalize during codegen.
cc: #79018
cc: #94287
This updates the standard library's documentation to use the new syntax. The
documentation is worthwhile to update as it should be more idiomatic
(particularly for features like this, which are nice for users to get acquainted
with). The general codebase is likely more hassle than benefit to update: it'll
hurt git blame, and generally updates can be done by folks updating the code if
(and when) that makes things more readable with the new format.
A few places in the compiler and library code are updated (mostly just due to
already having been done when this commit was first authored).