mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Suggest a fix for NonZero*
<- *
coercion error
This commit is contained in:
parent
37c21d6fc7
commit
7163e7ff65
@ -223,6 +223,16 @@ symbols! {
|
||||
LintPass,
|
||||
Mutex,
|
||||
N,
|
||||
NonZeroI128,
|
||||
NonZeroI16,
|
||||
NonZeroI32,
|
||||
NonZeroI64,
|
||||
NonZeroI8,
|
||||
NonZeroU128,
|
||||
NonZeroU16,
|
||||
NonZeroU32,
|
||||
NonZeroU64,
|
||||
NonZeroU8,
|
||||
None,
|
||||
Ok,
|
||||
Option,
|
||||
|
@ -34,6 +34,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.annotate_expected_due_to_let_ty(err, expr, error);
|
||||
self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr);
|
||||
self.suggest_compatible_variants(err, expr, expected, expr_ty);
|
||||
self.suggest_non_zero_new_unwrap(err, expr, expected, expr_ty);
|
||||
if self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty) {
|
||||
return;
|
||||
}
|
||||
@ -418,6 +419,59 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_non_zero_new_unwrap(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
expr: &hir::Expr<'_>,
|
||||
expected: Ty<'tcx>,
|
||||
expr_ty: Ty<'tcx>,
|
||||
) {
|
||||
let tcx = self.tcx;
|
||||
let (adt, unwrap) = match expected.kind() {
|
||||
// In case Option<NonZero*> is wanted, but * is provided, suggest calling new
|
||||
ty::Adt(adt, substs) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
|
||||
// Unwrap option
|
||||
let Some(fst) = substs.first() else { return };
|
||||
let ty::Adt(adt, _) = fst.expect_ty().kind() else { return };
|
||||
|
||||
(adt, "")
|
||||
}
|
||||
// In case NonZero* is wanted, but * is provided also add `.unwrap()` to satisfy types
|
||||
ty::Adt(adt, _) => (adt, ".unwrap()"),
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let map = [
|
||||
(sym::NonZeroU8, tcx.types.u8),
|
||||
(sym::NonZeroU16, tcx.types.u16),
|
||||
(sym::NonZeroU32, tcx.types.u32),
|
||||
(sym::NonZeroU64, tcx.types.u64),
|
||||
(sym::NonZeroU128, tcx.types.u128),
|
||||
(sym::NonZeroI8, tcx.types.i8),
|
||||
(sym::NonZeroI16, tcx.types.i16),
|
||||
(sym::NonZeroI32, tcx.types.i32),
|
||||
(sym::NonZeroI64, tcx.types.i64),
|
||||
(sym::NonZeroI128, tcx.types.i128),
|
||||
];
|
||||
|
||||
let Some((s, _)) = map
|
||||
.iter()
|
||||
.find(|&&(s, _)| self.tcx.is_diagnostic_item(s, adt.did()))
|
||||
.filter(|&&(_, t)| { self.can_coerce(expr_ty, t) })
|
||||
else { return };
|
||||
|
||||
let path = self.tcx.def_path_str(adt.non_enum_variant().def_id);
|
||||
|
||||
err.multipart_suggestion(
|
||||
format!("consider calling `{s}::new`"),
|
||||
vec![
|
||||
(expr.span.shrink_to_lo(), format!("{path}::new(")),
|
||||
(expr.span.shrink_to_hi(), format!("){unwrap}")),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn get_conversion_methods(
|
||||
&self,
|
||||
span: Span,
|
||||
|
@ -39,6 +39,7 @@ macro_rules! nonzero_integers {
|
||||
#[repr(transparent)]
|
||||
#[rustc_layout_scalar_valid_range_start(1)]
|
||||
#[rustc_nonnull_optimization_guaranteed]
|
||||
#[rustc_diagnostic_item = stringify!($Ty)]
|
||||
pub struct $Ty($Int);
|
||||
|
||||
impl $Ty {
|
||||
|
@ -0,0 +1,9 @@
|
||||
fn main() {
|
||||
let _: std::num::NonZeroU64 = 1;
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP consider calling `NonZeroU64::new`
|
||||
|
||||
let _: Option<std::num::NonZeroU64> = 1;
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP consider calling `NonZeroU64::new`
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/non_zero_assigned_something.rs:2:35
|
||||
|
|
||||
LL | let _: std::num::NonZeroU64 = 1;
|
||||
| -------------------- ^ expected struct `NonZeroU64`, found integer
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
help: consider calling `NonZeroU64::new`
|
||||
|
|
||||
LL | let _: std::num::NonZeroU64 = NonZeroU64::new(1).unwrap();
|
||||
| ++++++++++++++++ ++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/non_zero_assigned_something.rs:6:43
|
||||
|
|
||||
LL | let _: Option<std::num::NonZeroU64> = 1;
|
||||
| ---------------------------- ^ expected enum `Option`, found integer
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected enum `Option<NonZeroU64>`
|
||||
found type `{integer}`
|
||||
help: consider calling `NonZeroU64::new`
|
||||
|
|
||||
LL | let _: Option<std::num::NonZeroU64> = NonZeroU64::new(1);
|
||||
| ++++++++++++++++ +
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user