Simplify suggestion.

This commit is contained in:
Markus Reiter 2024-04-23 21:19:12 +02:00
parent 3fe0be9e38
commit 7531eafa7e
No known key found for this signature in database
GPG Key ID: 245293B51702655B
3 changed files with 22 additions and 39 deletions

View File

@ -2227,7 +2227,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> bool { ) -> bool {
let tcx = self.tcx; let tcx = self.tcx;
let (adt, args, unwrap) = match expected.kind() { let (adt, args, unwrap) = match expected.kind() {
// In case Option<NonZero*> is wanted, but * is provided, suggest calling new // In case `Option<NonZero<T>>` is wanted, but `T` is provided, suggest calling `new`.
ty::Adt(adt, args) if tcx.is_diagnostic_item(sym::Option, adt.did()) => { ty::Adt(adt, args) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
let nonzero_type = args.type_at(0); // Unwrap option type. let nonzero_type = args.type_at(0); // Unwrap option type.
let ty::Adt(adt, args) = nonzero_type.kind() else { let ty::Adt(adt, args) = nonzero_type.kind() else {
@ -2235,7 +2235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}; };
(adt, args, "") (adt, args, "")
} }
// In case `NonZero<*>` is wanted but `*` is provided, also add `.unwrap()` to satisfy types. // In case `NonZero<T>` is wanted but `T` is provided, also add `.unwrap()` to satisfy types.
ty::Adt(adt, args) => (adt, args, ".unwrap()"), ty::Adt(adt, args) => (adt, args, ".unwrap()"),
_ => return false, _ => return false,
}; };
@ -2244,32 +2244,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return false; return false;
} }
// FIXME: This can be simplified once `NonZero<T>` is stable.
let coercable_types = [
("NonZeroU8", tcx.types.u8),
("NonZeroU16", tcx.types.u16),
("NonZeroU32", tcx.types.u32),
("NonZeroU64", tcx.types.u64),
("NonZeroU128", tcx.types.u128),
("NonZeroI8", tcx.types.i8),
("NonZeroI16", tcx.types.i16),
("NonZeroI32", tcx.types.i32),
("NonZeroI64", tcx.types.i64),
("NonZeroI128", tcx.types.i128),
];
let int_type = args.type_at(0); let int_type = args.type_at(0);
if !self.can_coerce(expr_ty, int_type) {
let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| {
if *t == int_type && self.can_coerce(expr_ty, *t) { Some(nonzero_alias) } else { None }
}) else {
return false; return false;
}; }
err.multipart_suggestion( err.multipart_suggestion(
format!("consider calling `{nonzero_alias}::new`"), format!("consider calling `{}::new`", sym::NonZero),
vec![ vec![
(expr.span.shrink_to_lo(), format!("{nonzero_alias}::new(")), (expr.span.shrink_to_lo(), format!("{}::new(", sym::NonZero)),
(expr.span.shrink_to_hi(), format!("){unwrap}")), (expr.span.shrink_to_hi(), format!("){unwrap}")),
], ],
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,

View File

@ -1,9 +1,9 @@
fn main() { fn main() {
let _: std::num::NonZeroU64 = 1; let _: std::num::NonZero<u64> = 1;
//~^ ERROR mismatched types //~^ ERROR mismatched types
//~| HELP consider calling `NonZeroU64::new` //~| HELP consider calling `NonZero::new`
let _: Option<std::num::NonZeroU64> = 1; let _: Option<std::num::NonZero<u64>> = 1;
//~^ ERROR mismatched types //~^ ERROR mismatched types
//~| HELP consider calling `NonZeroU64::new` //~| HELP consider calling `NonZero::new`
} }

View File

@ -1,32 +1,32 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/non_zero_assigned_something.rs:2:35 --> $DIR/non_zero_assigned_something.rs:2:37
| |
LL | let _: std::num::NonZeroU64 = 1; LL | let _: std::num::NonZero<u64> = 1;
| -------------------- ^ expected `NonZero<u64>`, found integer | ---------------------- ^ expected `NonZero<u64>`, found integer
| | | |
| expected due to this | expected due to this
| |
= note: expected struct `NonZero<u64>` = note: expected struct `NonZero<u64>`
found type `{integer}` found type `{integer}`
help: consider calling `NonZeroU64::new` help: consider calling `NonZero::new`
| |
LL | let _: std::num::NonZeroU64 = NonZeroU64::new(1).unwrap(); LL | let _: std::num::NonZero<u64> = NonZero::new(1).unwrap();
| ++++++++++++++++ ++++++++++ | +++++++++++++ ++++++++++
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/non_zero_assigned_something.rs:6:43 --> $DIR/non_zero_assigned_something.rs:6:45
| |
LL | let _: Option<std::num::NonZeroU64> = 1; LL | let _: Option<std::num::NonZero<u64>> = 1;
| ---------------------------- ^ expected `Option<NonZero<u64>>`, found integer | ------------------------------ ^ expected `Option<NonZero<u64>>`, found integer
| | | |
| expected due to this | expected due to this
| |
= note: expected enum `Option<NonZero<u64>>` = note: expected enum `Option<NonZero<u64>>`
found type `{integer}` found type `{integer}`
help: consider calling `NonZeroU64::new` help: consider calling `NonZero::new`
| |
LL | let _: Option<std::num::NonZeroU64> = NonZeroU64::new(1); LL | let _: Option<std::num::NonZero<u64>> = NonZero::new(1);
| ++++++++++++++++ + | +++++++++++++ +
error: aborting due to 2 previous errors error: aborting due to 2 previous errors