about summary refs log tree commit diff
path: root/compiler/rustc_mir_build
AgeCommit message (Collapse)AuthorLines
2022-03-02rename ErrorReported -> ErrorGuaranteedmark-4/+4
2022-02-286 - Make more use of `let_chains`Caio-118/+97
Continuation of #94376. cc #53667
2022-02-25Enable rustc_pass_by_value for SpanMark Rousskov-3/+3
2022-02-25Switch bootstrap cfgsMark Rousskov-1/+1
2022-02-23rustc_errors: let `DiagnosticBuilder::emit` return a "guarantee of emission".Eduard-Mihai Burtescu-2/+8
2022-02-23Replace `&mut DiagnosticBuilder`, in signatures, with `&mut Diagnostic`.Eduard-Mihai Burtescu-8/+3
2022-02-21Auto merge of #93505 - lcnr:substsref-vs-ty-list, r=michaelwoeristerbors-7/+4
safely `transmute<&List<Ty<'tcx>>, &List<GenericArg<'tcx>>>` This PR has 3 relevant steps which are is split in distinct commits. The first commit now interns `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>` together, potentially reusing memory while allowing free conversions between these two using `List<Ty<'tcx>>::as_substs()` and `SubstsRef<'tcx>::try_as_type_list()`. Using this, we then use `&'tcx List<Ty<'tcx>>` instead of a `SubstsRef<'tcx>` for tuple fields, simplifying a bunch of code. Finally, as tuple fields and other generic arguments now use a different `TypeFoldable<'tcx>` impl, we optimize the impl for `List<Ty<'tcx>>` improving perf by slightly less than 1% in tuple heavy benchmarks.
2022-02-21use `List<Ty<'tcx>>` for tupleslcnr-7/+4
2022-02-20Revert "Auto merge of #93800 - b-naber:static-initializers-mir-val, r=oli-obk"Mark Rousskov-9/+12
This reverts commit a240ccd81c74c105b6f5fe84c46f8d36edb7e306, reversing changes made to 393fdc10483da930cdbb00eabc3635030d2e776f. This PR was likely responsible for a relatively large regression in dist-x86_64-msvc-alt builder times, from approximately 1.7 to 2.8 hours, bringing that builder into the pool of the slowest builders we currently have. This seems to be limited to the alt builder due to needing parallel-compiler enabled, likely leading to slow LLVM compilation for some reason.
2022-02-20Auto merge of #93678 - steffahn:better_unsafe_diagnostics, r=nagisabors-17/+5
Improve `unused_unsafe` lint I’m going to add some motivation and explanation below, particularly pointing the changes in behavior from this PR. _Edit:_ Looking for existing issues, looks like this PR fixes #88260. _Edit2:_ Now also contains code that closes #90776.
2022-02-20Improve `unused_unsafe` lintFrank Steffahn-17/+5
Main motivation: Fixes some issues with the current behavior. This PR is more-or-less completely re-implementing the unused_unsafe lint; it’s also only done in the MIR-version of the lint, the set of tests for the `-Zthir-unsafeck` version no longer succeeds (and is thus disabled, see `lint-unused-unsafe.rs`). On current nightly, ```rs unsafe fn unsf() {} fn inner_ignored() { unsafe { #[allow(unused_unsafe)] unsafe { unsf() } } } ``` doesn’t create any warnings. This situation is not unrealistic to come by, the inner `unsafe` block could e.g. come from a macro. Actually, this PR even includes removal of one unused `unsafe` in the standard library that was missed in a similar situation. (The inner `unsafe` coming from an external macro hides the warning, too.) The reason behind this problem is how the check currently works: * While generating MIR, it already skips nested unsafe blocks (i.e. unsafe nested in other unsafe) so that the inner one is always the one considered unused * To differentiate the cases of no unsafe operations inside the `unsafe` vs. a surrounding `unsafe` block, there’s some ad-hoc magic walking up the HIR to look for surrounding used `unsafe` blocks. There’s a lot of problems with this approach besides the one presented above. E.g. the MIR-building uses checks for `unsafe_op_in_unsafe_fn` lint to decide early whether or not `unsafe` blocks in an `unsafe fn` are redundant and ought to be removed. ```rs unsafe fn granular_disallow_op_in_unsafe_fn() { unsafe { #[deny(unsafe_op_in_unsafe_fn)] { unsf(); } } } ``` ``` error: call to unsafe function is unsafe and requires unsafe block (error E0133) --> src/main.rs:13:13 | 13 | unsf(); | ^^^^^^ call to unsafe function | note: the lint level is defined here --> src/main.rs:11:16 | 11 | #[deny(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ = note: consult the function's documentation for information on how to avoid undefined behavior warning: unnecessary `unsafe` block --> src/main.rs:10:5 | 9 | unsafe fn granular_disallow_op_in_unsafe_fn() { | --------------------------------------------- because it's nested under this `unsafe` fn 10 | unsafe { | ^^^^^^ unnecessary `unsafe` block | = note: `#[warn(unused_unsafe)]` on by default ``` Here, the intermediate `unsafe` was ignored, even though it contains a unsafe operation that is not allowed to happen in an `unsafe fn` without an additional `unsafe` block. Also closures were problematic and the workaround/algorithms used on current nightly didn’t work properly. (I skipped trying to fully understand what it was supposed to do, because this PR uses a completely different approach.) ```rs fn nested() { unsafe { unsafe { unsf() } } } ``` ``` warning: unnecessary `unsafe` block --> src/main.rs:10:9 | 9 | unsafe { | ------ because it's nested under this `unsafe` block 10 | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block | = note: `#[warn(unused_unsafe)]` on by default ``` vs ```rs fn nested() { let _ = || unsafe { let _ = || unsafe { unsf() }; }; } ``` ``` warning: unnecessary `unsafe` block --> src/main.rs:9:16 | 9 | let _ = || unsafe { | ^^^^^^ unnecessary `unsafe` block | = note: `#[warn(unused_unsafe)]` on by default warning: unnecessary `unsafe` block --> src/main.rs:10:20 | 10 | let _ = || unsafe { unsf() }; | ^^^^^^ unnecessary `unsafe` block ``` *note that this warning kind-of suggests that **both** unsafe blocks are redundant* -------------------------------------------------------------------------------- I also dislike the fact that it always suggests keeping the outermost `unsafe`. E.g. for ```rs fn granularity() { unsafe { unsafe { unsf() } unsafe { unsf() } unsafe { unsf() } } } ``` I prefer if `rustc` suggests removing the more-course outer-level `unsafe` instead of the fine-grained inner `unsafe` blocks, which it currently does on nightly: ``` warning: unnecessary `unsafe` block --> src/main.rs:10:9 | 9 | unsafe { | ------ because it's nested under this `unsafe` block 10 | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block | = note: `#[warn(unused_unsafe)]` on by default warning: unnecessary `unsafe` block --> src/main.rs:11:9 | 9 | unsafe { | ------ because it's nested under this `unsafe` block 10 | unsafe { unsf() } 11 | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block warning: unnecessary `unsafe` block --> src/main.rs:12:9 | 9 | unsafe { | ------ because it's nested under this `unsafe` block ... 12 | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block ``` -------------------------------------------------------------------------------- Needless to say, this PR addresses all these points. For context, as far as my understanding goes, the main advantage of skipping inner unsafe blocks was that a test case like ```rs fn top_level_used() { unsafe { unsf(); unsafe { unsf() } unsafe { unsf() } unsafe { unsf() } } } ``` should generate some warning because there’s redundant nested `unsafe`, however every single `unsafe` block _does_ contain some statement that uses it. Of course this PR doesn’t aim change the warnings on this kind of code example, because the current behavior, warning on all the inner `unsafe` blocks, makes sense in this case. As mentioned, during MIR building all the unsafe blocks *are* kept now, and usage is attributed to them. The way to still generate a warning like ``` warning: unnecessary `unsafe` block --> src/main.rs:11:9 | 9 | unsafe { | ------ because it's nested under this `unsafe` block 10 | unsf(); 11 | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block | = note: `#[warn(unused_unsafe)]` on by default warning: unnecessary `unsafe` block --> src/main.rs:12:9 | 9 | unsafe { | ------ because it's nested under this `unsafe` block ... 12 | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block warning: unnecessary `unsafe` block --> src/main.rs:13:9 | 9 | unsafe { | ------ because it's nested under this `unsafe` block ... 13 | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block ``` in this case is by emitting a `unused_unsafe` warning for all of the `unsafe` blocks that are _within a **used** unsafe block_. The previous code had a little HIR traversal already anyways to collect a set of all the unsafe blocks (in order to afterwards determine which ones are unused afterwards). This PR uses such a traversal to do additional things including logic like _always_ warn for an `unsafe` block that’s inside of another **used** unsafe block. The traversal is expanded to include nested closures in the same go, this simplifies a lot of things. The whole logic around `unsafe_op_in_unsafe_fn` is a little complicated, there’s some test cases of corner-cases in this PR. (The implementation involves differentiating between whether a used unsafe block was used exclusively by operations where `allow(unsafe_op_in_unsafe_fn)` was active.) The main goal was to make sure that code should compile successfully if all the `unused_unsafe`-warnings are addressed _simultaneously_ (by removing the respective `unsafe` blocks) no matter how complicated the patterns of `unsafe_op_in_unsafe_fn` being disallowed and allowed throughout the function are. -------------------------------------------------------------------------------- One noteworthy design decision I took here: An `unsafe` block with `allow(unused_unsafe)` **is considered used** for the purposes of linting about redundant contained unsafe blocks. So while ```rs fn granularity() { unsafe { //~ ERROR: unnecessary `unsafe` block unsafe { unsf() } unsafe { unsf() } unsafe { unsf() } } } ``` warns for the outer `unsafe` block, ```rs fn top_level_ignored() { #[allow(unused_unsafe)] unsafe { #[deny(unused_unsafe)] { unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block unsafe { unsf() } //~ ERROR: unnecessary `unsafe` block } } } ``` warns on the inner ones.
2022-02-20Auto merge of #94062 - Mark-Simulacrum:drop-print-cfg, r=oli-obkbors-1/+1
Move ty::print methods to Drop-based scope guards Primary goal is reducing codegen of the TLS access for each closure, which shaves ~3 seconds of bootstrap time over rustc as a whole.
2022-02-19Adopt let else in more placesest31-48/+27
2022-02-16Move ty::print methods to Drop-based scope guardsMark Rousskov-1/+1
2022-02-15use AllocId and Ty in ExprKind::StaticRef and delay ConstValue constructionb-naber-15/+7
2022-02-15use ConstantKind::Val in StaticRefb-naber-1/+6
2022-02-15Overhaul `Const`.Nicholas Nethercote-92/+99
Specifically, rename the `Const` struct as `ConstS` and re-introduce `Const` as this: ``` pub struct Const<'tcx>(&'tcx Interned<ConstS>); ``` This now matches `Ty` and `Predicate` more closely, including using pointer-based `eq` and `hash`. Notable changes: - `mk_const` now takes a `ConstS`. - `Const` was copy, despite being 48 bytes. Now `ConstS` is not, so need a we need separate arena for it, because we can't use the `Dropless` one any more. - Many `&'tcx Const<'tcx>`/`&Const<'tcx>` to `Const<'tcx>` changes - Many `ct.ty` to `ct.ty()` and `ct.val` to `ct.val()` changes. - Lots of tedious sigil fiddling.
2022-02-15Overhaul `RegionKind` and `Region`.Nicholas Nethercote-1/+1
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-11/+11
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-12change to a struct variantEllen-1/+1
2022-02-11add tainted_by_errors to mir::BodyMichael Goulet-2/+5
2022-02-11Revert "Auto merge of #92007 - oli-obk:lazy_tait2, r=nikomatsakis"Oli Scherer-4/+2
This reverts commit e7cc3bddbe0d0e374d05e7003e662bba1742dbae, reversing changes made to 734368a200904ef9c21db86c595dc04263c87be0.
2022-02-09Ensure that queries only return Copy types.Camille GILLOT-1/+1
2022-02-07Auto merge of #92007 - oli-obk:lazy_tait2, r=nikomatsakisbors-2/+4
Lazy type-alias-impl-trait Previously opaque types were processed by 1. replacing all mentions of them with inference variables 2. memorizing these inference variables in a side-table 3. at the end of typeck, resolve the inference variables in the side table and use the resolved type as the hidden type of the opaque type This worked okayish for `impl Trait` in return position, but required lots of roundabout type inference hacks and processing. This PR instead stops this process of replacing opaque types with inference variables, and just keeps the opaque types around. Whenever an opaque type `O` is compared with another type `T`, we make the comparison succeed and record `T` as the hidden type. If `O` is compared to `U` while there is a recorded hidden type for it, we grab the recorded type (`T`) and compare that against `U`. This makes implementing * https://github.com/rust-lang/rfcs/pull/2515 much simpler (previous attempts on the inference based scheme were very prone to ICEs and general misbehaviour that was not explainable except by random implementation defined oddities). r? `@nikomatsakis` fixes #93411 fixes #88236
2022-02-03Rollup merge of #93589 - est31:option_then, r=cjgillotYuki Okushi-1/+1
Use Option::then in two places
2022-02-02More let_else adoptionsest31-74/+67
2022-02-02Lazily resolve type-alias-impl-trait defining usesOli Scherer-2/+4
by using an opaque type obligation to bubble up comparisons between opaque types and other types Also uses proper obligation causes so that the body id works, because out of some reason nll uses body ids for logic instead of just diagnostics.
2022-02-02Use Option::then in two placesest31-1/+1
2022-02-01add a rustc::query_stability lintlcnr-0/+1
2022-01-29Check the number of arguments first in `is_recursive_call`Tomasz Miąsko-4/+10
2022-01-26Ignore unwinding edges when checking for unconditional recursionTomasz Miąsko-4/+8
The unconditional recursion lint determines if all execution paths eventually lead to a self-recursive call. The implementation always follows unwinding edges which limits its practical utility. For example, it would not lint function `f` because a call to `g` might unwind. It also wouldn't lint function `h` because an overflow check preceding the self-recursive call might unwind: ```rust pub fn f() { g(); f(); } pub fn g() { /* ... */ } pub fn h(a: usize) { h(a + 1); } ``` To avoid the issue, assume that terminators that might continue execution along non-unwinding edges do so.
2022-01-21Rollup merge of #93046 - est31:let_else, r=davidtwcoMatthias Krüger-21/+17
Use let_else in even more places Followup of #89933, #91018, #91481.
2022-01-21Remove a span from hir::ExprKind::MethodCallCameron Steffen-2/+2
2022-01-18Formally implement let chainsCaio-23/+58
2022-01-18Use let_else in even more placesest31-21/+17
2022-01-17Auto merge of #90986 - camsteffen:nested-filter, r=cjgillotbors-7/+1
Replace `NestedVisitorMap` with generic `NestedFilter` This is an attempt to make the `intravisit::Visitor` API simpler and "more const" with regard to nested visiting. With this change, `intravisit::Visitor` does not visit nested things by default, unless you specify `type NestedFilter = nested_filter::OnlyBodies` (or `All`). `nested_visit_map` returns `Self::Map` instead of `NestedVisitorMap<Self::Map>`. It panics by default (unreachable if `type NestedFilter` is omitted). One somewhat trixty thing here is that `nested_filter::{OnlyBodies, All}` live in `rustc_middle` so that they may have `type Map = map::Map` and so that `impl Visitor`s never need to specify `type Map` - it has a default of `Self::NestedFilter::Map`.
2022-01-17Auto merge of #92816 - tmiasko:rm-llvm-asm, r=Amanieubors-47/+3
Remove deprecated LLVM-style inline assembly The `llvm_asm!` was deprecated back in #87590 1.56.0, with intention to remove it once `asm!` was stabilized, which already happened in #91728 1.59.0. Now it is time to remove `llvm_asm!` to avoid continued maintenance cost. Closes #70173. Closes #92794. Closes #87612. Closes #82065. cc `@rust-lang/wg-inline-asm` r? `@Amanieu`
2022-01-16Replace NestedVisitorMap with NestedFilterCameron Steffen-7/+1
2022-01-16Auto merge of #92805 - BoxyUwU:revert-lazy-anon-const-substs, r=lcnrbors-7/+5
partially revertish `lazily "compute" anon const default substs` reverts #87280 except for some of the changes around `ty::Unevaluated` having a visitor and a generic for promoted why revert: <https://github.com/rust-lang/rust/pull/92805#issuecomment-1010736049> r? `@lcnr`
2022-01-15Reduce use of local_def_id_to_hir_id.Camille GILLOT-34/+30
2022-01-15attempt to re-add `ty::Unevaluated` visitor and friendsEllen-8/+6
2022-01-15initial revertEllen-13/+13
2022-01-13Auto merge of #89861 - nbdd0121:closure, r=wesleywiserbors-4/+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-12Remove deprecated LLVM-style inline assemblyTomasz Miąsko-47/+3
2022-01-11Store a `Symbol` instead of an `Ident` in `VariantDef`/`FieldDef`Aaron Hill-11/+6
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-1/+1
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-3/+3
This span is unused and is superseded by capture_kind_expr_id in CaptureInfo
2022-01-04Rollup merge of #91907 - lcnr:const-arg-infer, r=BoxyUwUMatthias Krüger-3/+6
Allow `_` as the length of array types and repeat expressions r? `@BoxyUwU` cc `@varkor`
2021-12-23implement `generic_arg_infer` for array lengthslcnr-3/+6
2021-12-22Store a `DefId` instead of an `AdtDef` in `AggregateKind::Adt`Aaron Hill-1/+1
The `AggregateKind` enum ends up in the final mir `Body`. Currently, any changes to `AdtDef` (regardless of how significant they are) will legitimately cause the overall result of `optimized_mir` to change, invalidating any codegen re-use involving that mir. This will get worse once we start hashing the `Span` inside `FieldDef` (which is itself contained in `AdtDef`). To try to reduce these kinds of invalidations, this commit changes `AggregateKind::Adt` to store just the `DefId`, instead of the full `AdtDef`. This allows the result of `optimized_mir` to be unchanged if the `AdtDef` changes in a way that doesn't actually affect any of the MIR we build.