Skip to content

Commit

Permalink
Added ability to report on generic argument mismatch better
Browse files Browse the repository at this point in the history
Needs some checking over and some tests have altered that need sanity checking, but overall this is starting to get somewhere now.
  • Loading branch information
strottos committed Feb 25, 2024
1 parent bb8b11e commit 24599a8
Show file tree
Hide file tree
Showing 19 changed files with 649 additions and 83 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub use rustc_error_messages::{
fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle,
LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagnosticMessage,
};
pub use rustc_lint_defs::{pluralize, Applicability};
pub use rustc_lint_defs::{a_or_an, display_list_with_comma_and, pluralize, Applicability};
pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker};
pub use rustc_span::ErrorGuaranteed;
pub use snippet::Style;
Expand Down
424 changes: 396 additions & 28 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1370,6 +1370,11 @@ impl<'tcx> InferCtxt<'tcx> {
self.inner.borrow_mut().effect_unification_table().find(var).vid
}

/// Check variables are equal
pub fn check_ty_vars_equal(&self, a: ty::TyVid, b: ty::TyVid) -> bool {
self.inner.borrow_mut().type_variables().check_equal(a, b)
}

/// Resolves an int var to a rigid int type, if it was constrained to one,
/// or else the root int var in the unification table.
pub fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_infer/src/infer/type_variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
self.sub_root_var(a) == self.sub_root_var(b)
}

/// Returns `true` if `a` and `b` have same "root" (i.e., `a == b`).
pub fn check_equal(&mut self, a: ty::TyVid, b: ty::TyVid) -> bool {
self.root_var(a) == self.root_var(b)
}

/// Retrieves the type to which `vid` has been instantiated, if
/// any.
pub fn probe(&mut self, vid: ty::TyVid) -> TypeVariableValue<'tcx> {
Expand Down
33 changes: 33 additions & 0 deletions compiler/rustc_lint_defs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,39 @@ macro_rules! pluralize {
};
}

/// Grammatical tool for displaying messages to end users in a nice form.
///
/// Returns "an" if the given string starts with a vowel, and "a" otherwise.
pub fn a_or_an(s: &str) -> &'static str {
let mut chars = s.chars();
let Some(mut first_alpha_char) = chars.next() else {
return "a";
};
if first_alpha_char == '`' {
let Some(next) = chars.next() else {
return "a";
};
first_alpha_char = next;
}
if ["a", "e", "i", "o", "u", "&"].contains(&&first_alpha_char.to_lowercase().to_string()[..]) {
"an"
} else {
"a"
}
}

/// Grammatical tool for displaying messages to end users in a nice form.
///
/// Take a list ["a", "b", "c"] and output a display friendly version "a, b and c"
pub fn display_list_with_comma_and<T: std::fmt::Display>(v: &[T]) -> String {
match v.len() {
0 => "".to_string(),
1 => v[0].to_string(),
2 => format!("{} and {}", v[0], v[1]),
_ => format!("{}, {}", v[0], display_list_with_comma_and(&v[1..])),
}
}

/// Indicates the confidence in the correctness of a suggestion.
///
/// All suggestions are marked with an `Applicability`. Tools use the applicability of a suggestion
Expand Down
14 changes: 7 additions & 7 deletions tests/ui/argument-suggestions/extra_arguments.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ note: function defined here
--> $DIR/extra_arguments.rs:2:4
|
LL | fn one_arg<T>(_a: T) {}
| ^^^^^^^ -----
| ^^^^^^^

error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/extra_arguments.rs:23:3
Expand All @@ -60,7 +60,7 @@ note: function defined here
--> $DIR/extra_arguments.rs:2:4
|
LL | fn one_arg<T>(_a: T) {}
| ^^^^^^^ -----
| ^^^^^^^

error[E0061]: this function takes 1 argument but 3 arguments were supplied
--> $DIR/extra_arguments.rs:24:3
Expand All @@ -74,7 +74,7 @@ note: function defined here
--> $DIR/extra_arguments.rs:2:4
|
LL | fn one_arg<T>(_a: T) {}
| ^^^^^^^ -----
| ^^^^^^^
help: remove the extra arguments
|
LL - one_arg(1, "", 1.0);
Expand Down Expand Up @@ -319,7 +319,7 @@ note: function defined here
--> $DIR/extra_arguments.rs:2:4
|
LL | fn one_arg<T>(_a: T) {}
| ^^^^^^^ -----
| ^^^^^^^

