Commit Graph

5521 Commits

Author SHA1 Message Date
Jonathan Brouwer 40d7cb890f Rollup merge of #150271 - Jamesbarford:chore/refactor-struct-placeholder-pt2, r=lcnr
Move struct placeholder pt2

r? ghost
2026-01-29 17:47:29 +01:00
James Barford-Evans 25c1365507 Part 2 refactoring of moving placeholder types to rustc_type_ir 2026-01-29 11:11:40 +00:00
Esteban Küber 2b32446c7c Suggest changing iter/into_iter when the other was meant
When encountering a call to `iter` that should have been `into_iter` and vice-versa, provide a structured suggestion:

```
error[E0271]: type mismatch resolving `<IntoIter<{integer}, 3> as IntoIterator>::Item == &{integer}`
  --> $DIR/into_iter-when-iter-was-intended.rs:5:37
   |
LL |     let _a = [0, 1, 2].iter().chain([3, 4, 5].into_iter());
   |                               ----- ^^^^^^^^^^^^^^^^^^^^^ expected `&{integer}`, found integer
   |                               |
   |                               required by a bound introduced by this call
   |
note: the method call chain might not have had the expected associated types
  --> $DIR/into_iter-when-iter-was-intended.rs:5:47
   |
LL |     let _a = [0, 1, 2].iter().chain([3, 4, 5].into_iter());
   |                                     --------- ^^^^^^^^^^^ `IntoIterator::Item` is `{integer}` here
   |                                     |
   |                                     this expression has type `[{integer}; 3]`
note: required by a bound in `std::iter::Iterator::chain`
  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
help: consider not consuming the `[{integer}, 3]` to construct the `Iterator`
   |
LL -     let _a = [0, 1, 2].iter().chain([3, 4, 5].into_iter());
LL +     let _a = [0, 1, 2].iter().chain([3, 4, 5].iter());
   |
```
2026-01-25 23:12:05 +00:00
León Orell Valerian Liehr 7f5819317b mGCA: Render traits dyn incompatible if the ty of an assoc const refs Self (barring Self projections) 2026-01-21 12:53:48 +01:00
León Orell Valerian Liehr 7777958231 mGCA: Permit certain const projections in dyn-compatible traits 2026-01-21 12:53:46 +01:00
León Orell Valerian Liehr 8d524f096d mGCA: Make traits with type assoc consts dyn compatible...
...but require all assoc consts to be specified via bindings.
2026-01-21 12:53:44 +01:00
Jacob Pratt d37351bbe3 Rollup merge of #148637 - rustc_dyn_incompatible, r=lcnr
Replace `#[rustc_do_not_implement_via_object]` with `#[rustc_dyn_incompatible_trait]`

Background: `#[rustc_do_not_implement_via_object]` on a trait currently still allows `dyn Trait` to exist (if the trait is otherwise dyn-compatible), it just means that `dyn Trait` does not automatically implement `Trait` via the normal object candidate. For some traits, this means that `dyn Trait` does not implement `Trait` at all (e.g. `Unsize` and `Tuple`). For some traits, this means that `dyn Trait` implements `Trait`, but with different associated types (e.g. `Pointee`, `DiscriminantKind`). Both of these cases can can cause issues with codegen , as seen in https://github.com/rust-lang/rust/issues/148089 (and https://github.com/rust-lang/rust/issues/148089#issuecomment-3447803823 ), because codegen assumes that if `dyn Trait` does not implement `Trait` (including if `dyn Trait<Assoc = T>` does not implement `Trait` with `Assoc == T`), then `dyn Trait` cannot be constructed, so vtable accesses on `dyn Trait` are unreachable, but this is not the case if `dyn Trait` has multiple supertraits: one which is `#[rustc_do_not_implement_via_object]`, and one which we are doing the vtable access to call a method from.

This PR replaces `#[rustc_do_not_implement_via_object]` with `#[rustc_dyn_incompatible_trait]`, which makes the marked trait dyn-incompatible, making `dyn Trait` not well-formed, instead of it being well-formed but not implementing `Trait`. This resolves rust-lang/rust#148089 by making it not compile.

May fix rust-lang/rust#148615

