Commit Graph

7309 Commits

Author SHA1 Message Date
bors
cdd4ff8d81 Auto merge of #120367 - RalfJung:project_downcast_uninhabited, r=oli-obk
interpret: project_downcast: do not ICE for uninhabited variants

Fixes https://github.com/rust-lang/rust/issues/120337

This assertion was already under discussion for a bit; I think the [example](https://github.com/rust-lang/rust/issues/120337#issuecomment-1911076292) `@tmiasko` found is the final nail in the coffin. One could argue maybe MIR building should read the discriminant before projecting, but even then MIR optimizations should be allowed to remove that read, so the downcast should still not ICE. Maybe the downcast should be UB, but in this example UB already arises earlier when a value of type `E` is constructed.

r? `@oli-obk`
2024-01-26 12:50:02 +00:00
Ralf Jung
64cd13ff3b add test for GVN issue; cleanup in dataflow_const_prop 2024-01-26 10:40:29 +01:00
Ralf Jung
1025a12b64 interpret: project_downcast: do not ICE for uninhabited variants 2024-01-26 09:01:56 +01:00
Matthias Krüger
e400311486
Rollup merge of #120322 - compiler-errors:higher-ranked-async-closures, r=oli-obk
Don't manually resolve async closures in `rustc_resolve`

There's a comment here that talks about doing this "[so] closure [args] are detected as upvars rather than normal closure arg usages", but we do upvar analysis on the HIR now:

cd6d8f2a04/compiler/rustc_passes/src/upvars.rs (L21-L29)

Removing this ad-hoc logic makes it so that `async |x: &str|` now introduces an implicit binder, like regular closures.

r? ```@oli-obk```
2024-01-26 06:36:39 +01:00
Matthias Krüger
e04cba2724
Rollup merge of #120124 - nikic:fix-assembly-test, r=davidtwco
Split assembly tests for ELF and MachO

On ELF, the text section is opened with ".text", on MachO with ".section __TEXT,__text".

Previously, on ELF this test was actually matching a GNU note section, which is no longer emitted on Solaris starting with LLVM 18.

Fixes https://github.com/rust-lang/rust/issues/120105.

r? ```@davidtwco```
2024-01-26 06:36:38 +01:00
Matthias Krüger
a37fa37281
Rollup merge of #118803 - Nadrieril:min-exhaustive-patterns, r=compiler-errors
Add the `min_exhaustive_patterns` feature gate

## Motivation

Pattern-matching on empty types is tricky around unsafe code. For that reason, current stable rust conservatively requires arms for empty types in all but the simplest case. It has long been the intention to allow omitting empty arms when it's safe to do so. The [`exhaustive_patterns`](https://github.com/rust-lang/rust/issues/51085) feature allows the omission of all empty arms, but hasn't been stabilized because that was deemed dangerous around unsafe code.

## Proposal

This feature aims to stabilize an uncontroversial subset of exhaustive_patterns. Namely: when `min_exhaustive_patterns` is enabled and the data we're matching on is guaranteed to be valid by rust's operational semantics, then we allow empty arms to be omitted. E.g.:

```rust
let x: Result<T, !> = foo();
match x { // ok
    Ok(y) => ...,
}
let Ok(y) = x; // ok
```

If the place is not guaranteed to hold valid data (namely ptr dereferences, ref dereferences (conservatively) and union field accesses), then we keep stable behavior i.e. we (usually) require arms for the empty cases.

```rust
unsafe {
    let ptr: *const Result<u32, !> = ...;
    match *ptr {
        Ok(x) => { ... }
        Err(_) => { ... } // still required
    }
}
let foo: Result<u32, &!> = ...;
match foo {
    Ok(x) => { ... }
    Err(&_) => { ... } // still required because of the dereference
}
unsafe {
    let ptr: *const ! = ...;
    match *ptr {} // already allowed on stable
}
```

Note that we conservatively consider that a valid reference can point to invalid data, hence we don't allow arms of type `&!` and similar cases to be omitted. This could eventually change depending on [opsem decisions](https://github.com/rust-lang/unsafe-code-guidelines/issues/413). Whenever opsem is undecided on a case, we conservatively keep today's stable behavior.

I proposed this behavior in the [`never_patterns`](https://github.com/rust-lang/rust/issues/118155) feature gate but it makes sense on its own and could be stabilized more quickly. The two proposals nicely complement each other.

## Unresolved Questions

Part of the question is whether this requires an RFC. I'd argue this doesn't need one since there is no design question beyond the intent to omit unreachable patterns, but I'm aware the problem can be framed in ways that require design (I'm thinking of the [original never patterns proposal](https://smallcultfollowing.com/babysteps/blog/2018/08/13/never-patterns-exhaustive-matching-and-uninhabited-types-oh-my/), which would frame this behavior as "auto-nevering" happening).

EDIT: I initially proposed a future-compatibility lint as part of this feature, I don't anymore.
2024-01-26 06:36:36 +01:00
bors
dd2559e08e Auto merge of #116167 - RalfJung:structural-eq, r=lcnr
remove StructuralEq trait

The documentation given for the trait is outdated: *all* function pointers implement `PartialEq` and `Eq` these days. So the `StructuralEq` trait doesn't really seem to have any reason to exist any more.

One side-effect of this PR is that we allow matching on some consts that do not implement `Eq`. However, we already allowed matching on floats and consts containing floats, so this is not new, it is just allowed in more cases now. IMO it makes no sense at all to allow float matching but also sometimes require an `Eq` instance. If we want to require `Eq` we should adjust https://github.com/rust-lang/rust/pull/115893 to check for `Eq`, and rule out float matching for good.

Fixes https://github.com/rust-lang/rust/issues/115881
2024-01-26 00:17:00 +00:00
Matthias Krüger
4bca954634
Rollup merge of #120330 - compiler-errors:no-coroutine-info-in-coroutine-drop-body, r=nnethercote
Remove coroutine info when building coroutine drop body

Coroutine drop shims are not themselves coroutines, so erase the "`coroutine`" field from the body so that helper fns like `yield_ty` and `coroutine_kind` properly return `None` for the drop shim.
2024-01-25 17:39:29 +01:00
Matthias Krüger
8750bec42a
Rollup merge of #120306 - safinaskar:clone3-clean-up, r=petrochenkov
Clean up after clone3 removal from pidfd code (docs and tests)

https://github.com/rust-lang/rust/pull/113939 removed clone3 from pidfd code. This patchset does necessary clean up: fixes docs and tests
2024-01-25 17:39:28 +01:00
Nikita Popov
8866449c66 Split assembly tests for ELF and MachO
On ELF, the text section is opened with ".text", on MachO with
".section __TEXT,__text".

Previously, on ELF this test was actually matching a GNU note
section, which is no longer emitted on Solaris starting with
LLVM 18.

Fixes https://github.com/rust-lang/rust/issues/120105.
2024-01-25 16:17:35 +01:00
Matthias Krüger
0cbef470d5
Rollup merge of #120315 - estebank:issue-102629-2, r=wesleywiser
On E0308 involving `dyn Trait`, mention trait objects

When encountering a type mismatch error involving `dyn Trait`, mention the existence of boxed trait objects if the other type involved implements `Trait`.

Fix #102629.
2024-01-25 08:39:44 +01:00
Matthias Krüger
0c45e3c7dd
Rollup merge of #119895 - oli-obk:track_errors_3, r=matthewjasper
Remove `track_errors` entirely

follow up to https://github.com/rust-lang/rust/pull/119869

r? `@matthewjasper`

There are some diagnostic changes adding new diagnostics or not emitting some anymore. We can improve upon that in follow-up work imo.
2024-01-25 08:39:42 +01:00
Matthias Krüger
fd92d88c28
Rollup merge of #119389 - estebank:issue-116925, r=TaKO8Ki
Provide more context on recursive `impl` evaluation overflow

When an associated type `Self::Assoc` is part of a `where` clause, we end up unable to evaluate the requirement and emit a E0275.

We now point at the associated type if specified in the `impl`. If so, we also suggest using that type instead of `Self::Assoc`. Otherwise, we explain that these are not allowed.

```
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
  --> $DIR/impl-wf-cycle-1.rs:15:1
   |
LL | / impl<T: Grault> Grault for (T,)
LL | |
LL | | where
LL | |     Self::A: Baz,
LL | |     Self::B: Fiz,
   | |_________________^
LL |   {
LL |       type A = ();
   |       ------ associated type `<(T,) as Grault>::A` is specified here
   |
note: required for `(T,)` to implement `Grault`
  --> $DIR/impl-wf-cycle-1.rs:15:17
   |
LL | impl<T: Grault> Grault for (T,)
   |                 ^^^^^^     ^^^^
...
LL |     Self::A: Baz,
   |              --- unsatisfied trait bound introduced here
   = note: 1 redundant requirement hidden
   = note: required for `(T,)` to implement `Grault`
help: associated type for the current `impl` cannot be restricted in `where` clauses, remove this bound
   |
LL -     Self::A: Baz,
   |
```
```
error[E0275]: overflow evaluating the requirement `<T as B>::Type == <T as B>::Type`
  --> $DIR/impl-wf-cycle-3.rs:7:1
   |
LL | / impl<T> B for T
LL | | where
LL | |     T: A<Self::Type>,
   | |_____________________^
LL |   {
LL |       type Type = bool;
   |       --------- associated type `<T as B>::Type` is specified here
   |
note: required for `T` to implement `B`
  --> $DIR/impl-wf-cycle-3.rs:7:9
   |
LL | impl<T> B for T
   |         ^     ^
LL | where
LL |     T: A<Self::Type>,
   |        ------------- unsatisfied trait bound introduced here
help: replace the associated type with the type specified in this `impl`
   |
LL |     T: A<bool>,
   |          ~~~~
```
```
error[E0275]: overflow evaluating the requirement `<T as Filter>::ToMatch == <T as Filter>::ToMatch`
  --> $DIR/impl-wf-cycle-4.rs:5:1
   |
LL | / impl<T> Filter for T
LL | | where
LL | |     T: Fn(Self::ToMatch),
   | |_________________________^
   |
note: required for `T` to implement `Filter`
  --> $DIR/impl-wf-cycle-4.rs:5:9
   |
LL | impl<T> Filter for T
   |         ^^^^^^     ^
LL | where
LL |     T: Fn(Self::ToMatch),
   |        ----------------- unsatisfied trait bound introduced here
note: associated types for the current `impl` cannot be restricted in `where` clauses
  --> $DIR/impl-wf-cycle-4.rs:7:11
   |
LL |     T: Fn(Self::ToMatch),
   |           ^^^^^^^^^^^^^
```

Fix #116925
2024-01-25 08:39:41 +01:00
Matthias Krüger
8c6cf3c934
Rollup merge of #119305 - compiler-errors:async-fn-traits, r=oli-obk
Add `AsyncFn` family of traits

I'm proposing to add a new family of `async`hronous `Fn`-like traits to the standard library for experimentation purposes.

## Why do we need new traits?

On the user side, it is useful to be able to express `AsyncFn` trait bounds natively via the parenthesized sugar syntax, i.e. `x: impl AsyncFn(&str) -> String` when experimenting with async-closure code.

This also does not preclude `AsyncFn` becoming something else like a trait alias if a more fundamental desugaring (which can take many[^1] different[^2] forms) comes around. I think we should be able to play around with `AsyncFn` well before that, though.

I'm also not proposing stabilization of these trait names any time soon (we may even want to instead express them via new syntax, like `async Fn() -> ..`), but I also don't think we need to introduce an obtuse bikeshedding name, since `AsyncFn` just makes sense.

## The lending problem: why not add a more fundamental primitive of `LendingFn`/`LendingFnMut`?

Firstly, for `async` closures to be as flexible as possible, they must be allowed to return futures which borrow from the async closure's captures. This can be done by introducing `LendingFn`/`LendingFnMut` traits, or (equivalently) by adding a new generic associated type to `FnMut` which allows the return type to capture lifetimes from the `&mut self` argument of the trait. This was proposed in one of [Niko's blog posts](https://smallcultfollowing.com/babysteps/blog/2023/05/09/giving-lending-and-async-closures/).

Upon further experimentation, for the purposes of closure type- and borrow-checking, I've come to the conclusion that it's significantly harder to teach the compiler how to handle *general* lending closures which may borrow from their captures. This is, because unlike `Fn`/`FnMut`, the `LendingFn`/`LendingFnMut` traits don't form a simple "inheritance" hierarchy whose top trait is `FnOnce`.

```mermaid
flowchart LR
    Fn
    FnMut
    FnOnce
    LendingFn
    LendingFnMut

    Fn -- isa --> FnMut
    FnMut -- isa --> FnOnce

    LendingFn -- isa --> LendingFnMut

    Fn -- isa --> LendingFn
    FnMut -- isa --> LendingFnMut
```

For example:

```
fn main() {
  let s = String::from("hello, world");
  let f = move || &s;
  let x = f(); // This borrows `f` for some lifetime `'1` and returns `&'1 String`.
```

That trait hierarchy means that in general for "lending" closures, like `f` above, there's not really a meaningful return type for `<typeof(f) as FnOnce>::Output` -- it can't return `&'static str`, for example.

### Special-casing this problem:

By splitting out these traits manually, and making sure that each trait has its own associated future type, we side-step the issue of having to answer the questions of a general `LendingFn`/`LendingFnMut` implementation, since the compiler knows how to generate built-in implementations for first-class constructs like async closures, including the required future types for the (by-move) `AsyncFnOnce` and (by-ref) `AsyncFnMut`/`AsyncFn` trait implementations.

[^1]: For example, with trait transformers, we may eventually be able to write: `trait AsyncFn = async Fn;`
[^2]: For example, via the introduction of a more fundamental "`LendingFn`" trait, plus a [special desugaring with augmented trait aliases](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Lending.20closures.20and.20Fn*.28.29.20-.3E.20impl.20Trait/near/408471480).
2024-01-25 08:39:41 +01:00
bors
039d887928 Auto merge of #119911 - NCGThompson:is-statically-known, r=oli-obk
Replacement of #114390: Add new intrinsic `is_var_statically_known` and optimize pow for powers of two

This adds a new intrinsic `is_val_statically_known` that lowers to [``@llvm.is.constant.*`](https://llvm.org/docs/LangRef.html#llvm-is-constant-intrinsic).` It also applies the intrinsic in the int_pow methods to recognize and optimize the idiom `2isize.pow(x)`. See #114390 for more discussion.

While I have extended the scope of the power of two optimization from #114390, I haven't added any new uses for the intrinsic. That can be done in later pull requests.

Note: When testing or using the library, be sure to use `--stage 1` or higher. Otherwise, the intrinsic will be a noop and the doctests will be skipped. If you are trying out edits, you may be interested in [`--keep-stage 0`](https://rustc-dev-guide.rust-lang.org/building/suggested.html#faster-builds-with---keep-stage).

Fixes #47234
Resolves #114390
`@Centri3`
2024-01-25 05:16:53 +00:00
Michael Goulet
3004e8c44b Remove coroutine info when building coroutine drop body 2024-01-25 03:26:29 +00:00
bors
68411c9554 Auto merge of #119627 - oli-obk:const_prop_lint_n̵o̵n̵sense, r=cjgillot
Remove all ConstPropNonsense

We track all locals and projections on them ourselves within the const propagator and only use the InterpCx to actually do some low level operations or read from constants (via `OpTy` we get for said constants).

This helps moving the const prop lint out from the normal pipeline and running it just based on borrowck information. This in turn allows us to make progress on https://github.com/rust-lang/rust/pull/108730#issuecomment-1875557745

there are various follow up cleanups that can be done after this PR (e.g. not matching on Rvalue twice and doing binop checks twice), but lets try landing this one first.

r? `@RalfJung`
2024-01-25 03:16:07 +00:00
Nadrieril
95a14d43d7 Implement feature gate logic 2024-01-25 00:12:32 +01:00
Michael Goulet
8c2ae804e3 Don't manually resolve async closures in rustc_resolve 2024-01-24 20:48:07 +00:00
Esteban Küber
796814d916 Account for expected dyn Trait found impl Trait 2024-01-24 16:57:15 +00:00
Esteban Küber
d992d9cd56 On E0308 involving dyn Trait, mention trait objects
When encountering a type mismatch error involving `dyn Trait`, mention
the existence of boxed trait objects if the other type involved
implements `Trait`.

Partially addresses #102629.
2024-01-24 16:32:24 +00:00
León Orell Valerian Liehr
7403d5821a
Rollup merge of #120285 - est31:remove_extra_pound, r=fmease
Remove extra # from url in suggestion

The suggestion added in #119805 contains an unnecessary # hash sign.
2024-01-24 15:43:14 +01:00
León Orell Valerian Liehr
fee8f00024
Rollup merge of #120284 - petrochenkov:typrivisit2, r=oli-obk
privacy: Refactor top-level visiting in `TypePrivacyVisitor`

Full hierarchical visiting (`nested_filter::All`) is not necessary, visiting all item-likes in isolation is enough.
Tracking current item is not necessary, just keeping the current `mod` item is enough.
`visit_generic_arg` should behave like its default version, including checking types of const arguments.
Some comments, including FIXMEs, are also added.

Noticed while reading code to review https://github.com/rust-lang/rust/pull/113671.
r? ``@oli-obk``
2024-01-24 15:43:14 +01:00
León Orell Valerian Liehr
8290589f24
Rollup merge of #120265 - nikic:no-no-system-llvm, r=nagisa
Remove no-system-llvm

We currently have a bunch of codegen tests that use no-system-llvm -- however, all of those tests also pass with system LLVM 16.

I've opted to remove `no-system-llvm` entirely, as there's basically no valid use case for it anymore:

 * The only thing this option could have legitimately been used for (testing the target feature support that requires an LLVM patch) doesn't use it, and the need for this will go away with LLVM 18 anyway.
 * In cases where the test depends on optimizations/fixes from newer LLVM versions, `min-llvm-version` should be used instead.
 * In case it depends on optimization/fixes from newer LLVM versions that have been backported into our fork, `min-system-llvm-version` (with the major version larger than the one in our fork) should be used instead.

r? `````@cuviper`````
2024-01-24 15:43:13 +01:00
León Orell Valerian Liehr
8bd126cb18
Rollup merge of #120185 - Zalathar:auto-derived, r=wesleywiser
coverage: Don't instrument `#[automatically_derived]` functions

This PR makes the coverage instrumentor detect and skip functions that have [`#[automatically_derived]`](https://doc.rust-lang.org/reference/attributes/derive.html#the-automatically_derived-attribute) on their enclosing impl block.

Most notably, this means that methods generated by built-in derives (e.g. `Clone`, `Debug`, `PartialEq`) are now ignored by coverage instrumentation, and won't appear as executed or not-executed in coverage reports.

This is a noticeable change in user-visible behaviour, but overall I think it's a net improvement. For example, we've had a few user requests for this sort of change (e.g. #105055, https://github.com/rust-lang/rust/issues/84605#issuecomment-1902069040), and I believe it's the behaviour that most users will expect/prefer by default.

It's possible to imagine situations where users would want to instrument these derived implementations, but I think it's OK to treat that as an opportunity to consider adding more fine-grained option flags to control the details of coverage instrumentation, while leaving this new behaviour as the default.

(Also note that while `-Cinstrument-coverage` is a stable feature, the exact details of coverage instrumentation are allowed to change. So we *can* make this change; the main question is whether we *should*.)

Fixes #105055.
2024-01-24 15:43:12 +01:00
León Orell Valerian Liehr
e0a4f43903
Rollup merge of #119616 - rylev:wasm32-wasi-preview2, r=petrochenkov,m-ou-se
Add a new `wasm32-wasi-preview2` target

This is the initial implementation of the MCP https://github.com/rust-lang/compiler-team/issues/694 creating a new tier 3 target `wasm32-wasi-preview2`. That MCP has been seconded and will most likely be approved in a little over a week from now. For more information on the need for this target, please read the [MCP](https://github.com/rust-lang/compiler-team/issues/694).

There is one aspect of this PR that will become insta-stable once these changes reach a stable compiler:
* A new `target_family` named `wasi` is introduced. This target family incorporates all wasi targets including `wasm32-wasi` and its derivative `wasm32-wasi-preview1-threads`. The difference between `target_family = wasi` and `target_os = wasi` will become much clearer when `wasm32-wasi` is renamed to `wasm32-wasi-preview1` and the `target_os` becomes `wasm32-wasi-preview1`. You can read about this target rename in [this MCP](https://github.com/rust-lang/compiler-team/issues/695) which has also been seconded and will hopefully be officially approved soon.

Additional technical details include:
* Both `std::sys::wasi_preview2` and `std::os::wasi_preview2` have been created and mostly use `#[path]` annotations on their submodules to reach into the existing `wasi` (soon to be `wasi_preview1`) modules. Over time the differences between `wasi_preview1` and `wasi_preview2` will grow and most like all `#[path]` based module aliases will fall away.
* Building `wasi-preview2` relies on a [`wasi-sdk`](https://github.com/WebAssembly/wasi-sdk) in the same way that `wasi-preview1` does (one must include a `wasi-root` path in the `Config.toml` pointing to sysroot included in the wasi-sdk). The target should build against [wasi-sdk v21](https://github.com/WebAssembly/wasi-sdk/releases/tag/wasi-sdk-21) without modifications. However, the wasi-sdk itself is growing [preview2 support](https://github.com/WebAssembly/wasi-sdk/pull/370) so this might shift rapidly. We will be following along quickly to make sure that building the target remains possible as the wasi-sdk changes.
* This requires a [patch to libc](https://github.com/rylev/rust-libc/tree/wasm32-wasi-preview2) that we'll need to land in conjunction with this change. Until that patch lands the target won't actually build.
2024-01-24 15:43:12 +01:00
Askar Safin
1ee773e242 This commit is part of clone3 clean up. Merge tests from tests/ui/command/command-create-pidfd.rs
to library/std/src/sys/pal/unix/process/process_unix/tests.rs to remove code
duplication
2024-01-24 17:23:42 +03:00
Askar Safin
57f9d1f01a This commit is part of clone3 clean up. As part of clean up we will
remove tests/ui/command/command-create-pidfd.rs . But it contains
very useful comment, so let's move the comment to library/std/src/sys/pal/unix/rand.rs ,
which contains another instance of the same Docker problem
2024-01-24 15:22:00 +03:00
Ralf Jung
0df7810734 remove StructuralEq trait 2024-01-24 07:56:23 +01:00
est31
9676e18868 Remove extra # from url 2024-01-24 00:41:45 +01:00
bors
0b7730105f Auto merge of #120283 - fmease:rollup-rk0f6r5, r=fmease
Rollup of 9 pull requests

Successful merges:

 - #112806 (Small code improvements in `collect_intra_doc_links.rs`)
 - #119766 (Split tait and impl trait in assoc items logic)
 - #120139 (Do not normalize closure signature when building `FnOnce` shim)
 - #120160 (Manually implement derived `NonZero` traits.)
 - #120171 (Fix assume and assert in jump threading)
 - #120183 (Add `#[coverage(off)]` to closures introduced by `#[test]` and `#[bench]`)
 - #120195 (add several resolution test cases)
 - #120259 (Split Diagnostics for Uncommon Codepoints: Add List to Display Characters Involved)
 - #120261 (Provide structured suggestion to use trait objects in some cases of `if` arm type divergence)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-01-23 22:44:44 +00:00
Vadim Petrochenkov
ba75970473 privacy: Refactor top-level visiting in TypePrivacyVisitor 2024-01-24 00:42:01 +03:00
León Orell Valerian Liehr
3f2f8eee02
Rollup merge of #120261 - estebank:issue-102629, r=wesleywiser
Provide structured suggestion to use trait objects in some cases of `if` arm type divergence

```
error[E0308]: `if` and `else` have incompatible types
  --> $DIR/suggest-box-on-divergent-if-else-arms.rs:15:9
   |
LL |       let _ = if true {
   |  _____________-
LL | |         Struct
   | |         ------ expected because of this
LL | |     } else {
LL | |         foo()
   | |         ^^^^^ expected `Struct`, found `Box<dyn Trait>`
LL | |     };
   | |_____- `if` and `else` have incompatible types
   |
   = note: expected struct `Struct`
              found struct `Box<dyn Trait>`
help: `Struct` implements `Trait` so you can box it to coerce to the trait object `Box<dyn Trait>`
   |
LL |         Box::new(Struct)
   |         +++++++++      +

error[E0308]: `if` and `else` have incompatible types
  --> $DIR/suggest-box-on-divergent-if-else-arms.rs:20:9
   |
LL |       let _ = if true {
   |  _____________-
LL | |         foo()
   | |         ----- expected because of this
LL | |     } else {
LL | |         Struct
   | |         ^^^^^^ expected `Box<dyn Trait>`, found `Struct`
LL | |     };
   | |_____- `if` and `else` have incompatible types
   |
   = note: expected struct `Box<dyn Trait>`
              found struct `Struct`
   = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
help: store this in the heap by calling `Box::new`
   |
LL |         Box::new(Struct)
   |         +++++++++      +

error[E0308]: `if` and `else` have incompatible types
  --> $DIR/suggest-box-on-divergent-if-else-arms.rs:25:9
   |
LL |   fn bar() -> impl Trait {
   |               ---------- the found opaque type
...
LL |       let _ = if true {
   |  _____________-
LL | |         Struct
   | |         ------ expected because of this
LL | |     } else {
LL | |         bar()
   | |         ^^^^^ expected `Struct`, found opaque type
LL | |     };
   | |_____- `if` and `else` have incompatible types
   |
   = note:   expected struct `Struct`
           found opaque type `impl Trait`
help: `Struct` implements `Trait` so you can box both arms and coerce to the trait object `Box<dyn Trait>`
   |
LL ~         Box::new(Struct) as Box<dyn Trait>
LL |     } else {
LL ~         Box::new(bar())
   |

error[E0308]: `if` and `else` have incompatible types
  --> $DIR/suggest-box-on-divergent-if-else-arms.rs:30:9
   |
LL |   fn bar() -> impl Trait {
   |               ---------- the expected opaque type
...
LL |       let _ = if true {
   |  _____________-
LL | |         bar()
   | |         ----- expected because of this
LL | |     } else {
LL | |         Struct
   | |         ^^^^^^ expected opaque type, found `Struct`
LL | |     };
   | |_____- `if` and `else` have incompatible types
   |
   = note: expected opaque type `impl Trait`
                   found struct `Struct`
help: `Struct` implements `Trait` so you can box both arms and coerce to the trait object `Box<dyn Trait>`
   |
LL ~         Box::new(bar()) as Box<dyn Trait>
LL |     } else {
LL ~         Box::new(Struct)
   |
```

Partially address #102629.
2024-01-23 21:53:59 +01:00
León Orell Valerian Liehr
4d9b983368
Rollup merge of #120259 - HTGAzureX1212:HTGAzureX1212/split-diagnostics-uncommon-codepoints, r=Manishearth
Split Diagnostics for Uncommon Codepoints: Add List to Display Characters Involved

This Pull Request adds a list of the uncommon codepoints involved in the `uncommon_codepoints` lint, as outlined as a first step in #120228.

Example rendered diagnostic:
```
error: identifier contains an uncommon Unicode codepoint: 'µ'
  --> $DIR/lint-uncommon-codepoints.rs:3:7
   |
LL | const µ: f64 = 0.000001;
   |       ^
   |
note: the lint level is defined here
  --> $DIR/lint-uncommon-codepoints.rs:1:9
   |
LL | #![deny(uncommon_codepoints)]
   |         ^^^^^^^^^^^^^^^^^^^
```

(Retrying #120258.)
2024-01-23 21:53:59 +01:00
León Orell Valerian Liehr
7ee8142420
Rollup merge of #120195 - bvanjoi:add-some-resolution-test-case, r=petrochenkov
add several resolution test cases

r? ``@petrochenkov``
2024-01-23 21:53:58 +01:00
León Orell Valerian Liehr
ecb8702308
Rollup merge of #120183 - Zalathar:test-closure, r=compiler-errors
Add `#[coverage(off)]` to closures introduced by `#[test]` and `#[bench]`

These closures are an internal implementation detail of the `#[test]` and `#[bench]` attribute macros, so from a user perspective there is no reason to instrument them for coverage.

Skipping them makes coverage reports slightly cleaner, and will also allow other changes to span processing during coverage instrumentation, without having to worry about how they affect the `#[test]` macro.

The `#[coverage(off)]` attribute has no effect when `-Cinstrument-coverage` is not used.

Fixes #120046.

---

Note that this PR has no effect on the user-written function that has the `#[test]` attribute attached to it. That function will still be instrumented as normal.
2024-01-23 21:53:58 +01:00
León Orell Valerian Liehr
6cca9b33ec
Rollup merge of #120171 - cjgillot:jump-threading-assume-assert, r=tmiasko
Fix assume and assert in jump threading

r? ``@tmiasko``
2024-01-23 21:53:57 +01:00
León Orell Valerian Liehr
5da220a095
Rollup merge of #119766 - oli-obk:split_tait_and_atpit, r=compiler-errors
Split tait and impl trait in assoc items logic

And simplify the assoc item logic where applicable.

This separation shows that it is easier to reason about impl trait in assoc items compared with TAITs. See https://rust-lang.zulipchat.com/#narrow/stream/315482-t-compiler.2Fetc.2Fopaque-types/topic/impl.20trait.20in.20associated.20type for some discussion.

The current plan is to try to stabilize impl trait in associated items before TAIT, as they do not have any issues with their defining scopes (see https://github.com/rust-lang/rust/issues/107645 for why this is not a trivial or uncontroversial topic).
2024-01-23 21:53:56 +01:00
León Orell Valerian Liehr
3b1c2eb44c
Rollup merge of #120270 - compiler-errors:randos, r=lcnr
A bunch of random modifications

r? oli-obk

Kitchen sink of changes that I didn't know where to put elsewhere. Documentation tweaks mostly, but also removing some unreachable code and simplifying the pretty printing for closures/coroutines.
2024-01-23 21:19:56 +01:00
León Orell Valerian Liehr
dd538b5f05
Rollup merge of #119805 - chenyukang:yukang-fix-119530, r=davidtwco
Suggest array::from_fn for array initialization

Fixes #119530
2024-01-23 21:19:52 +01:00
León Orell Valerian Liehr
e8f9e5481e
Rollup merge of #119028 - oberien:patch-1, r=cjgillot
Add more weirdness to weird-exprs.rs
2024-01-23 21:19:52 +01:00
Nicholas Thompson
9dccd5dce1 Further Implement Power of Two Optimization 2024-01-23 12:03:50 -05:00
Nicholas Thompson
971e37ff7e Further Implement is_val_statically_known 2024-01-23 12:02:31 -05:00
Oli Scherer
e904a640ac Stop using eval_rvalue_into_place in const prop 2024-01-23 16:34:42 +00:00
bohan
851d4c4e24 add several resolution test cases 2024-01-24 00:01:59 +08:00
Oli Scherer
db7cd57091 Remove track_errors entirely 2024-01-23 15:23:22 +00:00
Michael Goulet
5fc39e0796 Random type checker changes 2024-01-23 15:10:23 +00:00
bors
6265a95b37 Auto merge of #119044 - RalfJung:intern-without-types, r=oli-obk
const-eval interning: get rid of type-driven traversal

This entirely replaces our const-eval interner, i.e. the code that takes the final result of a constant evaluation from the local memory of the const-eval machine to the global `tcx` memory. The main goal of this change is to ensure that we can detect mutable references that sneak into this final value -- this is something we want to reject for `static` and `const`, and while const-checking performs some static analysis to ensure this, I would be much more comfortable stabilizing const_mut_refs if we had a dynamic check that sanitizes the final value. (This is generally the approach we have been using on const-eval: do a static check to give nice errors upfront, and then do a dynamic check to be really sure that the properties we need for soundness, actually hold.)

We can do this now that https://github.com/rust-lang/rust/pull/118324 landed and each pointer comes with a bit (completely independent of its type) storing whether mutation is permitted through this pointer or not.

The new interner is a lot simpler than the old one: previously we did a complete type-driven traversal to determine the mutability of all memory we see, and then a second pass to intern any leftover raw pointers. The new interner simply recursively traverses the allocation holding the final result, and all allocations reachable from it (which can be determined from the raw bytes of the result, without knowing anything about types), and ensures they all get interned. The initial allocation is interned as immutable for `const` and pomoted and non-interior-mutable `static`; all other allocations are interned as immutable for `static`, `const`, and promoted. The main subtlety is justifying that those inner allocations may indeed be interned immutably, i.e., that mutating them later would anyway already be UB:
- for promoteds, we rely on the analysis that does promotion to ensure that this is sound.
- for `const` and `static`, we check that all pointers in the final result that point to things that are new (i.e., part of this const evaluation) are immutable, i.e., were created via `&<expr>` at a non-interior-mutable type. Mutation through immutable pointers is UB so we are free to intern that memory as immutable.

Interning raises an error if it encounters a dangling pointer or a mutable pointer that violates the above rules.

I also extended our type-driven const validity checks to ensure that `&mut T` in the final value of a const points to mutable memory, at least if `T` is not zero-sized. This catches cases of people turning `&i32` into `&mut i32` (which would still be considered a read-only pointer). Similarly, when these checks encounter an `UnsafeCell`, they are checking that it lives in mutable memory. (Both of these only traverse the newly created values; if those point to other consts/promoteds, the check stops there. But that's okay, we don't have to catch all the UB.) I co-developed this with the stricter interner changes but I can split it out into a separate PR if you prefer.

This PR does have the immediate effect of allowing some new code on stable, for instance:
```rust
const CONST_RAW: *const Vec<i32> = &Vec::new() as *const _;
```
Previously that code got rejected since the type-based interner didn't know what to do with that pointer. It's a raw pointer, we cannot trust its type. The new interner does not care about types so it sees no issue with this code; there's an immutable pointer pointing to some read-only memory (storing a `Vec<i32>`), all is good. Accepting this code pretty much commits us to non-type-based interning, but I think that's the better strategy anyway.

This PR also leads to slightly worse error messages when the final value of a const contains a dangling reference. Previously we would complete interning and then the type-based validation would detect this dangling reference and show a nice error saying where in the value (i.e., in which field) the dangling reference is located. However, the new interner cannot distinguish dangling references from dangling raw pointers, so it must throw an error when it encounters either of them. It doesn't have an understanding of the value structure so all it can say is "somewhere in this constant there's a dangling pointer". (Later parts of the compiler don't like dangling pointers/references so we have to reject them either during interning or during validation.) This could potentially be improved by doing validation before interning, but that's a larger change that I have not attempted yet. (It's also subtle since we do want validation to use the final mutability bits of all involved allocations, and currently it is interning that marks a bunch of allocations as immutable -- that would have to still happen before validation.)

`@rust-lang/wg-const-eval` I hope you are okay with this plan. :)
`@rust-lang/lang` paging you in since this accepts new code on stable as explained above. Please let me know if you think FCP is necessary.
2024-01-23 14:08:08 +00:00
HTGAzureX1212.
3a07333a8a
address requested changes 2024-01-23 21:16:24 +08:00
Ryan Levick
31ecf34125 Add the wasm32-wasi-preview2 target
Signed-off-by: Ryan Levick <me@ryanlevick.com>
2024-01-23 13:26:16 +01:00