parser: more friendly hints for handling `async move` in the 2015 edition
Fixes#114219
An error is emitted when encountering an async move block in the 2015 edition.
Another appropriate location to raise an error is after executing [let path = this.parse_path(PathStyle::Expr)?](https://github.com/rust-lang/rust/blob/master/compiler/rustc_parse/src/parser/stmt.rs#L152), but it seems somewhat premature to invoke `create_err` at that stage.
Expand, rename and improve `incorrect_fn_null_checks` lint
This PR,
- firstly, expand the lint by now linting on references
- secondly, it renames the lint `incorrect_fn_null_checks` -> `useless_ptr_null_checks`
- and thirdly it improves the lint by catching `ptr::from_mut`, `ptr::from_ref`, as well as `<*mut _>::cast` and `<*const _>::cast_mut`
Fixes https://github.com/rust-lang/rust/issues/113601
cc ```@est31```
It lints against features that are inteded to be internal to the
compiler and standard library. Implements MCP #596.
We allow `internal_features` in the standard library and compiler as those
use many features and this _is_ the standard library from the "internal to the compiler and
standard library" after all.
Marking some features as internal wasn't exactly the most scientific approach, I just marked some
mostly obvious features. While there is a categorization in the macro,
it's not very well upheld (should probably be fixed in another PR).
We always pass `-Ainternal_features` in the testsuite
About 400 UI tests and several other tests use internal features.
Instead of throwing the attribute on each one, just always allow them.
There's nothing wrong with testing internal features^^
Infer type in irrefutable slice patterns with fixed length as array
Fixes https://github.com/rust-lang/rust/issues/76342
In irrefutable slice patterns with a fixed length, we can infer the type as an array type. We now choose to prefer some implementations over others, e.g. in:
```
struct Zeroes;
const ARR: [usize; 2] = [0; 2];
const ARR2: [usize; 2] = [2; 2];
impl Into<&'static [usize; 2]> for Zeroes {
fn into(self) -> &'static [usize; 2] {
&ARR
}
}
impl Into<&'static [usize]> for Zeroes {
fn into(self) -> &'static [usize] {
&ARR2
}
}
fn main() {
let &[a, b] = Zeroes.into();
}
```
We now prefer the impl candidate `impl Into<&'static [usize; 2]> for Zeroes`, it's not entirely clear to me that this is correct, but given that the slice impl would require a type annotation anyway, this doesn't seem unreasonable.
r? `@lcnr`
Fix suggestion spans for expr from macro expansions
### Issue #112007: rustc shows expanded `writeln!` macro in code suggestion
#### Before This PR
```
help: consider using a semicolon here
|
6 | };
| +
help: you might have meant to return this value
--> C:\Users\hayle\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\macros\mod.rs:557:9
|
55| return $dst.write_fmt($crate::format_args_nl!($($arg)*));
| ++++++ +
```
#### After This PR
```
help: consider using a semicolon here
|
LL | };
| +
help: you might have meant to return this value
|
LL | return writeln!(w, "but not here");
| ++++++ +
```
### Issue #110017: `format!` `.into()` suggestion deletes the `format` macro
#### Before This PR
```
help: call `Into::into` on this expression to convert `String` into `Box<dyn std::error::Error>`
--> /Users/eric/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/macros.rs:121:12
|
12| res.into()
| +++++++
```
#### After This PR
```
help: call `Into::into` on this expression to convert `String` into `Box<dyn std::error::Error>`
|
LL | Err(format!("error: {x}").into())
| +++++++
```
---
Fixes#112007.
Fixes#110017.
This patch adds a feature gate `async_fn_track_caller` that is separate from `closure_track_caller`. This is to allow enabling `async_fn_track_caller` separately.
Fixes#110009
Rollup of 5 pull requests
Successful merges:
- #114079 (Use `upvar_tys` in more places, make it return a list)
- #114166 (Add regression test for resolving `--extern libc=test.rlib`)
- #114321 (get auto traits for parallel rustc)
- #114335 (fix and extend ptr_comparison test)
- #114347 (x.py print more detailed format files and untracked files count)
r? `@ghost`
`@rustbot` modify labels: rollup
Improve `invalid_reference_casting` lint
This PR is a follow-up to https://github.com/rust-lang/rust/pull/111567 and https://github.com/rust-lang/rust/pull/113422.
This PR does multiple things:
- First it adds support for deferred de-reference, the goal is to support code like this, where the casting and de-reference are not done on the same expression
```rust
let myself = self as *const Self as *mut Self;
*myself = Self::Ready(value);
```
- Second it does not lint anymore on SB/TB UB code by only checking assignments (`=`, `+=`, ...) and creation of mutable references `&mut *`
- Thirdly it greatly improves the diagnostics in particular for cast from `&mut` to `&mut` or assignments
- ~~And lastly it renames the lint from `cast_ref_to_mut` to `invalid_reference_casting` which is more consistent with the ["rules"](https://github.com/rust-lang/rust-clippy/issues/2845) and also more consistent with what the lint checks~~ *https://github.com/rust-lang/rust/pull/113422*
This PR is best reviewed commit by commit.
r? compiler
Miri: fix error on dangling pointer inbounds offset
We used to claim that the pointer was "dereferenced", but that is just not true.
Can be reviewed commit-by-commit. The first commit is an unrelated rename that didn't seem worth splitting into its own PR.
r? `@oli-obk`
Fix invalid slice coercion suggestion reported in turbofish
This PR fixes the invalid slice coercion suggestion reported in turbofish and inferred generics by not emitting them.
Fixes https://github.com/rust-lang/rust/issues/110063
Don't check unnecessarily that impl trait is RPIT
We have this random `return_type_impl_trait` function to detect if a function returns an RPIT which is used in outlives suggestions, but removing it doesn't actually change any diagnostics. Let's just remove it.
Also, suppress a spurious outlives error from a ReError.
Fixes#114274
Account for macros when suggesting a new let binding
Provide a structured suggestion when the expression comes from a macro expansion:
```
error[E0716]: temporary value dropped while borrowed
--> $DIR/borrowck-let-suggestion.rs:2:17
|
LL | let mut x = vec![1].iter();
| ^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
LL |
LL | x.use_mut();
| - borrow later used here
|
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider using a `let` binding to create a longer lived value
|
LL ~ let binding = vec![1];
LL ~ let mut x = binding.iter();
|
```
cleanup: remove pointee types
This can't be merged until the oldest LLVM version we support uses opaque pointers, which will be the case after #114148. (Also note `-Cllvm-args="-opaque-pointers=0"` can technically be used in LLVM 15, though I don't think we should support that configuration.)
I initially hoped this would provide some minor perf win, but in https://github.com/rust-lang/rust/pull/105412#issuecomment-1341224450 it had very little impact, so this is only valuable as a cleanup.
As a followup, this will enable #96242 to be resolved.
r? `@ghost`
`@rustbot` label S-blocked
Improve diagnostic for wrong borrow on binary operations
This PR improves the diagnostic for wrong borrow on binary operations by suggesting to reborrow on appropriate expressions.
```diff
+ = note: an implementation for `&Foo * &Foo` exist
+ help: consider reborrowing both sides
+ |
+ LL | let _ = &*ref_mut_foo * &*ref_mut_foo;
+ | ++ ++
```
Fixes https://github.com/rust-lang/rust/issues/109352
Change default panic handler message format.
This changes the default panic hook's message format from:
```
thread '{thread}' panicked at '{message}', {location}
```
to
```
thread '{thread}' panicked at {location}:
{message}
```
This puts the message on its own line without surrounding quotes, making it easiser to read. For example:
Before:
```
thread 'main' panicked at 'env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`', src/main.rs:4:6
```
After:
```
thread 'main' panicked at src/main.rs:4:6:
env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`
```
---
See this PR by `@nyurik,` which does that for only multi-line messages (specifically because of `assert_eq`): https://github.com/rust-lang/rust/pull/111071
This is the change that does that for *all* panic messages.
Detect trait upcasting through struct tail unsizing in new solver select
Oops, we were able to hide trait upcasting behind a parent unsize goal that evaluated to `Certainty::Yes`. Let's do rematching for `Certainty::Yes` unsize goals with `BuiltinImplSource::Misc` sources (corresponding to all of the other unsize rules) to make sure we end up selecting any nested goals which may be satisfied via `BuiltinImplSource::TraitUpcasting` or `::TupleUnsizing`.
r? ``@lcnr``
Update lexer emoji diagnostics to Unicode 15.0
This replaces the `unic-emoji-char` dep tree (which hasn't been updated for a while) with `unicode-properties` crate which contains Unicode 15.0 data.
Improves diagnostics for added emoji characters in recent years. (See tests).
cc #101840
cc ``@Manishearth``
Map RPITIT's opaque type bounds back from projections to opaques
An RPITIT in a program's AST is eventually translated into both a projection GAT and an opaque. The opaque is used for default trait methods, like:
```
trait Foo {
fn bar() -> impl Sized { 0i32 }
}
```
The item bounds for both the projection and opaque are identical, and both have a *projection* self ty. This is mostly okay, since we can normalize this projection within the default trait method body to the opaque, but it does two things:
1. it leads to bugs in places where we don't normalize item bounds, like `deduce_future_output_from_obligations`
2. it leads to extra match arms that are both suspicious looking and also easy to miss
This PR maps the opaque type bounds of the RPITIT's *opaque* back to the opaque's self type to avoid this quirk. Then we can fix the UI test for #108304 (1.) and also remove a bunch of match arms (2.).
Fixes#108304
r? `@spastorino`
Check lazy type aliases for well-formedness
Previously we didn't check if `T: Mul` holds given lazy `type Alias<T> = <T as Mul>::Output;`.
Now we do. It only makes sense.
`@rustbot` label F-lazy_type_alias
r? `@oli-obk`
Only golden arches
A number of tests in the test suite have applied the somewhat comedic practice of ignoring *every* single target architecture that rustc has ever supported. This is silly, when they are clearly tests built around certain assumptions, primarily of the x86-64 architecture, or in one case when they are only relevant for a handful of 32-bit targets. This has even resulted, in one case, in the same architecture being ignored twice!
Document these better, and use a "revision + only-arch" idiom in the test headers to denote the "golden arches" that actually pass these tests.
Don't install default projection bound for return-position `impl Trait` in trait methods with no body
This ensures that we never try to project to an opaque type in a trait method that has no body to infer its hidden type, which means we never later call `type_of` on that opaque. This is because opaque types try to reveal their hidden type when proving auto traits.
I thought about this a lot, and I think this is a fix that's less likely to introduce other strange downstream ICEs than #113461.
Fixes#113434
r? `@spastorino`
Fix invalid suggestion for mismatched types in closure arguments
This PR fixes the invalid suggestion for mismatched types in closure arguments.
The invalid suggestion came from a wrongly created span in the parser for closure arguments that don't have a type specified. Specifically, the span in this case was the last token span, but in the case of tuples, the span represented the last parenthesis instead of the whole tuple, which is fixed by taking the more accurate span of the pattern.
There is one unfortunate downside of this fix, it worsens even more the diagnostic for mismatched types in closure args without an explicit type. This happens because there is no correct span for implied inferred type. I tried also fixing this but it's a rabbit hole.
Fixes https://github.com/rust-lang/rust/issues/114180
`const`-stablilize `NonNull::as_ref`
A bunch of pointer to reference methods have been made unstably const some time ago in #91823 under the feature gate `const_ptr_as_ref`.
Out of these, `NonNull::as_ref` can be implemented as a `const fn` in stable rust today, so i hereby propose to const stabilize this function only.
Tracking issue: #91822
``@rustbot`` label +T-libs-api -T-libs
The invalid suggestion came from a wrongly created span in `rustc_parse'
for closure arguments that didn't have a type specified. Specifically,
the span in this case was the last token span, but in the case of
tuples, the span represented the last parenthesis instead of the whole
tuple, which is fixed by taking the more accurate span of the pattern.
Combining revisions with only-arch allows specifying
that a test only applies to a handful of targets.
This allows removing a large amount of repetition
in the test suite for tests that do not benefit.
The revisions are suboptimal for this for some tests,
so they aren't preferred in those cases.
Gracefully handle ternary operator
Fixes#112578
~~May not be the best way to do this as it doesn't check for a single `:`, so it could perhaps appear even when the actual issue is just a missing semicolon. May not be the biggest deal, though?~~
Nevermind, got it working properly now ^^
Update the minimum external LLVM to 15
With this change, we'll have stable support for LLVM 15 through 17 (pending release).
For reference, the previous increase to LLVM 14 was #107573.
Refactor + improve diagnostics for `&mut T`/`T` mismatch inside Option/Result
Follow up to #114052. This also makes the diagnostics structured + translatable.
r? `@WaffleLapkin`
Rename and allow `cast_ref_to_mut` lint
This PR is a small subset of https://github.com/rust-lang/rust/pull/112431, that is the renaming of the lint (`cast_ref_to_mut` -> `invalid_reference_casting`).
BUT also temporarily change the default level of the lint from deny-by-default to allow-by-default until https://github.com/rust-lang/rust/pull/112431 is merged.
r? `@Nilstrieb`
I could not find a test for this particular use case. The closest I got
was `tests/ui/imports/issue-37887.rs`, but that is a regression test
for a different use case.
fix(resolve): update the ambiguity glob binding as warning recursively
Fixes#47525Fixes#56593, but `issue-56593-2.rs` is not fixed to ensure backward compatibility.
Fixes#98467Fixes#105235Fixes#112713
This PR had added a field called `warn_ambiguous` in `NameBinding` which is only for back compatibly reason and used for lint.
More details: https://github.com/rust-lang/rust/pull/112743
r? `@petrochenkov`
Rollup of 7 pull requests
Successful merges:
- #113773 (Don't attempt to compute layout of type referencing error)
- #114107 (Prevent people from assigning me as a PR reviewer)
- #114124 (tests/ui/proc-macro/*: Migrate FIXMEs to check-pass)
- #114171 (Fix switch-stdout test for none unix/windows platforms)
- #114172 (Fix issue_15149 test for the SGX target)
- #114173 (btree/map.rs: remove "Basic usage" text)
- #114174 (doc: replace wrong punctuation mark)
r? `@ghost`
`@rustbot` modify labels: rollup
tests/ui/proc-macro/*: Migrate FIXMEs to check-pass
proc-macros are processed early in the compiler pipeline. There is no need to involve codegen. So change to check-pass.
I have also looked through each changed test and to me it is sufficiently clear that codegen is not needed for the purpose of the test.
I skipped changing `tests/ui/proc-macro/no-missing-docs.rs` in this commit because it was not clear to me that it can be changed to check-pass.
Part of #62277
Rollup of 7 pull requests
Successful merges:
- #114099 (privacy: no nominal visibility for assoc fns )
- #114128 (When flushing delayed span bugs, write to the ICE dump file even if it doesn't exist)
- #114138 (Adjust spans correctly for fn -> method suggestion)
- #114146 (Skip reporting item name when checking RPITIT GAT's associated type bounds hold)
- #114147 (Insert RPITITs that were shadowed by missing ADTs that resolve to [type error])
- #114155 (Replace a lazy `RefCell<Option<T>>` with `OnceCell<T>`)
- #114164 (Add regression test for `--cap-lints allow` and trait bounds warning)
r? `@ghost`
`@rustbot` modify labels: rollup
Add regression test for `--cap-lints allow` and trait bounds warning
Closes#43134
I have verified that the test fails if stderr begins to contain output by making sure the test fails when I add
eprintln!("some output on stderr");
to the compiler (I added it to `fn build_session()`).
Skip reporting item name when checking RPITIT GAT's associated type bounds hold
Doesn't really make sense to label an item that has a name that users can't really mention. Fixes#114145. Also fixes#113794.
r? `@spastorino`
privacy: no nominal visibility for assoc fns
Fixes#113860.
When `staged_api` is enabled, effective visibilities are computed earlier and this can trigger an ICE in some cases.
In particular, if a impl of a trait method has a visibility then an error will be reported for that, but when privacy invariants are being checked, the effective visibility will still be greater than the nominal visbility and that will trigger a `span_bug!`.
However, this invariant - that effective visibilites are limited to nominal visibility - doesn't make sense for associated functions.
Diagnostic namespace
This PR implements the basic infrastructure for accepting the `#[diagnostic]` attribute tool namespace as specified in https://github.com/rust-lang/rfcs/pull/3368. Note: This RFC is not merged yet, but it seems like it will be accepted soon. I open this PR early on to get feedback on the actual implementation as soon as possible. This hopefully enables getting at least the diagnostic namespace to stable rust "soon", so that crates do not need to bump their MSRV if we stabilize actual attributes in this namespace.
This PR only adds infrastructure accept attributes from this namespace, it does not add any specific attribute. Therefore the compiler will emit a lint warning for each attribute that's actually used. This namespace is added behind a feature flag, so it will be only available on a nightly compiler for now.
cc `@estebank` as they've supported me in planing, specifying and implementing this feature.
When `staged_api` is enabled, effective visibilities are computed earlier
and this can trigger an ICE in some cases.
In particular, if a impl of a trait method has a visibility then an error
will be reported for that, but when privacy invariants are being checked,
the effective visibility will still be greater than the nominal visbility
and that will trigger a `span_bug!`.
However, this invariant - that effective visibilites are limited to
nominal visibility - doesn't make sense for associated functions.
Signed-off-by: David Wood <david@davidtw.co>
I have verified that the test fails if stderr begins to contain output
by making sure the test fails when I add
eprintln!("some output on stderr");
to the compiler (I added it to `fn build_session()`).
Move two tests from `tests/ui/std` to `library/std/tests`
Hi, there,
This pull request comes from this issue (#99417), sorry I made some mistakes creating the pull request, it's my first one.
Regression test `println!()` panic message on `ErrorKind::BrokenPipe`
No existing test (that I could find) failed if the `panic!()` of the `println!()` family of functions was removed, or if its message was changed:
104f4300cf/library/std/src/io/stdio.rs (L1007-L1009)
So add such a test.
This is in preparation of adding a hint about the existence of [`unix_sigpipe`](https://github.com/rust-lang/rust/issues/97889) if that is the reason for the panic.
Even if we don't end up adding a hint, this is still a sensible test to have, I think.
`@rustbot` label +A-testsuite +A-io +T-libs +O-unix
tests/ui/hello_world/main.rs: Remove FIXME (#62277)
The purpose of the test is to make sure that compiling hello world produces no compiler output. To properly test that, we need to run the entire compiler pipeline. We don't want the test to pass if codegen accidentally starts writing to stdout. So keep it as build-pass.
Part of #62277
Turns out opaque types can have hidden types registered during mir validation
See the newly added test's documentation for an explanation.
fixes#114121
proc-macros are processed early in the compiler pipeline. There is no
need to involve codegen. So change to check-pass.
I have also looked through each changed test and to me it is
sufficiently clear that codegen is not needed for the purpose of the
test.
I skipped changing tests/ui/proc-macro/no-missing-docs.rs in this commit
because it was not clear to me that it can be changed to check-pass.
The purpose of the test is to make sure that compiling hello world
produces no compiler output. To properly test that, we need to run the
entire compiler pipeline. We don't want the test to pass if codegen
accidentally starts writing to stdout. So keep it as build-pass.
Replace in-tree `rustc_apfloat` with the new version of the crate
Replace the in-tree version of `rustc_apfloat` with the new version of the crate which has been correctly licensed. The new crate incorporates upstream changes from LLVM since the original port was done including many correctness fixes and has been extensively fuzz tested to validate correctness.
Fixes#100233Fixes#102403Fixes#113407Fixes#113409Fixes#55993Fixes#93224Closes#93225Closes#109573
lint/ctypes: fix `()` return type checks
Fixes#113436.
`()` is normally FFI-unsafe, but is FFI-safe when used as a return type. It is also desirable that a transparent newtype for `()` is FFI-safe when used as a return type.
In order to support this, when a type was deemed FFI-unsafe, because of a `()` type, and was used in return type - then the type was considered FFI-safe. However, this was the wrong approach - it didn't check that the `()` was part of a transparent newtype! The consequence of this is that the presence of a `()` type in a more complex return type would make it the entire type be considered safe (as long as the `()` type was the first that the lint found) - which is obviously incorrect.
Instead, this logic is removed, and after [consultation with t-lang](https://github.com/rust-lang/rust/issues/113436#issuecomment-1640756721), I've fixed the bugs and inconsistencies and made `()` FFI-safe within types.
I also refactor a function, but that's not too exciting.
new unstable option: -Zwrite-long-types-to-disk
This option guards the logic of writing long type names in files and instead using short forms in error messages in rustc_middle/ty/error behind a flag. The main motivation for this change is to disable this behaviour when running ui tests.
This logic can be triggered by running tests in a directory that has a long enough path, e.g. /my/very-long-path/where/rust-codebase/exists/
This means ui tests can fail depending on how long the path to their file is.
Some ui tests actually rely on this behaviour for their assertions, so for those we enable the flag manually.
Double check that hidden types match the expected hidden type
Fixes https://github.com/rust-lang/rust/issues/113278 specifically, but I left a TODO for where we should also add some hardening.
It feels a bit like papering over the issue, but at least this way we don't get unsoundness, but just surprising errors. Errors will be improved and given spans before this PR lands.
r? `@compiler-errors` `@lcnr`
Don't say that a type is uncallable if its fn signature has errors in it
This is fallout from #106309, where we don't consider param-env candidates that reference errors because they unify with everything. This means, however, that we don't consider an APIT like `impl Fn(MissingType)` isn't considered to implement `Fn`, for example.
We can double-check that with a weaker heuristic [`extract_callable_info`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#method.extract_callable_info), and suppress the knock-down error using that.
Fixes#113566
Rollup of 7 pull requests
Successful merges:
- #114008 (coverage: Obtain the `__llvm_covfun` section name outside a per-function loop)
- #114014 (builtin_macros: expect raw strings too)
- #114043 (docs(LazyLock): add example pass local LazyLock variable to struct)
- #114051 (Add regression test for invalid "unused const" in method)
- #114052 (Suggest `{Option,Result}::as_ref()` instead of `cloned()` in some cases)
- #114058 (Add help for crate arg when crate name is invalid)
- #114060 (abi: unsized field in union - assert to delay bug )
r? `@ghost`
`@rustbot` modify labels: rollup
abi: unsized field in union - assert to delay bug
Fixes#113279.
> Unions cannot have unsized fields, and as such, layout computation for
unions asserts that each union field is sized (as this would normally
have halted compilation earlier).
>
> However, if a generator ends up with an unsized local - a circumstance
in which an error will always have been emitted earlier, for example, if
attempting to dereference a `&str` - then the generator transform will
produce a union with an unsized field.
>
> Since https://github.com/rust-lang/rust/pull/110107, later passes will be run, such as constant propagation,
and can attempt layout computation on the generator, which will result
in layout computation of `str` in the context of it being a field of a
union - and so the aforementioned assertion would cause an ICE.
>
> It didn't seem appropriate to try and detect this case in the MIR body
and skip this specific pass; tainting the MIR body or delaying a bug
from the generator transform (or elsewhere) wouldn't prevent this either
(as neither would prevent the later pass from running); and tainting when
the deref of `&str` is reported, if that's possible, would unnecessarily
prevent potential other errors from being reported later in compilation,
and is very tailored to this specific case of getting a unsized type in
a generator.
>
> Given that this circumstance can only happen when an error should have
already been reported, the correct fix appears to be just changing the
assert to a delayed bug. This will still assert if there is some
circumstance where this occurs and no error has been reported, but it
won't crash the compiler in this instance.
While debugging this, I noticed a translation ICE in a delayed bug, so I fixed that too:
> During borrowck, the `MultiSpan` from a buffered diagnostic is cloned and
used to emit a delayed bug indicating a diagnostic was buffered - when
the buffered diagnostic is translated, then the cloned `MultiSpan` may
contain labels which can only render with the diagnostic's arguments, but
the delayed bug being emitted won't have those arguments. Adds a function
which clones `MultiSpan` without also cloning the contained labels, and
use this function when creating the buffered diagnostic delayed bug.
Suggest `{Option,Result}::as_ref()` instead of `cloned()` in some cases
Fixes#114050
When we have an expr available that produces the type expectation, we can suggest appending `.as_ref()` to the span, instead of cloning the expr producing the mismatch
Add regression test for invalid "unused const" in method
The warning can be reproduced with 1.63 but not with 1.64.
$ rustc +1.63 tests/ui/lint/unused/const-local-var.rs
warning: constant `F` is never used
--> tests/ui/lint/unused/const-local-var.rs:14:9
|
14 | const F: i32 = 2;
| ^^^^^^^^^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
$ rustc +1.64 tests/ui/lint/unused/const-local-var.rs
Add a regression test to prevent the problem from re-appearing.
Closes#69016
Normalize the RHS of an `Unsize` goal in the new solver
`Unsize` goals are... tricky. Not only do they structurally match on their self type, but they're also structural on their other type parameter. I'm pretty certain that it is both incomplete and also just plain undesirable to not consider normalizing the RHS of an unsize goal. More practically, I'd like for this code to work:
```rust
trait A {}
trait B: A {}
impl A for usize {}
impl B for usize {}
trait Mirror {
type Assoc: ?Sized;
}
impl<T: ?Sized> Mirror for T {
type Assoc = T;
}
fn main() {
// usize: Unsize<dyn B>
let x = Box::new(1usize) as Box<<dyn B as Mirror>::Assoc>;
// dyn A: Unsize<dyn B>
let y = x as Box<<dyn A as Mirror>::Assoc>;
}
```
---
In order to achieve this, we add `EvalCtxt::normalize_non_self_ty` (naming modulo bikeshedding), which *must* be used for all non-self type arguments that are structurally matched in candidate assembly. Currently this is only necessary for `Unsize`'s argument, but I could see future traits requiring this (hopefully rarely) in the future. It uses `repeat_while_none` to limit infinite looping, and normalizes the self type until it is no longer an alias.
Also, we need to fix feature gate detection for `trait_upcasting` and `unsized_tuple_coercion` when HIR typeck has unnormalized types. We can do that by checking the `ImplSource` returned by selection, which necessitates adding a new impl source for tuple upcasting.
Unions cannot have unsized fields, and as such, layout computation for
unions asserts that each union field is sized (as this would normally
have halted compilation earlier).
However, if a generator ends up with an unsized local - a circumstance
in which an error will always have been emitted earlier, for example, if
attempting to dereference a `&str` - then the generator transform will
produce a union with an unsized field.
Since #110107, later passes will be run, such as constant propagation,
and can attempt layout computation on the generator, which will result
in layout computation of `str` in the context of it being a field of a
union - and so the aforementioned assertion would cause an ICE.
It didn't seem appropriate to try and detect this case in the MIR body
and skip this specific pass; tainting the MIR body or delaying a bug
from the generator transform (or elsewhere) wouldn't prevent this either
(as neither would prevent the later pass from running); and tainting when
the deref of `&str` is reported, if that's possible, would unnecessarily
prevent potential other errors from being reported later in compilation,
and is very tailored to this specific case of getting a unsized type in
a generator.
Given that this circumstance can only happen when an error should have
already been reported, the correct fix appears to be just changing the
assert to a delayed bug. This will still assert if there is some
circumstance where this occurs and no error has been reported, but it
won't crash the compiler in this instance.
Signed-off-by: David Wood <david@davidtw.co>
interpret: Unify projections for MPlaceTy, PlaceTy, OpTy
For ~forever, we didn't really have proper shared code for handling projections into those three types. This is mostly because `PlaceTy` projections require `&mut self`: they might have to `force_allocate` to be able to represent a project part-way into a local.
This PR finally fixes that, by enhancing `Place::Local` with an `offset` so that such an optimized place can point into a part of a place without having requiring an in-memory representation. If we later write to that place, we will still do `force_allocate` -- for now we don't have an optimized path in `write_immediate` that would avoid allocation for partial overwrites of immediately stored locals. But in `write_immediate` we have `&mut self` so at least this no longer pollutes all our type signatures.
(Ironically, I seem to distantly remember that many years ago, `Place::Local` *did* have an `offset`, and I removed it to simplify things. I guess I didn't realize why it was so useful... I am also not sure if this was actually used to achieve place projection on `&self` back then.)
The `offset` had type `Option<Size>`, where `None` represent "no projection was applied". This is needed because locals *can* be unsized (when they are arguments) but `Place::Local` cannot store metadata: if the offset is `None`, this refers to the entire local, so we can use the metadata of the local itself (which must be indirect); if a projection gets applied, since the local is indirect, it will turn into a `Place::Ptr`. (Note that even for indirect locals we can have `Place::Local`: when the local appears in MIR, we always start with `Place::Local`, and only check `frame.locals` later. We could eagerly normalize to `Place::Ptr` but I don't think that would actually simplify things much.)
Having done all that, we can finally properly abstract projections: we have a new `Projectable` trait that has the basic methods required for projecting, and then all projection methods are implemented for anything that implements that trait. We can even implement it for `ImmTy`! (Not that we need that, but it seems neat.) The visitor can be greatly simplified; it doesn't need its own trait any more but it can use the `Projectable` trait. We also don't need the separate `Mut` visitor any more; that was required only to reflect that projections on `PlaceTy` needed `&mut self`.
It is possible that there are some more `&mut self` that can now become `&self`... I guess we'll notice that over time.
r? `@oli-obk`
Reimplement C-str literals
This reverts #113334, cc `@fmease.`
While converting lexer tokens to ast Tokens in `rustc_parse`, we check the edition of the span of the token. If the edition < 2021, we split the token into two, one being the identifier and other being the str literal.
The warning can be reproduced with 1.63 but not with 1.64.
$ rustc +1.63 tests/ui/lint/unused/const-local-var.rs
warning: constant `F` is never used
--> tests/ui/lint/unused/const-local-var.rs:14:9
|
14 | const F: i32 = 2;
| ^^^^^^^^^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
$ rustc +1.64 tests/ui/lint/unused/const-local-var.rs
Add a regression test to prevent the problem from re-appearing.
If a raw string was used in the `env!` invocation, then it should also
be shown in the diagnostic messages as a raw string.
Signed-off-by: David Wood <david@davidtw.co>
fix(resolve): skip panic when resolution is dummy
Fixes#113953
Skip the panic when the binding refers to a dummy node during the finalization.
r? `@petrochenkov`
fix intra-doc links on nested `use` and `extern crate` items
This PR fixes two rustdoc ICEs that happen if there are any intra-doc links on nested `use` or `extern crate` items, for example:
```rust
/// Re-export [`fmt`] and [`io`].
pub use std::{fmt, io}; // "nested" use = use with braces
/// Re-export [`std`].
pub extern crate std;
```
Nested use items were incorrectly considered private and therefore didn't have their intra-doc links resolved. I fixed this by always resolving intra-doc links for nested `use` items that are declared `pub`.
<details>
During AST->HIR lowering, nested `use` items are desugared like this:
```rust
pub use std::{}; // "list stem"
pub use std::fmt;
pub use std::io;
```
Each of these HIR nodes has it's own effective visibility and the list stem is always considered private.
To check the effective visibility of an AST node, the AST node is mapped to a HIR node with `Resolver::local_def_id`, which returns the (private) list stem for nested use items.
</details>
For `extern crate`, there was a hack in rustdoc that stored the `DefId` of the crate itself in the cleaned item, instead of the `DefId` of the `extern crate` item. This made rustdoc look at the resolved links of the extern crate's crate root instead of the `extern crate` item. I've removed this hack and instead translate the `DefId` in the appropriate places.
As as side effect of fixing `extern crate`, i've turned
```rust
#[doc(masked)]
extern crate self as _;
```
into a no-op instead of hiding all trait impls. Proper verification for `doc(masked)` is included as a bonus.
fixes https://github.com/rust-lang/rust/issues/113896
lint/ctypes: only try normalize
Fixes#113900.
Now that this lint runs on any external-ABI fn-ptr, normalization won't always succeed, so use `try_normalize_erasing_regions` instead.
This is necessary for closure captures in 2021 edition, as they capture individual fields, not the full mentioned variables. So it may try to capture a field of an opaque (because the hidden type is known to be something with a field).
This option guards the logic of writing long type names in files and
instead using short forms in error messages in rustc_middle/ty/error
behind a flag. The main motivation for this change is to disable this
behaviour when running ui tests.
This logic can be triggered by running tests in a directory that has a
long enough path, e.g. /my/very-long-path/where/rust-codebase/exists/
This means ui tests can fail depending on how long the path to their
file is.
Some ui tests actually rely on this behaviour for their assertions,
so for those we enable the flag manually.
Fix #[inline(always)] on closures with target feature 1.1
Fixes#108655. I think this is the most obvious solution that isn't overly complicated. The comment includes more justification, but I think this is likely better than demoting the `#[inline(always)]` to `#[inline]`, since existing code is unaffected.
Support interpolated block for `try` and `async`
I'm putting this up for T-lang discussion, to decide whether or not they feel like this should be supported. This was raised in #112952, which surprised me. There doesn't seem to be a *technical* reason why we don't support this.
### Precedent:
This is supported:
```rust
macro_rules! always {
($block:block) => {
if true $block
}
}
fn main() {
always!({});
}
```
### Counterpoint:
However, for context, this is *not* supported:
```rust
macro_rules! unsafe_block {
($block:block) => {
unsafe $block
}
}
fn main() {
unsafe_block!({});
}
```
If this support for `async` and `try` with interpolated blocks is *not* desirable, then I can convert them to instead the same diagnostic as `unsafe $block` and make this situation a lot less ambiguous.
----
I'll try to write up more before T-lang triage on Tuesday. I couldn't find anything other than #69760 for why something like `unsafe $block` is not supported, and even that PR doesn't have much information.
Fixes#112952
Tweak spans for self arg, fix borrow suggestion for signature mismatch
1. Adjust a suggestion message that was annoying me
2. Fix#112503 by recording the right spans for the `self` part of the `&self` 0th argument
3. Remove the suggestion for adjusting a trait signature on type mismatch, bc that's gonna probably break all the other impls of the trait even if it fixes its one usage 😅
Rollup of 4 pull requests
Successful merges:
- #113887 (new solver: add a separate cache for coherence)
- #113910 (Add FnPtr ty to SMIR)
- #113913 (error/E0691: include alignment in error message)
- #113914 (rustc_target: drop duplicate code)
r? `@ghost`
`@rustbot` modify labels: rollup
error/E0691: include alignment in error message
Include the computed alignment of the violating field when rejecting transparent types with non-trivially aligned ZSTs.
ZST member fields in transparent types must have an alignment of 1 (to ensure it does not raise the layout requirements of the transparent field). The current error message looks like this:
```text
LL | struct Foobar(u32, [u32; 0]);
| ^^^^^^^^ has alignment larger than 1
```
This patch changes the report to include the alignment of the violating field:
```text
LL | struct Foobar(u32, [u32; 0]);
| ^^^^^^^^ has alignment of 4, which is larger than 1
```
In case of unknown alignments, it will yield:
```text
LL | struct Foobar(u32, [u32; 0]);
| ^^^^^^^^ may have alignment larger than 1
```
This allows developers to get a better grasp why a specific field is rejected. Knowing the alignment of the violating field makes it easier to judge where that alignment-requirement originates, and thus hopefully provide better hints on how to mitigate the problem.
This idea was proposed in 2022 in #98071 as part of a bigger change. This commit simply extracts this error-message change, to decouple it from the other diagnostic improvements.
(Originally proposed by `@compiler-errors` in #98071)
Prototype: Add unstable `-Z reference-niches` option
MCP: rust-lang/compiler-team#641
Relevant RFC: rust-lang/rfcs#3204
This prototype adds a new `-Z reference-niches` option, controlling the range of valid bit-patterns for reference types (`&T` and `&mut T`), thereby enabling new enum niching opportunities. Like `-Z randomize-layout`, this setting is crate-local; as such, references to built-in types (primitives, tuples, ...) are not affected.
The possible settings are (here, `MAX` denotes the all-1 bit-pattern):
| `-Z reference-niches=` | Valid range |
|:---:|:---:|
| `null` (the default) | `1..=MAX` |
| `size` | `1..=(MAX- size)` |
| `align` | `align..=MAX.align_down_to(align)` |
| `size,align` | `align..=(MAX-size).align_down_to(align)` |
------
This is very WIP, and I'm not sure the approach I've taken here is the best one, but stage 1 tests pass locally; I believe this is in a good enough state to unleash this upon unsuspecting 3rd-party code, and see what breaks.
Now that this lint runs on any external-ABI fn-ptr, normalization won't
always succeed, so use `try_normalize_erasing_regions` instead.
Signed-off-by: David Wood <david@davidtw.co>
Still more complexity, but this allows computing exact `NaiveLayout`s
for null-optimized enums, and thus allows calls like
`transmute::<Option<&T>, &U>()` to work in generic contexts.
Include the computed alignment of the violating field when rejecting
transparent types with non-trivially aligned ZSTs.
ZST member fields in transparent types must have an alignment of 1 (to
ensure it does not raise the layout requirements of the transparent
field). The current error message looks like this:
LL | struct Foobar(u32, [u32; 0]);
| ^^^^^^^^ has alignment larger than 1
This patch changes the report to include the alignment of the violating
field:
LL | struct Foobar(u32, [u32; 0]);
| ^^^^^^^^ has alignment of 4, which is larger than 1
In case of unknown alignments, it will yield:
LL | struct Foobar<T>(u32, [T; 0]);
| ^^^^^^ may have alignment larger than 1
This allows developers to get a better grasp why a specific field is
rejected. Knowing the alignment of the violating field makes it easier
to judge where that alignment-requirement originates, and thus hopefully
provide better hints on how to mitigate the problem.
This idea was proposed in 2022 in #98071 as part of a bigger change.
This commit simply extracts this error-message change, to decouple it
from the other diagnostic improvements.
Support `--print KIND=PATH` command line syntax
As is already done for `--emit KIND=PATH` and `-L KIND=PATH`.
In the discussion of #110785, it was pointed out that `--print KIND=PATH` is nicer than trying to apply the single global `-o` path to `--print`'s output, because in general there can be multiple print requests within a single rustc invocation, and anyway `-o` would already be used for a different meaning in the case of `link-args` and `native-static-libs`.
I am interested in using `--print cfg=PATH` in Buck2. Currently Buck2 works around the lack of support for `--print KIND=PATH` by [indirecting through a Python wrapper script](d43cf3a51a/prelude/rust/tools/get_rustc_cfg.py) to redirect rustc's stdout into the location dictated by the build system.
From skimming Cargo's usages of `--print`, it definitely seems like it would benefit from `--print KIND=PATH` too. Currently it is working around the lack of this by inserting `--crate-name=___ --print=crate-name` so that it can look for a line containing `___` as a delimiter between the 2 other `--print` informations it actually cares about. This is commented as a "HACK" and "abuse". 31eda6f7c3/src/cargo/core/compiler/build_context/target_info.rs (L242) (FYI `@weihanglo` as you dealt with this recently in https://github.com/rust-lang/cargo/pull/11633.)
Mentioning reviewers active in #110785: `@fee1-dead` `@jyn514` `@bjorn3`
THis significantly complicates `NaiveLayout` logic, but is necessary to
ensure that bounds like `NonNull<T>: PointerLike` hold in generic
contexts.
Also implement exact layout computation for structs.
Refactor vtable encoding and optimize it for the case of multiple marker traits
This PR does two things
- Refactor `prepare_vtable_segments` (this was motivated by the other change, `prepare_vtable_segments` was quite hard to understand and while trying to edit it I've refactored it)
- Mostly remove `loop`s labeled `break`s/`continue`s whenever there is a simpler solution
- Also use `?`
- Make vtable format a bit more efficient wrt to marker traits
- See the tests for an example
Fixes https://github.com/rust-lang/rust/issues/113840
cc `@crlf0710`
----
Review wise it's probably best to review each commit individually, as then it's more clear why the refactoring is correct.
I can split the last two commits (which change behavior) into a separate PR if it makes reviewing easier
new solver: don't consider blanket impls multiple times
only consider candidates which rely on the self type in `assemble_candidates_after_normalizing_self_ty`.
r? ``@compiler-errors``
Verify that all crate sources are in sync
This ensures that rustc will not attempt to link against a cdylib as if it is a rust dylib when an rlib for the same crate is available. Previously rustc didn't actually check if any further formats of a crate which has been loaded are of the same version and if they are actually valid. This caused a cdylib to be interpreted as rust dylib as soon as the corresponding rlib was loaded. As cdylibs don't export any rust symbols, linking would fail if rustc decides to link against the cdylib rather than the rlib.
Two crates depended on the previous behavior by separately compiling a test crate as both rlib and dylib. These have been changed to capture their original spirit to the best of my ability while still working when rustc verifies that all crates are in sync. It is unlikely that build systems depend on the current behavior and in any case we are taking a lot of measures to ensure that any change to either the source or the compilation options (including crate type) results in rustc rejecting it as incompatible. We merely didn't do this check here for now obsolete perf reasons.
Fixes https://github.com/rust-lang/rust/issues/10786
Fixes https://github.com/rust-lang/rust/issues/82151
Fixes https://github.com/rust-lang/rust/issues/82972
Closes https://github.com/bevy-cheatbook/bevy-cheatbook/issues/114
Use the correct span for displaying the line following a derive sugge…
`span` here is the main span of the diagnostic. In the linked issue's case, this belongs to `main.rs`. However, the line numbers (and line we are trying to display) are in `name.rs`, so using `span_to_lines` gives us the wrong `FileLines`.
Use `parts[0].span` (the span of the suggestion) here like the rest of the code does to get the right file.
Not sure if this needs a dedicated test because this fixes an existing error in the UI suite
Fixes#113844
Fix inline_const with interpolated block
Interpolation already worked when we had a `const $block` that wasn't a statement expr:
```
fn foo() {
let _ = const $block;
}
```
But it was failing when the const block was in statement expr position:
```
fn foo() {
const $block;
}
```
... because of a bug in a check for const items. This fixes that.
---
cc https://github.com/rust-lang/rust/pull/112953#issuecomment-1631354481, though I don't think this requires an FCP since it's already supported in exprs and seems to me to be fully a parser bug.
Consider `()` within types to be FFI-safe, and `()` to be FFI-safe as a
return type (incl. when in a transparent newtype).
Signed-off-by: David Wood <david@davidtw.co>
`()` is normally FFI-unsafe, but is FFI-safe when used as a return type.
It is also desirable that a transparent newtype for `()` is FFI-safe when
used as a return type.
In order to support this, when an type was deemed FFI-unsafe, because of
a `()` type, and was used in return type - then the type was considered
FFI-safe. However, this was the wrong approach - it didn't check that the
`()` was part of a transparent newtype! The consequence of this is that
the presence of a `()` type in a more complex return type would make it
the entire type be considered safe (as long as the `()` type was the
first that the lint found) - which is obviously incorrect.
Instead, this logic is removed, and a unit return type or a transparent
wrapper around a unit is checked for directly for functions and fn-ptrs.
Signed-off-by: David Wood <david@davidtw.co>
Better diagnostics for dlltool errors.
When dlltool fails, show the full command that was executed. In particular, llvm-dlltool is not very helpful, printing a generic usage message rather than what actually went wrong, so stdout and stderr aren't of much use when troubleshooting.
allow opaques to be defined by trait queries, again
This basically reverts #112963.
Moreover, all call-sites of `enter_canonical_trait_query` can now define opaque types, see the ui test `defined-by-user-annotation.rs`.
Fixes#113689
r? `@compiler-errors` `@oli-obk`