summary refs log tree commit diff
path: root/compiler/rustc_infer/src
AgeCommit message (Collapse)AuthorLines
2024-01-31Auto merge of #120346 - petrochenkov:ownodes, r=oli-obkbors-2/+2
hir: Refactor getters for owner nodes
2024-01-30Auto merge of #119101 - compiler-errors:outlives, r=lcnrbors-35/+70
Normalize region obligation in lexical region resolution with next-gen solver This normalizes region obligations when we `resolve_regions`, since they may be unnormalized with deferred projection equality. It's pretty hard to add tests that exercise this without also triggering MIR borrowck errors (because we don't normalize there yet). I've added one test with two revisions that should test that we both 1. normalize region obligations in the param env, and 2. normalize registered region obligations during lexical region resolution.
2024-01-30Rollup merge of #120342 - oli-obk:track_errors6, r=nnethercoteGuillaume Gomez-1/+2
Remove various `has_errors` or `err_count` uses follow up to https://github.com/rust-lang/rust/pull/119895 r? `@nnethercote` since you recently did something similar. There are so many more of these, but I wanted to get a PR out instead of growing the commit list indefinitely. The commits all work on their own and can be reviewed commit by commit.
2024-01-30hir: Remove `hir::Map::{owner,expect_owner}`Vadim Petrochenkov-2/+2
2024-01-30Remove the lifetime from `DiagnosticArgValue`.Nicholas Nethercote-6/+6
Because it's almost always static. This makes `impl IntoDiagnosticArg for DiagnosticArgValue` trivial, which is nice. There are a few diagnostics constructed in `compiler/rustc_mir_build/src/check_unsafety.rs` and `compiler/rustc_mir_transform/src/errors.rs` that now need symbols converted to `String` with `to_string` instead of `&str` with `as_str`, but that' no big deal, and worth it for the simplifications elsewhere.
2024-01-30Apply suggestions from reviewMichael Goulet-36/+22
2024-01-30Normalize caller boundsMichael Goulet-9/+30
2024-01-30Deeply normalize when processing registered region obligationsMichael Goulet-8/+36
2024-01-29Stop using `String` for error codes.Nicholas Nethercote-46/+46
Error codes are integers, but `String` is used everywhere to represent them. Gross! This commit introduces `ErrCode`, an integral newtype for error codes, replacing `String`. It also introduces a constant for every error code, e.g. `E0123`, and removes the `error_code!` macro. The constants are imported wherever used with `use rustc_errors::codes::*`. With the old code, we have three different ways to specify an error code at a use point: ``` error_code!(E0123) // macro call struct_span_code_err!(dcx, span, E0123, "msg"); // bare ident arg to macro call \#[diag(name, code = "E0123")] // string struct Diag; ``` With the new code, they all use the `E0123` constant. ``` E0123 // constant struct_span_code_err!(dcx, span, E0123, "msg"); // constant \#[diag(name, code = E0123)] // constant struct Diag; ``` The commit also changes the structure of the error code definitions: - `rustc_error_codes` now just defines a higher-order macro listing the used error codes and nothing else. - Because that's now the only thing in the `rustc_error_codes` crate, I moved it into the `lib.rs` file and removed the `error_codes.rs` file. - `rustc_errors` uses that macro to define everything, e.g. the error code constants and the `DIAGNOSTIC_TABLES`. This is in its new `codes.rs` file.
2024-01-25Track ErrorGuaranteed instead of conjuring it from thin airOli Scherer-1/+2
2024-01-25Remove unused featuresclubby789-2/+0
2024-01-24Account for expected `dyn Trait` found `impl Trait`Esteban Küber-0/+20
2024-01-24On E0308 involving `dyn Trait`, mention trait objectsEsteban Küber-0/+49
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-23Rollup merge of #120261 - estebank:issue-102629, r=wesleywiserLeón Orell Valerian Liehr-16/+102
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-23Suggest boxing both arms of if expr if that solves divergent arms involving ↵Esteban Küber-16/+70
`impl Trait` When encountering the following ```rust // run-rustfix trait Trait {} struct Struct; impl Trait for Struct {} fn foo() -> Box<dyn Trait> { Box::new(Struct) } fn bar() -> impl Trait { Struct } fn main() { let _ = if true { Struct } else { foo() //~ ERROR E0308 }; let _ = if true { foo() } else { Struct //~ ERROR E0308 }; let _ = if true { Struct } else { bar() // impl Trait }; let _ = if true { bar() // impl Trait } else { Struct }; } ``` suggest boxing both arms ```rust let _ = if true { Box::new(Struct) as Box<dyn Trait> } else { Box::new(bar()) }; let _ = if true { Box::new(bar()) as Box<dyn Trait> } else { Box::new(Struct) }; ```
2024-01-22Suggest boxing if then expr if that solves divergent armsEsteban Küber-0/+32
When encountering ```rust let _ = if true { Struct } else { foo() // -> Box<dyn Trait> }; ``` if `Struct` implements `Trait`, suggest boxing the then arm tail expression. Part of #102629.
2024-01-22Make generic const type mismatches not hide trait impls from the trait solverOli Scherer-24/+10
2024-01-22Tweak error counting.Nicholas Nethercote-5/+6
We have several methods indicating the presence of errors, lint errors, and delayed bugs. I find it frustrating that it's very unclear which one you should use in any particular spot. This commit attempts to instill a basic principle of "use the least general one possible", because that reflects reality in practice -- `has_errors` is the least general one and has by far the most uses (esp. via `abort_if_errors`). Specifics: - Add some comments giving some usage guidelines. - Prefer `has_errors` to comparing `err_count` to zero. - Remove `has_errors_or_span_delayed_bugs` because it's a weird one: in the cases where we need to count delayed bugs, we should really be counting lint errors as well. - Rename `is_compilation_going_to_fail` as `has_errors_or_lint_errors_or_span_delayed_bugs`, for consistency with `has_errors` and `has_errors_or_lint_errors`. - Change a few other `has_errors_or_lint_errors` calls to `has_errors`, as per the "least general" principle. This didn't turn out to be as neat as I hoped when I started, but I think it's still an improvement.
2024-01-20Rollup merge of #119613 - gavinleroy:expose-obligations, r=lcnrMatthias Krüger-1/+24
Expose Obligations created during type inference. This PR is a first pass at exposing the trait obligations generated and solved for during the type-check progress. Exposing these obligations allows for rustc plugins to use the public interface for proof trees (provided by the next gen trait solver). The changes proposed track *all* obligations during the type-check process, this is desirable to not only look at the trees of failed obligations, but also those of successfully proved obligations. This feature is placed behind an unstable compiler option `track-trait-obligations` which should be used together with the `next-solver` option. I should note that the main interface is the function `inspect_typeck` made public in `rustc_hir_typeck/src/lib.rs` which allows the caller to provide a callback granting access to the `FnCtxt`. r? `@lcnr`
2024-01-19Add trait obligation tracking to FulfillCtxt and expose FnCtxt in ↵Gavin Gray-1/+24
rustc_infer using callback. Pass each obligation to an fn callback with its respective inference context. This avoids needing to keep around copies of obligations or inference contexts. Specify usability of inspect_typeck in comment.
2024-01-18Rollup merge of #120021 - lcnr:const-var-value, r=compiler-errorsMatthias Krüger-146/+60
don't store const var origins for known vars r? types
2024-01-17Auto merge of #119922 - nnethercote:fix-Diag-code-is_lint, r=oli-obkbors-2/+2
Rework how diagnostic lints are stored. `Diagnostic::code` has the type `DiagnosticId`, which has `Error` and `Lint` variants. Plus `Diagnostic::is_lint` is a bool, which should be redundant w.r.t. `Diagnostic::code`. Seems simple. Except it's possible for a lint to have an error code, in which case its `code` field is recorded as `Error`, and `is_lint` is required to indicate that it's a lint. This is what happens with `derive(LintDiagnostic)` lints. Which means those lints don't have a lint name or a `has_future_breakage` field because those are stored in the `DiagnosticId::Lint`. It's all a bit messy and confused and seems unintentional. This commit: - removes `DiagnosticId`; - changes `Diagnostic::code` to `Option<String>`, which means both errors and lints can straightforwardly have an error code; - changes `Diagnostic::is_lint` to `Option<IsLint>`, where `IsLint` is a new type containing a lint name and a `has_future_breakage` bool, so all lints can have those, error code or not. r? `@oli-obk`
2024-01-16Auto merge of #119947 - compiler-errors:old-solver-instantiate-response, r=lcnrbors-4/+12
Make sure to instantiate placeholders correctly in old solver When creating the query substitution guess for an input placeholder type like `!1_T` (in universe 1), we were guessing the response substitution with something like `!0_T`. This failed to unify with `!1_T`, causing an ICE. This PR reworks the query substitution guess code to work a bit more like the new solver. I'm *pretty* sure this is correct, though I'd really appreciate some scrutiny from someone (*cough* lcnr) who knows a bit more about query instantiation :) Fixes #119941 r? lcnr
2024-01-16don't store const var origins for known varslcnr-146/+60
2024-01-15Rollup merge of #119897 - compiler-errors:fulfillment-errors, r=lcnrMatthias Krüger-14/+14
`OutputTypeParameterMismatch` -> `SignatureMismatch` I'm probably missing something that made this rename more complicated. What did you end up getting stuck on when renaming this selection error, `@lcnr?` **also** I renamed the `FulfillmentErrorCode` variants. This is just churn but I wanted to do it forever. I can move it out of this PR if desired. r? lcnr
2024-01-15Rollup merge of #119818 - oli-obk:even_more_follow_up_errors3, r=compiler-errorsMatthias Krüger-7/+0
Silence some follow-up errors [3/x] this is one piece of the requested cleanups from https://github.com/rust-lang/rust/pull/117449 Keep error types around, even in obligations. These help silence follow-up errors, as we now figure out that some types (most notably inference variables) are equal to an error type. But it also allows figuring out more types in the presence of errors, possibly causing more errors.
2024-01-14Rework how diagnostic lints are stored.Nicholas Nethercote-2/+2
`Diagnostic::code` has the type `DiagnosticId`, which has `Error` and `Lint` variants. Plus `Diagnostic::is_lint` is a bool, which should be redundant w.r.t. `Diagnostic::code`. Seems simple. Except it's possible for a lint to have an error code, in which case its `code` field is recorded as `Error`, and `is_lint` is required to indicate that it's a lint. This is what happens with `derive(LintDiagnostic)` lints. Which means those lints don't have a lint name or a `has_future_breakage` field because those are stored in the `DiagnosticId::Lint`. It's all a bit messy and confused and seems unintentional. This commit: - removes `DiagnosticId`; - changes `Diagnostic::code` to `Option<String>`, which means both errors and lints can straightforwardly have an error code; - changes `Diagnostic::is_lint` to `Option<IsLint>`, where `IsLint` is a new type containing a lint name and a `has_future_breakage` bool, so all lints can have those, error code or not.
2024-01-13Make sure to instantiate placeholders correctly in old solverMichael Goulet-4/+12
2024-01-12Remove redundant Code from FulfillmentErrorCode variantsMichael Goulet-14/+14
2024-01-12rename `reported_signature_mismatch` to reflect its uselcnr-3/+3
2024-01-11Keep error types around, even in obligations.Oli Scherer-7/+0
These help silence follow up errors
2024-01-11Rollup merge of #118915 - compiler-errors:alias-nits, r=lcnrMatthias Krüger-8/+7
Add some comments, add `can_define_opaque_ty` check to `try_normalize_ty_recur` Follow-up from #117278, since I was recently re-reviewing this code.
2024-01-10Simplify some redundant namesMichael Goulet-8/+7
2024-01-10Rename consuming chaining methods on `DiagnosticBuilder`.Nicholas Nethercote-1/+1
In #119606 I added them and used a `_mv` suffix, but that wasn't great. A `with_` prefix has three different existing uses. - Constructors, e.g. `Vec::with_capacity`. - Wrappers that provide an environment to execute some code, e.g. `with_session_globals`. - Consuming chaining methods, e.g. `Span::with_{lo,hi,ctxt}`. The third case is exactly what we want, so this commit changes `DiagnosticBuilder::foo_mv` to `DiagnosticBuilder::with_foo`. Thanks to @compiler-errors for the suggestion.
2024-01-10Add `DiagCtxt::delayed_bug`.Nicholas Nethercote-21/+14
We have `span_delayed_bug` and often pass it a `DUMMY_SP`. This commit adds `delayed_bug`, which matches pairs like `err`/`span_err` and `warn`/`span_warn`.
2024-01-10Rename `struct_span_err!` as `struct_span_code_err!`.Nicholas Nethercote-6/+6
Because it takes an error code after the span. This avoids the confusing overlap with the `DiagCtxt::struct_span_err` method, which doesn't take an error code.
2024-01-09Auto merge of #118968 - aliemjay:canon-static, r=lcnrbors-56/+27
unify query canonicalization mode Exclude from canonicalization only the static lifetimes that appear in the param env because of #118965 . Any other occurrence can be canonicalized safely AFAICT. r? `@lcnr`
2024-01-08Remove `DiagnosticBuilder::delay_as_bug_without_consuming`.Nicholas Nethercote-2/+2
The existing uses are replaced in one of three ways. - In a function that also has calls to `emit`, just rearrange the code so that exactly one of `delay_as_bug` or `emit` is called on every path. - In a function returning a `DiagnosticBuilder`, use `downgrade_to_delayed_bug`. That's good enough because it will get emitted later anyway. - In `unclosed_delim_err`, one set of errors is being replaced with another set, so just cancel the original errors.
2024-01-08Remove all eight `DiagnosticBuilder::*_with_code` methods.Nicholas Nethercote-9/+9
These all have relatively low use, and can be perfectly emulated with a simpler construction method combined with `code` or `code_mv`.
2024-01-08Use chaining in `DiagnosticBuilder` construction.Nicholas Nethercote-3/+2
To avoid the use of a mutable local variable, and because it reads more nicely.
2024-01-08Make `DiagnosticBuilder::emit` consuming.Nicholas Nethercote-3/+3
This works for most of its call sites. This is nice, because `emit` very much makes sense as a consuming operation -- indeed, `DiagnosticBuilderState` exists to ensure no diagnostic is emitted twice, but it uses runtime checks. For the small number of call sites where a consuming emit doesn't work, the commit adds `DiagnosticBuilder::emit_without_consuming`. (This will be removed in subsequent commits.) Likewise, `emit_unless` becomes consuming. And `delay_as_bug` becomes consuming, while `delay_as_bug_without_consuming` is added (which will also be removed in subsequent commits.) All this requires significant changes to `DiagnosticBuilder`'s chaining methods. Currently `DiagnosticBuilder` method chaining uses a non-consuming `&mut self -> &mut Self` style, which allows chaining to be used when the chain ends in `emit()`, like so: ``` struct_err(msg).span(span).emit(); ``` But it doesn't work when producing a `DiagnosticBuilder` value, requiring this: ``` let mut err = self.struct_err(msg); err.span(span); err ``` This style of chaining won't work with consuming `emit` though. For that, we need to use to a `self -> Self` style. That also would allow `DiagnosticBuilder` production to be chained, e.g.: ``` self.struct_err(msg).span(span) ``` However, removing the `&mut self -> &mut Self` style would require that individual modifications of a `DiagnosticBuilder` go from this: ``` err.span(span); ``` to this: ``` err = err.span(span); ``` There are *many* such places. I have a high tolerance for tedious refactorings, but even I gave up after a long time trying to convert them all. Instead, this commit has it both ways: the existing `&mut self -> Self` chaining methods are kept, and new `self -> Self` chaining methods are added, all of which have a `_mv` suffix (short for "move"). Changes to the existing `forward!` macro lets this happen with very little additional boilerplate code. I chose to add the suffix to the new chaining methods rather than the existing ones, because the number of changes required is much smaller that way. This doubled chainging is a bit clumsy, but I think it is worthwhile because it allows a *lot* of good things to subsequently happen. In this commit, there are many `mut` qualifiers removed in places where diagnostics are emitted without being modified. In subsequent commits: - chaining can be used more, making the code more concise; - more use of chaining also permits the removal of redundant diagnostic APIs like `struct_err_with_code`, which can be replaced easily with `struct_err` + `code_mv`; - `emit_without_diagnostic` can be removed, which simplifies a lot of machinery, removing the need for `DiagnosticBuilderState`.
2024-01-05Rollup merge of #119506 - ↵Matthias Krüger-1/+4
compiler-errors:visibilities-for-object-safety-error, r=Nilstrieb Use `resolutions(()).effective_visiblities` to avoid cycle errors in `report_object_error` Inside of `report_object_error`, using the `effective_visibilities` query causes cycles since it calls `type_of`, which itself may call `typeck`, which may end up reporting its own object-safety errors. Fixes #119346 Fixes #119502
2024-01-05Rollup merge of #119538 - nnethercote:cleanup-errors-5, r=compiler-errorsMichael Goulet-24/+18
Cleanup error handlers: round 5 More rustc_errors cleanups. A sequel to https://github.com/rust-lang/rust/pull/119171. r? ````@compiler-errors````
2024-01-05Rollup merge of #119148 - estebank:bare-traits, r=davidtwcoMichael Goulet-1/+21
Tweak suggestions for bare trait used as a type ``` error[E0782]: trait objects must include the `dyn` keyword --> $DIR/not-on-bare-trait-2021.rs:11:11 | LL | fn bar(x: Foo) -> Foo { | ^^^ | help: use a generic type parameter, constrained by the trait `Foo` | LL | fn bar<T: Foo>(x: T) -> Foo { | ++++++++ ~ help: you can also use `impl Foo`, but users won't be able to specify the type paramer when calling the `fn`, having to rely exclusively on type inference | LL | fn bar(x: impl Foo) -> Foo { | ++++ help: alternatively, use a trait object to accept any type that implements `Foo`, accessing its methods at runtime using dynamic dispatch | LL | fn bar(x: &dyn Foo) -> Foo { | ++++ error[E0782]: trait objects must include the `dyn` keyword --> $DIR/not-on-bare-trait-2021.rs:11:19 | LL | fn bar(x: Foo) -> Foo { | ^^^ | help: use `impl Foo` to return an opaque type, as long as you return a single underlying type | LL | fn bar(x: Foo) -> impl Foo { | ++++ help: alternatively, you can return an owned trait object | LL | fn bar(x: Foo) -> Box<dyn Foo> { | +++++++ + ``` Fix #119525: ``` error[E0038]: the trait `Ord` cannot be made into an object --> $DIR/bare-trait-dont-suggest-dyn.rs:3:33 | LL | fn ord_prefer_dot(s: String) -> Ord { | ^^^ `Ord` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: the trait cannot be made into an object because it uses `Self` as a type parameter ::: $SRC_DIR/core/src/cmp.rs:LL:COL | = note: the trait cannot be made into an object because it uses `Self` as a type parameter help: consider using an opaque type instead | LL | fn ord_prefer_dot(s: String) -> impl Ord { | ++++ ```
2024-01-05Use `resolutions(()).effective_visiblities` to avoid cycle errorsMichael Goulet-1/+4
2024-01-04Silence redundant warning when E0038 will be emittedEsteban Küber-1/+21
2024-01-03Rename some `Diagnostic` setters.Nicholas Nethercote-24/+18
`Diagnostic` has 40 methods that return `&mut Self` and could be considered setters. Four of them have a `set_` prefix. This doesn't seem necessary for a type that implements the builder pattern. This commit removes the `set_` prefixes on those four methods.
2024-01-01Minor improvements in comment forGurinder Singh-2/+2
2023-12-30Auto merge of #116012 - cjgillot:gvn-const, r=oli-obkbors-1/+4
Implement constant propagation on top of MIR SSA analysis This implements the idea I proposed in https://github.com/rust-lang/rust/pull/110719#issuecomment-1718324700 Based on https://github.com/rust-lang/rust/pull/109597 The value numbering "GVN" pass formulates each rvalue that appears in MIR with an abstract form (the `Value` enum), and assigns an integer `VnIndex` to each. This abstract form can be used to deduplicate values, reusing an earlier local that holds the same value instead of recomputing. This part is proposed in #109597. From this abstract representation, we can perform more involved simplifications, for example in https://github.com/rust-lang/rust/pull/111344. With the abstract representation `Value`, we can also attempt to evaluate each to a constant using the interpreter. This builds a `VnIndex -> OpTy` map. From this map, we can opportunistically replace an operand or a rvalue with a constant if their value has an associated `OpTy`. The most relevant commit is [Evaluated computed values to constants.](https://github.com/rust-lang/rust/commit/2767c4912ea249c2f613a9cedcd6c13ea1237e54)" r? `@oli-obk`
2023-12-28Remove movability from TyKind::CoroutineMichael Goulet-2/+2