Skip to content

Commit 5459edf

Browse files
Rollup merge of #100349 - TaKO8Ki:remove-type-string-comparison, r=lcnr
Refactor: remove a type string comparison
2 parents a6116b9 + 54cf66f commit 5459edf

File tree

3 files changed

+77
-8
lines changed

3 files changed

+77
-8
lines changed

compiler/rustc_typeck/src/check/demand.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -598,13 +598,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
598598
};
599599

600600
let self_ty = self.typeck_results.borrow().expr_ty(&method_expr[0]);
601-
let self_ty = format!("{:?}", self_ty);
602601
let name = method_path.ident.name;
603-
let is_as_ref_able = (self_ty.starts_with("&std::option::Option")
604-
|| self_ty.starts_with("&std::result::Result")
605-
|| self_ty.starts_with("std::option::Option")
606-
|| self_ty.starts_with("std::result::Result"))
607-
&& (name == sym::map || name == sym::and_then);
602+
let is_as_ref_able = match self_ty.peel_refs().kind() {
603+
ty::Adt(def, _) => {
604+
(self.tcx.is_diagnostic_item(sym::Option, def.did())
605+
|| self.tcx.is_diagnostic_item(sym::Result, def.did()))
606+
&& (name == sym::map || name == sym::and_then)
607+
}
608+
_ => false,
609+
};
608610
match (is_as_ref_able, self.sess().source_map().span_to_snippet(method_path.ident.span)) {
609611
(true, Ok(src)) => {
610612
let suggestion = format!("as_ref().{}", src);
@@ -792,7 +794,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
792794
_ if is_range_literal(expr) => true,
793795
_ => false,
794796
};
795-
let sugg_expr = if needs_parens { format!("({src})") } else { src };
796797

797798
if let Some(sugg) = self.can_use_as_ref(expr) {
798799
return Some((
@@ -820,6 +821,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
820821
}
821822
}
822823

824+
let sugg_expr = if needs_parens { format!("({src})") } else { src };
823825
return Some(match mutability {
824826
hir::Mutability::Mut => (
825827
sp,

src/test/ui/suggestions/as-ref.rs

+7
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,11 @@ fn main() {
1717
// note: do not suggest because of `E: usize`
1818
let x: &Result<usize, usize> = &Ok(3);
1919
let y: Result<&usize, usize> = x; //~ ERROR mismatched types [E0308]
20+
21+
let multiple_ref_opt = &&Some(Foo);
22+
multiple_ref_opt.map(|arg| takes_ref(arg)); //~ ERROR mismatched types [E0308]
23+
multiple_ref_opt.and_then(|arg| Some(takes_ref(arg))); //~ ERROR mismatched types [E0308]
24+
let multiple_ref_result = &&Ok(Foo);
25+
multiple_ref_result.map(|arg| takes_ref(arg)); //~ ERROR mismatched types [E0308]
26+
multiple_ref_result.and_then(|arg| Ok(takes_ref(arg))); //~ ERROR mismatched types [E0308]
2027
}

src/test/ui/suggestions/as-ref.stderr

+61-1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,66 @@ LL | let y: Result<&usize, usize> = x;
9797
= note: expected enum `Result<&usize, usize>`
9898
found reference `&Result<usize, usize>`
9999

100-
error: aborting due to 7 previous errors
100+
error[E0308]: mismatched types
101+
--> $DIR/as-ref.rs:22:42
102+
|
103+
LL | multiple_ref_opt.map(|arg| takes_ref(arg));
104+
| --- --------- ^^^ expected `&Foo`, found struct `Foo`
105+
| | |
106+
| | arguments to this function are incorrect
107+
| help: consider using `as_ref` instead: `as_ref().map`
108+
|
109+
note: function defined here
110+
--> $DIR/as-ref.rs:3:4
111+
|
112+
LL | fn takes_ref(_: &Foo) {}
113+
| ^^^^^^^^^ -------
114+
115+
error[E0308]: mismatched types
116+
--> $DIR/as-ref.rs:23:52
117+
|
118+
LL | multiple_ref_opt.and_then(|arg| Some(takes_ref(arg)));
119+
| -------- --------- ^^^ expected `&Foo`, found struct `Foo`
120+
| | |
121+
| | arguments to this function are incorrect
122+
| help: consider using `as_ref` instead: `as_ref().and_then`
123+
|
124+
note: function defined here
125+
--> $DIR/as-ref.rs:3:4
126+
|
127+
LL | fn takes_ref(_: &Foo) {}
128+
| ^^^^^^^^^ -------
129+
130+
error[E0308]: mismatched types
131+
--> $DIR/as-ref.rs:25:45
132+
|
133+
LL | multiple_ref_result.map(|arg| takes_ref(arg));
134+
| --- --------- ^^^ expected `&Foo`, found struct `Foo`
135+
| | |
136+
| | arguments to this function are incorrect
137+
| help: consider using `as_ref` instead: `as_ref().map`
138+
|
139+
note: function defined here
140+
--> $DIR/as-ref.rs:3:4
141+
|
142+
LL | fn takes_ref(_: &Foo) {}
143+
| ^^^^^^^^^ -------
144+
145+
error[E0308]: mismatched types
146+
--> $DIR/as-ref.rs:26:53
147+
|
148+
LL | multiple_ref_result.and_then(|arg| Ok(takes_ref(arg)));
149+
| -------- --------- ^^^ expected `&Foo`, found struct `Foo`
150+
| | |
151+
| | arguments to this function are incorrect
152+
| help: consider using `as_ref` instead: `as_ref().and_then`
153+
|
154+
note: function defined here
155+
--> $DIR/as-ref.rs:3:4
156+
|
157+
LL | fn takes_ref(_: &Foo) {}
158+
| ^^^^^^^^^ -------
159+
160+
error: aborting due to 11 previous errors
101161

102162
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)