Commit Graph

241 Commits

Author SHA1 Message Date
bors
574830f573 Auto merge of #96094 - Elliot-Roberts:fix_doctests, r=compiler-errors
Begin fixing all the broken doctests in `compiler/`

Begins to fix #95994.
All of them pass now but 24 of them I've marked with `ignore HELP (<explanation>)` (asking for help) as I'm unsure how to get them to work / if we should leave them as they are.
There are also a few that I marked `ignore` that could maybe be made to work but seem less important.
Each `ignore` has a rough "reason" for ignoring after it parentheses, with

- `(pseudo-rust)` meaning "mostly rust-like but contains foreign syntax"
- `(illustrative)` a somewhat catchall for either a fragment of rust that doesn't stand on its own (like a lone type), or abbreviated rust with ellipses and undeclared types that would get too cluttered if made compile-worthy.
- `(not-rust)` stuff that isn't rust but benefits from the syntax highlighting, like MIR.
- `(internal)` uses `rustc_*` code which would be difficult to make work with the testing setup.

Those reason notes are a bit inconsistently applied and messy though. If that's important I can go through them again and try a more principled approach. When I run `rg '```ignore \(' .` on the repo, there look to be lots of different conventions other people have used for this sort of thing. I could try unifying them all if that would be helpful.

I'm not sure if there was a better existing way to do this but I wrote my own script to help me run all the doctests and wade through the output. If that would be useful to anyone else, I put it here: https://github.com/Elliot-Roberts/rust_doctest_fixing_tool
2022-05-07 06:30:29 +00:00
Oli Scherer
db02e61038 Generate an intermediate temporary for Drop constants.
To limit the fallout from this, don't do this for the last (or only) operand in an rvalue.
2022-05-04 09:09:52 +00:00
Elliot Roberts
7907385999 fix most compiler/ doctests 2022-05-02 17:40:30 -07:00
Dylan DPC
38e3f523c0 Rollup merge of #93313 - tmiasko:uninhabited, r=tmandry
Check if call return type is visibly uninhabited when building MIR

The main motivation behind the change is to expose information about diverging
calls to the generator transform and match the precision of drop range tracking
which already understands that call expressions with visibly uninhabited types
diverges.

This change should also accept strictly more programs than before. That is
programs that were previously rejected due to errors raised by control-flow
sensitive checks in a code that is no longer considered reachable.

Fixes #93161.
2022-04-20 18:26:01 +02:00
bors
080d5452e1 Auto merge of #94468 - Amanieu:global_asm_sym, r=nagisa
Implement sym operands for global_asm!

Tracking issue: #93333

This PR is pretty much a complete rewrite of `sym` operand support for inline assembly so that the same implementation can be shared by `asm!` and `global_asm!`. The main changes are:
- At the AST level, `sym` is represented as a special `InlineAsmSym` AST node containing a path instead of an `Expr`.
- At the HIR level, `sym` is split into `SymStatic` and `SymFn` depending on whether the path resolves to a static during AST lowering (defaults to `SynFn` if `get_early_res` fails).
  - `SymFn` is just an `AnonConst`. It runs through typeck and we just collect the resulting type at the end. An error is emitted if the type is not a `FnDef`.
  - `SymStatic` directly holds a path and the `DefId` of the `static` that it is pointing to.
- The representation at the MIR level is mostly unchanged. There is a minor change to THIR where `SymFn` is a constant instead of an expression.
- At the codegen level we need to apply the target's symbol mangling to the result of `tcx.symbol_name()` depending on the target. This is done by calling the LLVM name mangler, which handles all of the details.
  - On Mach-O, all symbols have a leading underscore.
  - On x86 Windows, different mangling is used for cdecl, stdcall, fastcall and vectorcall.
  - No mangling is needed on other platforms.

