Skip to content

Commit

Permalink
Specify when type parameter shadows primitive type
Browse files Browse the repository at this point in the history
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
  • Loading branch information
estebank committed Sep 16, 2016
1 parent c87ba3f commit 68e8624
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 5 deletions.
13 changes: 12 additions & 1 deletion src/librustc/infer/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
17 changes: 14 additions & 3 deletions src/librustc_errors/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,21 @@ impl<'a> DiagnosticBuilder<'a> {
expected: &fmt::Display,
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
}

Expand Down Expand Up @@ -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()),
}
}
}
25 changes: 25 additions & 0 deletions src/test/ui/mismatched_types/issue-35030.rs
Original file line number Diff line number Diff line change
@@ -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));
}
11 changes: 11 additions & 0 deletions src/test/ui/mismatched_types/issue-35030.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 68e8624

Please sign in to comment.