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`
Restrict recursive opaque type check
We have a recursive opaque check in writeback to avoid inferring the hidden of an opaque type to be itself:
33a2c2487a/compiler/rustc_hir_typeck/src/writeback.rs (L556-L575)
Issue #113619 treats `make_option2` as not defining the TAIT `TestImpl` since it is inferred to have the definition `TestImpl := B<TestImpl>`, which fails this check. This regressed in #102700 (5d15beb591), I think due to the refactoring that made us record the hidden types of TAITs during writeback.
However, nothing actually seems to go bad if we relax this recursion checker to only check for directly recursive definitions. This PR fixes#113619 by changing this recursive check from being a visitor to just checking that the hidden type is exactly the same as the opaque being inferred.
Alternatively, we may be able to fix#113619 by restricting this recursion check only to RPITs/async fns. It seems to only be possible to use misuse the recursion check to cause ICEs for TAITs (though I didn't try too hard to create a bad RPIT example... may be possible, actually.)
r? `@oli-obk`
--
Fixes#113314
Fix removal span calculation of `unused_qualifications` suggestion
Given a path such as `std::ops::Index<str>`, calculate the unnecessary qualification removal span by computing the beginning of the entire span until the ident span of the last path segment, which handles generic arguments and lifetime arguments in the last path segment. Previous logic only kept the ident span of the last path segment which is incorrect.
Closes#113808.
Safe Transmute: Fix ICE (due to UnevaluatedConst)
This patch updates the code that looks at the `Assume` type when evaluating if transmutation is possible. An ICE was being triggered in the case that the `Assume` parameter contained an unevaluated const (in this test case, due to a function with missing parameter names).
Fixes#110892
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.
miri: fail when calling a function that requires an unavailable target feature
miri will report an UB when calling a function that has a `#[target_feature(enable = ...)]` attribute is called and the required feature is not available.
"Available features" are the same that `is_x86_feature_detected!` (or equivalent) reports to be available during miri execution (which can be enabled or disabled with the `-C target-feature` flag).
This patch updates the code that looks at the `Assume` type when evaluating if
transmutation is possible. An ICE was being triggered in the case that the
`Assume` parameter contained an unevaluated const (in this test case, due to a
function with missing parameter names).
Fixes#110892
Generate safe stable code for derives on empty enums
Generate `match *self {}` instead of `unsafe { core::intrinsics::unreachable() }`.
This is:
1. safe
2. stable
for the benefit of everyone looking at these derived impls through `cargo expand`.
[Both expansions compile to the same code at all optimization levels (including `0`).](https://rust.godbolt.org/z/P79joGMh3)
Add support for inherent projections in new solver
Not hard to support these, and it cuts out a really big chunk of failing UI tests with `--compare-mode=next-solver`
r? `@lcnr` (feel free to reassign, anyone can review this)
Generate `match *self {}` instead of `unsafe { core::intrinsics::unreachable() }`.
This is:
1. safe
2. stable
for the benefit of everyone looking at these derived impls through `cargo expand`.
Both expansions compile to the same code at all optimization levels (including `0`).
Don't call `predicate_must_hold`-esque functions during fulfillment in intercrate
Fixes#113415
Given that this only happens in `translate_substs`, I don't actually think that this is something that you can weaponize, but it's still sketchy regardless.
r? `@lcnr`
Check entry type as part of item type checking.
This code is currently executed inside the root `analysis` query.
Instead, check it during `check_for_entry_fn(CRATE_DEF_ID)` to hopefully avoid some re-executions.
`CRATE_DEF_ID` is chosen by considering that entry fn are typically at crate root, so the corresponding HIR should already be in the dependencies.
Add `#[rustc_confusables]` attribute to allow targeted "no method" error suggestions on standard library types
After this PR, the standard library developer can annotate methods on e.g. `BTreeSet::push` with `#[rustc_confusables("insert")]`. When the user mistypes `btreeset.push()`, `BTreeSet::insert` will be suggested if there are no other candidates to suggest. This PR lays the foundations for contributors to add `rustc_confusables` annotations to standard library types for targeted suggestions, as specified in #59450, or to address cases such as #108437.
### Example
Assume `BTreeSet` is the standard library type:
```
// Standard library definition
#![feature(rustc_attrs)]
struct BTreeSet;
impl BTreeSet {
#[rustc_confusables("push")]
fn insert(&self) {}
}
// User code
fn main() {
let x = BTreeSet {};
x.push();
}
```
A new suggestion (which has lower precedence than suggestions for misspellings and only is shown when there are no misspellings suggestions) will be added to hint the user maybe they intended to write `x.insert()` instead:
```
error[E0599]: no method named `push` found for struct `BTreeSet` in the current scope
--> test.rs:12:7
|
3 | struct BTreeSet;
| --------------- method `push` not found for this struct
...
12 | x.push();
| ^^^^ method not found in `BTreeSet`
|
help: you might have meant to use `insert`
|
12 | x.insert();
| ~~~~~~
error: aborting due to previous error
```
Hide `compiler_builtins` in the prelude
This crate is a private implementation detail. We only need to insert it into the crate graph for linking and should not expose any of its public API.
Fixes#113533
"no method" errors on standard library types
The standard library developer can annotate methods on e.g.
`BTreeSet::push` with `#[rustc_confusables("insert")]`. When the user
mistypes `btreeset.push()`, `BTreeSet::insert` will be suggested if
there are no other candidates to suggest.
Implement "items do not inherit unsafety" note for THIR unsafeck
Implements the "items do not inherit unsafety from separate enclosing items" note from the MIR unsafety checker in the THIR unsafety checker (`-Z thir-unsafeck`) to maintain parity between the two unsafety checkers. The logic to find the separate enclosing item is nearly the same as in the MIR unsafety checker.
Structurally normalize in selection
We need to do this because of the fact that we're checking the `Ty::kind` on a type during selection, but goals passed into select are not necessarily normalized.
Right now, we're (kinda) unnecessarily normalizing the RHS of a trait upcasting goal, which is broken for different reasons (#113393). But I'm waiting for this PR to land before discussing that one.
r? `@lcnr`
Resurrect: rustc_target: Add alignment to indirectly-passed by-value types, correcting the alignment of byval on x86 in the process.
Same as #111551, which I [accidentally closed](https://github.com/rust-lang/rust/pull/111551#issuecomment-1571222612) :/
---
This resurrects PR #103830, which has sat idle for a while.
Beyond #103830, this also:
- fixes byval alignment for types containing vectors on Darwin (see `tests/codegen/align-byval-vector.rs`)
- fixes byval alignment for overaligned types on x86 Windows (see `tests/codegen/align-byval.rs`)
- fixes ABI for types with 128bit requested alignment on ARM64 Linux (see `tests/codegen/aarch64-struct-align-128.rs`)
r? `@nikic`
---
`@pcwalton's` original PR description is reproduced below:
Commit 88e4d2c from five years ago removed
support for alignment on indirectly-passed arguments because of problems with
the `i686-pc-windows-msvc` target. Unfortunately, the `memcpy` optimizations I
recently added to LLVM 16 depend on this to forward `memcpy`s. This commit
attempts to fix the problems with `byval` parameters on that target and now
correctly adds the `align` attribute.
The problem is summarized in [this comment] by `@eddyb.` Briefly, 32-bit x86 has
special alignment rules for `byval` parameters: for the most part, their
alignment is forced to 4. This is not well-documented anywhere but in the Clang
source. I looked at the logic in Clang `TargetInfo.cpp` and tried to replicate
it here. The relevant methods in that file are
`X86_32ABIInfo::getIndirectResult()` and
`X86_32ABIInfo::getTypeStackAlignInBytes()`. The `align` parameter attribute
for `byval` parameters in LLVM must match the platform ABI, or miscompilations
will occur. Note that this doesn't use the approach suggested by eddyb, because
I felt it was overkill to store the alignment in `on_stack` when special
handling is really only needed for 32-bit x86.
As a side effect, this should fix#80127, because it will make the `align`
parameter attribute for `byval` parameters match the platform ABI on LLVM
x86-64.
[this comment]: #80822 (comment)
Allow escaping bound vars during `normalize_erasing_regions` in new solver
Add `AllowEscapingBoundVars` to `deeply_normalize`, and use it in the new solver in the `query_normalize` routine.
Ideally, we'd make all `query_normalize` calls handle pass in `AllowEscapingBoundVars` individually, because really the only `query_normalize` call that needs `AllowEscapingBoundVars::Yes` is the one in `try_normalize_generic_arg_after_erasing_regions`, but I think that's kind of overkill. I am happy to be convinced otherwise, though.
r? `@lcnr`
Use maybe_body_owned_by for multiple suggestions
This is a continued work from https://github.com/rust-lang/rust/pull/113567
We have several other suggestions not working for closure, this PR use `maybe_body_owned_by` to fix them and add test cases for them.
This crate is a private implementation detail. We only need to insert it
into the crate graph for linking and should not expose any of its public
API.
Fixes#113533
Eliminate ZST allocations in `Box` and `Vec`
This PR fixes 2 issues with `Box` and `RawVec` related to ZST allocations. Specifically, the `Allocator` trait requires that:
- If you allocate a zero-sized layout then you must later deallocate it, otherwise the allocator may leak memory.
- You cannot pass a ZST pointer to the allocator that you haven't previously allocated.
These restrictions exist because an allocator implementation is allowed to allocate non-zero amounts of memory for a zero-sized allocation. For example, `malloc` in libc does this.
Currently, ZSTs are handled differently in `Box` and `Vec`:
- `Vec` never allocates when `T` is a ZST or if the vector capacity is 0.
- `Box` just blindly passes everything on to the allocator, including ZSTs.
This causes problems due to the free conversions between `Box<[T]>` and `Vec<T>`, specifically that ZST allocations could get leaked or a dangling pointer could be passed to `deallocate`.
This PR fixes this by changing `Box` to not allocate for zero-sized values and slices. It also fixes a bug in `RawVec::shrink` where shrinking to a size of zero did not actually free the backing memory.
Implement selection for `Unsize` for better coercion behavior
In order for much of coercion to succeed, we need to be able to deal with partial ambiguity of `Unsize` traits during selection. However, I pessimistically implemented selection in the new trait solver to just bail out with ambiguity if it was a built-in impl:
9227ff28af/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs (L126)
This implements a proper "rematch" procedure for dealing with built-in `Unsize` goals, so that even if the goal is ambiguous, we are able to get nested obligations which are used in the coercion selection-like loop:
9227ff28af/compiler/rustc_hir_typeck/src/coercion.rs (L702)
Second commit just moves a `resolve_vars_if_possible` call to fix a bug where we weren't detecting a trait upcasting to occur.
r? ``@lcnr``
(re-)tighten sourceinfo span of adjustments in MIR
Diagnostics rely on the spans of MIR statements being (approximately) correct in order to give suggestions relative to that span (i.e. `shrink_to_hi` and `shrink_to_lo`).
I discovered that we're *intentionally* lowering THIR exprs with their parent expr's span if they come from adjustments that are due to a parent expression. While I understand why that may be desirable to demonstrate the relationship of an adjustment and the expression that requires it, it leads to
1. very verbose borrowck output
2. incorrect spans for suggestions
Some diagnostics get around that by giving suggestions relative to other spans we've collected during MIR lowering, such as the span of the method's identifier (e.g. `name` in `.name()`), but this doesn't work too well when things come from desugaring.
I assume it also has lead to numerous tweaks and complications to diagnostics code down the road, which this PR doesn't necessarily aim to fix but may open the gates to fixing later... The last three commits are simplifications due to the fact that we can assume that the move span actually points to what is being moved (and a test).
This regressed in #89110, which was debated somewhat in #90286. cc `@Aaron1011` who originally made this change.
r? diagnostics
Fixes#113547Fixes#111016
Rollup of 4 pull requests
Successful merges:
- #112717 (Implement a few more rvalue translation to smir)
- #113310 (Don't suggest `impl Trait` in path position)
- #113497 (Support explicit 32-bit MIPS ABI for the synthetic object)
- #113560 (Lint against misplaced where-clauses on associated types in traits)
r? `@ghost`
`@rustbot` modify labels: rollup
Lint against misplaced where-clauses on associated types in traits
Extends the scope of the lint `deprecated_where_clause_location` (#89122) from associated types in impls to associated types in any location (impl or trait). This is only relevant for `#![feature(associated_type_defaults)]`. Previously we didn't warn on the following code for example:
```rs
#![feature(associated_type_defaults)]
trait Trait { type Assoc where u32: Copy = (); }
```
Personally I would've preferred to emit a *hard* error here instead of a lint warning since the feature is unstable but unfortunately we are constrained by back compat as associated type defaults won't necessarily trigger the feature-gate error if they are inside of a macro call (since they use a post-expansion feature-gate due to historical reasons, see also #66004).
I've renamed and moved related preexisting tests: 1. They test AST validation passes not the parser & thus shouldn't live in `parser/` (historical reasons?). 2. One test file was named after type aliases even though it tests assoc tys.
`@rustbot` label A-lint
Structurally resolve in pattern matching when peeling refs in new solver
Let me know if you want me to commit the minimized test:
```rust
fn test() {}
fn test2() {}
fn main() {
let tests: &[(_, fn())] = &[
("test", test),
("test2", test2),
];
for (a, b) in tests {
todo!();
}
}
```
In that test above, the match scrutinee is `<std::vec::Iter<(&'static str, fn())> as Iterator>::Item`, which we cannot peel the refs from.
We also need to structurally resolve in the loop, since structural resolve is inherently shallow. I haven't come up with a test where this matters, but I can if you care.
Also, I removed two other calls to `resolve_vars_with_obligations` in diagnostics code that I'm pretty convinced are not useful.
r? `@lcnr`
Enable coinduction support for Safe Transmute
This patch adds the `#[rustc_coinductive]` annotation to `BikeshedIntrinsicFrom`, so that it's possible to compute transmutability for recursive types.
## Motivation
Safe Transmute currently already supports references (#110662). However, if a type is implemented recursively, it leads to an infinite loop when we try to check if transmutation is safe.
A couple simple examples that one might want to write, that are currently not possible to check transmutability for:
```rs
#[repr(C)] struct A(&'static B);
#[repr(C)] struct B(&'static A);
```
```rs
#[repr(C)]
enum IList<'a> { Nil, Cons(isize, &'a IList<'a>) }
#[repr(C)]
enum UList<'a> { Nil, Cons(usize, &'a UList<'a>) }
```
Previously, `@jswrenn` was considering writing a co-inductive solver from scratch, just for the `rustc_tranmsute` crate. Later on as I started working on Safe Transmute myself, I came across the `#[rustc_coinductive]` annotation, which is currently only being used for the `Sized` trait. Leveraging this trait actually solved the problem entirely, and it saves a lot of duplicate work that would have had to happen in `rustc_transmute`.
Uplift `clippy::fn_null_check` lint
This PR aims at uplifting the `clippy::fn_null_check` lint into rustc.
## `incorrect_fn_null_checks`
(warn-by-default)
The `incorrect_fn_null_checks` lint checks for expression that checks if a function pointer is null.
### Example
```rust
let fn_ptr: fn() = /* somehow obtained nullable function pointer */
if (fn_ptr as *const ()).is_null() { /* ... */ }
```
### Explanation
Function pointers are assumed to be non-null, checking for their nullity is incorrect.
-----
Mostly followed the instructions for uplifting a clippy lint described here: https://github.com/rust-lang/rust/pull/99696#pullrequestreview-1134072751
`@rustbot` label: +I-lang-nominated
r? compiler
Replace RPITIT current impl with new strategy that lowers as a GAT
This PR replaces the current implementation of RPITITs with the new implementation that we had under -Zlower-impl-trait-in-trait-to-assoc-ty flag that lowers the RPIT as a GAT on the trait and on the impls that implement that trait.
Opening this PR as a draft because this goes after #112682, ~#112981~ and ~#112983~.
As soon as those are merged, I can rebase and we should run perf, crater and test a lot.
r? `@compiler-errors`
Add filter with following segment while lookup typo for path
From the discussion: https://github.com/rust-lang/rust/pull/112917#discussion_r1239150173
Seems we can not get the assoc items for `Struct`, `Enum` in the resolving phase.
A obvious filter is avoid suggesting the same name with the following segment path.
Use `following_seg` can extend the function `smart_resolve_partial_mod_path_errors` for more scenarios, such as `std::sync_error::atomic::AtomicBool` in test case.
r? `@estebank`
Don't call `query_normalize` when reporting similar impls
Firstly, It's sketchy to be using `query_normalize` at all during HIR typeck -- it's asking for an ICE 😅. Secondly, we're normalizing an impl trait ref that potentially has parameter types in `ty::ParamEnv::empty()`, which is kinda sketchy as well.
The only UI test change from removing this normalization is that we don't evaluate anonymous constants in impls, which end up giving us really ugly suggestions:
```
error[E0277]: the trait bound `[X; 35]: Default` is not satisfied
--> /home/gh-compiler-errors/test.rs:4:5
|
4 | <[X; 35] as Default>::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `[X; 35]`
|
= help: the following other types implement trait `Default`:
&[T]
&mut [T]
[T; 32]
[T; core::::array::{impl#30}::{constant#0}]
[T; core::::array::{impl#31}::{constant#0}]
[T; core::::array::{impl#32}::{constant#0}]
[T; core::::array::{impl#33}::{constant#0}]
[T; core::::array::{impl#34}::{constant#0}]
and 27 others
```
So just fold the impls with a `BottomUpFolder` that calls `ty::Const::eval`. This doesn't work totally correctly with generic-const-exprs, but it's fine for stable code, and this is error reporting after all.
Structurally normalize again for byte string lit pat checking
We need to structurally normalize the pointee of a match scrutinee when trying to match byte string patterns -- we used[^1] to call `structurally_resolve_type`, which errors for type vars[^2], but lcnr added `try_structurally_resolve_type`[^3] in the mean time, which is the right thing to use here since it's totally opportunistic.
Fixes rust-lang/trait-system-refactor-initiative#38
[^1]: #112428
[^2]: #112993
[^3]: #113086
Reveal opaques in new solver
We were testing against the wrong reveal mode 😨
Also a couple of misc commits that I don't want to really put in separate prs
r? ``@lcnr``
tests: unset `RUSTC_LOG_COLOR` in a test
Setting `RUSTC_LOG_COLOR=always` is sometimes useful if tools that one pipes `RUSTC_LOG` into support coloured output, but it makes this test fail because it has a `.stderr` file with `WARN` log output.
Rollup of 8 pull requests
Successful merges:
- #113413 (Add needs-triage to all new issues)
- #113426 (Don't ICE in `resolve_bound_vars` when associated return-type bounds are in bad positions)
- #113427 (Remove `variances_of` on RPITIT GATs, remove its one use-case)
- #113441 (miri: check that assignments do not self-overlap)
- #113453 (Remove unused from_method from rustc_on_unimplemented)
- #113456 (Avoid calling report_forbidden_specialization for RPITITs)
- #113466 (Update cargo)
- #113467 (Fix comment of `fn_can_unwind`)
r? `@ghost`
`@rustbot` modify labels: rollup
Remove unused from_method from rustc_on_unimplemented
Fixes#113439
`on_unimplemented_note` was calling `item_name` for RPITITs and that produced ICEs. I've added a regression test for that but also have removed `from_method` symbol entirely because it wasn't even used and by doing that the `item_name` call was also removed.
r? ``@compiler-errors``
Do not assert >1 RPITITs on collect_return_position_impl_trait_in_trait_tys
Fixes#113403
Assert on collect_return_position_impl_trait_in_trait_tys is not correct when we call it from type_of(GAT). The included test is an example of a situation that collector collects 0 types.
r? `@compiler-errors`
Prefer object candidates in new selection
`dyn Any` shouldn't be using [this implementation](https://doc.rust-lang.org/std/any/trait.Any.html#impl-Any-for-T) during codegen.
Prefer object candidates over other candidates, except for other object candidates.
Revert "alloc: Allow comparing Boxs over different allocators", add regression test
Temporary fix for #113283
Adds a test to fix the regression introduced in 001b081cc1 and revert that commit. The test fails without the revert.
Dont ICE for `dyn* Trait: Trait` (built-in object) goals during selection in new trait solver
We were ICEing too eagerly during selection for `dyn*` goals -- both for dyn unsizing candidates and for built-in object candidates. The former should only be performed on `dyn` objects, but the latter are totally fine.
Revert the lexing of `c"…"` string literals
Fixes \[after beta-backport\] #113235.
Further progress is tracked in #113333.
This PR *manually* reverts parts of #108801 (since a git-revert would've been too coarse-grained & messy)
and git-reverts #111647.
CC `@fee1-dead` (#108801) `@klensy` (#111647)
r? `@compiler-errors`
`@rustbot` label F-c_str_literals beta-nominated
Rollup of 8 pull requests
Successful merges:
- #113010 (rust-installer & rls: remove exclusion from rustfmt & tidy )
- #113317 ( -Ztrait-solver=next: stop depending on old solver)
- #113319 (`TypeParameterDefinition` always require a `DefId`)
- #113320 (Add some extra information to opaque type cycle errors)
- #113321 (Move `ty::ConstKind` to `rustc_type_ir`)
- #113337 (Winnow specialized impls during selection in new solver)
- #113355 (Move most coverage code out of `rustc_codegen_ssa`)
- #113356 (Add support for NetBSD/riscv64 aka. riscv64gc-unknown-netbsd.)
r? `@ghost`
`@rustbot` modify labels: rollup
Winnow specialized impls during selection in new solver
We need to be able to winnow impls that are specialized by more specific impls in order for codegen to be able to proceed.
r? ``@lcnr``
Add some extra information to opaque type cycle errors
Plus a bunch of cleanups.
This should help users debug query cycles due to auto trait checking. We'll probably want to fix cycle errors in most (or all?) cases by looking at the current item's hidden types (new solver does this), and by delaying the auto trait checks to after typeck.
Effects/keyword generics MVP
This adds `feature(effects)`, which adds `const host: bool` to the generics of const functions, const traits and const impls. This will be used to replace the current logic around const traits.
r? `@oli-obk`
implement `ConstEvaluatable` goals in new solver
this only supports stable const generics. `feature(generic_const_exprs)` needs to extend that function is non-trivial ways. Leaving this for someone else or some later date.
r? `@BoxyUwU`