r? `@nagisa`
cc `@eddyb`
2022-04-16 04:46:01 +00:00
Dylan DPC
ba9c3a13ee Rollup merge of #96026 - matthiaskrgr:clippy_compl_1304, r=Dylan-DPC
couple of clippy::complexity fixes
2022-04-15 20:50:47 +02:00
ouz-a
c20bb1d59f Update issue-92893.stderr 2022-04-14 23:42:15 +03:00
Amanieu d'Antras
dc345d8bff Reimplement lowering of sym operands for asm! so that it also works with global_asm! 2022-04-14 15:32:03 +01:00
Matthias Krüger
7c2d57e0fa couple of clippy::complexity fixes 2022-04-13 22:51:34 +02:00
b-naber
3be987e076 dont make lit_to_mir_constant a query 2022-04-08 11:56:21 +02:00
b-naber
0078e54185 rebase and use ty::Const in patterns again 2022-04-02 12:21:00 +02:00
b-naber
ac60db231c do use ty::Const in patterns and abstract consts 2022-04-02 12:20:59 +02:00
b-naber
b38077ea0b change thir to use mir::ConstantKind instead of ty::Const 2022-04-02 12:20:56 +02:00
Dylan DPC
1b7d6dbd30 Rollup merge of #95497 - nyurik:compiler-spell-comments, r=compiler-errors
Spellchecking compiler comments

This PR cleans up the rest of the spelling mistakes in the compiler comments. This PR does not change any literal or code spelling issues.
2022-03-31 04:57:28 +02:00
bors
a40c595695 Auto merge of #95436 - cjgillot:static-mut, r=oli-obk
Remember mutability in `DefKind::Static`.

This allows to compute the `BodyOwnerKind` from `DefKind` only, and
removes a direct dependency of some MIR queries onto HIR.

As a side effect, it also simplifies metadata, since we don't need 4
flavours of `EntryKind::*Static` any more.
2022-03-30 22:09:56 +00:00
Yuri Astrakhan
a6dd658254 Addressed comments by @compiler-errors and @bjorn3 2022-03-30 17:04:46 -04:00
Yuri Astrakhan
5160f8f843 Spellchecking compiler comments
This PR cleans up the rest of the spelling mistakes in the compiler comments. This PR does not change any literal or code spelling issues.
2022-03-30 15:14:15 -04:00
bors
05142a7e44 Auto merge of #95466 - Dylan-DPC:rollup-g7ddr8y, r=Dylan-DPC
Rollup of 5 pull requests

Successful merges:

 - #95294 (Document Linux kernel handoff in std::io::copy and std::fs::copy)
 - #95443 (Clarify how `src/tools/x` searches for python)
 - #95452 (fix since field version for termination stabilization)
 - #95460 (Spellchecking compiler code)
 - #95461 (Spellchecking some comments)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
2022-03-30 07:45:42 +00:00
Yuri Astrakhan
7e8201ae0a Spellchecking some comments
This PR attempts to clean up some minor spelling mistakes in comments
2022-03-30 01:39:38 -04:00
Camille GILLOT
21a554caf6 Remember mutability in DefKind::Static.
This allows to compute the `BodyOwnerKind` from `DefKind` only, and
removes a direct dependency of some MIR queries onto HIR.

