Auto merge of #44059 - oli-obk:ok_suggestion, r=nikomatsakis
Suggest `Ok(())` when encountering `Result::<(), E>::Ok()`
This commit is contained in:
commit
6f82dea299
@ -119,10 +119,10 @@ impl<K: UnifyKey> VarValue<K> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can't use V:LatticeValue, much as I would like to,
|
/// We can't use V:LatticeValue, much as I would like to,
|
||||||
// because frequently the pattern is that V=Option<U> for some
|
/// because frequently the pattern is that V=Option<U> for some
|
||||||
// other type parameter U, and we have no way to say
|
/// other type parameter U, and we have no way to say
|
||||||
// Option<U>:LatticeValue.
|
/// Option<U>:LatticeValue.
|
||||||
|
|
||||||
impl<K: UnifyKey> UnificationTable<K> {
|
impl<K: UnifyKey> UnificationTable<K> {
|
||||||
pub fn new() -> UnificationTable<K> {
|
pub fn new() -> UnificationTable<K> {
|
||||||
@ -249,7 +249,7 @@ impl<K: UnifyKey> sv::SnapshotVecDelegate for Delegate<K> {
|
|||||||
fn reverse(_: &mut Vec<VarValue<K>>, _: ()) {}
|
fn reverse(_: &mut Vec<VarValue<K>>, _: ()) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// # Base union-find algorithm, where we are just making sets
|
/// # Base union-find algorithm, where we are just making sets
|
||||||
|
|
||||||
impl<'tcx, K: UnifyKey> UnificationTable<K>
|
impl<'tcx, K: UnifyKey> UnificationTable<K>
|
||||||
where K::Value: Combine
|
where K::Value: Combine
|
||||||
@ -281,11 +281,11 @@ impl<'tcx, K: UnifyKey> UnificationTable<K>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// # Non-subtyping unification
|
/// # Non-subtyping unification
|
||||||
//
|
///
|
||||||
// Code to handle keys which carry a value, like ints,
|
/// Code to handle keys which carry a value, like ints,
|
||||||
// floats---anything that doesn't have a subtyping relationship we
|
/// floats---anything that doesn't have a subtyping relationship we
|
||||||
// need to worry about.
|
/// need to worry about.
|
||||||
|
|
||||||
impl<'tcx, K, V> UnificationTable<K>
|
impl<'tcx, K, V> UnificationTable<K>
|
||||||
where K: UnifyKey<Value = Option<V>>,
|
where K: UnifyKey<Value = Option<V>>,
|
||||||
|
@ -38,6 +38,7 @@ pub fn check_legal_trait_for_method_call(tcx: TyCtxt, span: Span, trait_id: DefI
|
|||||||
enum CallStep<'tcx> {
|
enum CallStep<'tcx> {
|
||||||
Builtin(Ty<'tcx>),
|
Builtin(Ty<'tcx>),
|
||||||
DeferredClosure(ty::FnSig<'tcx>),
|
DeferredClosure(ty::FnSig<'tcx>),
|
||||||
|
/// e.g. enum variant constructors
|
||||||
Overloaded(MethodCallee<'tcx>),
|
Overloaded(MethodCallee<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2472,7 +2472,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize,
|
fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize,
|
||||||
arg_count: usize, error_code: &str, variadic: bool,
|
arg_count: usize, error_code: &str, variadic: bool,
|
||||||
def_span: Option<Span>) {
|
def_span: Option<Span>, sugg_unit: bool) {
|
||||||
let mut err = sess.struct_span_err_with_code(sp,
|
let mut err = sess.struct_span_err_with_code(sp,
|
||||||
&format!("this function takes {}{} parameter{} but {} parameter{} supplied",
|
&format!("this function takes {}{} parameter{} but {} parameter{} supplied",
|
||||||
if variadic {"at least "} else {""},
|
if variadic {"at least "} else {""},
|
||||||
@ -2482,13 +2482,23 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
if arg_count == 1 {" was"} else {"s were"}),
|
if arg_count == 1 {" was"} else {"s were"}),
|
||||||
error_code);
|
error_code);
|
||||||
|
|
||||||
err.span_label(sp, format!("expected {}{} parameter{}",
|
|
||||||
if variadic {"at least "} else {""},
|
|
||||||
expected_count,
|
|
||||||
if expected_count == 1 {""} else {"s"}));
|
|
||||||
if let Some(def_s) = def_span {
|
if let Some(def_s) = def_span {
|
||||||
err.span_label(def_s, "defined here");
|
err.span_label(def_s, "defined here");
|
||||||
}
|
}
|
||||||
|
if sugg_unit {
|
||||||
|
let mut sugg_span = sp.end_point();
|
||||||
|
// remove closing `)` from the span
|
||||||
|
sugg_span.hi = sugg_span.lo;
|
||||||
|
err.span_suggestion(
|
||||||
|
sugg_span,
|
||||||
|
"expected the unit value `()`. You can create one with a pair of parenthesis",
|
||||||
|
String::from("()"));
|
||||||
|
} else {
|
||||||
|
err.span_label(sp, format!("expected {}{} parameter{}",
|
||||||
|
if variadic {"at least "} else {""},
|
||||||
|
expected_count,
|
||||||
|
if expected_count == 1 {""} else {"s"}));
|
||||||
|
}
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2497,7 +2507,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
match tuple_type.sty {
|
match tuple_type.sty {
|
||||||
ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
|
ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
|
||||||
parameter_count_error(tcx.sess, sp_args, arg_types.len(), args.len(),
|
parameter_count_error(tcx.sess, sp_args, arg_types.len(), args.len(),
|
||||||
"E0057", false, def_span);
|
"E0057", false, def_span, false);
|
||||||
expected_arg_tys = &[];
|
expected_arg_tys = &[];
|
||||||
self.err_args(args.len())
|
self.err_args(args.len())
|
||||||
}
|
}
|
||||||
@ -2526,13 +2536,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
fn_inputs.to_vec()
|
fn_inputs.to_vec()
|
||||||
} else {
|
} else {
|
||||||
parameter_count_error(tcx.sess, sp_args, expected_arg_count,
|
parameter_count_error(tcx.sess, sp_args, expected_arg_count,
|
||||||
supplied_arg_count, "E0060", true, def_span);
|
supplied_arg_count, "E0060", true, def_span, false);
|
||||||
expected_arg_tys = &[];
|
expected_arg_tys = &[];
|
||||||
self.err_args(supplied_arg_count)
|
self.err_args(supplied_arg_count)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// is the missing argument of type `()`?
|
||||||
|
let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
|
||||||
|
self.resolve_type_vars_if_possible(&expected_arg_tys[0]).is_nil()
|
||||||
|
} else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
|
||||||
|
self.resolve_type_vars_if_possible(&fn_inputs[0]).is_nil()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
parameter_count_error(tcx.sess, sp_args, expected_arg_count,
|
parameter_count_error(tcx.sess, sp_args, expected_arg_count,
|
||||||
supplied_arg_count, "E0061", false, def_span);
|
supplied_arg_count, "E0061", false, def_span, sugg_unit);
|
||||||
expected_arg_tys = &[];
|
expected_arg_tys = &[];
|
||||||
self.err_args(supplied_arg_count)
|
self.err_args(supplied_arg_count)
|
||||||
};
|
};
|
||||||
|
19
src/test/ui/span/missing-unit-argument.rs
Normal file
19
src/test/ui/span/missing-unit-argument.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
fn foo(():(), ():()) {}
|
||||||
|
fn bar(():()) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _: Result<(), String> = Ok();
|
||||||
|
foo();
|
||||||
|
foo(());
|
||||||
|
bar();
|
||||||
|
}
|
45
src/test/ui/span/missing-unit-argument.stderr
Normal file
45
src/test/ui/span/missing-unit-argument.stderr
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
error[E0061]: this function takes 1 parameter but 0 parameters were supplied
|
||||||
|
--> $DIR/missing-unit-argument.rs:15:33
|
||||||
|
|
|
||||||
|
15 | let _: Result<(), String> = Ok();
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
help: expected the unit value `()`. You can create one with a pair of parenthesis
|
||||||
|
|
|
||||||
|
15 | let _: Result<(), String> = Ok(());
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error[E0061]: this function takes 2 parameters but 0 parameters were supplied
|
||||||
|
--> $DIR/missing-unit-argument.rs:16:5
|
||||||
|
|
|
||||||
|
11 | fn foo(():(), ():()) {}
|
||||||
|
| ----------------------- defined here
|
||||||
|
...
|
||||||
|
16 | foo();
|
||||||
|
| ^^^^^ expected 2 parameters
|
||||||
|
|
||||||
|
error[E0061]: this function takes 2 parameters but 1 parameter was supplied
|
||||||
|
--> $DIR/missing-unit-argument.rs:17:9
|
||||||
|
|
|
||||||
|
11 | fn foo(():(), ():()) {}
|
||||||
|
| ----------------------- defined here
|
||||||
|
...
|
||||||
|
17 | foo(());
|
||||||
|
| ^^ expected 2 parameters
|
||||||
|
|
||||||
|
error[E0061]: this function takes 1 parameter but 0 parameters were supplied
|
||||||
|
--> $DIR/missing-unit-argument.rs:18:5
|
||||||
|
|
|
||||||
|
12 | fn bar(():()) {}
|
||||||
|
| ---------------- defined here
|
||||||
|
...
|
||||||
|
18 | bar();
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
help: expected the unit value `()`. You can create one with a pair of parenthesis
|
||||||
|
|
|
||||||
|
18 | bar(());
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
Loading…
Reference in New Issue
Block a user