1. 25 2月, 2022 1 次提交
  2. 21 2月, 2022 5 次提交
    • M
      debuginfo: Simplify TypeMap used during LLVM debuginfo generation. · e72e6399
      Michael Woerister 提交于
      The previous implementation was written before types were properly
      normalized for code generation and had to assume a more complicated
      relationship between types and their debuginfo -- generating separate
      identifiers for debuginfo nodes that were based on normalized types.
      
      Since types are now already normalized, we can use them as identifiers
      for debuginfo nodes.
      e72e6399
    • B
      Auto merge of #94066 - Mark-Simulacrum:factor-out-simple-def-kind, r=davidtwco · 026d8ce7
      bors 提交于
      Remove SimpleDefKind
      
      Now that rustc_query_system depends on rustc_hir, we can just directly make use of the regular DefKind.
      026d8ce7
    • B
      Auto merge of #93678 - steffahn:better_unsafe_diagnostics, r=nagisa · 45e2c288
      bors 提交于
      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.
      45e2c288
    • F
      Improve `unused_unsafe` lint · 8f8689fb
      Frank Steffahn 提交于
      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.
      8f8689fb
    • B
      Auto merge of #94062 - Mark-Simulacrum:drop-print-cfg, r=oli-obk · 523a1b1d
      bors 提交于
      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.
      523a1b1d
  3. 20 2月, 2022 26 次提交
  4. 19 2月, 2022 8 次提交