error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/extra_arguments.rs:54:3
Expand All @@ -334,7 +334,7 @@ note: function defined here
--> $DIR/extra_arguments.rs:2:4
|
LL | fn one_arg<T>(_a: T) {}
| ^^^^^^^ -----
| ^^^^^^^

error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/extra_arguments.rs:55:3
Expand All @@ -349,7 +349,7 @@ note: function defined here
--> $DIR/extra_arguments.rs:2:4
|
LL | fn one_arg<T>(_a: T) {}
| ^^^^^^^ -----
| ^^^^^^^

error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/extra_arguments.rs:60:3
Expand All @@ -364,7 +364,7 @@ note: function defined here
--> $DIR/extra_arguments.rs:2:4
|
LL | fn one_arg<T>(_a: T) {}
| ^^^^^^^ -----
| ^^^^^^^

error: aborting due to 22 previous errors

Expand Down
20 changes: 10 additions & 10 deletions tests/ui/argument-suggestions/invalid_arguments.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:6:4
|
LL | fn two_arg_same(_a: i32, _b: i32) {}
| ^^^^^^^^^^^^ -------
| ^^^^^^^^^^^^ ------- -------

error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:17:16
Expand All @@ -38,7 +38,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:6:4
|
LL | fn two_arg_same(_a: i32, _b: i32) {}
| ^^^^^^^^^^^^ -------
| ^^^^^^^^^^^^ ------- -------

error[E0308]: arguments to this function are incorrect
--> $DIR/invalid_arguments.rs:18:3
Expand Down Expand Up @@ -66,7 +66,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:7:4
|
LL | fn two_arg_diff(_a: i32, _b: f32) {}
| ^^^^^^^^^^^^ -------
| ^^^^^^^^^^^^ ------- -------

error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:20:16
Expand All @@ -80,7 +80,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:7:4
|
LL | fn two_arg_diff(_a: i32, _b: f32) {}
| ^^^^^^^^^^^^ -------
| ^^^^^^^^^^^^ ------- -------

error[E0308]: arguments to this function are incorrect
--> $DIR/invalid_arguments.rs:21:3
Expand Down Expand Up @@ -108,7 +108,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:8:4
|
LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
| ^^^^^^^^^^^^^^ -------
| ^^^^^^^^^^^^^^ ------- ------- --------

error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:25:21
Expand All @@ -122,7 +122,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:8:4
|
LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
| ^^^^^^^^^^^^^^ -------
| ^^^^^^^^^^^^^^ ------- ------- --------

error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:26:26
Expand All @@ -136,7 +136,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:8:4
|
LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
| ^^^^^^^^^^^^^^ --------
| ^^^^^^^^^^^^^^ ------- ------- --------

error[E0308]: arguments to this function are incorrect
--> $DIR/invalid_arguments.rs:28:3
Expand Down Expand Up @@ -207,7 +207,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:9:4
|
LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
| ^^^^^^^^^^^^^^^^ -------
| ^^^^^^^^^^^^^^^^ ------- ------- --------

error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:35:23
Expand All @@ -221,7 +221,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:9:4
|
LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
| ^^^^^^^^^^^^^^^^ -------
| ^^^^^^^^^^^^^^^^ ------- ------- --------

error[E0308]: mismatched types
--> $DIR/invalid_arguments.rs:36:26
Expand All @@ -235,7 +235,7 @@ note: function defined here
--> $DIR/invalid_arguments.rs:9:4
|
LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
| ^^^^^^^^^^^^^^^^ --------
| ^^^^^^^^^^^^^^^^ ------- ------- --------

