about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/types.rs31
-rw-r--r--tests/ui/lint/clashing-extern-fn.rs4
-rw-r--r--tests/ui/lint/clashing-extern-fn.stderr48
4 files changed, 35 insertions, 49 deletions
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index d89e615e14a..c8de5e87753 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -33,6 +33,7 @@
 #![feature(let_chains)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
+#![feature(try_blocks)]
 #![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 47ceb4b7d28..68b1f435a4c 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -877,6 +877,37 @@ fn ty_is_known_nonnull<'tcx>(
                 .filter_map(|variant| transparent_newtype_field(tcx, variant))
                 .any(|field| ty_is_known_nonnull(tcx, typing_env, field.ty(tcx, args), mode))
         }
+        ty::Pat(base, pat) => {
+            ty_is_known_nonnull(tcx, typing_env, *base, mode)
+                || Option::unwrap_or_default(
+                    try {
+                        match **pat {
+                            ty::PatternKind::Range { start, end, include_end } => {
+                                match (start, end) {
+                                    (Some(start), None) => {
+                                        start.try_to_value()?.try_to_bits(tcx, typing_env)? > 0
+                                    }
+                                    (Some(start), Some(end)) => {
+                                        let start =
+                                            start.try_to_value()?.try_to_bits(tcx, typing_env)?;
+                                        let end =
+                                            end.try_to_value()?.try_to_bits(tcx, typing_env)?;
+
+                                        if include_end {
+                                            // This also works for negative numbers, as we just need
+                                            // to ensure we aren't wrapping over zero.
+                                            start > 0 && end >= start
+                                        } else {
+                                            start > 0 && end > start
+                                        }
+                                    }
+                                    _ => false,
+                                }
+                            }
+                        }
+                    },
+                )
+        }
         _ => false,
     }
 }
diff --git a/tests/ui/lint/clashing-extern-fn.rs b/tests/ui/lint/clashing-extern-fn.rs
index 1d1c07b66b2..e4477c96202 100644
--- a/tests/ui/lint/clashing-extern-fn.rs
+++ b/tests/ui/lint/clashing-extern-fn.rs
@@ -499,13 +499,11 @@ mod pattern_types {
         extern "C" {
             fn pt_non_zero_usize() -> pattern_type!(usize is 1..);
             fn pt_non_zero_usize_opt() -> Option<pattern_type!(usize is 1..)>;
-            //~^ WARN not FFI-safe
             fn pt_non_zero_usize_opt_full_range() -> Option<pattern_type!(usize is 0..)>;
             //~^ WARN not FFI-safe
             fn pt_non_null_ptr() -> pattern_type!(usize is 1..);
             fn pt_non_zero_usize_wrapper() -> NonZeroUsize;
             fn pt_non_zero_usize_wrapper_opt() -> Option<NonZeroUsize>;
-            //~^ WARN not FFI-safe
         }
     }
     mod b {
@@ -515,12 +513,10 @@ mod pattern_types {
             // cases are warning for, from both a caller-convenience and optimisation perspective.
             fn pt_non_zero_usize() -> usize;
             fn pt_non_zero_usize_opt() -> usize;
-            //~^ WARN `pt_non_zero_usize_opt` redeclared with a different signature
             fn pt_non_null_ptr() -> *const ();
             //~^ WARN `pt_non_null_ptr` redeclared with a different signature
             fn pt_non_zero_usize_wrapper() -> usize;
             fn pt_non_zero_usize_wrapper_opt() -> usize;
-            //~^ WARN `pt_non_zero_usize_wrapper_opt` redeclared with a different signature
         }
     }
 }
diff --git a/tests/ui/lint/clashing-extern-fn.stderr b/tests/ui/lint/clashing-extern-fn.stderr
index a2fc9e77492..118b18b224c 100644
--- a/tests/ui/lint/clashing-extern-fn.stderr
+++ b/tests/ui/lint/clashing-extern-fn.stderr
@@ -17,17 +17,8 @@ LL |             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usiz
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 
-warning: `extern` block uses type `Option<(usize) is 1..=>`, which is not FFI-safe
-  --> $DIR/clashing-extern-fn.rs:501:43
-   |
-LL |             fn pt_non_zero_usize_opt() -> Option<pattern_type!(usize is 1..)>;
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
 warning: `extern` block uses type `Option<(usize) is 0..=>`, which is not FFI-safe
-  --> $DIR/clashing-extern-fn.rs:503:54
+  --> $DIR/clashing-extern-fn.rs:502:54
    |
 LL |             fn pt_non_zero_usize_opt_full_range() -> Option<pattern_type!(usize is 0..)>;
    |                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -35,15 +26,6 @@ LL |             fn pt_non_zero_usize_opt_full_range() -> Option<pattern_type!(u
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 
-warning: `extern` block uses type `Option<NonZeroUsize>`, which is not FFI-safe
-  --> $DIR/clashing-extern-fn.rs:507:51
-   |
-LL |             fn pt_non_zero_usize_wrapper_opt() -> Option<NonZeroUsize>;
-   |                                                   ^^^^^^^^^^^^^^^^^^^^ not FFI-safe
-   |
-   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
-   = note: enum has no representation hint
-
 warning: `clash` redeclared with a different signature
   --> $DIR/clashing-extern-fn.rs:13:13
    |
@@ -285,20 +267,8 @@ LL |             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usiz
    = note: expected `unsafe extern "C" fn() -> usize`
               found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZero<usize>>>`
 
-warning: `pt_non_zero_usize_opt` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:517:13
-   |
-LL |             fn pt_non_zero_usize_opt() -> Option<pattern_type!(usize is 1..)>;
-   |             ------------------------------------------------------------------ `pt_non_zero_usize_opt` previously declared here
-...
-LL |             fn pt_non_zero_usize_opt() -> usize;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
-   |
-   = note: expected `unsafe extern "C" fn() -> Option<(usize) is 1..=>`
-              found `unsafe extern "C" fn() -> usize`
-
 warning: `pt_non_null_ptr` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:519:13
+  --> $DIR/clashing-extern-fn.rs:516:13
    |
 LL |             fn pt_non_null_ptr() -> pattern_type!(usize is 1..);
    |             ---------------------------------------------------- `pt_non_null_ptr` previously declared here
@@ -309,17 +279,5 @@ LL |             fn pt_non_null_ptr() -> *const ();
    = note: expected `unsafe extern "C" fn() -> (usize) is 1..=`
               found `unsafe extern "C" fn() -> *const ()`
 
-warning: `pt_non_zero_usize_wrapper_opt` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:522:13
-   |
-LL |             fn pt_non_zero_usize_wrapper_opt() -> Option<NonZeroUsize>;
-   |             ----------------------------------------------------------- `pt_non_zero_usize_wrapper_opt` previously declared here
-...
-LL |             fn pt_non_zero_usize_wrapper_opt() -> usize;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
-   |
-   = note: expected `unsafe extern "C" fn() -> Option<NonZeroUsize>`
-              found `unsafe extern "C" fn() -> usize`
-
-warning: 28 warnings emitted
+warning: 24 warnings emitted