File tree 4 files changed +49
-0
lines changed
src/tools/rust-analyzer/crates
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 @@ -461,6 +461,7 @@ define_symbols! {
461
461
test,
462
462
then,
463
463
thiscall,
464
+ to_string,
464
465
trace_macros,
465
466
transmute_opts,
466
467
transmute_trait,
You can’t perform that action at this time.
0 commit comments