error[E0308]: arguments to this function are incorrect
--> $DIR/invalid_arguments.rs:38:3
Expand Down
24 changes: 23 additions & 1 deletion tests/ui/argument-suggestions/too-long.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,31 @@ note: method defined here
|
LL | fn foo(
| ^^^
...
LL | &self,
LL | a: i32,
| ------
LL | b: i32,
| ------
LL | c: i32,
| ------
LL | d: i32,
| ------
LL | e: i32,
| ------
LL | f: i32,
| ------
LL | g: i32,
| ------
LL | h: i32,
| ------
LL | i: i32,
| ------
LL | j: i32,
| ------
LL | k: i32,
| ------
LL | l: i32,
| ------
help: consider dereferencing the borrow
|
LL | qux.foo(a, b, c, d, e, *f, g, h, i, j, k, l);
Expand Down
31 changes: 23 additions & 8 deletions tests/ui/async-await/coroutine-desc.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ LL | fun(async {}, async {});
| --- -------- ^^^^^^^^ expected `async` block, found a different `async` block
| | |
| | the expected `async` block
| | expected argument `f2` to be an `async` block because that argument needs to match the type of this parameter
| arguments to this function are incorrect
|
= note: expected `async` block `{async block@$DIR/coroutine-desc.rs:10:9: 10:17}`
Expand All @@ -13,14 +14,19 @@ note: function defined here
--> $DIR/coroutine-desc.rs:8:4
|
LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
| ^^^ -----
| ^^^ - ----- -----
| | | |
| | | this parameter needs to match the `async` block type of `f1`
| | `f2` needs to match the type of this parameter
| `f1` and `f2` all reference this parameter F

error[E0308]: mismatched types
--> $DIR/coroutine-desc.rs:12:16
|
LL | fun(one(), two());
| --- ^^^^^ expected future, found a different future
| |
| --- ----- ^^^^^ expected future, found a different future
| | |
| | expected argument `f2` to be a future because that argument needs to match the type of this parameter
| arguments to this function are incorrect
|
= help: consider `await`ing on both `Future`s
Expand All @@ -29,15 +35,20 @@ note: function defined here
--> $DIR/coroutine-desc.rs:8:4
|
LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
| ^^^ -----
| ^^^ - ----- -----
| | | |
| | | this parameter needs to match the future type of `f1`
| | `f2` needs to match the type of this parameter
| `f1` and `f2` all reference this parameter F

error[E0308]: mismatched types
--> $DIR/coroutine-desc.rs:14:26
|
LL | fun((async || {})(), (async || {})());
| --- -- ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body
| | |
| | the expected `async` closure body
| --- --------------- ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body
| | | |
| | | the expected `async` closure body
| | expected argument `f2` to be an `async` closure body because that argument needs to match the type of this parameter
| arguments to this function are incorrect
|
= note: expected `async` closure body `{async closure body@$DIR/coroutine-desc.rs:14:19: 14:21}`
Expand All @@ -46,7 +57,11 @@ note: function defined here
--> $DIR/coroutine-desc.rs:8:4
|
LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
| ^^^ -----
| ^^^ - ----- -----
| | | |
| | | this parameter needs to match the `async` closure body type of `f1`
| | `f2` needs to match the type of this parameter
| `f1` and `f2` all reference this parameter F

error: aborting due to 3 previous errors

Expand Down
11 changes: 8 additions & 3 deletions tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ error[E0308]: mismatched types
--> $DIR/coerce-reborrow-multi-arg-fail.rs:4:18
|
LL | test(&mut 7, &7);
| ---- ^^ types differ in mutability
| |
| ---- ------ ^^ types differ in mutability
| | |
| | expected argument `_b` to be an `&mut {integer}` because that argument needs to match the type of this parameter
| arguments to this function are incorrect
|
= note: expected mutable reference `&mut {integer}`
Expand All @@ -12,7 +13,11 @@ note: function defined here
--> $DIR/coerce-reborrow-multi-arg-fail.rs:1:4
|
LL | fn test<T>(_a: T, _b: T) {}
| ^^^^ -----
| ^^^^ - ----- -----
| | | |
| | | this parameter needs to match the `&mut {integer}` type of `_a`
| | `_b` needs to match the type of this parameter
| `_a` and `_b` all reference this parameter T

error: aborting due to 1 previous error

Expand Down
10 changes: 5 additions & 5 deletions tests/ui/coercion/coerce-to-bang.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
| ^^^ ----
| ^^^ -------- ---- --------

error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:18:13
Expand All @@ -28,7 +28,7 @@ note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
| ^^^ ----
| ^^^ -------- ---- --------

error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:26:12
Expand All @@ -44,7 +44,7 @@ note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
| ^^^ ----
| ^^^ -------- ---- --------

error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:36:12
Expand All @@ -60,7 +60,7 @@ note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
| ^^^ ----
| ^^^ -------- ---- --------

error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:45:12
Expand All @@ -76,7 +76,7 @@ note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
| ^^^ ----
| ^^^ -------- ---- --------

error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:50:21
Expand Down
Loading

0 comments on commit 24599a8

Please sign in to comment.