summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src
AgeCommit message (Collapse)AuthorLines
2025-03-14Revert "Rollup merge of #136274 - compiler-errors:sized-wf, r=lcnr"Michael Goulet-9/+62
This reverts commit a8ecb79d19e1bad732dae7f34f2481499db12f7c, reversing changes made to 40c4e05013c1805044ae2611ba0b95c0acecd331. (cherry picked from commit 9ea587e023dfa4458c5003ba74ae02bd146ec2df)
2025-02-14Auto merge of #137010 - workingjubilee:rollup-g00c07v, r=workingjubileebors-2/+2
Rollup of 9 pull requests Successful merges: - #135439 (Make `-O` mean `OptLevel::Aggressive`) - #136460 (Simplify `rustc_span` `analyze_source_file`) - #136904 (add `IntoBounds` trait) - #136908 ([AIX] expect `EINVAL` for `pthread_mutex_destroy`) - #136924 (Add profiling of bootstrap commands using Chrome events) - #136951 (Use the right binder for rebinding `PolyTraitRef`) - #136981 (ci: switch loongarch jobs to free runners) - #136992 (Update backtrace) - #136993 ([cg_llvm] Remove dead error message) r? `@ghost` `@rustbot` modify labels: rollup
2025-02-13Rollup merge of #136951 - compiler-errors:clause-binder, r=lqdJubilee-2/+2
Use the right binder for rebinding `PolyTraitRef` Fixes #136940 I committed a slightly different test which still demonstrates the issue.
2025-02-13adjust derive_errorlcnr-26/+108
2025-02-13normalizes-to rework rigid alias handlinglcnr-4/+1
2025-02-13Use BikeshedGuaranteedNotDrop in unsafe binder type WF tooMichael Goulet-1/+4
2025-02-13Implement and use BikeshedGuaranteedNoDrop for union/unsafe field validityMichael Goulet-1/+143
2025-02-12Use the right binder for rebinding PolyTraitRefMichael Goulet-2/+2
2025-02-12Rollup merge of #136838 - compiler-errors:escaping-unsize, r=fmeaseGuillaume Gomez-2/+3
Check whole `Unsize` predicate for escaping bound vars Fixes #136799
2025-02-12Auto merge of #136905 - matthiaskrgr:rollup-8zwcgta, r=matthiaskrgrbors-10/+77
Rollup of 8 pull requests Successful merges: - #135549 (Document some safety constraints and use more safe wrappers) - #135965 (In "specify type" suggestion, skip type params that are already known) - #136193 (Implement pattern type ffi checks) - #136646 (Add a TyPat in the AST to reuse the generic arg lowering logic) - #136874 (Change the issue number for `likely_unlikely` and `cold_path`) - #136884 (Lower fn items as ZST valtrees and delay a bug) - #136885 (i686-linux-android: increase CPU baseline to Pentium 4 (without an actual change) - #136891 (Check sig for errors before checking for unconstrained anonymous lifetime) r? `@ghost` `@rustbot` modify labels: rollup
2025-02-12Rollup merge of #135965 - estebank:shorten-ty-sugg, r=lcnrMatthias Krüger-10/+77
In "specify type" suggestion, skip type params that are already known When we suggest specifying a type for an expression or pattern, like in a `let` binding, we previously would print the entire type as the type system knew it. We now look at the params that have *no* inference variables, so they are fully known to the type system which means that they don't need to be specified. This helps in suggestions for types that are really long, because we can usually skip most of the type params and make the annotation as short as possible: ``` error[E0282]: type annotations needed for `Result<_, ((..., ..., ..., ...), ..., ..., ...)>` --> $DIR/really-long-type-in-let-binding-without-sufficient-type-info.rs:7:9 | LL | let y = Err(x); | ^ ------ type must be known at this point | help: consider giving `y` an explicit type, where the type for type parameter `T` is specified | LL | let y: Result<T, _> = Err(x); | ++++++++++++++ ``` Fix #135919.
2025-02-11Make DeeplyNormalize a real type opMichael Goulet-3/+55
2025-02-11Rollup merge of #136584 - oli-obk:pattern-types-generic, r=BoxyUwUMatthias Krüger-2/+42
Prevent generic pattern types from being used in libstd Pattern types should follow the same rules that patterns follow. So a pattern type range must not wrap and not be empty. While we reject such invalid ranges at layout computation time, that only happens during monomorphization in the case of const generics. This is the exact same issue as other const generic math has, and since there's no solution there yet, I put these pattern types behind a separate incomplete feature. These are not necessary for the pattern types MVP (replacing the layout range attributes in libcore and rustc). cc #136574 (new tracking issue for the `generic_pattern_types` feature gate) r? ``@lcnr`` cc ``@scottmcm`` ``@joshtriplett``
2025-02-10Check whole Unsize predicate for escaping bound varsMichael Goulet-2/+3
2025-02-08Rustfmtbjorn3-162/+206
2025-02-06stabilize `feature(trait_upcasting)`Waffle Lapkin-62/+1
2025-02-06Rollup merge of #136311 - compiler-errors:vtable-fixes-2, r=lcnrMatthias Krüger-5/+21
Ensure that we never try to monomorphize the upcasting or vtable calls of impossible dyn types Check for impossible obligations in the `dyn Trait` type we're trying to compute its the vtable upcasting and method call slots. r? lcnr
2025-02-06Prevent generic pattern types from being used in libstdOli Scherer-2/+42
2025-02-05Pass spans around new solverMichael Goulet-12/+22
2025-02-05Remove span from delegateMichael Goulet-2/+0
2025-02-04Rollup merge of #136520 - compiler-errors:redundant-layout-assert, r=lcnrMatthias Krüger-105/+2
Remove unnecessary layout assertions for object-safe receivers The soundness of `DispatchFromDyn` relies on the fact that, like all other built-in marker-like layout traits (e.g. `Sized`, `CoerceUnsized`), the guarantees that they enforce in *generic* code via traits will result in assumptions that we can rely on in codegen. Specifically, `DispatchFromDyn` ensures that we end up with a receiver that is a valid pointer type, and its implementation validity recursively ensures that the ABI of that pointer type upholds the `Scalar` or `ScalarPair` representation for sized and unsized pointees, respectively. The check that this layout guarantee holds for arbitrary, possibly generic receiver types that also may exist in possibly impossible-to-instantiate where clauses is overkill IMO, and leads to several ICEs due to the fact that computing layouts before monomorphization is going to be fallible at best. This PR removes the check altogether, since it just exists as a sanity check from very long ago, 6f2a161b1bbe6234188d6cfb3cabddef1e6ef20f. Fixes #125810 Fixes #90110 This PR is an alternative to #136195. cc `@adetaylor.` I didn't realize in that PR that the layout checks that were being modified were simply *sanity checks*, rather than being actually necessary for soundness.
2025-02-04Remove unnecessary layout assertions for object-safe receiversMichael Goulet-105/+2
2025-02-03Simplify recursive logicEsteban Küber-42/+49
2025-02-03In "specify type" suggestion, skip type params that are already knownEsteban Küber-12/+72
When we suggest specifying a type for an expression or pattern, like in a `let` binding, we previously would print the entire type as the type system knew it. We now look at the params that have *no* inference variables, so they are fully known to the type system which means that they don't need to be specified. This helps in suggestions for types that are really long, because we can usually skip most of the type params and make the annotation as short as possible: ``` error[E0282]: type annotations needed for `Result<_, ((..., ..., ..., ...), ..., ..., ...)>` --> $DIR/really-long-type-in-let-binding-without-sufficient-type-info.rs:7:9 | LL | let y = Err(x); | ^ ------ type must be known at this point | help: consider giving `y` an explicit type, where the type for type parameter `T` is specified | LL | let y: Result<T, _> = Err(x); | ++++++++++++++ ```
2025-02-03Make error message less awkwardMichael Goulet-1/+1
2025-02-03Check Sizedness of return type in WFMichael Goulet-61/+8
2025-02-02Rollup merge of #136414 - estebank:expected-return-type, r=oli-obkMatthias Krüger-3/+1
Shorten error message for callable with wrong return type ``` error: expected `{closure@...}` to return `Ret`, but it returns `Other` ``` instead of ``` error: expected `{closure@...}` to be a closure that returns `Ret`, but it returns `Other` ```
2025-02-02Rollup merge of #136415 - estebank:highlight-clarification, r=compiler-errorsMatthias Krüger-18/+28
Highlight clarifying information in "expected/found" error When the expected and found types have the same textual representation, we add clarifying in parentheses. We now visually highlight it in the output. Detect a corner case where the clarifying information would be the same for both types and skip it, as it doesn't add anything useful. ![Screenshot of the rustc highlighted output on the terminal](https://github.com/user-attachments/assets/aa4b9433-5332-4941-b2c2-1a43e5cadff7)
2025-02-02Rollup merge of #136412 - estebank:fn-ptr-cast-suggestion, r=jieyouxuMatthias Krüger-13/+8
Tweak fn pointer suggestion span Use a more targeted span when suggesting casting an `fn` item to an `fn` pointer. ``` error[E0308]: cannot coerce functions which must be inlined to function pointers --> $DIR/cast.rs:10:33 | LL | let _: fn(isize) -> usize = callee; | ------------------ ^^^^^^ cannot coerce functions which must be inlined to function pointers | | | expected due to this | = note: expected fn pointer `fn(_) -> _` found fn item `fn(_) -> _ {callee}` = note: fn items are distinct from fn pointers help: consider casting to a fn pointer | LL | let _: fn(isize) -> usize = callee as fn(isize) -> usize; | +++++++++++++++++++++ ``` ``` error[E0308]: mismatched types --> $DIR/fn-pointer-mismatch.rs:42:30 | LL | let d: &fn(u32) -> u32 = foo; | --------------- ^^^ expected `&fn(u32) -> u32`, found fn item | | | expected due to this | = note: expected reference `&fn(_) -> _` found fn item `fn(_) -> _ {foo}` help: consider using a reference | LL | let d: &fn(u32) -> u32 = &foo; | + ``` Previously we'd point at the whole expression for replacement, instead of marking what was being added. We could also modify the suggestions for `&(name as fn())`, but for that we require storing more accurate spans than we have now.
2025-02-02Rollup merge of #136328 - estebank:long-ty-path, r=jieyouxu,lqdMatthias Krüger-571/+90
Rework "long type names" printing logic Make it so more type-system types can be printed in a shortened version (like `Predicate`s). Centralize printing the information about the "full type name path". Make the "long type path" for the file where long types are written part of `Diag`, so that it becomes easier to keep track of it, and ensure it will always will be printed out last in the diagnostic by making its addition to the output implicit. Tweak the shortening of types in "expected/found" labels. Remove dead file `note.rs`.
2025-02-02Rollup merge of #136279 - Zalathar:ensure-ok, r=oli-obkMatthias Krüger-6/+8
Rename `tcx.ensure()` to `tcx.ensure_ok()`, and improve the associated docs This is all based on my archaeology for https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp/topic/.60TyCtxtEnsure.60. The main renamings are: - `tcx.ensure()` → `tcx.ensure_ok()` - `tcx.ensure_with_value()` → `tcx.ensure_done()` - Query modifier `ensure_forwards_result_if_red` → `return_result_from_ensure_ok` Hopefully these new names are a better fit for the *actual* function and purpose of these query call modes.
2025-02-02Highlight clarifying information in "expected/found" errorEsteban Küber-18/+28
When the expected and found types have the same textual representation, we add clarifying in parentheses. We now visually highlight it in the output. Detect a corner case where the clarifying information would be the same for both types and skip it, as it doesn't add anything useful.
2025-02-02Shorten error message for callable with wrong return typeEsteban Küber-3/+1
``` error: expected `{closure@...}` to return `Ret`, but it returns `Other` ``` instead of ``` error: expected `{closure@...}` to be a closure that returns `Ret`, but it returns `Other` ```
2025-02-02Tweak fn pointer suggestion spanEsteban Küber-13/+8
Use a more targeted span when suggesting casting an `fn` item to an `fn` pointer. ``` error[E0308]: cannot coerce functions which must be inlined to function pointers --> $DIR/cast.rs:10:33 | LL | let _: fn(isize) -> usize = callee; | ------------------ ^^^^^^ cannot coerce functions which must be inlined to function pointers | | | expected due to this | = note: expected fn pointer `fn(_) -> _` found fn item `fn(_) -> _ {callee}` = note: fn items are distinct from fn pointers help: consider casting to a fn pointer | LL | let _: fn(isize) -> usize = callee as fn(isize) -> usize; | +++++++++++++++++++++ ``` ``` error[E0308]: mismatched types --> $DIR/fn-pointer-mismatch.rs:42:30 | LL | let d: &fn(u32) -> u32 = foo; | --------------- ^^^ expected `&fn(u32) -> u32`, found fn item | | | expected due to this | = note: expected reference `&fn(_) -> _` found fn item `fn(_) -> _ {foo}` help: consider using a reference | LL | let d: &fn(u32) -> u32 = &foo; | + ``` Previously we'd point at the whole expression for replacement, instead of marking what was being added. We could also modify the suggestions for `&(name as fn())`, but for that we require storing more accurate spans than we have now.
2025-02-01Rollup merge of #130514 - compiler-errors:unsafe-binders, r=oli-obkMatthias Krüger-2/+19
Implement MIR lowering for unsafe binders This is the final bit of the unsafe binders puzzle. It implements MIR, CTFE, and codegen for unsafe binders, and enforces that (for now) they are `Copy`. Later on, I'll introduce a new trait that relaxes this requirement to being "is `Copy` or `ManuallyDrop<T>`" which more closely models how we treat union fields. Namely, wrapping unsafe binders is now `Rvalue::WrapUnsafeBinder`, which acts much like an `Rvalue::Aggregate`. Unwrapping unsafe binders are implemented as a MIR projection `ProjectionElem::UnwrapUnsafeBinder`, which acts much like `ProjectionElem::Field`. Tracking: - https://github.com/rust-lang/rust/issues/130516
2025-02-01Rename `tcx.ensure()` to `tcx.ensure_ok()`Zalathar-6/+8
2025-02-01Rollup merge of #135900 - compiler-errors:derive-wf, r=lcnrMatthias Krüger-542/+595
Manually walk into WF obligations in `BestObligation` proof tree visitor When we encounter a `WellFormed` obligation in the `BestObligation` proof tree visitor, ignore the proof tree and call `wf::unnormalized_obligations` to derive well-formed obligations with the correct cause codes. This is to avoid having to replicate the somewhat delicate logic that `wf.rs` does to set up its obligation causes... Don't see a better way to do this. vibes?? r? lcnr
2025-01-31Rework "long type names" printing logicEsteban Küber-571/+90
Make it so more type-system types can be printed in a shortened version (like `Predicate`s). Centralize printing the information about the "full type name path". Make the "long type path" for the file where long types are written part of `Diag`, so that it becomes easier to keep track of it, and ensure it will always will be printed out last in the diagnostic by making its addition to the output implicit. Tweak the shortening of types in "expected/found" labels. Remove dead file `note.rs`.
2025-01-31Auto merge of #136350 - matthiaskrgr:rollup-6eqfyvh, r=matthiaskrgrbors-6/+5
Rollup of 9 pull requests Successful merges: - #134531 ([rustdoc] Add `--extract-doctests` command-line flag) - #135860 (Compiler: Finalize dyn compatibility renaming) - #135992 (Improve documentation when adding a new target) - #136194 (Support clobber_abi in BPF inline assembly) - #136325 (Delay a bug when indexing unsized slices) - #136326 (Replace our `LLVMRustDIBuilderRef` with LLVM-C's `LLVMDIBuilderRef`) - #136330 (Remove unnecessary hooks) - #136336 (Overhaul `rustc_middle::util`) - #136341 (Remove myself from vacation) r? `@ghost` `@rustbot` modify labels: rollup
2025-01-31Ensure that we never try to monomorphize the upcasting of impossible dyn typesMichael Goulet-5/+21
2025-01-31Manually walk into WF obligations in BestObligation proof tree visitorMichael Goulet-62/+105
2025-01-31Move fulfillment error derivation into new moduleMichael Goulet-496/+506
2025-01-31Enforce unsafe binders must be Copy (for now)Michael Goulet-2/+19
2025-01-31Rollup merge of #135860 - fmease:compiler-mv-obj-save-dyn-compat-ii, r=jieyouxuMatthias Krüger-6/+5
Compiler: Finalize dyn compatibility renaming Update the Reference link to use the new URL fragment from https://github.com/rust-lang/reference/pull/1666 (this change has finally hit stable). Fixes a FIXME. Follow-up to #130826. Part of #130852. ~~Blocking it on #133372.~~ (merged) r? ghost
2025-01-31Auto merge of #136332 - jhpratt:rollup-aa69d0e, r=jhprattbors-24/+90
Rollup of 9 pull requests Successful merges: - #132156 (When encountering unexpected closure return type, point at return type/expression) - #133429 (Autodiff Upstreaming - rustc_codegen_ssa, rustc_middle) - #136281 (`rustc_hir_analysis` cleanups) - #136297 (Fix a typo in profile-guided-optimization.md) - #136300 (atomic: extend compare_and_swap migration docs) - #136310 (normalize `*.long-type.txt` paths for compare-mode tests) - #136312 (Disable `overflow_delimited_expr` in edition 2024) - #136313 (Filter out RPITITs when suggesting unconstrained assoc type on too many generics) - #136323 (Fix a typo in conventions.md) r? `@ghost` `@rustbot` modify labels: rollup
2025-01-31Rollup merge of #132156 - estebank:closure-return, r=Nadrieril,compiler-errorsJacob Pratt-24/+90
When encountering unexpected closure return type, point at return type/expression ``` error[E0271]: expected `{closure@fallback-closure-wrap.rs:18:40}` to be a closure that returns `()`, but it returns `!` --> $DIR/fallback-closure-wrap.rs:19:9 | LL | let error = Closure::wrap(Box::new(move || { | ------- LL | panic!("Can't connect to server."); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `!` | = note: expected unit type `()` found type `!` = note: required for the cast from `Box<{closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47}>` to `Box<dyn FnMut()>` ``` ``` error[E0271]: expected `{closure@dont-ice-for-type-mismatch-in-closure-in-async.rs:6:10}` to be a closure that returns `bool`, but it returns `Option<()>` --> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:6:16 | LL | call(|| -> Option<()> { | ---- ------^^^^^^^^^^ | | | | | expected `bool`, found `Option<()>` | required by a bound introduced by this call | = note: expected type `bool` found enum `Option<()>` note: required by a bound in `call` --> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:3:25 | LL | fn call(_: impl Fn() -> bool) {} | ^^^^ required by this bound in `call` ``` ``` error[E0271]: expected `{closure@f670.rs:28:13}` to be a closure that returns `Result<(), _>`, but it returns `!` --> f670.rs:28:20 | 28 | let c = |e| -> ! { | -------^ | | | expected `Result<(), _>`, found `!` ... 32 | f().or_else(c); | ------- required by a bound introduced by this call -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs:1433:28 | = note: expected enum `Result<(), _>` found type `!` note: required by a bound in `Result::<T, E>::or_else` --> /home/gh-estebank/rust/library/core/src/result.rs:1406:39 | 1406 | pub fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F> { | ^^^^^^^^^^^^ required by this bound in `Result::<T, E>::or_else` ``` CC #111539.
2025-01-31Auto merge of #135318 - compiler-errors:vtable-fixes, r=lcnrbors-122/+64
Fix deduplication mismatches in vtables leading to upcasting unsoundness We currently have two cases where subtleties in supertraits can trigger disagreements in the vtable layout, e.g. leading to a different vtable layout being accessed at a callsite compared to what was prepared during unsizing. Namely: ### #135315 In this example, we were not normalizing supertraits when preparing vtables. In the example, ``` trait Supertrait<T> { fn _print_numbers(&self, mem: &[usize; 100]) { println!("{mem:?}"); } } impl<T> Supertrait<T> for () {} trait Identity { type Selff; } impl<Selff> Identity for Selff { type Selff = Selff; } trait Middle<T>: Supertrait<()> + Supertrait<T> { fn say_hello(&self, _: &usize) { println!("Hello!"); } } impl<T> Middle<T> for () {} trait Trait: Middle<<() as Identity>::Selff> {} impl Trait for () {} fn main() { (&() as &dyn Trait as &dyn Middle<()>).say_hello(&0); } ``` When we prepare `dyn Trait`, we see a supertrait of `Middle<<() as Identity>::Selff>`, which itself has two supertraits `Supertrait<()>` and `Supertrait<<() as Identity>::Selff>`. These two supertraits are identical, but they are not duplicated because we were using structural equality and *not* considering normalization. This leads to a vtable layout with two trait pointers. When we upcast to `dyn Middle<()>`, those two supertraits are now the same, leading to a vtable layout with only one trait pointer. This leads to an offset error, and we call the wrong method. ### #135316 This one is a bit more interesting, and is the bulk of the changes in this PR. It's a bit similar, except it uses binder equality instead of normalization to make the compiler get confused about two vtable layouts. In the example, ``` trait Supertrait<T> { fn _print_numbers(&self, mem: &[usize; 100]) { println!("{mem:?}"); } } impl<T> Supertrait<T> for () {} trait Trait<T, U>: Supertrait<T> + Supertrait<U> { fn say_hello(&self, _: &usize) { println!("Hello!"); } } impl<T, U> Trait<T, U> for () {} fn main() { (&() as &'static dyn for<'a> Trait<&'static (), &'a ()> as &'static dyn Trait<&'static (), &'static ()>) .say_hello(&0); } ``` When we prepare the vtable for `dyn for<'a> Trait<&'static (), &'a ()>`, we currently consider the PolyTraitRef of the vtable as the key for a supertrait. This leads two two supertraits -- `Supertrait<&'static ()>` and `for<'a> Supertrait<&'a ()>`. However, we can upcast[^up] without offsetting the vtable from `dyn for<'a> Trait<&'static (), &'a ()>` to `dyn Trait<&'static (), &'static ()>`. This is just instantiating the principal trait ref for a specific `'a = 'static`. However, when considering those supertraits, we now have only one distinct supertrait -- `Supertrait<&'static ()>` (which is deduplicated since there are two supertraits with the same substitutions). This leads to similar offsetting issues, leading to the wrong method being called. [^up]: I say upcast but this is a cast that is allowed on stable, since it's not changing the vtable at all, just instantiating the binder of the principal trait ref for some lifetime. The solution here is to recognize that a vtable isn't really meaningfully higher ranked, and to just treat a vtable as corresponding to a `TraitRef` so we can do this deduplication more faithfully. That is to say, the vtable for `dyn for<'a> Tr<'a>` and `dyn Tr<'x>` are always identical, since they both would correspond to a set of free regions on an impl... Do note that `Tr<for<'a> fn(&'a ())>` and `Tr<fn(&'static ())>` are still distinct. ---- There's a bit more that can be cleaned up. In codegen, we can stop using `PolyExistentialTraitRef` basically everywhere. We can also fix SMIR to stop storing `PolyExistentialTraitRef` in its vtable allocations. As for testing, it's difficult to actually turn this into something that can be tested with `rustc_dump_vtable`, since having multiple supertraits that are identical is a recipe for ambiguity errors. Maybe someone else is more creative with getting that attr to work, since the tests I added being run-pass tests is a bit unsatisfying. Miri also doesn't help here, since it doesn't really generate vtables that are offset by an index in the same way as codegen. r? `@lcnr` for the vibe check? Or reassign, idk. Maybe let's talk about whether this makes sense. <sup>(I guess an alternative would also be to not do any deduplication of vtable supertraits (or only a really conservative subset) rather than trying to normalize and deduplicate more faithfully here. Not sure if that works and is sufficient tho.)</sup> cc `@steffahn` -- ty for the minimizations cc `@WaffleLapkin` -- since you're overseeing the feature stabilization :3 Fixes #135315 Fixes #135316
2025-01-30review comment: change `span` argumentEsteban Küber-4/+9
2025-01-30Remove `unwrap()`sEsteban Küber-3/+6
2025-01-30Add closure labelsEsteban Küber-2/+2