The traits that are currently marked `#[rustc_do_not_implement_via_object]` are: `Sized`, `MetaSized`, `PointeeSized`, `TransmuteFrom`, `Unsize`, `BikeshedGuaranteedNoDrop`, `DiscriminantKind`, `Destruct`, `Tuple`, `FnPtr`, `Pointee`. Of these:
* `Sized` and `FnPtr` are already not dyn-compatible (`FnPtr: Copy`, which implies `Sized`)
* `MetaSized`
    * Removed `#[rustc_do_not_implement_via_object]`. Still dyn-compatible after this change. (Has a special-case in the trait solvers to ignore the object candidate for `dyn MetaSized`, since it `dyn MetaSized: MetSized` comes from the sized candidate that all `dyn Trait` get.)
* `PointeeSized`
    * Removed `#[rustc_do_not_implement_via_object]`. It doesn't seem to have been doing anything anyway ([playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=a395626c8bef791b87a2d371777b7841)), since `PointeeSized` is removed before trait solving(?).
* `Pointee`, `DiscriminantKind`, `Unsize`, and `Tuple` being dyn-compatible without having `dyn Trait: Trait` (with same assoc tys) can be observed to cause codegen issues (https://github.com/rust-lang/rust/issues/148089) so should be made dyn-incompatible
* `Destruct`, `TransmuteFrom`, and `BikeshedGuaranteedNoDrop` I'm not sure if would be useful as object types, but they can be relaxed to being dyn-compatible later if it is determined they should be.

-----

<details> <summary> resolved </summary>

Questions before merge:

1. `dyn MetaSized: MetaSized` having both `SizedCandidate` and `ObjectCandidate`
    1. I'm not sure if the checks in compiler/rustc_trait_selection/src/traits/project.rs and compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs were "load-bearing" for `MetaSized` (which is the only trait that was previously `#[rustc_do_not_implement_via_object]` that is still dyn-compatible after this change). Is it fine to just remove them? Removing them (as I did in the second commit) doesn't change any UI test results.
    3. IIUC, `dyn MetaSized` could get its `MetaSized` implementation in two ways: the object candidate (the normal `dyn Trait: Trait`) that was supressed by `#[rustc_do_not_implement_via_object]`, and the `SizedCandidate` (that all `dyn Trait` get for `dyn Trait: MetaSized`). Given that `MetaSized` has no associated types or methods, is it fine that these both exist now? Or is it better to only have the `SizedCandidate` and leave these checks in (i.e. drop the second commit, and remove the FIXMEs)?
    4. Resolved: the trait solvers special-case `dyn MetaSized` to ignore the object candidate in preference to the sizedness candidate (technically the check is for any `is_sizedness_trait`, but only `MetaSized` gets this far (`Sized` is inherently dyn-incompatible, and `dyn PointeeSized` is ill-formed for other reasons)
4. Diagnostics improvements?
    1. The diagnostics are kinda bad. If you have a `trait Foo: Pointee {}`, you now get a note that reads like *Foo* "opted out of dyn-compatbility", when really `Pointee` did that.
    2. Resolved: can be improved later

  <details> <summary>diagnostic example</summary>

```rs
#![feature(ptr_metadata)]

trait C: std::ptr::Pointee {}

fn main() {
    let y: &dyn C;
}
```

```rs
error[E0038]: the trait `C` is not dyn compatible
  --> c.rs:6:17
   |
 6 |     let y: &dyn C;
   |                 ^ `C` is not dyn compatible
   |
note: for a trait to be dyn compatible it needs to allow building a vtable
      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
  --> /home/zachary/opt_mount/zachary/Programming/rust-compiler-2/library/core/src/ptr/metadata.rs:57:1
   |
57 | #[rustc_dyn_incompatible_trait]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatbility
   |
  ::: c.rs:3:7
   |
 3 | trait C: std::ptr::Pointee {}
   |       - this trait is not dyn compatible...

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0038`.
  ```

  </details> </details>

  Still investigating "3. `compiler/rustc_hir/src/attrs/encode_cross_crate.rs`: Should `DynIncompatibleTrait` attribute be encoded cross crate?"
2026-01-21 02:04:01 -05:00
Jacob Pratt 69fa72e21e Rollup merge of #151351 - yukang-fix-150052-deduplicate-const-trait-supertraits, r=Kivooeo
Deduplicate diagnostics for const trait supertraits

Fixes rust-lang/rust#150052
2026-01-20 19:46:31 -05:00
Zachary S c3205f98dd Replace #[rustc_do_not_implement_via_object] with #[rustc_dyn_incompatible_trait], which makes the marked trait dyn-incompatible.
Removes the attribute from `MetaSized` and `PointeeSized`, with a special case in the trait solvers for `MetaSized`.

`dyn MetaSized` is a perfectly cromulent type, and seems to only have had #[rustc_do_not_implement_via_object] so the builtin object
candidate does not overlap with the builtin MetaSized impl that all `dyn` types get.
Resolves this with a special case by checking `is_sizedness_trait` where the trait solvers previously checked `implement_via_object`.

`dyn PointeeSized` alone is rejected for other reasons (since `dyn PointeeSized` is considered to have no principal trait because `PointeeSized`
is removed at an earlier stage of the compiler), but `(dyn PointeeSized + Send)` is valid and equivalent to `dyn Send`.

Add suggestions from code review

Update compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs and tests

Co-authored-by: lcnr <rust@lcnr.de>
2026-01-20 12:54:40 -06:00
Jonathan Brouwer 958d1f907b Rollup merge of #150879 - remove_diag_lints, r=Kivooeo
Remove the diagnostic lints

Removes the `untranslatable_diagnostic` and `diagnostic_outside_of_impl` lints
These lints are allowed for a while already. Per https://github.com/rust-lang/compiler-team/issues/959, we no longer want to enforce struct diagnostics for all usecases, so this is no longer useful.

r? @Kivooeo
I recommend reviewing commit by commit (also feel free to wait with reviewing until the MCP is accepted)

@rustbot +S-blocked
Blocked by https://github.com/rust-lang/compiler-team/issues/959
2026-01-19 20:53:20 +01:00
Jonathan Brouwer a66a2e31eb Rollup merge of #150550 - borrowck_cleanup_2, r=lcnr
Miscellaneous cleanups to borrowck related code

r? lcnr
2026-01-19 20:53:20 +01:00
Jonathan Brouwer 0ee7d96253 Remove all allows for diagnostic_outside_of_impl and untranslatable_diagnostic throughout the codebase
This PR was mostly made by search&replacing
2026-01-19 17:39:49 +01:00
Boxy Uwu 3705ebb3cb implied bounds comments 2026-01-19 16:08:54 +00:00
Zalathar 7ec34defe9 Temporarily re-export assert_matches! to reduce stabilization churn 2026-01-19 18:26:53 +11:00
yukang e519c686cf Deduplicate diagnostics for const trait supertraits 2026-01-19 11:15:53 +08:00
mu001999 7510f747a8 Normalize type_const items even with feature generic_const_exprs 2026-01-18 12:46:42 +08:00
Jacob Pratt 23f6cb5f12 Rollup merge of #151082 - issue-141403, r=Kivooeo
Silence unused type param error on struct parse error

Given

```
#[derive(Clone)]
struct B<T> {
    a: A<(T, u32)> // <- note, comma is missing here
    /// asdf
    b: u32,
}
```

do not emit unnecessary "unused `T`" error.

Fix rust-lang/rust#141403.
2026-01-15 19:35:47 -05:00
Esteban Küber 9750d22c17 Silence unused type param and inference errors on struct parse error 2026-01-15 21:16:48 +00:00
bors 22c74ba918 Auto merge of #151056 - mejrs:do_not_recommend, r=JonathanBrouwer
Port `diagnostic::do_not_recommend` to new attr parsing

r? @jdonszelmann
2026-01-15 19:35:19 +00:00
Jonathan Brouwer cbcd1c3eef Rollup merge of #151036 - issue-151026, r=mati865
Better handle when trying to iterate on a `Range` of a type that isn't `Step`

Mention when a trait bound corresponds to an unstable trait.

Mention `Range` when `Step` bound is unment, and explain that only some std types impl `Iterator` for `Range`.

CC rust-lang/rust#151026
2026-01-14 11:05:40 +01:00
Jonathan Brouwer 4e4bee8add Rollup merge of #150406 - matches-let-chain, r=Kivooeo,oli-obk,BoxyUwU,fmease
Change some `matches!(.., .. if ..)` with let-chains

Follow up to rust-lang/rust#149933.
2026-01-14 11:05:37 +01:00
Guillaume Gomez 6c700ecd6a Rollup merge of #150737 - smithdb3/fix-150576, r=chenyukang
diagnostics: make implicit Sized bounds explicit in E0277

When a trait parameter depends upon Sized, the error message only referred to the full trait itself and didn't mention Sized. This makes the failure to implement Sized explicit. It also notes when the Sized trait bound is explicit or implicit.

Fixes rust-lang/rust#150576
2026-01-13 23:39:08 +01:00
mejrs a1e2cea685 Port do_not_recommend to new attr parsing 2026-01-13 20:43:37 +01:00
Esteban Küber 814647f047 Change some matches!(.., .. if ..) with let-chains 2026-01-13 17:13:22 +00:00
Esteban Küber cafe91749f On unmet trait bound, mention if trait is unstable 2026-01-13 01:16:58 +00:00
Heath Dutton🕴️ afe76df79c Don't suggest replacing closure parameter with type name
When a closure has an inferred parameter type like `|ch|` and the
expected type differs in borrowing (e.g., `char` vs `&char`), the
suggestion code would incorrectly suggest `|char|` instead of the
valid `|ch: char|`.

This happened because the code couldn't walk explicit `&` references
in the HIR when the type is inferred, and fell back to replacing the
entire parameter span with the expected type name.

Fix by only emitting the suggestion when we can properly identify the
`&` syntax to remove.
2026-01-12 18:07:38 -05:00
Matthias Krüger 79445c315e Rollup merge of #150861 - folding-cleanups, r=lcnr
Folding/`ReErased` cleanups

Various cleanups I found while reading this code closely, mostly involving folding and the use of `ReErased`.

r? @lcnr
2026-01-12 13:32:07 +01:00
rust-bors[bot] 44a5b55557 Auto merge of #150748 - nnethercote:canonicalizer-cleanups, r=lcnr
Canonicalizer cleanups

Some cleanups in and around the canonicalizers, found while I was looking closely at this code.

r? @lcnr
2026-01-11 22:58:38 +00:00
Nicholas Nethercote 46d8c2beeb Clean up src/dst transmute mess.
- Remove the vacuous `Types`, which provides extremely little value.
- Make sure `src` comes before `dst` in all transmute-related functions.
  (Currently it's a mix: sometimes `src` is first, sometimes it is
  second`.)
2026-01-12 09:22:58 +11:00
Daniel Smith 291d0a9a4b diagnostics: make implicit Sized bounds explicit in E0277
When a trait parameter depends upon Sized, the error message only
referred to the full trait itself and didn't mention Sized. This makes
the failure to implement Sized explicit. It also notes when the Sized
trait bound is explicit or implicit.
2026-01-08 16:07:18 -05:00
Noah Lev 1c2cb16e82 mgca: Type-check fields of tuple expr const args 2026-01-08 11:09:07 -08:00
Noah Lev a9749be514 mgca: Type-check fields of ADT constructor expr const args 2026-01-08 10:52:58 -08:00
Nicholas Nethercote e4bbfe8856 Avoid using to_vec to clone Vecs.
It's weird. `clone` is better.
2026-01-08 15:03:56 +11:00
mu001999 d572e6d415 Add span field for ConstArg 2026-01-07 08:44:32 +08:00
Matthias Krüger 7af208fe0b Rollup merge of #150570 - Human9000-bit:main, r=jieyouxu
Removed confusing diagnostics note for trait required for `?` operator use

- **test: modified `bad-question-mark-on-trait-objects` to match expected behavior**
- **removed confusing message from diagnostics**

fixes [#150527](https://github.com/rust-lang/rust/issues/150527)
2026-01-03 10:09:29 +01:00
Matthias Krüger 78376fd39c Rollup merge of #150558 - estebank:multiple-dep-versions, r=jieyouxu
Detect cases where `?` is applied on a type that could be coming from a different crate version than expected

```
error[E0277]: `?` couldn't convert the error to `dependency::Error`
  --> replaced
   |
LL | fn main() -> Result<(), Error> {
   |              ----------------- expected `dependency::Error` because of this
...
LL |     Err(Error2)?;
   |     -----------^ the trait `From<Error2>` is not implemented for `dependency::Error`
   |     |
   |     this can't be annotated with `?` because it has type `Result<_, Error2>`
   |
   = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
help: the trait `From<Error2>` is not implemented for `dependency::Error`
      but trait `From<()>` is implemented for it
  --> replaced
   |
LL | impl From<()> for Error {
   | ^^^^^^^^^^^^^^^^^^^^^^^
   = help: for that trait implementation, expected `()`, found `Error2`
   = note: there are multiple different versions of crate `dependency` in the dependency graph
   = help: you can use `cargo tree` to explore your dependency tree
```

The existing checks rely on having access to the actual types/traits that diverged to detect they are called the same, come from different crates with the same name. The new check is less specific, merely looking to see if the crate name the involved type belongs has multiple crates.

CC rust-lang/rust#78552.
2026-01-03 10:09:29 +01:00
Jonathan Brouwer ce43d6cd01 Rollup merge of #150441 - fee1-dead-contrib:push-smqzpwrpvqll, r=estebank
do not suggest method call removal if it changes receiver type

Fixes rust-lang/rust#149487, cc `@estebank`
2026-01-02 23:13:22 +01:00
human9000 97e5cabb91 removed confusing message from diagnostics 2026-01-02 00:57:43 +05:00
Esteban Küber 22bb4fe147 Detect cases where ? is applied on a type that could be coming from a different crate version than expected
```
error[E0277]: `?` couldn't convert the error to `dependency::Error`
  --> replaced
   |
LL | fn main() -> Result<(), Error> {
   |              ----------------- expected `dependency::Error` because of this
...
LL |     Err(Error2)?;
   |     -----------^ the trait `From<Error2>` is not implemented for `dependency::Error`
   |     |
   |     this can't be annotated with `?` because it has type `Result<_, Error2>`
   |
   = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
help: the trait `From<Error2>` is not implemented for `dependency::Error`
      but trait `From<()>` is implemented for it
  --> replaced
   |
LL | impl From<()> for Error {
   | ^^^^^^^^^^^^^^^^^^^^^^^
   = help: for that trait implementation, expected `()`, found `Error2`
   = note: there are multiple different versions of crate `dependency` in the dependency graph
   = help: you can use `cargo tree` to explore your dependency tree
```

The existing checks rely on having access to the actual types/traits that diverged to detect they are called the same, come from different crates with the same name. The new check is less specific, merely looking to see if the crate name the involved type belongs has multiple crates.
2025-12-31 23:40:16 +00:00
Jonathan Brouwer be715d4685 Rollup merge of #150239 - nnethercote:simplify-TypeFreshener-methods, r=lcnr
Simplify `TypeFreshener` methods.

`freshen_{ty,const}` take a `Result` and just do a fold if the input is `Ok`. It's simpler to do those folds at the call site, and only call `freshen_{ty,const}` in the `Err` case. That way we can also avoid useless fold operations on the results of `new_{int,uint,float}`.

Also, make some `bug!` calls more concise.

r? `@lcnr`
2025-12-30 10:42:27 +01:00
Deadbeef 998a0df610 more sophisticated checking 2025-12-28 19:04:37 -05:00
Deadbeef bc2853f4c1 do not suggest method call removal if it changes receiver type 2025-12-27 14:34:22 -05:00
Esteban Küber 9f566f2463 Don't use matches! when == suffices
In the codebase we sometimes use `matches!` for values that can actually just be compared. Replace them with `==`.
2025-12-26 20:28:19 +00:00
Nicholas Nethercote 63d30f1a0a s/fresh_trait_ref/fresh_trait_pred.
Because `fresh_trait_pred` is the name of the field/argument. The `_ref`
suffix appears to be a typo, or left over from earlier versions of the
code.
2025-12-22 23:46:34 +11:00
Nicholas Nethercote 5c49aee9ec Remove InferCtxt::freshen.
Sometimes we freshen using a new `TypeFreshener`, and sometimes we
freshen with an existing `TypeFreshener`. For the former we have the
method `InferCtxt::freshen`. For the latter we just call `fold_with`.
This asymmetry has been confusing to me.

This commit removes `InferCtxt::freshen` so that all the freshening
sites consistently use `fold_with` and it's obvious if each one is using
a new or existing `TypeFreshener`.
2025-12-22 23:32:11 +11:00
Nicholas Nethercote 1bb9ff05c0 Remove InferCtxt::freshener.
I have always found this confusingly named, because it creates a new
freshener rather than returning an existing one. We can remove it and
just use `TypeFreshener::new()` at the two call sites, avoiding this
confusion.
2025-12-22 17:48:37 +11:00
Yotam Ofek 462a8b3410 Dogfood strip_circumfix 2025-12-20 13:56:25 +02:00
bors 31010ca61c Auto merge of #149442 - chenyukang:yukang-fix-mark-span-note-144304, r=estebank
Fix span note for question mark expression

Fixes rust-lang/rust#144304

Seems it's better to fix the note instead of modifying the span to cover the whole expression.

r? `@estebank`
2025-12-16 16:06:43 +00:00
David Wood ba9262936e hir/trait_sel: prohibit scalable vectors in types
Extend well-formedness checking and HIR analysis to prohibit the use of
scalable vectors in structs, enums, unions, tuples and arrays. LLVM does
not support scalable vectors being members of other types, so these
restrictions are necessary.

Co-authored-by: Jamie Cunliffe <Jamie.Cunliffe@arm.com>
2025-12-16 11:00:12 +00:00
yukang d0bd4df3aa Fix span note for question mark expression 2025-12-13 12:53:50 +08:00