about summary refs log tree commit diff
path: root/compiler/rustc_borrowck/src/diagnostics
AgeCommit message (Collapse)AuthorLines
2022-03-02rename ErrorReported -> ErrorGuaranteedmark-26/+26
2022-02-273 - Make more use of let_chainsCaio-43/+32
Continuation of #94376. cc #53667
2022-02-25Auto merge of #93368 - eddyb:diagbld-guarantee, r=estebankbors-69/+74
rustc_errors: let `DiagnosticBuilder::emit` return a "guarantee of emission". That is, `DiagnosticBuilder` is now generic over the return type of `.emit()`, so we'll now have: * `DiagnosticBuilder<ErrorReported>` for error (incl. fatal/bug) diagnostics * can only be created via a `const L: Level`-generic constructor, that limits allowed variants via a `where` clause, so not even `rustc_errors` can accidentally bypass this limitation * asserts `diagnostic.is_error()` on emission, just in case the construction restriction was bypassed (e.g. by replacing the whole `Diagnostic` inside `DiagnosticBuilder`) * `.emit()` returns `ErrorReported`, as a "proof" token that `.emit()` was called (though note that this isn't a real guarantee until after completing the work on #69426) * `DiagnosticBuilder<()>` for everything else (warnings, notes, etc.) * can also be obtained from other `DiagnosticBuilder`s by calling `.forget_guarantee()` This PR is a companion to other ongoing work, namely: * #69426 and it's ongoing implementation: #93222 the API changes in this PR are needed to get statically-checked "only errors produce `ErrorReported` from `.emit()`", but doesn't itself provide any really strong guarantees without those other `ErrorReported` changes * #93244 would make the choices of API changes (esp. naming) in this PR fit better overall In order to be able to let `.emit()` return anything trustable, several changes had to be made: * `Diagnostic`'s `level` field is now private to `rustc_errors`, to disallow arbitrary "downgrade"s from "some kind of error" to "warning" (or anything else that doesn't cause compilation to fail) * it's still possible to replace the whole `Diagnostic` inside the `DiagnosticBuilder`, sadly, that's harder to fix, but it's unlikely enough that we can paper over it with asserts on `.emit()` * `.cancel()` now consumes `DiagnosticBuilder`, preventing `.emit()` calls on a cancelled diagnostic * it's also now done internally, through `DiagnosticBuilder`-private state, instead of having a `Level::Cancelled` variant that can be read (or worse, written) by the user * this removes a hazard of calling `.cancel()` on an error then continuing to attach details to it, and even expect to be able to `.emit()` it * warnings were switched to *only* `can_emit_warnings` on emission (instead of pre-cancelling early) * `struct_dummy` was removed (as it relied on a pre-`Cancelled` `Diagnostic`) * since `.emit()` doesn't consume the `DiagnosticBuilder` <sub>(I tried and gave up, it's much more work than this PR)</sub>, we have to make `.emit()` idempotent wrt the guarantees it returns * thankfully, `err.emit(); err.emit();` can return `ErrorReported` both times, as the second `.emit()` call has no side-effects *only* because the first one did do the appropriate emission * `&mut Diagnostic` is now used in a lot of function signatures, which used to take `&mut DiagnosticBuilder` (in the interest of not having to make those functions generic) * the APIs were already mostly identical, allowing for low-effort porting to this new setup * only some of the suggestion methods needed some rework, to have the extra `DiagnosticBuilder` functionality on the `Diagnostic` methods themselves (that change is also present in #93259) * `.emit()`/`.cancel()` aren't available, but IMO calling them from an "error decorator/annotator" function isn't a good practice, and can lead to strange behavior (from the caller's perspective) * `.downgrade_to_delayed_bug()` was added, letting you convert any `.is_error()` diagnostic into a `delay_span_bug` one (which works because in both cases the guarantees available are the same) This PR should ideally be reviewed commit-by-commit, since there is a lot of fallout in each. r? `@estebank` cc `@Manishearth` `@nikomatsakis` `@mark-i-m`
2022-02-24Auto merge of #94131 - Mark-Simulacrum:fmt-string, r=oli-obkbors-8/+4
Always format to internal String in FmtPrinter This avoids monomorphizing for different parameters, decreasing generic code instantiated downstream from rustc_middle -- locally seeing 7% unoptimized LLVM IR line wins on rustc_borrowck, for example. We likely can't/shouldn't get rid of the Result-ness on most functions, though some further cleanup avoiding fmt::Error where we now know it won't occur may be possible, though somewhat painful -- fmt::Write is a pretty annoying API to work with in practice when you're trying to use it infallibly.
2022-02-23rustc_errors: let `DiagnosticBuilder::emit` return a "guarantee of emission".Eduard-Mihai Burtescu-27/+49
2022-02-23Replace `&mut DiagnosticBuilder`, in signatures, with `&mut Diagnostic`.Eduard-Mihai Burtescu-45/+28
2022-02-21use `List<Ty<'tcx>>` for tupleslcnr-5/+4
2022-02-20Always format to internal String in FmtPrinterMark Rousskov-8/+4
This avoids monomorphizing for different parameters, decreasing generic code instantiated downstream from rustc_middle.
2022-02-20Rollup merge of #94146 - est31:let_else, r=cjgillotMatthias Krüger-35/+16
Adopt let else in more places Continuation of #89933, #91018, #91481, #93046, #93590, #94011. I have extended my clippy lint to also recognize tuple passing and match statements. The diff caused by fixing it is way above 1 thousand lines. Thus, I split it up into multiple pull requests to make reviewing easier. This is the biggest of these PRs and handles the changes outside of rustdoc, rustc_typeck, rustc_const_eval, rustc_trait_selection, which were handled in PRs #94139, #94142, #94143, #94144.
2022-02-19Adopt let else in more placesest31-35/+16
2022-02-19Rollup merge of #94006 - pierwill:upvar-field, r=nikomatsakisMatthias Krüger-6/+16
Use a `Field` in `ConstraintCategory::ClosureUpvar` As part of #90317, we do not want `HirId` to implement `Ord`, `PartialOrd`. This line of code has made that difficult https://github.com/rust-lang/rust/blob/1b27144afc77031ba9c05d86c06c64485589775a/compiler/rustc_borrowck/src/region_infer/mod.rs#L2184 since it sorts a [`ConstraintCategory::ClosureUpvar(HirId)`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.ConstraintCategory.html#variant.ClosureUpvar). This PR makes that variant take a [`Field`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.Field.html) instead. r? `@nikomatsakis`
2022-02-17Rollup merge of #94011 - est31:let_else, r=lcnrMatthias Krüger-12/+7
Even more let_else adoptions Continuation of #89933, #91018, #91481, #93046, #93590.
2022-02-16Use a `Field` in `ConstraintCategory::ClosureUpvar`pierwill-6/+16
2022-02-16Adopt let_else in even more placesest31-12/+7
2022-02-15Overhaul `RegionKind` and `Region`.Nicholas Nethercote-29/+27
Specifically, change `Region` from this: ``` pub type Region<'tcx> = &'tcx RegionKind; ``` to this: ``` pub struct Region<'tcx>(&'tcx Interned<RegionKind>); ``` This now matches `Ty` and `Predicate` more closely. Things to note - Regions have always been interned, but we haven't been using pointer-based `Eq` and `Hash`. This is now happening. - I chose to impl `Deref` for `Region` because it makes pattern matching a lot nicer, and `Region` can be viewed as just a smart wrapper for `RegionKind`. - Various methods are moved from `RegionKind` to `Region`. - There is a lot of tedious sigil changes. - A couple of types like `HighlightBuilder`, `RegionHighlightMode` now have a `'tcx` lifetime because they hold a `Ty<'tcx>`, so they can call `mk_region`. - A couple of test outputs change slightly, I'm not sure why, but the new outputs are a little better.
2022-02-15Overhaul `TyS` and `Ty`.Nicholas Nethercote-20/+20
Specifically, change `Ty` from this: ``` pub type Ty<'tcx> = &'tcx TyS<'tcx>; ``` to this ``` pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>); ``` There are two benefits to this. - It's now a first class type, so we can define methods on it. This means we can move a lot of methods away from `TyS`, leaving `TyS` as a barely-used type, which is appropriate given that it's not meant to be used directly. - The uniqueness requirement is now explicit, via the `Interned` type. E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather than via `TyS`, which wasn't obvious at all. Much of this commit is boring churn. The interesting changes are in these files: - compiler/rustc_middle/src/arena.rs - compiler/rustc_middle/src/mir/visit.rs - compiler/rustc_middle/src/ty/context.rs - compiler/rustc_middle/src/ty/mod.rs Specifically: - Most mentions of `TyS` are removed. It's very much a dumb struct now; `Ty` has all the smarts. - `TyS` now has `crate` visibility instead of `pub`. - `TyS::make_for_test` is removed in favour of the static `BOOL_TY`, which just works better with the new structure. - The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned` (pointer-based, for the `Equal` case) and partly on `TyS` (contents-based, for the other cases). - There are many tedious sigil adjustments, i.e. adding or removing `*` or `&`. They seem to be unavoidable.
2022-02-12Handle Fn family trait call errrorDeadbeef-2/+2
2022-02-12Rebased and improved errorsDeadbeef-1/+3
2022-02-12Improve error messages even moreDeadbeef-107/+37
2022-02-11rework borrowck errors so that it's harder to not set taintedMichael Goulet-12/+2
2022-02-11implement tainted_by_errors in mir borrowckMichael Goulet-41/+37
2022-02-11Auto merge of #93893 - oli-obk:sad_revert, r=oli-obkbors-87/+21
Revert lazy TAIT PR Revert https://github.com/rust-lang/rust/pull/92306 (sorry `@Aaron1011,` will include your changes in the fix PR) Revert https://github.com/rust-lang/rust/pull/93783 Revert https://github.com/rust-lang/rust/pull/92007 fixes https://github.com/rust-lang/rust/issues/93788 fixes https://github.com/rust-lang/rust/issues/93794 fixes https://github.com/rust-lang/rust/issues/93821 fixes https://github.com/rust-lang/rust/issues/93831 fixes https://github.com/rust-lang/rust/issues/93841
2022-02-11Revert "Auto merge of #92306 - Aaron1011:opaque-type-op, r=oli-obk"Oli Scherer-87/+21
This reverts commit 1f0a96862ac9d4c6ca3e4bb500c8b9eac4d83049, reversing changes made to bf242bb1199e25ca2274df5c4114e0c9436b74e9.
2022-02-10Remove further usage of `&hir::Map`Frank Steffahn-2/+2
2022-02-08Improve opaque type higher-ranked region error message under NLLAaron Hill-21/+87
Currently, any higher-ranked region errors involving opaque types fall back to a generic "higher-ranked subtype error" message when run under NLL. This PR adds better error message handling for this case, giving us the same kinds of error messages that we currently get without NLL: ``` error: implementation of `MyTrait` is not general enough --> $DIR/opaque-hrtb.rs:12:13 | LL | fn foo() -> impl for<'a> MyTrait<&'a str> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `MyTrait` is not general enough | = note: `impl MyTrait<&'2 str>` must implement `MyTrait<&'1 str>`, for any lifetime `'1`... = note: ...but it actually implements `MyTrait<&'2 str>`, for some specific lifetime `'2` error: aborting due to previous error ``` To accomplish this, several different refactoring needed to be made: * We now have a dedicated `InstantiateOpaqueType` struct which implements `TypeOp`. This is used to invoke `instantiate_opaque_types` during MIR type checking. * `TypeOp` is refactored to pass around a `MirBorrowckCtxt`, which is needed to report opaque type region errors. * We no longer assume that all `TypeOp`s correspond to canonicalized queries. This allows us to properly handle opaque type instantiation (which does not occur in a query) as a `TypeOp`. A new `ErrorInfo` associated type is used to determine what additional information is used during higher-ranked region error handling. * The body of `try_extract_error_from_fulfill_cx` has been moved out to a new function `try_extract_error_from_region_constraints`. This allows us to re-use the same error reporting code between canonicalized queries (which can extract region constraints directly from a fresh `InferCtxt`) and opaque type handling (which needs to take region constraints from the pre-existing `InferCtxt` that we use throughout MIR borrow checking).
2022-02-02Rollup merge of #93590 - est31:let_else, r=lcnrMatthias Krüger-72/+65
More let_else adoptions Continuation of #89933, #91018, #91481, #93046.
2022-02-02Rollup merge of #93221 - alyssaverkade:fix-93093, r=wesleywiserMatthias Krüger-6/+26
[borrowck] Fix help on mutating &self in async fns Previously, when rustc was provided an async function that tried to mutate through a shared reference to an implicit self (as shown in the ui test), rustc would suggest modifying the parameter signature to `&mut` + the fully qualified name of the ty (in the case of the repro `S`). If a user modified their code to match the suggestion, the compiler would not accept it. This commit modifies the suggestion so that when rustc is provided the ui test that is also attached in this commit, it suggests (correctly) `&mut self`. We try to be careful about distinguishing between implicit and explicit self annotations, since the latter seem to be handled correctly already. This is my first PR here so I'm pretty sure I probably missed something/could use better terminology. I also didn't try to make the match exhaustive since implicit self is the only real special case that I need to handle (that I'm aware of), and I'm pretty sure there's a cleaner way to do this so any advice would be greatly appreciated! (I'm also not terribly confident about how I wrote the ui tests) here is your cc as requested `@compiler-errors` This is an attempt to fix #93093
2022-02-02More let_else adoptionsest31-72/+65
2022-01-22[borrowck] Fix help on mutating &self in async fnsAlyssa Verkade-6/+26
Previously, when rustc was provided an async function that tried to mutate through a shared reference to an implicit self (as shown in the ui test), rustc would suggest modifying the parameter signature to `&mut` + the fully qualified name of the ty (in the case of the repro `S`). If a user modified their code to match the suggestion, the compiler would not accept it. This commit modifies the suggestion so that when rustc is provided the ui test that is also attached in this commit, it suggests (correctly) `&mut self`. We try to be careful about distinguishing between implicit and explicit self annotations, since the latter seem to be handled correctly already. Fixes rust-lang/rust#93093
2022-01-19Store a `Symbol` instead of an `Ident` in `AssocItem`Aaron Hill-1/+1
This is the same idea as #92533, but for `AssocItem` instead of `VariantDef`/`FieldDef`. With this change, we no longer have any uses of `#[stable_hasher(project(...))]`
2022-01-17Use Term in ProjectionPredicatekadmin-1/+4
ProjectionPredicate should be able to handle both associated types and consts so this adds the first step of that. It mainly just pipes types all the way down, not entirely sure how to handle consts, but hopefully that'll come with time.
2022-01-15Reduce use of local_def_id_to_hir_id.Camille GILLOT-37/+34
2022-01-15Return a LocalDefId in get_parent_item.Camille GILLOT-2/+2
2022-01-13Auto merge of #89861 - nbdd0121:closure, r=wesleywiserbors-5/+4
Closure capture cleanup & refactor Follow up of #89648 Each commit is self-contained and the rationale/changes are documented in the commit message, so it's advisable to review commit by commit. The code is significantly cleaner (at least IMO), but that could have some perf implication, so I'd suggest a perf run. r? `@wesleywiser` cc `@arora-aman`
2022-01-11Store a `Symbol` instead of an `Ident` in `VariantDef`/`FieldDef`Aaron Hill-1/+1
The field is also renamed from `ident` to `name. In most cases, we don't actually need the `Span`. A new `ident` method is added to `VariantDef` and `FieldDef`, which constructs the full `Ident` using `tcx.def_ident_span()`. This method is used in the cases where we actually need an `Ident`. This makes incremental compilation properly track changes to the `Span`, without all of the invalidations caused by storing a `Span` directly via an `Ident`.
2022-01-07Remove region from UpvarCapture and move it to CapturedPlaceGary Guo-4/+3
Region info is completely unnecessary for upvar capture kind computation and is only needed to create the final upvar tuple ty. Doing so makes creation of UpvarCapture very cheap and expose further cleanup opportunity.
2022-01-07Remove span from UpvarCapture::ByValueGary Guo-1/+1
This span is unused and is superseded by capture_kind_expr_id in CaptureInfo
2021-12-29Refactor variance diagnostics to work with more typesAaron Hill-7/+37
Instead of special-casing mutable pointers/references, we now support general generic types (currently, we handle `ty::Ref`, `ty::RawPtr`, and `ty::Adt`) When a `ty::Adt` is involved, we show an additional note explaining which of the type's generic parameters is invariant (e.g. the `T` in `Cell<T>`). Currently, we don't explain *why* a particular generic parameter ends up becoming invariant. In the general case, this could require printing a long 'backtrace' of types, so doing this would be more suitable for a follow-up PR. We still only handle the case where our variance switches to `ty::Invariant`.
2021-12-19Auto merge of #91957 - nnethercote:rm-SymbolStr, r=oli-obkbors-3/+3
Remove `SymbolStr` This was originally proposed in https://github.com/rust-lang/rust/pull/74554#discussion_r466203544. As well as removing the icky `SymbolStr` type, it allows the removal of a lot of `&` and `*` occurrences. Best reviewed one commit at a time. r? `@oli-obk`
2021-12-18get_mut_span_in_struct_field uses span.betweenLucas Kent-8/+6
2021-12-17Improve suggestion to change struct field to &mutLucas Kent-26/+13
2021-12-15Remove in_band_lifetimes from borrowckDániel Buga-10/+10
2021-12-15Remove unnecessary sigils around `Symbol::as_str()` calls.Nicholas Nethercote-3/+3
2021-12-11Rollup merge of #89734 - estebank:issue-72312, r=nikomatsakisMatthias Krüger-0/+1
Point at capture points for non-`'static` reference crossing a `yield` point ``` error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement --> $DIR/issue-72312.rs:10:24 | LL | pub async fn start(&self) { | ^^^^^ this data with an anonymous lifetime `'_`... ... LL | require_static(async move { | -------------- ...is required to live as long as `'static` here... LL | &self; | ----- ...and is captured here | note: `'static` lifetime requirement introduced by this trait bound --> $DIR/issue-72312.rs:2:22 | LL | fn require_static<T: 'static>(val: T) -> T { | ^^^^^^^ error: aborting due to previous error For more information about this error, try `rustc --explain E0759`. ``` Fix #72312.
2021-12-10Suggest using a temporary variable to fix borrowck errorsNoah Lev-2/+114
In Rust, nesting method calls with both require `&mut` access to `self` produces a borrow-check error: error[E0499]: cannot borrow `*self` as mutable more than once at a time --> src/lib.rs:7:14 | 7 | self.foo(self.bar()); | ---------^^^^^^^^^^- | | | | | | | second mutable borrow occurs here | | first borrow later used by call | first mutable borrow occurs here That's because Rust has a left-to-right evaluation order, and the method receiver is passed first. Thus, the argument to the method cannot then mutate `self`. There's an easy solution to this error: just extract a local variable for the inner argument: let tmp = self.bar(); self.foo(tmp); However, the error doesn't give any suggestion of how to solve the problem. As a result, new users may assume that it's impossible to express their code correctly and get stuck. This commit adds a (non-structured) suggestion to extract a local variable for the inner argument to solve the error. The suggestion uses heuristics that eliminate most false positives, though there are a few false negatives (cases where the suggestion should be emitted but is not). Those other cases can be implemented in a future change.
2021-12-10Point at capture points for non-`'static` reference crossing a `yield` pointEsteban Kuber-0/+1
``` error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement --> $DIR/issue-72312.rs:10:24 | LL | pub async fn start(&self) { | ^^^^^ this data with an anonymous lifetime `'_`... ... LL | require_static(async move { | -------------- ...is required to live as long as `'static` here... LL | &self; | ----- ...and is captured here | note: `'static` lifetime requirement introduced by this trait bound --> $DIR/issue-72312.rs:2:22 | LL | fn require_static<T: 'static>(val: T) -> T { | ^^^^^^^ error: aborting due to previous error For more information about this error, try `rustc --explain E0759`. ``` Fix #72312.
2021-12-02Rollup merge of #91394 - Mark-Simulacrum:bump-stage0, r=pietroalbiniMatthias Krüger-27/+40
Bump stage0 compiler r? `@pietroalbini` (or anyone else)
2021-12-01Auto merge of #90446 - cjgillot:late-elided, r=jackh726bors-1/+1
Lint elided lifetimes in path during lifetime resolution. The lifetime elision lint is known to be brittle and can be redundant with later lifetime resolution errors. This PR aims to remove the redundancy by performing the lint after lifetime resolution. This PR proposes to carry the information that an elision should be linted against by using a special `LifetimeName`. I am not certain this is the best solution, but it is certainly the easiest. Fixes https://github.com/rust-lang/rust/issues/60199 Fixes https://github.com/rust-lang/rust/issues/55768 Fixes https://github.com/rust-lang/rust/issues/63110 Fixes https://github.com/rust-lang/rust/issues/71957
2021-12-01Rollup merge of #90985 - camsteffen:diag-name-usage, r=jackh726Matthias Krüger-20/+15
Use `get_diagnostic_name` more
2021-11-30Merge Implicit and ImplicitMissing.Camille GILLOT-3/+1