diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 9e3c093883661..834362c7854f0 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -336,21 +336,37 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { ("`async` blocks are only allowed in Rust 2018 or later".to_string(), suggestion) } else { // check if we are in situation of typo like `True` instead of `true`. - let override_suggestion = - if ["true", "false"].contains(&item_str.to_string().to_lowercase().as_str()) { - let item_typo = item_str.to_string().to_lowercase(); - Some((item_span, "you may want to use a bool value instead", item_typo)) - // FIXME(vincenzopalazzo): make the check smarter, - // and maybe expand with levenshtein distance checks - } else if item_str.as_str() == "printf" { - Some(( - item_span, - "you may have meant to use the `print` macro", - "print!".to_owned(), - )) - } else { - suggestion - }; + let override_suggestion = if ["true", "false"] + .contains(&item_str.to_string().to_lowercase().as_str()) + { + let item_typo = item_str.to_string().to_lowercase(); + Some((item_span, "you may want to use a bool value instead", item_typo)) + // FIXME(vincenzopalazzo): make the check smarter, + // and maybe expand with levenshtein distance checks + } else if item_str.as_str() == "printf" { + Some(( + item_span, + "you may have meant to use the `print` macro", + "print!".to_owned(), + )) + } else if ["max", "min"].contains(&item_str.as_str()) + && let PathSource::Expr(Some(Expr { + kind: ExprKind::Call(_, args), + span: call_span, + .. + })) = source + && args.len() == 2 + { + let arg0 = self.r.tcx.sess.source_map().span_to_snippet(args[0].span).unwrap(); + let arg1 = self.r.tcx.sess.source_map().span_to_snippet(args[1].span).unwrap(); + Some(( + *call_span, + "you may have meant to use the method syntax", + format!("{arg0}.{item_str}({arg1})"), + )) + } else { + suggestion + }; (format!("not found in {mod_str}"), override_suggestion) }; diff --git a/tests/ui/did_you_mean/method-syntax-for-min-max.rs b/tests/ui/did_you_mean/method-syntax-for-min-max.rs new file mode 100644 index 0000000000000..b36d61f453a54 --- /dev/null +++ b/tests/ui/did_you_mean/method-syntax-for-min-max.rs @@ -0,0 +1,29 @@ +fn main() { + //~^ HELP consider importing this function + //~| HELP consider importing this function + //~| HELP consider importing this function + //~| HELP consider importing this function + let x = 2; + let y = 4; + + max(x, y); + //~^ ERROR cannot find function `max` in this scope + //~| HELP you may have meant to use the method syntax + let _ = min(x, y); + //~^ ERROR cannot find function `min` in this scope + //~| HELP you may have meant to use the method syntax + println!("{}", min(43, 43)); + //~^ ERROR cannot find function `min` in this scope + //~| HELP you may have meant to use the method syntax + let _ = vec![max(f(), g())]; + //~^ ERROR cannot find function `max` in this scope + //~| HELP you may have meant to use the method syntax +} + +const fn f() -> u32 { + 4 +} + +const fn g() -> u32 { + 2 +} diff --git a/tests/ui/did_you_mean/method-syntax-for-min-max.stderr b/tests/ui/did_you_mean/method-syntax-for-min-max.stderr new file mode 100644 index 0000000000000..3e2b6d0997a42 --- /dev/null +++ b/tests/ui/did_you_mean/method-syntax-for-min-max.stderr @@ -0,0 +1,67 @@ +error[E0425]: cannot find function `max` in this scope + --> $DIR/method-syntax-for-min-max.rs:9:5 + | +LL | max(x, y); + | ^^^ not found in this scope + | +help: you may have meant to use the method syntax + | +LL - max(x, y); +LL + x.max(y); + | +help: consider importing this function + | +LL + use std::cmp::max; + | + +error[E0425]: cannot find function `min` in this scope + --> $DIR/method-syntax-for-min-max.rs:12:13 + | +LL | let _ = min(x, y); + | ^^^ not found in this scope + | +help: you may have meant to use the method syntax + | +LL - let _ = min(x, y); +LL + let _ = x.min(y); + | +help: consider importing this function + | +LL + use std::cmp::min; + | + +error[E0425]: cannot find function `min` in this scope + --> $DIR/method-syntax-for-min-max.rs:15:20 + | +LL | println!("{}", min(43, 43)); + | ^^^ not found in this scope + | +help: you may have meant to use the method syntax + | +LL - println!("{}", min(43, 43)); +LL + println!("{}", 43.min(43)); + | +help: consider importing this function + | +LL + use std::cmp::min; + | + +error[E0425]: cannot find function `max` in this scope + --> $DIR/method-syntax-for-min-max.rs:18:18 + | +LL | let _ = vec![max(f(), g())]; + | ^^^ not found in this scope + | +help: you may have meant to use the method syntax + | +LL - let _ = vec![max(f(), g())]; +LL + let _ = vec![f().max(g())]; + | +help: consider importing this function + | +LL + use std::cmp::max; + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0425`.