Rollup merge of #70784 - estebank:suggest-type-fundamental-method, r=matthewjasper
Consider methods on fundamental `impl` when method is not found on numeric type Fix #47759.
This commit is contained in:
commit
dff5a113c2
3 changed files with 42 additions and 4 deletions
|
@ -271,11 +271,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let mut candidates = all_traits(self.tcx).into_iter().filter_map(|info| {
|
let mut candidates = all_traits(self.tcx).into_iter().filter_map(|info| {
|
||||||
self.associated_item(info.def_id, item_name, Namespace::ValueNS)
|
self.associated_item(info.def_id, item_name, Namespace::ValueNS)
|
||||||
});
|
});
|
||||||
if let (true, false, SelfSource::MethodCall(expr), Some(_)) = (
|
// There are methods that are defined on the primitive types and won't be
|
||||||
|
// found when exploring `all_traits`, but we also need them to be acurate on
|
||||||
|
// our suggestions (#47759).
|
||||||
|
let fund_assoc = |opt_def_id: Option<DefId>| {
|
||||||
|
opt_def_id
|
||||||
|
.and_then(|id| self.associated_item(id, item_name, Namespace::ValueNS))
|
||||||
|
.is_some()
|
||||||
|
};
|
||||||
|
let lang_items = tcx.lang_items();
|
||||||
|
let found_candidate = candidates.next().is_some()
|
||||||
|
|| fund_assoc(lang_items.i8_impl())
|
||||||
|
|| fund_assoc(lang_items.i16_impl())
|
||||||
|
|| fund_assoc(lang_items.i32_impl())
|
||||||
|
|| fund_assoc(lang_items.i64_impl())
|
||||||
|
|| fund_assoc(lang_items.i128_impl())
|
||||||
|
|| fund_assoc(lang_items.u8_impl())
|
||||||
|
|| fund_assoc(lang_items.u16_impl())
|
||||||
|
|| fund_assoc(lang_items.u32_impl())
|
||||||
|
|| fund_assoc(lang_items.u64_impl())
|
||||||
|
|| fund_assoc(lang_items.u128_impl())
|
||||||
|
|| fund_assoc(lang_items.f32_impl())
|
||||||
|
|| fund_assoc(lang_items.f32_runtime_impl())
|
||||||
|
|| fund_assoc(lang_items.f64_impl())
|
||||||
|
|| fund_assoc(lang_items.f64_runtime_impl());
|
||||||
|
if let (true, false, SelfSource::MethodCall(expr), true) = (
|
||||||
actual.is_numeric(),
|
actual.is_numeric(),
|
||||||
actual.has_concrete_skeleton(),
|
actual.has_concrete_skeleton(),
|
||||||
source,
|
source,
|
||||||
candidates.next(),
|
found_candidate,
|
||||||
) {
|
) {
|
||||||
let mut err = struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
tcx.sess,
|
tcx.sess,
|
||||||
|
|
|
@ -4,4 +4,6 @@ extern crate issue_29181 as foo;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
0.homura(); //~ ERROR no method named `homura` found
|
0.homura(); //~ ERROR no method named `homura` found
|
||||||
|
// Issue #47759, detect existing method on the fundamental impl:
|
||||||
|
let _ = |x: f64| x * 2.0.exp(); //~ ERROR can't call method `exp` on ambiguous numeric type
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,18 @@ error[E0599]: no method named `homura` found for type `{integer}` in the current
|
||||||
LL | 0.homura();
|
LL | 0.homura();
|
||||||
| ^^^^^^ method not found in `{integer}`
|
| ^^^^^^ method not found in `{integer}`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0689]: can't call method `exp` on ambiguous numeric type `{float}`
|
||||||
|
--> $DIR/issue-29181.rs:8:30
|
||||||
|
|
|
||||||
|
LL | let _ = |x: f64| x * 2.0.exp();
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
help: you must specify a concrete type for this numeric value, like `f32`
|
||||||
|
|
|
||||||
|
LL | let _ = |x: f64| x * 2.0_f32.exp();
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0599`.
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0599, E0689.
|
||||||
|
For more information about an error, try `rustc --explain E0599`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue