about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection
AgeCommit message (Collapse)AuthorLines
2023-02-06Rollup merge of #106477 - ↵Matthias Krüger-1/+3
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-06Modify existing bounds if they existEdward Shen-0/+2
2023-02-06remove unused importsklensy-1/+0
2023-02-03intern external constraintsMichael Goulet-21/+17
2023-02-03Rollup merge of #107427 - detrumi:builtin-impl-candidates, r=compiler-errorsDylan DPC-0/+25
Add candidates for DiscriminantKind builtin Part of #107379
2023-02-03Autotrait bounds on dyn-safe trait methodsDavid Tolnay-10/+50
2023-02-03Use new helper inside probeWilco Kusee-6/+2
2023-02-01Improve pretty-printing of `HirIdValidator` errorsArpad Borsos-1/+1
This now uses `node_to_string` for both missing and seen Ids, which includes the snippet of code for which the Id was allocated. Also removes the duplicated printing of `HirId`, as `node_to_string` includes that already. Similarly, changes all other users of `node_to_string` that do so, and changes the output of `node_to_string`, which is now "$hirid ($what `$span` in $path)".
2023-02-01Simplify discriminant_kind goal using new helper functionWilco Kusee-14/+7
2023-02-01Add candidates for DiscriminantKind builtinWilco Kusee-0/+36
2023-01-31Rollup merge of #107486 - compiler-errors:bound-ty-keep-name, r=oli-obkGuillaume Gomez-2/+2
Track bound types like bound regions When we instantiate bound types into placeholder types, we throw away the names for some reason. These names are particularly useful for error reporting once we have `for<T>` binders. r? types
2023-01-31Rollup merge of #107467 - WaffleLapkin:uneq, r=oli-obkGuillaume Gomez-14/+17
Improve enum checks Some light refactoring.
2023-01-31Rollup merge of #107348 - lcnr:project-solve-new, r=compiler-errorsGuillaume Gomez-45/+86
small refactor to new projection code extract `eq_term_and_make_canonical_response` into a helper function which also is another guarantee that the expected term does not influence candidate selection for projections. also change `evaluate_all(vec![single_goal])` to use `evaluate_goal`. the second commit now also adds a `debug_assert!` to `evaluate_goal`.
2023-01-31Auto merge of #106399 - estebank:type-err-span-label, r=nagisabors-3/+9
Modify primary span label for E0308 Looking at the reactions to https://hachyderm.io/`@ekuber/109622160673605438,` a lot of people seem to have trouble understanding the current output, where the primary span label on type errors talks about the specific types that diverged, but these can be deeply nested type parameters. Because of that we could see "expected i32, found u32" in the label while the note said "expected Vec<i32>, found Vec<u32>". This understandably confuses people. I believe that once people learn to read these errors it starts to make more sense, but this PR changes the output to be more in line with what people might expect, without sacrificing terseness. Fix #68220.
2023-01-31Rollup merge of #107479 - compiler-errors:probe-can-call-ocx, r=BoxyUwUYuki Okushi-1/+1
Use `ObligationCtxt::new_in_snapshot` in `satisfied_from_param_env` We can evaluate nested `ConstEvaluatable` obligations in an evaluation probe, which will ICE if we use `ObligationCtxt::new`. Fixes #107474 Fixes #106666 r? `@BoxyUwU` but feel free to reassign cc `@JulianKnodt` who i think added this assertion code Not sure if the rustdoc test is needed, but can't hurt. They're the same root cause, though.
2023-01-30Track bound types like bound regionsMichael Goulet-2/+2
2023-01-30Tweak E0271 wordingEsteban Küber-2/+6
2023-01-30Modify primary span label for E0308Esteban Küber-1/+3
The previous output was unintuitive to users.
2023-01-30nitsMichael Goulet-16/+16
2023-01-30Trait upcasting support in new solverMichael Goulet-59/+107
2023-01-30Implement unsizing in the new trait solverMichael Goulet-0/+192
2023-01-30Use ObligationCtxt::new_in_snapshot in satisfied_from_param_envMichael Goulet-1/+1
2023-01-30Replace enum `==`s with `match`es where it makes senseMaybe Waffle-14/+17
2023-01-30Rollup merge of #107146 - compiler-errors:unsizing-params, r=cjgillotDylan DPC-44/+10
Make `unsizing_params_for_adt` into a query Addresses a FIXME in confirmation. r? ``@ghost``
2023-01-29Auto merge of #106253 - nbdd0121:upcast, r=compiler-errorsbors-20/+39
Skip possible where_clause_object_safety lints when checking `multiple_supertrait_upcastable` Fix #106247 To achieve this, I lifted the `WhereClauseReferencesSelf` out from `object_safety_violations` and move it into `is_object_safe` (which is changed to a new query). cc `@dtolnay` r? `@compiler-errors`
2023-01-29Rollup merge of #107401 - ↵Matthias Krüger-8/+5
lenko-d:remove_the_usize_field_from_CandidateSource_AliasBound, r=compiler-errors remove the usize field from CandidateSource::AliasBound Fixes [#107380](https://github.com/rust-lang/rust/issues/107380)
2023-01-28Make unsizing_params_for_adt into a queryMichael Goulet-44/+10
2023-01-28Auto merge of #107303 - compiler-errors:intern-canonical-var-values, r=lcnrbors-26/+4
Intern `CanonicalVarValues` So that they are copy :sparkles:
2023-01-28Auto merge of #107206 - cjgillot:no-h2l-map, r=WaffleLapkinbors-9/+6
Remove HirId -> LocalDefId map from HIR. Having this map in HIR prevents the creating of new definitions after HIR has been built. Thankfully, we do not need it. Based on https://github.com/rust-lang/rust/pull/103902
2023-01-28Rename `is_object_safe` to `check_is_object_safe` to hint side effectsGary Guo-8/+11
2023-01-28Make `is_object_safe` a query and move lint_object_unsafe_trait call thereGary Guo-14/+32
2023-01-28Replace `object_safety_violations().is_empty()` calls with `is_object_safe`Gary Guo-3/+1
2023-01-28Use field-less variant for AliasBound.Lenko Donchev-6/+5
2023-01-28Rollup merge of #107398 - scottmcm:its-their-funeral, r=dtolnayMatthias Krüger-4/+4
Remove `ControlFlow::{BREAK, CONTINUE}` Libs-API decided to remove these in #102697. Follow-up to #107023, which removed them from `compiler/`, but a couple new ones showed up since that was merged. r? libs
2023-01-28Remove `HirId -> LocalDefId` map from HIR.Camille GILLOT-9/+6
2023-01-27remove the usize field from CandidateSource::AliasBoundLenko Donchev-7/+5
2023-01-28Rollup merge of #107344 - compiler-errors:new-solver-tweaks, r=lcnrMatthias Krüger-23/+54
Minor tweaks in the new solver 1. `InferCtxt::probe` is not needed in `compute_subtype_goal` and `compute_well_formed_goal`. 2. Add a handful of comments. 3. Add a micro-optimization in `consider_assumption` where we check the def-ids of the assumption and goal match before instantiating any binders. r? ``@lcnr``
2023-01-28Rollup merge of #107306 - ↵Matthias Krüger-10/+20
compiler-errors:correct-sugg-for-closure-arg-needs-borrow, r=oli-obk Correct suggestions for closure arguments that need a borrow Fixes #107301 by dealing with binders correctly Fixes another issue where we were suggesting adding just `&` when we expected `&mut _` in a closure arg
2023-01-28Rollup merge of #107103 - compiler-errors:new-solver-evaluate_obligation, r=lcnrMatthias Krüger-6/+37
Use new solver in `evaluate_obligation` query (when new solver is enabled) (only when `-Ztrait-solver=next`, of course) ... Does this make sense? It seems to me like it should be reasonable, but maybe there's some reason why this is a bad idea. r? ``@lcnr`` Needs a perf run because I guess this `solver == TraitSolver::Next` check is on a hot path.
2023-01-27Remove `ControlFlow::{BREAK, CONTINUE}`Scott McMurray-4/+4
Libs-API decided to remove these in #102697. Follow-up to #107023, which removed them from `compiler/`, but a couple new ones showed up since that was merged.
2023-01-28Auto merge of #101692 - cjgillot:generator-lazy-witness, r=oli-obkbors-40/+257
Compute generator saved locals on MIR Generators are currently type-checked by introducing a `witness` type variable, which is unified with a `GeneratorWitness(captured types)` whose purpose is to ensure that the auto traits correctly migrate from the captured types to the `witness` type. This requires computing the captured types on HIR during type-checking, only to re-do it on MIR later. This PR proposes to drop the HIR-based computation, and only keep the MIR one. This is done in 3 steps. 1. During type-checking, the `witness` type variable is never unified. This allows to stall all the obligations that depend on it until the end of type-checking. Then, the stalled obligations are marked as successful, and saved into the typeck results for later verification. 2. At type-checking writeback, `witness` is replaced by `GeneratorWitnessMIR(def_id, substs)`. From this point on, all trait selection involving `GeneratorWitnessMIR` will fetch the MIR-computed locals, similar to what opaque types do. There is no lifetime to be preserved here: we consider all the lifetimes appearing in this witness type to be higher-ranked. 3. After borrowck, the stashed obligations are verified against the actually computed types, in the `check_generator_obligations` query. If any obligation was wrongly marked as fulfilled in step 1, it should be reported here. There are still many issues: - ~I am not too happy having to filter out some locals from the checked bounds, I think this is MIR building that introduces raw pointers polluting the analysis;~ solved by a check specific to static variables. - the diagnostics for captured types don't show where they are used/dropped; - I do not attempt to support chalk. cc `@eholk` `@jyn514` for the drop-tracking work r? `@oli-obk` as you warned me of potential unsoundness
2023-01-27Pacify tidy.Camille GILLOT-5/+5
2023-01-27Restrict amount of ignored locals.Camille GILLOT-1/+1
2023-01-27Compute generator saved locals on MIR.Camille GILLOT-9/+184
2023-01-27Micro-optimization in consider_assumptionMichael Goulet-2/+6
2023-01-27Add some commentsMichael Goulet-0/+31
2023-01-27No need to probe when computing goalsMichael Goulet-21/+17
2023-01-27Introduce GeneratorWitnessMIR.Camille GILLOT-3/+33
2023-01-27Separate trait selection from ambiguity reporting.Camille GILLOT-23/+3
2023-01-27Do not abort compilation when failing to normalize opaque types.Camille GILLOT-11/+43