summary refs log tree commit diff
path: root/compiler/rustc_borrowck/src/diagnostics
AgeCommit message (Collapse)AuthorLines
2025-03-28Don't use `kw::Empty` in `hir::Lifetime::ident`.Nicholas Nethercote-3/+3
`hir::Lifetime::ident` currently sometimes uses `kw::Empty` for elided lifetimes and sometimes uses `kw::UnderscoreLifetime`, and the distinction is used when creating some error suggestions, e.g. in `Lifetime::suggestion` and `ImplicitLifetimeFinder::visit_ty`. I found this *really* confusing, and it took me a while to understand what was going on. This commit replaces all uses of `kw::Empty` in `hir::Lifetime::ident` with `kw::UnderscoreLifetime`. It adds a new field `hir::Lifetime::is_path_anon` that mostly replaces the old empty/underscore distinction and makes things much clearer. Some other notable changes: - Adds a big comment to `Lifetime` talking about permissable field values. - Adds some assertions in `new_named_lifetime` about what ident values are permissible for the different `LifetimeRes` values. - Adds a `Lifetime::new` constructor that does some checking to make sure the `is_elided` and `is_anonymous` states are valid. - `add_static_impl_trait_suggestion` now looks at `Lifetime::res` instead of the ident when creating the suggestion. This is the one case where `is_path_anon` doesn't replace the old empty/underscore distinction. - A couple of minor pretty-printing improvements.
2025-03-19Use `Option<Ident>` for lowered param names.Nicholas Nethercote-7/+7
Parameter patterns are lowered to an `Ident` by `lower_fn_params_to_names`, which is used when lowering bare function types, trait methods, and foreign functions. Currently, there are two exceptional cases where the lowered param can become an empty `Ident`. - If the incoming pattern is an empty `Ident`. This occurs if the parameter is anonymous, e.g. in a bare function type. - If the incoming pattern is neither an ident nor an underscore. Any such parameter will have triggered a compile error (hence the `span_delayed_bug`), but lowering still occurs. This commit replaces these empty `Ident` results with `None`, which eliminates a number of `kw::Empty` uses, and makes it impossible to fail to check for these exceptional cases. Note: the `FIXME` comment in `is_unwrap_or_empty_symbol` is removed. It actually should have been removed in #138482, the precursor to this PR. That PR changed the lowering of wild patterns to `_` symbols instead of empty symbols, which made the mentioned underscore check load-bearing.
2025-03-17Rollup merge of #138384 - nnethercote:hir-ItemKind-idents, r=fmeaseMatthias Krüger-3/+5
Move `hir::Item::ident` into `hir::ItemKind`. `hir::Item` has an `ident` field. - It's always non-empty for these item kinds: `ExternCrate`, `Static`, `Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`, Trait`, TraitAalis`. - It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`, `Impl`. - For `Use`, it is non-empty for `UseKind::Single` and empty for `UseKind::{Glob,ListStem}`. All of this is quite non-obvious; the only documentation is a single comment saying "The name might be a dummy name in case of anonymous items". Some sites that handle items check for an empty ident, some don't. This is a very C-like way of doing things, but this is Rust, we have sum types, we can do this properly and never forget to check for the exceptional case and never YOLO possibly empty identifiers (or possibly dummy spans) around and hope that things will work out. This is step towards `kw::Empty` elimination (#137978). r? `@fmease`
2025-03-18Move `hir::Item::ident` into `hir::ItemKind`.Nicholas Nethercote-3/+5
`hir::Item` has an `ident` field. - It's always non-empty for these item kinds: `ExternCrate`, `Static`, `Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`, Trait`, TraitAalis`. - It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`, `Impl`. - For `Use`, it is non-empty for `UseKind::Single` and empty for `UseKind::{Glob,ListStem}`. All of this is quite non-obvious; the only documentation is a single comment saying "The name might be a dummy name in case of anonymous items". Some sites that handle items check for an empty ident, some don't. This is a very C-like way of doing things, but this is Rust, we have sum types, we can do this properly and never forget to check for the exceptional case and never YOLO possibly empty identifiers (or possibly dummy spans) around and hope that things will work out. The commit is large but it's mostly obvious plumbing work. Some notable things. - A similar transformation makes sense for `ast::Item`, but this is already a big change. That can be done later. - Lots of assertions are added to item lowering to ensure that identifiers are empty/non-empty as expected. These will be removable when `ast::Item` is done later. - `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does. - `lower_use_tree` is significantly simpler. No more confusing `&mut Ident` to deal with. - `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's used with `unwrap` in a few places; sometimes it's hard to tell exactly which item kinds might occur. None of these unwraps fail on the test suite. It's conceivable that some might fail on alternative input. We can deal with those if/when they happen. - In `trait_path` the `find_map`/`if let` is replaced with a loop, and things end up much clearer that way. - `named_span` no longer checks for an empty name; instead the call site now checks for a missing identifier if necessary. - `maybe_inline_local` doesn't need the `glob` argument, it can be computed in-function from the `renamed` argument. - `arbitrary_source_item_ordering::check_mod` had a big `if` statement that was just getting the ident from the item kinds that had one. It could be mostly replaced by a single call to the new `ItemKind::ident` method. - `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size, and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-17Use `strip_{prefix|suffix}` instead of `{starts|ends}_with`+indexingYotam Ofek-2/+2
2025-03-15Squash fold into tyMichael Goulet-2/+1
2025-03-12Move methods from `Map` to `TyCtxt`, part 4.Nicholas Nethercote-6/+6
Continuing the work from #137350. Removes the unused methods: `expect_variant`, `expect_field`, `expect_foreign_item`. Every method gains a `hir_` prefix.
2025-03-06Fail gracefully if mutating on a use closure and the closure it not declared mutSantiago Pastorino-1/+1
2025-02-25Teach structured errors to display short `Ty`Esteban Küber-9/+5
Make it so that every structured error annotated with `#[derive(Diagnostic)]` that has a field of type `Ty<'_>`, the printing of that value into a `String` will look at the thread-local storage `TyCtxt` in order to shorten to a length appropriate with the terminal width. When this happen, the resulting error will have a note with the file where the full type name was written to. ``` error[E0618]: expected function, found `((..., ..., ..., ...), ..., ..., ...)`` --> long.rs:7:5 | 6 | fn foo(x: D) { //~ `x` has type `(... | - `x` has type `((..., ..., ..., ...), ..., ..., ...)` 7 | x(); //~ ERROR expected function, found `(... | ^-- | | | call expression requires function | = note: the full name for the type has been written to 'long.long-type-14182675702747116984.txt' = note: consider using `--verbose` to print the full type name to the console ```
2025-02-22Greatly simplify lifetime captures in edition 2024Michael Goulet-4/+3
2025-02-22Fix binding mode problemsMichael Goulet-5/+5
2025-02-21Move methods from Map to TyCtxt, part 3.Nicholas Nethercote-22/+16
Continuing the work from #137162. Every method gains a `hir_` prefix.
2025-02-19Remove `MirVisitable`.Nicholas Nethercote-16/+18
The `MirVisitable` trait is just a complicated way to visit either a statement or a terminator. (And its impl for `Terminator` is unused.) It has a single use. This commit removes it, replacing it with an if/else, which is shorter and simpler.
2025-02-19Rollup merge of #137213 - nnethercote:rm-rustc_middle-mir-tcx, r=compiler-errorsMatthias Krüger-5/+3
Remove `rustc_middle::mir::tcx` module. This is a really weird module. For example, what does `tcx` in `rustc_middle::mir::tcx::PlaceTy` mean? The answer is "not much". The top-level module comment says: > Methods for the various MIR types. These are intended for use after > building is complete. Awfully broad for a module that has a handful of impl blocks for some MIR types, none of which really relates to `TyCtxt`. `git blame` indicates the comment is ancient, from 2015, and made sense then. This module is now vestigial. This commit removes it and moves all the code within into `rustc_middle::mir::statement`. Some specifics: - `Place`, `PlaceRef`, `Rvalue`, `Operand`, `BorrowKind`: they all have `impl` blocks in both the `tcx` and `statement` modules. The commit merges the former into the latter. - `BinOp`, `UnOp`: they only have `impl` blocks in `tcx`. The commit moves these into `statement`. - `PlaceTy`, `RvalueInitializationState`: they are defined in `tcx`. This commit moves them into `statement` *and* makes them available in `mir::*`, like many other MIR types. r? `@tmandry`
2025-02-19Remove `rustc_middle::mir::tcx` module.Nicholas Nethercote-5/+3
This is a really weird module. For example, what does `tcx` in `rustc_middle::mir::tcx::PlaceTy` mean? The answer is "not much". The top-level module comment says: > Methods for the various MIR types. These are intended for use after > building is complete. Awfully broad for a module that has a handful of impl blocks for some MIR types, none of which really relates to `TyCtxt`. `git blame` indicates the comment is ancient, from 2015, and made sense then. This module is now vestigial. This commit removes it and moves all the code within into `rustc_middle::mir::statement`. Some specifics: - `Place`, `PlaceRef`, `Rvalue`, `Operand`, `BorrowKind`: they all have `impl` blocks in both the `tcx` and `statement` modules. The commit merges the former into the latter. - `BinOp`, `UnOp`: they only have `impl` blocks in `tcx`. The commit moves these into `statement`. - `PlaceTy`, `RvalueInitializationState`: they are defined in `tcx`. This commit moves them into `statement` *and* makes them available in `mir::*`, like many other MIR types.
2025-02-18Move methods from `Map` to `TyCtxt`, part 2.Nicholas Nethercote-27/+23
Continuing the work started in #136466. Every method gains a `hir_` prefix, though for the ones that already have a `par_` or `try_par_` prefix I added the `hir_` after that.
2025-02-17Rollup merge of #136466 - nnethercote:start-removing-Map, r=cjgillotMatthias Krüger-52/+48
Start removing `rustc_middle::hir::map::Map` `rustc_middle::hir::map::Map` is now just a low-value wrapper around `TyCtxt`. This PR starts removing it. r? `@cjgillot`
2025-02-17Overhaul the `intravisit::Map` trait.Nicholas Nethercote-15/+15
First of all, note that `Map` has three different relevant meanings. - The `intravisit::Map` trait. - The `map::Map` struct. - The `NestedFilter::Map` associated type. The `intravisit::Map` trait is impl'd twice. - For `!`, where the methods are all unreachable. - For `map::Map`, which gets HIR stuff from the `TyCtxt`. As part of getting rid of `map::Map`, this commit changes `impl intravisit::Map for map::Map` to `impl intravisit::Map for TyCtxt`. It's fairly straightforward except various things are renamed, because the existing names would no longer have made sense. - `trait intravisit::Map` becomes `trait intravisit::HirTyCtxt`, so named because it gets some HIR stuff from a `TyCtxt`. - `NestedFilter::Map` assoc type becomes `NestedFilter::MaybeTyCtxt`, because it's always `!` or `TyCtxt`. - `Visitor::nested_visit_map` becomes `Visitor::maybe_tcx`. I deliberately made the new trait and associated type names different to avoid the old `type Map: Map` situation, which I found confusing. We now have `type MaybeTyCtxt: HirTyCtxt`.
2025-02-17Move some `Map` methods onto `TyCtxt`.Nicholas Nethercote-35/+31
The end goal is to eliminate `Map` altogether. I added a `hir_` prefix to all of them, that seemed simplest. The exceptions are `module_items` which became `hir_module_free_items` because there was already a `hir_module_items`, and `items` which became `hir_free_items` for consistency with `hir_module_free_items`.
2025-02-17Avoid unnecessary use of the `Map` trait.Nicholas Nethercote-2/+2
The `Map` trait is there for cases where `tcx` isn't available. This isn't one of those cases, so it's simpler to just call through `tcx` directly.
2025-02-15Rework name_regions to not rely on reverse scc graph for ↵Michael Goulet-6/+24
non-member-constrain usages
2025-02-14further simplify a matchdianne-12/+11
2025-02-13remove `fr_is_local` and `outlived_fr_is_local` fields from ↵dianne-31/+14
`ErrorConstraintInfo` `fr_is_local` was fully unused, and `outlived_fr_is_local` was used once
2025-02-13Rollup merge of #136559 - ↵Jacob Pratt-2/+5
compiler-errors:resolve-regions-for-type-test-failure, r=BoxyUwU Resolve named regions when reporting type test failures in NLL Just a improvement tweak to an error message that I broke out of a bigger PR that I had to close lol
2025-02-13Improved named region errorsMichael Goulet-2/+5
2025-02-12Auto merge of #135994 - 1c3t3a:rename-unsafe-ptr, r=oli-obkbors-1/+1
Rename rustc_middle::Ty::is_unsafe_ptr to is_raw_ptr The wording unsafe pointer is less common and not mentioned in a lot of places, instead this is usually called a "raw pointer". For the sake of uniformity, we rename this method. This came up during the review of https://github.com/rust-lang/rust/pull/134424. r? `@Noratrieb`
2025-02-11Deeply normalize signature in new solverMichael Goulet-2/+57
2025-02-10Rename rustc_middle::Ty::is_unsafe_ptr to is_raw_ptrBastian Kersting-1/+1
The wording unsafe pointer is less common and not mentioned in a lot of places, instead this is usually called a "raw pointer". For the sake of uniformity, we rename this method. This came up during the review of https://github.com/rust-lang/rust/pull/134424.
2025-02-08Rustfmtbjorn3-44/+48
2025-02-04fix NLL TLS end of function spansRémy Rakic-1/+13
2025-02-03Rollup merge of #136299 - lqd:polonius-next-episode-9, r=jackh726Matthias Krüger-2/+21
Ignore NLL boring locals in polonius diagnostics Another easy one ``@jackh726`` (the diff is inflated by blessed test expectations don't worry :) NLLs don't compute liveness for boring locals, and therefore cannot find them in causes explaining borrows. In polonius, we don't have this liveness optimization (we may be able to do something partially similar in the future, e.g. for function parameters and the like), so we do encounter these in diagnostics even though we don't want to. This PR: - restructures the polonius context into per-phase data, in spirit as you requested in an earlier review - stores the locals NLLs would consider boring into the errors/diagnostics data - ignores these if a boring local is found when trying to explain borrows This PR fixes around 80 cases of diagnostics differences between `-Zpolonius=next` and NLLs. I've also added explicit revisions to a few polonius tests (both for the in-tree implementation as well as the datalog implementation -- even if we'll eventually remove them). I didn't do this for all the "dead" expectations that were removed from #136112 for that same reason, it's fine. I'll soon/eventually add explicit revisions where they're needed: there's only a handful of tests left to fix. r? ``@jackh726``
2025-02-02Rollup merge of #136402 - notriddle:notriddle/let-expr-detector, ↵Matthias Krüger-18/+92
r=compiler-errors diagnostics: fix borrowck suggestions for if/while let conditionals This code detects the case where one of the borrows is inside the let init expr while the other end is not. If that happens, we don't want to suggest adding a semicolon, because it won't work. Fixes #133941
2025-02-02Rollup merge of #136368 - estebank:listify, r=fee1-deadMatthias Krüger-11/+9
Make comma separated lists of anything easier to make for errors Provide a new function `listify`, meant to be used in cases similar to `pluralize!`. When you have a slice of arbitrary elements that need to be presented to the user, `listify` allows you to turn that into a list of comma separated strings. This reduces a lot of redundant logic that happens often in diagnostics.
2025-02-02Rollup merge of #136328 - estebank:long-ty-path, r=jieyouxu,lqdMatthias Krüger-28/+4
Rework "long type names" printing logic Make it so more type-system types can be printed in a shortened version (like `Predicate`s). Centralize printing the information about the "full type name path". Make the "long type path" for the file where long types are written part of `Diag`, so that it becomes easier to keep track of it, and ensure it will always will be printed out last in the diagnostic by making its addition to the output implicit. Tweak the shortening of types in "expected/found" labels. Remove dead file `note.rs`.
2025-02-01diagnostics: fix borrowck suggestions for if/while let conditionalsMichael Howell-18/+92
This code detects the case where one of the borrows is inside the let init expr while the other end is not. If that happens, we don't want to suggest adding a semicolon, because it won't work.
2025-02-01Rollup merge of #130514 - compiler-errors:unsafe-binders, r=oli-obkMatthias Krüger-5/+8
Implement MIR lowering for unsafe binders This is the final bit of the unsafe binders puzzle. It implements MIR, CTFE, and codegen for unsafe binders, and enforces that (for now) they are `Copy`. Later on, I'll introduce a new trait that relaxes this requirement to being "is `Copy` or `ManuallyDrop<T>`" which more closely models how we treat union fields. Namely, wrapping unsafe binders is now `Rvalue::WrapUnsafeBinder`, which acts much like an `Rvalue::Aggregate`. Unwrapping unsafe binders are implemented as a MIR projection `ProjectionElem::UnwrapUnsafeBinder`, which acts much like `ProjectionElem::Field`. Tracking: - https://github.com/rust-lang/rust/issues/130516
2025-01-31Rework "long type names" printing logicEsteban Küber-28/+4
Make it so more type-system types can be printed in a shortened version (like `Predicate`s). Centralize printing the information about the "full type name path". Make the "long type path" for the file where long types are written part of `Diag`, so that it becomes easier to keep track of it, and ensure it will always will be printed out last in the diagnostic by making its addition to the output implicit. Tweak the shortening of types in "expected/found" labels. Remove dead file `note.rs`.
2025-01-31Make comma separated lists of anything easier to make for errorsEsteban Küber-11/+9
Provide a new function `listify`, meant to be used in cases similar to `pluralize!`. When you have a slice of arbitrary elements that need to be presented to the user, `listify` allows you to turn that into a list of comma separated strings. This reduces a lot of redundant logic that happens often in diagnostics.
2025-01-31Implement MIR, CTFE, and codegen for unsafe bindersMichael Goulet-5/+8
2025-01-31record boring locals in polonius contextRémy Rakic-2/+21
this is used in diagnostics to focus on relevant live locals to match NLL diagnostics
2025-01-31Move `find_self_call`.Nicholas Nethercote-8/+5
It's a function that does stuff with MIR and yet it weirdly has its own module in `rustc_middle::util`. This commit moves it into `rustc_middle::mir`, a more sensible home.
2025-01-29Rollup merge of #136212 - estebank:span-tweak, r=petrochenkovMatthias Krüger-15/+10
Tweak `&mut self` suggestion span ``` error[E0596]: cannot borrow `*self.s` as mutable, as it is behind a `&` reference --> $DIR/issue-38147-1.rs:17:9 | LL | self.s.push('x'); | ^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable | help: consider changing this to be a mutable reference | LL | fn f(&mut self) { | +++ ``` Note the suggestion to add `mut` instead of replacing the entire `&self` with `&mut self`.
2025-01-28Tweak `&mut self` suggestion spanEsteban Küber-15/+10
``` error[E0596]: cannot borrow `*self.s` as mutable, as it is behind a `&` reference --> $DIR/issue-38147-1.rs:17:9 | LL | self.s.push('x'); | ^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable | help: consider changing this to be a mutable reference | LL | fn f(&mut self) { | +++ ``` Note the suggestion to add `mut` instead of replacing the entire `&self` with `&mut self`.
2025-01-25Pass spans to perform_locally_in_new_solverMichael Goulet-1/+1
2025-01-25Rollup merge of #136018 - estebank:long-moved-type, r=jieyouxuMatthias Krüger-3/+31
Use short ty string for move errors ``` error[E0382]: use of moved value: `x` --> bay.rs:14:14 | 12 | fn foo(x: D) { | - move occurs because `x` has type `(((..., ..., ..., ...), ..., ..., ...), ..., ..., ...)`, which does not implement the `Copy` trait 13 | let _a = x; | - value moved here 14 | let _b = x; //~ ERROR use of moved value | ^ value used here after move | = note: the full type name has been written to 'bay.long-type-14349227078439097973.txt' = note: consider using `--verbose` to print the full type name to the console help: consider cloning the value if the performance cost is acceptable | 13 | let _a = x.clone(); | ++++++++ ``` Address 4th case in #135919.
2025-01-24Use short ty string for move errorsEsteban Küber-3/+31
``` error[E0382]: use of moved value: `x` --> bay.rs:14:14 | 12 | fn foo(x: D) { | - move occurs because `x` has type `(((..., ..., ..., ...), ..., ..., ...), ..., ..., ...)`, which does not implement the `Copy` trait 13 | let _a = x; | - value moved here 14 | let _b = x; //~ ERROR use of moved value | ^ value used here after move | = note: the full type name has been written to 'bay.long-type-14349227078439097973.txt' = note: consider using `--verbose` to print the full type name to the console help: consider cloning the value if the performance cost is acceptable | 13 | let _a = x.clone(); | ++++++++ ```
2025-01-23`visit_x_unambig`Boxy-1/+1
2025-01-23Split hir `TyKind` and `ConstArgKind` in two and update `hir::Visitor`Boxy-4/+4
2025-01-23Make `hir::TyKind::TraitObject` use tagged ptrBoxy-1/+1
2025-01-21Move supertrait_def_ids into the elaborate module like all other fnsMichael Goulet-3/+4