about summary refs log tree commit diff
path: root/compiler/rustc_infer
AgeCommit message (Collapse)AuthorLines
2024-02-10hir: Remove `hir::Map::{opt_parent_id,parent_id,get_parent,find_parent}`Vadim Petrochenkov-24/+23
2024-02-10Auto merge of #120712 - compiler-errors:async-closures-harmonize, r=oli-obkbors-1/+2
Harmonize `AsyncFn` implementations, make async closures conditionally impl `Fn*` traits This PR implements several changes to the built-in and libcore-provided implementations of `Fn*` and `AsyncFn*` to address two problems: 1. async closures do not implement the `Fn*` family traits, leading to breakage: https://crater-reports.s3.amazonaws.com/pr-120361/index.html 2. *references* to async closures do not implement `AsyncFn*`, as a consequence of the existing blanket impls of the shape `AsyncFn for F where F: Fn, F::Output: Future`. In order to fix (1.), we implement `Fn` traits appropriately for async closures. It turns out that async closures can: * always implement `FnOnce`, meaning that they're drop-in compatible with `FnOnce`-bound combinators like `Option::map`. * conditionally implement `Fn`/`FnMut` if they have no captures, which means that existing usages of async closures should *probably* work without breakage (crater checking this: https://github.com/rust-lang/rust/pull/120712#issuecomment-1930587805). In order to fix (2.), we make all of the built-in callables implement `AsyncFn*` via built-in impls, and instead adjust the blanket impls for `AsyncFn*` provided by libcore to match the blanket impls for `Fn*`.
2024-02-10Remove unnecessary `min_specialization` after bootstrapZalathar-1/+1
These crates all needed specialization for `newtype_index!`, which will no longer be necessary when the current nightly eventually becomes the next bootstrap compiler.
2024-02-09Rollup merge of #120828 - nnethercote:fix-stash-steal, r=oli-obkMatthias Krüger-19/+25
Fix `ErrorGuaranteed` unsoundness with stash/steal. When you stash an error, the error count is incremented. You can then use the non-zero error count to get an `ErrorGuaranteed`. You can then steal the error, which decrements the error count. You can then cancel the error. Example code: ``` fn unsound(dcx: &DiagCtxt) -> ErrorGuaranteed { let sp = rustc_span::DUMMY_SP; let k = rustc_errors::StashKey::Cycle; dcx.struct_err("bogus").stash(sp, k); // increment error count on stash let guar = dcx.has_errors().unwrap(); // ErrorGuaranteed from error count > 0 let err = dcx.steal_diagnostic(sp, k).unwrap(); // decrement error count on steal err.cancel(); // cancel error guar // ErrorGuaranteed with no error emitted! } ``` This commit fixes the problem in the simplest way: by not counting stashed errors in `DiagCtxt::{err_count,has_errors}`. However, just doing this without any other changes leads to over 40 ui test failures. Mostly because of uninteresting extra errors (many saying "type annotations needed" when type inference fails), and in a few cases, due to delayed bugs causing ICEs when no normal errors are printed. To fix these, this commit adds `DiagCtxt::stashed_err_count`, and uses it in three places alongside `DiagCtxt::{has_errors,err_count}`. It's dodgy to rely on it, because unlike `DiagCtxt::err_count` it can go up and down. But it's needed to preserve existing behaviour, and at least the three places that need it are now obvious. r? oli-obk
2024-02-09Rollup merge of #120693 - nnethercote:invert-diagnostic-lints, r=davidtwcoMatthias Krüger-0/+2
Invert diagnostic lints. That is, change `diagnostic_outside_of_impl` and `untranslatable_diagnostic` from `allow` to `deny`, because more than half of the compiler has been converted to use translated diagnostics. This commit removes more `deny` attributes than it adds `allow` attributes, which proves that this change is warranted. r? ````@davidtwco````
2024-02-09Fix `ErrorGuaranteed` unsoundness with stash/steal.Nicholas Nethercote-19/+25
When you stash an error, the error count is incremented. You can then use the non-zero error count to get an `ErrorGuaranteed`. You can then steal the error, which decrements the error count. You can then cancel the error. Example code: ``` fn unsound(dcx: &DiagCtxt) -> ErrorGuaranteed { let sp = rustc_span::DUMMY_SP; let k = rustc_errors::StashKey::Cycle; dcx.struct_err("bogus").stash(sp, k); // increment error count on stash let guar = dcx.has_errors().unwrap(); // ErrorGuaranteed from error count > 0 let err = dcx.steal_diagnostic(sp, k).unwrap(); // decrement error count on steal err.cancel(); // cancel error guar // ErrorGuaranteed with no error emitted! } ``` This commit fixes the problem in the simplest way: by not counting stashed errors in `DiagCtxt::{err_count,has_errors}`. However, just doing this without any other changes leads to over 40 ui test failures. Mostly because of uninteresting extra errors (many saying "type annotations needed" when type inference fails), and in a few cases, due to delayed bugs causing ICEs when no normal errors are printed. To fix these, this commit adds `DiagCtxt::stashed_err_count`, and uses it in three places alongside `DiagCtxt::{has_errors,err_count}`. It's dodgy to rely on it, because unlike `DiagCtxt::err_count` it can go up and down. But it's needed to preserve existing behaviour, and at least the three places that need it are now obvious.
2024-02-08Rollup merge of #120590 - compiler-errors:dead, r=NilstriebMatthias Krüger-7/+5
Remove unused args from functions `#[instrument]` suppresses the unused arguments from a function, *and* suppresses unused methods too! This PR removes things which are only used via `#[instrument]` calls, and fixes some other errors (privacy?) that I will comment inline. It's possible that some of these arguments were being passed in for the purposes of being instrumented, but I am unconvinced by most of them.
2024-02-08sort suggestions for object diagnosticMichael Goulet-1/+2
2024-02-08Auto merge of #120544 - BoxyUwU:enter_forall, r=lcnrbors-74/+106
Introduce `enter_forall` to supercede `instantiate_binder_with_placeholders` r? `@lcnr` Long term we'd like to experiment with decrementing the universe count after "exiting" binders so that we do not end up creating infer vars in non-root universes even when they logically reside in the root universe. The fact that we dont do this currently results in a number of issues in the new trait solver where we consider goals to be ambiguous because otherwise it would require lowering the universe of an infer var. i.e. the goal `?x.0 eq <T as Trait<?y.1>>::Assoc` where the alias is rigid would not be able to instantiate `?x` with the alias as there would be a universe error. This PR is the first-ish sort of step towards being able to implement this as eventually we would want to decrement the universe in `enter_forall`. Unfortunately its Difficult to actually implement decrementing universes nicely so this is a separate step which moves us closer to the long term goal :sparkles:
2024-02-08reviews + rebaseBoxy-57/+49
2024-02-08rename `instantiate_binder_with_placeholders`Boxy-7/+24
2024-02-08introduce `enter_forall`Boxy-34/+57
2024-02-08Rollup merge of #120734 - nnethercote:SubdiagnosticMessageOp, r=compiler-errorsMatthias Krüger-42/+12
Add `SubdiagnosticMessageOp` as a trait alias. It avoids a lot of repetition. r? matthewjasper
2024-02-08Add `SubdiagnosticMessageOp` as a trait alias.Nicholas Nethercote-42/+12
It avoids a lot of repetition.
2024-02-07hir: Remove `fn opt_hir_id` and `fn opt_span`Vadim Petrochenkov-4/+3
2024-02-06Rollup merge of #120513 - compiler-errors:normalize-regions-for-nll, r=lcnrMatthias Krüger-38/+64
Normalize type outlives obligations in NLL for new solver Normalize the type outlives assumptions and obligations in MIR borrowck. This should fix any of the lazy-norm-related MIR borrowck problems. Also some cleanups from last PR: 1. Normalize obligations in a loop in lexical region resolution 2. Use `deeply_normalize_with_skipped_universes` in lexical resolution since we may have, e.g. `for<'a> Alias<'a>: 'b`. r? lcnr
2024-02-06Rollup merge of #120670 - lcnr:effect-var-storage, r=fee1-deadMatthias Krüger-52/+29
cleanup effect var handling r? types
2024-02-06Add CoroutineClosure to TyKind, AggregateKind, UpvarArgsMichael Goulet-8/+41
2024-02-06Invert diagnostic lints.Nicholas Nethercote-0/+2
That is, change `diagnostic_outside_of_impl` and `untranslatable_diagnostic` from `allow` to `deny`, because more than half of the compiler has be converted to use translated diagnostics. This commit removes more `deny` attributes than it adds `allow` attributes, which proves that this change is warranted.
2024-02-05cleanup effect var handlinglcnr-52/+29
2024-02-02Remove dead args from functionsMichael Goulet-7/+5
2024-02-03`Diagnostic` cleanupsNicholas Nethercote-2/+2
- `emitted_at` isn't used outside the crate. - `code` and `messages` are public fields, so there's no point have trivial getters/setters for them. - `suggestions` is public, so the comment about "functionality on `Diagnostic`" isn't needed.
2024-02-02Normalize the whole PolyTypeOutlivesPredicate, more simplificationsMichael Goulet-23/+37
2024-02-02Don't hang when there's an infinite loop of outlives obligationsMichael Goulet-1/+7
2024-02-02Do process_registered_region_obligations in a loopMichael Goulet-16/+22
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