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; - //~^ WARN not FFI-safe fn pt_non_zero_usize_opt_full_range() -> Option; //~^ 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; - //~^ 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`, which is not FFI-safe - --> $DIR/clashing-extern-fn.rs:501:43 - | -LL | fn pt_non_zero_usize_opt() -> Option; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -35,15 +26,6 @@ LL | fn pt_non_zero_usize_opt_full_range() -> Option`, which is not FFI-safe - --> $DIR/clashing-extern-fn.rs:507:51 - | -LL | fn pt_non_zero_usize_wrapper_opt() -> Option; - | ^^^^^^^^^^^^^^^^^^^^ 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 usize` found `unsafe extern "C" fn() -> Option>>` -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; - | ------------------------------------------------------------------ `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; - | ----------------------------------------------------------- `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` - found `unsafe extern "C" fn() -> usize` - -warning: 28 warnings emitted +warning: 24 warnings emitted