remove a type string comparison

This commit is contained in:
Takayuki Maeda 2022-08-10 11:42:46 +09:00
parent 93ab13b4e8
commit 54cf66f241
3 changed files with 77 additions and 8 deletions

View File

@ -598,13 +598,15 @@ fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, St
};
let self_ty = self.typeck_results.borrow().expr_ty(&method_expr[0]);
let self_ty = format!("{:?}", self_ty);
let name = method_path.ident.name;
let is_as_ref_able = (self_ty.starts_with("&std::option::Option")
|| self_ty.starts_with("&std::result::Result")
|| self_ty.starts_with("std::option::Option")
|| self_ty.starts_with("std::result::Result"))
&& (name == sym::map || name == sym::and_then);
let is_as_ref_able = match self_ty.peel_refs().kind() {
ty::Adt(def, _) => {
(self.tcx.is_diagnostic_item(sym::Option, def.did())
|| self.tcx.is_diagnostic_item(sym::Result, def.did()))
&& (name == sym::map || name == sym::and_then)
}
_ => false,
};
match (is_as_ref_able, self.sess().source_map().span_to_snippet(method_path.ident.span)) {
(true, Ok(src)) => {
let suggestion = format!("as_ref().{}", src);
@ -792,7 +794,6 @@ pub fn check_ref(
_ if is_range_literal(expr) => true,
_ => false,
};
let sugg_expr = if needs_parens { format!("({src})") } else { src };
if let Some(sugg) = self.can_use_as_ref(expr) {
return Some((
@ -820,6 +821,7 @@ pub fn check_ref(
}
}
let sugg_expr = if needs_parens { format!("({src})") } else { src };
return Some(match mutability {
hir::Mutability::Mut => (
sp,

View File

@ -17,4 +17,11 @@ fn main() {
// note: do not suggest because of `E: usize`
let x: &Result<usize, usize> = &Ok(3);
let y: Result<&usize, usize> = x; //~ ERROR mismatched types [E0308]
let multiple_ref_opt = &&Some(Foo);
multiple_ref_opt.map(|arg| takes_ref(arg)); //~ ERROR mismatched types [E0308]
multiple_ref_opt.and_then(|arg| Some(takes_ref(arg))); //~ ERROR mismatched types [E0308]
let multiple_ref_result = &&Ok(Foo);
multiple_ref_result.map(|arg| takes_ref(arg)); //~ ERROR mismatched types [E0308]
multiple_ref_result.and_then(|arg| Ok(takes_ref(arg))); //~ ERROR mismatched types [E0308]
}

View File

@ -97,6 +97,66 @@ LL | let y: Result<&usize, usize> = x;
= note: expected enum `Result<&usize, usize>`
found reference `&Result<usize, usize>`
error: aborting due to 7 previous errors
error[E0308]: mismatched types
--> $DIR/as-ref.rs:22:42
|
LL | multiple_ref_opt.map(|arg| takes_ref(arg));
| --- --------- ^^^ expected `&Foo`, found struct `Foo`
| | |
| | arguments to this function are incorrect
| help: consider using `as_ref` instead: `as_ref().map`
|
note: function defined here
--> $DIR/as-ref.rs:3:4
|
LL | fn takes_ref(_: &Foo) {}
| ^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/as-ref.rs:23:52
|
LL | multiple_ref_opt.and_then(|arg| Some(takes_ref(arg)));
| -------- --------- ^^^ expected `&Foo`, found struct `Foo`
| | |
| | arguments to this function are incorrect
| help: consider using `as_ref` instead: `as_ref().and_then`
|
note: function defined here
--> $DIR/as-ref.rs:3:4
|
LL | fn takes_ref(_: &Foo) {}
| ^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/as-ref.rs:25:45
|
LL | multiple_ref_result.map(|arg| takes_ref(arg));
| --- --------- ^^^ expected `&Foo`, found struct `Foo`
| | |
| | arguments to this function are incorrect
| help: consider using `as_ref` instead: `as_ref().map`
|
note: function defined here
--> $DIR/as-ref.rs:3:4
|
LL | fn takes_ref(_: &Foo) {}
| ^^^^^^^^^ -------
error[E0308]: mismatched types
--> $DIR/as-ref.rs:26:53
|
LL | multiple_ref_result.and_then(|arg| Ok(takes_ref(arg)));
| -------- --------- ^^^ expected `&Foo`, found struct `Foo`
| | |
| | arguments to this function are incorrect
| help: consider using `as_ref` instead: `as_ref().and_then`
|
note: function defined here
--> $DIR/as-ref.rs:3:4
|
LL | fn takes_ref(_: &Foo) {}
| ^^^^^^^^^ -------
error: aborting due to 11 previous errors
For more information about this error, try `rustc --explain E0308`.