diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2016-09-07 18:40:31 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2016-09-15 20:06:29 -0700 |
| commit | 68e8624d05bc9b291fc3d945aaf5c1cb24bf015f (patch) | |
| tree | 4ab82df7b25b87e929bdd75af2b4c515a2499bf7 /src | |
| parent | c87ba3f1222ba20d491e8ed76a04977283280742 (diff) | |
Specify when type parameter shadows primitive type
When a type parameter shadows a primitive type, the error message
was non obvious. For example, given the file `file.rs`:
```rust
trait Parser<T> {
fn parse(text: &str) -> Option<T>;
}
impl<bool> Parser<bool> for bool {
fn parse(text: &str) -> Option<bool> {
Some(true)
}
}
fn main() {
println!("{}", bool::parse("ok").unwrap_or(false));
}
```
The output was:
```bash
% rustc file.rs
error[E0308]: mismatched types
--> file.rs:7:14
|
7 | Some(true)
| ^^^^ expected type parameter, found bool
|
= note: expected type `bool`
= note: found type `bool`
error: aborting due to previous error
```
We now show extra information about the type:
```bash
% rustc file.rs
error[E0308]: mismatched types
--> file.rs:7:14
|
7 | Some(true)
| ^^^^ expected type parameter, found bool
|
= note: expected type `bool` (type parameter)
= note: found type `bool` (bool)
error: aborting due to previous error
```
Fixes #35030
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/infer/error_reporting.rs | 13 | ||||
| -rw-r--r-- | src/librustc/ty/error.rs | 2 | ||||
| -rw-r--r-- | src/librustc_errors/lib.rs | 17 | ||||
| -rw-r--r-- | src/test/ui/mismatched_types/issue-35030.rs | 25 | ||||
| -rw-r--r-- | src/test/ui/mismatched_types/issue-35030.stderr | 11 |
5 files changed, 63 insertions, 5 deletions
diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index b8a3bdfcf25..2792968d427 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -547,7 +547,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { }; if !is_simple_error { - diag.note_expected_found(&"type", &expected, &found); + if expected == found { + if let &TypeError::Sorts(ref values) = terr { + diag.note_expected_found_extra( + &"type", &expected, &found, + &format!(" ({})", values.expected.sort_string(self.tcx)), + &format!(" ({})", values.found.sort_string(self.tcx))); + } else { + diag.note_expected_found(&"type", &expected, &found); + } + } else { + diag.note_expected_found(&"type", &expected, &found); + } } } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index d820fddea39..001f47af68c 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -210,7 +210,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { } impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { - fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> String { + pub fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> String { match self.sty { ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyStr | ty::TyNever => self.to_string(), diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index d82d7dbe70f..d2f3eea85f2 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -274,9 +274,20 @@ impl<'a> DiagnosticBuilder<'a> { found: &fmt::Display) -> &mut DiagnosticBuilder<'a> { + self.note_expected_found_extra(label, expected, found, &"", &"") + } + + pub fn note_expected_found_extra(&mut self, + label: &fmt::Display, + expected: &fmt::Display, + found: &fmt::Display, + expected_extra: &fmt::Display, + found_extra: &fmt::Display) + -> &mut DiagnosticBuilder<'a> + { // For now, just attach these as notes - self.note(&format!("expected {} `{}`", label, expected)); - self.note(&format!(" found {} `{}`", label, found)); + self.note(&format!("expected {} `{}`{}", label, expected, expected_extra)); + self.note(&format!(" found {} `{}`{}", label, found, found_extra)); self } @@ -764,4 +775,4 @@ pub fn expect<T, M>(diag: &Handler, opt: Option<T>, msg: M) -> T where Some(t) => t, None => diag.bug(&msg()), } -} \ No newline at end of file +} diff --git a/src/test/ui/mismatched_types/issue-35030.rs b/src/test/ui/mismatched_types/issue-35030.rs new file mode 100644 index 00000000000..006074ead13 --- /dev/null +++ b/src/test/ui/mismatched_types/issue-35030.rs @@ -0,0 +1,25 @@ +// Copyright 2016 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. + +// rustc-env:RUST_NEW_ERROR_FORMAT + +trait Parser<T> { + fn parse(text: &str) -> Option<T>; +} + +impl<bool> Parser<bool> for bool { + fn parse(text: &str) -> Option<bool> { + Some(true) + } +} + +fn main() { + println!("{}", bool::parse("ok").unwrap_or(false)); +} diff --git a/src/test/ui/mismatched_types/issue-35030.stderr b/src/test/ui/mismatched_types/issue-35030.stderr new file mode 100644 index 00000000000..aa017297a4e --- /dev/null +++ b/src/test/ui/mismatched_types/issue-35030.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/issue-35030.rs:19:14 + | +19 | Some(true) + | ^^^^ expected type parameter, found bool + | + = note: expected type `bool` (type parameter) + = note: found type `bool` (bool) + +error: aborting due to previous error + |
