Auto merge of #44059 - oli-obk:ok_suggestion, r=nikomatsakis

Suggest `Ok(())` when encountering `Result::<(), E>::Ok()`
This commit is contained in:
bors 2017-08-29 06:18:23 +00:00
commit 6f82dea299
5 changed files with 101 additions and 18 deletions

View File

@ -119,10 +119,10 @@ impl<K: UnifyKey> VarValue<K> {
}
}
// We can't use V:LatticeValue, much as I would like to,
// because frequently the pattern is that V=Option<U> for some
// other type parameter U, and we have no way to say
// Option<U>:LatticeValue.
/// We can't use V:LatticeValue, much as I would like to,
/// because frequently the pattern is that V=Option<U> for some
/// other type parameter U, and we have no way to say
/// Option<U>:LatticeValue.
impl<K: UnifyKey> 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>>, _: ()) {}
}
// # 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>
where K::Value: Combine
@ -281,11 +281,11 @@ impl<'tcx, K: UnifyKey> UnificationTable<K>
}
}
// # Non-subtyping unification
//
// Code to handle keys which carry a value, like ints,
// floats---anything that doesn't have a subtyping relationship we
// need to worry about.
/// # Non-subtyping unification
///
/// Code to handle keys which carry a value, like ints,
/// floats---anything that doesn't have a subtyping relationship we
/// need to worry about.
impl<'tcx, K, V> UnificationTable<K>
where K: UnifyKey<Value = Option<V>>,

View File

@ -38,6 +38,7 @@ pub fn check_legal_trait_for_method_call(tcx: TyCtxt, span: Span, trait_id: DefI
enum CallStep<'tcx> {
Builtin(Ty<'tcx>),
DeferredClosure(ty::FnSig<'tcx>),
/// e.g. enum variant constructors
Overloaded(MethodCallee<'tcx>),
}

View File

@ -2472,7 +2472,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize,
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,
&format!("this function takes {}{} parameter{} but {} parameter{} supplied",
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"}),
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 {
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();
}
@ -2497,7 +2507,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
match tuple_type.sty {
ty::TyTuple(arg_types, _) if 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 = &[];
self.err_args(args.len())
}
@ -2526,13 +2536,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn_inputs.to_vec()
} else {
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 = &[];
self.err_args(supplied_arg_count)
}
} 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,
supplied_arg_count, "E0061", false, def_span);
supplied_arg_count, "E0061", false, def_span, sugg_unit);
expected_arg_tys = &[];
self.err_args(supplied_arg_count)
};

View 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();
}

View 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