Skip to content

Commit

Permalink
unsafeck: Don't treat AscribeUserType as use
Browse files Browse the repository at this point in the history
Previously, if the MIR had an AscribeUserType statement that ascribed a
type to the pointee of a raw pointer, it would be treated as a dereference
of the raw pointer for purposes of unsafe-checking. For example, the
following code would be treated as containing a raw-pointer dereference:

    fn foo(ptr: *const bool) {
        let _: bool = *ptr;
    }

Producing this error:

    error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
     --> issue-80059.rs:2:12
      |
    2 |     let _: bool = *ptr;
      |            ^^^^ dereference of raw pointer

Note that the error points to the type ascription as having a
dereference! That's because the generated AscribeUserType MIR statement
is treated as containing a dereference of `_1`:

    AscribeUserType((*_1), +, UserTypeProjection { base: UserType(1), projs: [] });

Now the unsafe-checker ignores uses inside `AscribeUserType` statements,
which means this code now compiles successfully.

-----

Note that this code:

    fn foo(ptr: *const bool) {
        let _: bool = *ptr;
    }

does *not* produce an error (it compiles fine) because of the magical
behavior of the `_` (wildcard) pattern (see rust-lang#80059).
  • Loading branch information
camelid committed Jan 8, 2021
1 parent c8915ee commit 90004f0
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
9 changes: 8 additions & 1 deletion compiler/rustc_mir/src/transform/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,18 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
| StatementKind::StorageLive(..)
| StatementKind::StorageDead(..)
| StatementKind::Retag { .. }
| StatementKind::AscribeUserType(..)
| StatementKind::Coverage(..)
| StatementKind::Nop => {
// safe (at least as emitted during MIR construction)
}
StatementKind::AscribeUserType(..) => {
// safe (at least as emitted during MIR construction)
// This is handled separately because we don't want
// super_statement to be called.
// See this for more:
// https://github.com/rust-lang/rust/issues/80059#issuecomment-756968485
return;
}

StatementKind::LlvmInlineAsm { .. } => self.require_unsafe(
UnsafetyViolationKind::General,
Expand Down
7 changes: 7 additions & 0 deletions src/test/ui/unsafe/wildcard-type-ascription.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// check-pass

fn foo(ptr: *const bool) {
let _: bool = *ptr;
}

fn main() {}

0 comments on commit 90004f0

Please sign in to comment.