As a side effect, it also simplifies metadata, since we don't need 4
flavours of `EntryKind::*Static` any more.
2022-03-29 18:50:52 +02:00
Oli Scherer
264cd05b16 Revert "Auto merge of #93893 - oli-obk:sad_revert, r=oli-obk"
This reverts commit 6499c5e7fc, reversing
changes made to 78450d2d60.
2022-03-28 16:27:14 +00:00
Tomasz Miąsko
6f8a1ee45e Check if call return type is visibly uninhabited when building MIR 2022-03-24 23:56:12 +01:00
b-naber
19041d995d dont use a query for lit_to_constant 2022-03-23 20:18:34 +01:00
b-naber
5fcccd1739 use NonHirLiteral instead of ScalarLiteral, move pattern related code to pat_is_poly in IsThirPolymorphic 2022-03-23 11:34:33 +01:00
b-naber
9cd8bb0456 use ParamConst in ExprKind::ConstParam 2022-03-23 11:34:33 +01:00
b-naber
e2496b3cf4 remove thir::Visitor::visit_const 2022-03-23 11:34:32 +01:00
b-naber
f713b5017c change thir to lazily create constants 2022-03-23 11:34:32 +01:00
mark
bb8d4307eb rustc_error: make ErrorReported impossible to construct
There are a few places were we have to construct it, though, and a few
places that are more invasive to change. To do this, we create a
constructor with a long obvious name.
2022-03-16 10:35:24 -05:00
Nicholas Nethercote
ca5525d564 Improve AdtDef interning.
This commit makes `AdtDef` use `Interned`. Much the commit is tedious
changes to introduce getter functions. The interesting changes are in
`compiler/rustc_middle/src/ty/adt.rs`.
2022-03-11 13:31:24 +11:00
b-naber
40e4bd2d02 treat all mir::Constant values as ConstantKind::Val 2022-03-09 10:52:04 +01:00
b-naber
d92df974fe treat literals in ExprKind::StaticRef as mir::ConstantKind::Val 2022-03-08 10:04:28 +01:00
mark
e489a94dee rename ErrorReported -> ErrorGuaranteed 2022-03-02 09:45:25 -06:00
Caio
fe94f78b9b 6 - Make more use of let_chains
Continuation of #94376.

cc #53667
2022-02-28 21:12:52 -03:00
Mark Rousskov
76b13c9eea Enable rustc_pass_by_value for Span 2022-02-25 08:00:53 -05:00
bors
03a8cc7df1 Auto merge of #93505 - lcnr:substsref-vs-ty-list, r=michaelwoerister
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-21 16:03:38 +00:00
lcnr
1245131a11 use List<Ty<'tcx>> for tuples 2022-02-21 07:09:11 +01:00
Mark Rousskov
9f76214854 Revert "Auto merge of #93800 - b-naber:static-initializers-mir-val, r=oli-obk"
This reverts commit a240ccd81c, reversing
changes made to 393fdc1048.

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-20 21:56:20 -05:00
Frank Steffahn
8f8689fb31 Improve unused_unsafe lint
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-20 21:00:12 +01:00
est31
2ef8af6619 Adopt let else in more places 2022-02-19 17:27:43 +01:00
b-naber
fff06e5edc use AllocId and Ty in ExprKind::StaticRef and delay ConstValue construction 2022-02-15 21:18:33 +01:00
b-naber
5e0fab6da5 use ConstantKind::Val in StaticRef 2022-02-15 21:10:42 +01:00
Nicholas Nethercote
a95fb8b150 Overhaul Const.
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-15 16:19:59 +11:00
Nicholas Nethercote
7024dc523a Overhaul RegionKind and Region.
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-15 16:08:52 +11:00
Nicholas Nethercote
e9a0c429c5 Overhaul TyS and Ty.
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-15 16:03:24 +11:00
Michael Goulet
a431174c23 add tainted_by_errors to mir::Body 2022-02-11 12:45:51 -08:00
Oli Scherer
d54195db22 Revert "Auto merge of #92007 - oli-obk:lazy_tait2, r=nikomatsakis"
This reverts commit e7cc3bddbe, reversing
changes made to 734368a200.
2022-02-11 07:18:06 +00:00
Camille GILLOT
6c2ee885e6 Ensure that queries only return Copy types. 2022-02-09 20:07:38 +01:00
bors
e7cc3bddbe Auto merge of #92007 - oli-obk:lazy_tait2, r=nikomatsakis
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-07 23:40:26 +00:00
Yuki Okushi
7712dfd46e Rollup merge of #93589 - est31:option_then, r=cjgillot
Use Option::then in two places
2022-02-03 22:20:27 +09:00
est31
670f5c6ef3 More let_else adoptions 2022-02-02 17:11:01 +01:00