Skip to content

Commit 4308352

Browse files
authored
Merge pull request #18986 from Veykril/push-zlwvwlowpzqm
Goto `Display::fmt` when invoked on `to_string`
2 parents 4b716bb + e9b410d commit 4308352

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed

src/tools/rust-analyzer/crates/hir/src/semantics.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,8 @@ impl<'db> SemanticsImpl<'db> {
14831483
self.analyze(try_expr.syntax())?.resolve_try_expr(self.db, try_expr)
14841484
}
14851485

1486+
// This does not resolve the method call to the correct trait impl!
1487+
// We should probably fix that.
14861488
pub fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
14871489
self.analyze(call.syntax())?.resolve_method_call_as_callable(self.db, call)
14881490
}

src/tools/rust-analyzer/crates/ide-db/src/famous_defs.rs

+7
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ impl FamousDefs<'_, '_> {
142142
self.find_macro("core:unimplemented")
143143
}
144144

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+
}
145152
pub fn builtin_crates(&self) -> impl Iterator<Item = Crate> {
146153
IntoIterator::into_iter([
147154
self.std(),

src/tools/rust-analyzer/crates/ide/src/goto_definition.rs

+39
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,15 @@ fn find_definition_for_known_blanket_dual_impls(
185185
// Extract the `T` from `Result<T, ..>`
186186
[return_type.type_arguments().next()?, callable.receiver_param(sema.db)?.1],
187187
)?
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+
)?
188197
} else {
189198
return None;
190199
};
@@ -3231,6 +3240,36 @@ impl FromStr for A {
32313240
}
32323241
fn f() {
32333242
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();
32343273
}
32353274
"#,
32363275
);

src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs

+1
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ define_symbols! {
461461
test,
462462
then,
463463
thiscall,
464+
to_string,
464465
trace_macros,
465466
transmute_opts,
466467
transmute_trait,

0 commit comments

Comments
 (0)