about summary refs log tree commit diff
path: root/compiler/rustc_middle/src/traits/mod.rs
AgeCommit message (Collapse)AuthorLines
2023-03-20Enforce non-lifetime-binders in supertrait preds are not object safeMichael Goulet-2/+11
2023-03-14Remove box expressions from HIRclubby789-2/+0
2023-02-16Clarify `DerivedObligationCause` may hold alias idAlan Egerton-1/+5
2023-02-06Rollup merge of #106477 - ↵Matthias Krüger-0/+2
Nathan-Fenner:nathanf/refined-error-span-trait-impl, r=compiler-errors Refine error spans for "The trait bound `T: Trait` is not satisfied" when passing literal structs/tuples This PR adds a new heuristic which refines the error span reported for "`T: Trait` is not satisfied" errors, by "drilling down" into individual fields of structs/enums/tuples to point to the "problematic" value. Here's a self-contained example of the difference in error span: ```rs struct Burrito<Filling> { filling: Filling, } impl <Filling: Delicious> Delicious for Burrito<Filling> {} fn eat_delicious_food<Food: Delicious>(food: Food) {} fn will_type_error() { eat_delicious_food(Burrito { filling: Kale }); // ^~~~~~~~~~~~~~~~~~~~~~~~~ (before) The trait bound `Kale: Delicious` is not satisfied // ^~~~ (after) The trait bound `Kale: Delicious` is not satisfied } ``` (kale is fine, this is just a silly food-based example) Before this PR, the error span is identified as the entire argument to the generic function `eat_delicious_food`. However, since only `Kale` is the "problematic" part, we can point at it specifically. In particular, the primary error message itself mentions the missing `Kale: Delicious` trait bound, so it's much clearer if this part is called out explicitly. --- The _existing_ heuristic tries to label the right function argument in `point_at_arg_if_possible`. It goes something like this: - Look at the broken base trait `Food: Delicious` and find which generics it mentions (in this case, only `Food`) - Look at the parameter type definitions and find which of them mention `Filling` (in this case, only `food`) - If there is exactly one relevant parameter, label the corresponding argument with the error span, instead of the entire call This PR extends this heuristic by further refining the resulting expression span in the new `point_at_specific_expr_if_possible` function. For each `impl` in the (broken) chain, we apply the following strategy: The strategy to determine this span involves connecting information about our generic `impl` with information about our (struct) type and the (struct) literal expression: - Find the `impl` (`impl <Filling: Delicious> Delicious for Burrito<Filling>`) that links our obligation (`Kale: Delicious`) with the parent obligation (`Burrito<Kale>: Delicious`) - Find the "original" predicate constraint in the impl (`Filling: Delicious`) which produced our obligation. - Find all of the generics that are mentioned in the predicate (`Filling`). - Examine the `Self` type in the `impl`, and see which of its type argument(s) mention any of those generics. - Examing the definition for the `Self` type, and identify (for each of its variants) if there's a unique field which uses those generic arguments. - If there is a unique field mentioning the "blameable" arguments, use that field for the error span. Before we do any of this logic, we recursively call `point_at_specific_expr_if_possible` on the parent obligation. Hence we refine the `expr` "outwards-in" and bail at the first kind of expression/impl we don't recognize. This function returns a `Result<&Expr, &Expr>` - either way, it returns the `Expr` whose span should be reported as an error. If it is `Ok`, then it means it refined successfull. If it is `Err`, then it may be only a partial success - but it cannot be refined even further. --- I added a new test file which exercises this new behavior. A few existing tests were affected, since their error spans are now different. In one case, this leads to a different code suggestion for the autofix - although the new suggestion isn't _wrong_, it is different from what used to be. This change doesn't create any new errors or remove any existing ones, it just adjusts the spans where they're presented. --- Some considerations: right now, this check occurs in addition to some similar logic in `adjust_fulfillment_error_for_expr_obligation` function, which tidies up various kinds of error spans (not just trait-fulfillment error). It's possible that this new code would be better integrated into that function (or another one) - but I haven't looked into this yet. Although this code only occurs when there's a type error, it's definitely not as efficient as possible. In particular, there are definitely some cases where it degrades to quadratic performance (e.g. for a trait `impl` with 100+ generic parameters or 100 levels deep nesting of generic types). I'm not sure if these are realistic enough to worry about optimizing yet. There's also still a lot of repetition in some of the logic, where the behavior for different types (namely, `struct` vs `enum` variant) is _similar_ but not the same. --- I think the biggest win here is better targeting for tuples; in particular, if you're using tuples + traits to express variadic-like functions, the compiler can't tell you which part of a tuple has the wrong type, since the span will cover the entire argument. This change allows the individual field in the tuple to be highlighted, as in this example: ``` // NEW LL | want(Wrapper { value: (3, q) }); | ---- ^ the trait `T3` is not implemented for `Q` // OLD LL | want(Wrapper { value: (3, q) }); | ---- ^~~~~~~~~~~~~~~~~~~~~~~~~ the trait `T3` is not implemented for `Q` ``` Especially with large tuples, the existing error spans are not very effective at quickly narrowing down the source of the problem.
2023-02-03intern external constraintsMichael Goulet-0/+1
2023-01-27Impl HashStable/Encodable/Decodable for ObligationCause.Camille GILLOT-10/+18
2023-01-23Point at specific field in struct literal when trait fulfillment failsNathan Fenner-0/+2
2023-01-23fix: use LocalDefId instead of HirId in trait resVincenzo Palazzo-5/+6
use LocalDefId instead of HirId in trait resolution to simplify the obligation clause resolution Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
2022-12-13squash OpaqueTy and ProjectionTy into AliasTyMichael Goulet-1/+1
2022-11-27Prefer doc comments over `//`-comments in compilerMaybe Waffle-1/+1
2022-11-25move 2 candidates into builtin candidatelcnr-23/+0
2022-11-24Avoid `GenFuture` shim when compiling async constructsArpad Borsos-0/+20
Previously, async constructs would be lowered to "normal" generators, with an additional `from_generator` / `GenFuture` shim in between to convert from `Generator` to `Future`. The compiler will now special-case these generators internally so that async constructs will *directly* implement `Future` without the need to go through the `from_generator` / `GenFuture` shim. The primary motivation for this change was hiding this implementation detail in stack traces and debuginfo, but it can in theory also help the optimizer as there is less abstractions to see through.
2022-11-19Improve spans for RPITIT object-safety errorsMichael Goulet-2/+8
2022-11-08selection failure: recompute applicable implslcnr-3/+0
2022-11-05Enforce rust-check ABI in signatures, callsMichael Goulet-0/+2
2022-11-03CleanupsBoxy-1/+8
2022-10-27Revert "Make ClosureOutlivesRequirement not rely on an unresolved type"Michael Goulet-1/+1
This reverts commit a6b5f95fb028f9feb4a2957c06b35035be2c6155.
2022-10-19Make ClosureOutlivesRequirement not rely on an unresolved typeMichael Goulet-1/+1
2022-10-17Duplicate comment in mod.rsSamuel Moelius-5/+0
2022-10-07Remove tuple candidate, nothing special about itMichael Goulet-9/+2
2022-09-16Add AscribeUserTypeProvePredicateJack Huey-0/+5
2022-09-16Add to_constraint_category to ObligationCause and SubregionOriginJack Huey-0/+8
2022-09-16Revert "Better errors for implied static bound"Jack Huey-13/+0
This reverts commit c75817b0a75d4b6b01ee10900ba5d01d4915e6a8.
2022-09-13Better errors for implied static boundJack Huey-0/+13
2022-09-12Rollup merge of #101681 - compiler-errors:rpitit-obj-safety, r=lcnrDylan DPC-0/+9
Deny return-position `impl Trait` in traits for object safety Fixes #101667
2022-09-12Auto merge of #100251 - compiler-errors:tuple-trait-2, r=jackh726bors-2/+9
Implement `std::marker::Tuple` Split out from #99943 (https://github.com/rust-lang/rust/pull/99943#pullrequestreview-1064459183). Implements part of rust-lang/compiler-team#537 r? `@jackh726`
2022-09-11Deny RPITIT for object safetyMichael Goulet-0/+9
2022-09-09rename `codegen_fulfill_obligation`lcnr-1/+1
2022-09-08Add associated item binding to non-param-ty where clause suggestionsMichael Goulet-2/+2
2022-08-24Note binding obligation causes for const equate errorsMichael Goulet-0/+7
2022-08-21More docsMichael Goulet-5/+11
2022-08-21Rework point-at-argMichael Goulet-0/+4
2022-08-07Built-in implementation of Tuple traitMichael Goulet-2/+9
2022-07-24Combine redundant obligation cause codesMichael Goulet-10/+2
2022-07-21And for patterns tooMichael Goulet-2/+5
2022-07-21Do if-expression obligation stuff less eagerlyMichael Goulet-7/+9
2022-07-16Rollup merge of #99290 - compiler-errors:revert-98794, r=lcnrMatthias Krüger-9/+1
Revert "Highlight conflicting param-env candidates" This reverts #98794, commit 08135254dcf22be0d5661ea8f75e703b29a83514. Seems to have caused an incremental compilation bug. The root cause of the incr comp bug is somewhat unrelated but is triggered by this PR, so I don't feel comfortable with having this PR in the codebase until it can be investigated further. Fixes #99233.
2022-07-15Propagate Expectation around binop typeck code to construct more precise ↵Will Crichton-1/+2
trait obligations for binops.
2022-07-15Revert "Highlight conflicting param-env candidates"Michael Goulet-9/+1
This reverts commit 08135254dcf22be0d5661ea8f75e703b29a83514.
2022-07-15remove tcx from ObligationCauseCode::spanMichael Goulet-1/+1
2022-07-15Remove some more usages of guess_head_spanMichael Goulet-6/+1
2022-07-12Move abstract const to rustc_middle::tykadmin-1/+1
2022-07-08Highlight conflicting param-env candidatesMichael Goulet-1/+9
2022-07-05Add #[derive(TypeVisitable)]Alan Egerton-12/+23
2022-06-28Fix trait object reborrow suggestionMichael Goulet-1/+1
2022-06-27Rollup merge of #98506 - compiler-errors:object-safety-suggestions, r=oli-obkMatthias Krüger-38/+29
Fix span issues in object safety suggestions Fixes #98500
2022-06-27Rollup merge of #97780 - compiler-errors:field-wfcheck-before-sized, r=jackh726Matthias Krüger-1/+1
Check ADT field is well-formed before checking it is sized Fixes #96810. There is one diagnostics regression, in [`src/test/ui/generic-associated-types/bugs/issue-80626.stderr`](https://github.com/rust-lang/rust/pull/97780/files#diff-53795946378e78a0af23a10277c628ff79091c18090fdc385801ee70c1ba6963). I am not super concerned about it, since it's GAT related. We _could_ fix it, possibly by using the `FieldSized` obligation cause code instead of `BuiltinDerivedObligation`. But that would require changing `Sized` trait confirmation and the `adt_sized_constraint` query.
2022-06-25Fix span issues in object safety suggestionsMichael Goulet-38/+29
2022-06-21Point at return expression for RPIT-related errorMichael Goulet-0/+3
2022-06-13remove unnecessary `to_string` and `String::new`Takayuki Maeda-2/+2