Skip to content

Commit 02ebca2

Browse files
authored
Rollup merge of #140196 - Kivooeo:new-fix-two, r=wesleywiser
Improved diagnostics for non-primitive cast on non-primitive types (`Arc`, `Option`) here is a small fix that improving error messaging when user is trying to do something like this ```rust let _ = "x" as Arc<str>; let _ = 2 as Option<i32>; ``` before it looks like this ```rust error[E0605]: non-primitive cast: `&'static str` as `Arc<str>` --> src\main.rs:3:13 | 3 | let _ = "x" as Arc<str>; | ^^^^^^^^^^^^^^^ help: consider using the `From` trait instead: `Arc<str>::from("x")` error[E0605]: non-primitive cast: `i32` as `Option<i32>` --> src\main.rs:4:13 | 4 | let _ = 2 as Option<i32>; ``` which looks horrible to be honest so i made a small fix that make errors looks like this ```rust error[E0605]: non-primitive cast: `&'static str` as `Arc<str>` | 3 | let _ = "x" as Arc<str>; | ^^^^^^^^^^^^^^^ | = note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object help: consider using the `From` trait instead | 3 - let _ = "x" as Arc<str>; 3 + let _ = Arc::<str>::from("x"); | error[E0605]: non-primitive cast: `i32` as `Option<i32>` | 4 | let _ = 2 as Option<i32>; | ^^^^^^^^^^^^^^^^ | = note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object help: consider using the `From` trait instead | 4 - let _ = 2 as Option<i32>; 4 + let _ = Option::<i32>::from(2); ``` **What improves?** 1) `Arc<str>::from("x")` which makes no sense because of missing `::` 2) readability **Related Issue** fixes #135412
2 parents 4c0d38b + c9deaf6 commit 02ebca2

File tree

5 files changed

+74
-7
lines changed

5 files changed

+74
-7
lines changed

compiler/rustc_hir_typeck/src/cast.rs

+19-6
Original file line numberDiff line numberDiff line change
@@ -501,12 +501,25 @@ impl<'a, 'tcx> CastCheck<'tcx> {
501501
.must_apply_modulo_regions()
502502
{
503503
label = false;
504-
err.span_suggestion(
505-
self.span,
506-
"consider using the `From` trait instead",
507-
format!("{}::from({})", self.cast_ty, snippet),
508-
Applicability::MaybeIncorrect,
509-
);
504+
if let ty::Adt(def, args) = self.cast_ty.kind() {
505+
err.span_suggestion_verbose(
506+
self.span,
507+
"consider using the `From` trait instead",
508+
format!(
509+
"{}::from({})",
510+
fcx.tcx.value_path_str_with_args(def.did(), args),
511+
snippet
512+
),
513+
Applicability::MaybeIncorrect,
514+
);
515+
} else {
516+
err.span_suggestion(
517+
self.span,
518+
"consider using the `From` trait instead",
519+
format!("{}::from({})", self.cast_ty, snippet),
520+
Applicability::MaybeIncorrect,
521+
);
522+
};
510523
}
511524
}
512525

tests/ui/coercion/issue-73886.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@ error[E0605]: non-primitive cast: `u32` as `Option<_>`
88
--> $DIR/issue-73886.rs:4:13
99
|
1010
LL | let _ = 7u32 as Option<_>;
11-
| ^^^^^^^^^^^^^^^^^ help: consider using the `From` trait instead: `Option<_>::from(7u32)`
11+
| ^^^^^^^^^^^^^^^^^
1212
|
1313
= note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
14+
help: consider using the `From` trait instead
15+
|
16+
LL - let _ = 7u32 as Option<_>;
17+
LL + let _ = Option::<_>::from(7u32);
18+
|
1419

1520
error: aborting due to 2 previous errors
1621

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@ run-rustfix
2+
3+
use std::sync::Arc;
4+
5+
fn main() {
6+
let _ = Option::<_>::from(7u32);
7+
//~^ ERROR non-primitive cast: `u32` as `Option<_>`
8+
let _ = Arc::<str>::from("String");
9+
//~^ ERROR non-primitive cast: `&'static str` as `Arc<str>`
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@ run-rustfix
2+
3+
use std::sync::Arc;
4+
5+
fn main() {
6+
let _ = 7u32 as Option<_>;
7+
//~^ ERROR non-primitive cast: `u32` as `Option<_>`
8+
let _ = "String" as Arc<str>;
9+
//~^ ERROR non-primitive cast: `&'static str` as `Arc<str>`
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0605]: non-primitive cast: `u32` as `Option<_>`
2+
--> $DIR/non-primitive-cast-135412.rs:6:13
3+
|
4+
LL | let _ = 7u32 as Option<_>;
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
8+
help: consider using the `From` trait instead
9+
|
10+
LL - let _ = 7u32 as Option<_>;
11+
LL + let _ = Option::<_>::from(7u32);
12+
|
13+
14+
error[E0605]: non-primitive cast: `&'static str` as `Arc<str>`
15+
--> $DIR/non-primitive-cast-135412.rs:8:13
16+
|
17+
LL | let _ = "String" as Arc<str>;
18+
| ^^^^^^^^^^^^^^^^^^^^
19+
|
20+
= note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
21+
help: consider using the `From` trait instead
22+
|
23+
LL - let _ = "String" as Arc<str>;
24+
LL + let _ = Arc::<str>::from("String");
25+
|
26+
27+
error: aborting due to 2 previous errors
28+
29+
For more information about this error, try `rustc --explain E0605`.

0 commit comments

Comments
 (0)