File tree Expand file tree Collapse file tree 4 files changed +49
-0
lines changed
src/tools/rust-analyzer/crates Expand file tree Collapse file tree 4 files changed +49
-0
lines changed Original file line number Diff line number Diff line change @@ -1483,6 +1483,8 @@ impl<'db> SemanticsImpl<'db> {
1483
1483
self.analyze(try_expr.syntax())?.resolve_try_expr(self.db, try_expr)
1484
1484
}
1485
1485
1486
+ // This does not resolve the method call to the correct trait impl!
1487
+ // We should probably fix that.
1486
1488
pub fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
1487
1489
self.analyze(call.syntax())?.resolve_method_call_as_callable(self.db, call)
1488
1490
}
Original file line number Diff line number Diff line change @@ -142,6 +142,13 @@ impl FamousDefs<'_, '_> {
142
142
self.find_macro("core:unimplemented")
143
143
}
144
144
145
+ pub fn core_fmt_Display(&self) -> Option<Trait> {
146
+ self.find_trait("core:fmt:Display")
147
+ }
148
+
149
+ pub fn alloc_string_ToString(&self) -> Option<Trait> {
150
+ self.find_trait("alloc:string:ToString")
151
+ }
145
152
pub fn builtin_crates(&self) -> impl Iterator<Item = Crate> {
146
153
IntoIterator::into_iter([
147
154
self.std(),
Original file line number Diff line number Diff line change @@ -185,6 +185,15 @@ fn find_definition_for_known_blanket_dual_impls(
185
185
// Extract the `T` from `Result<T, ..>`
186
186
[return_type.type_arguments().next()?, callable.receiver_param(sema.db)?.1],
187
187
)?
188
+ } else if fn_name == sym::to_string && fd.alloc_string_ToString() == Some(t) {
189
+ let dual = fd.core_fmt_Display()?;
190
+ let dual_f = dual.function(sema.db, &sym::fmt)?;
191
+ sema.resolve_trait_impl_method(
192
+ return_type.clone(),
193
+ dual,
194
+ dual_f,
195
+ [callable.receiver_param(sema.db)?.1.strip_reference()],
196
+ )?
188
197
} else {
189
198
return None;
190
199
};
@@ -3231,6 +3240,36 @@ impl FromStr for A {
3231
3240
}
3232
3241
fn f() {
3233
3242
let a: Result<A, _> = "aaaaaa".parse$0();
3243
+ }
3244
+ "#,
3245
+ );
3246
+ }
3247
+
3248
+ #[test]
3249
+ fn to_string_call_to_display_definition() {
3250
+ check(
3251
+ r#"
3252
+ //- minicore:fmt
3253
+ //- /alloc.rs crate:alloc
3254
+ pub mod string {
3255
+ pub struct String;
3256
+ pub trait ToString {
3257
+ fn to_string(&self) -> String;
3258
+ }
3259
+
3260
+ impl<T: core::fmt::Display> ToString for T {
3261
+ fn to_string(&self) -> String { String }
3262
+ }
3263
+ }
3264
+ //- /lib.rs crate:lib deps:alloc
3265
+ use alloc::string::ToString;
3266
+ struct A;
3267
+ impl core::fmt::Display for A {
3268
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {}
3269
+ // ^^^
3270
+ }
3271
+ fn f() {
3272
+ A.to_string$0();
3234
3273
}
3235
3274
"#,
3236
3275
);
Original file line number Diff line number Diff line change @@ -460,6 +460,7 @@ define_symbols! {
460
460
test_case,
461
461
test,
462
462
thiscall,
463
+ to_string,
463
464
trace_macros,
464
465
transmute_opts,
465
466
transmute_trait,
You can’t perform that action at this time.
0 commit comments