Add invalid unary operator usage error code

This commit is contained in:
Guillaume Gomez 2017-05-27 21:34:59 +02:00
parent 998b19740c
commit 2969137a72
5 changed files with 64 additions and 6 deletions

View file

@ -316,10 +316,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
match self.lookup_op_method(ex, operand_ty, vec![], mname, trait_did, operand_expr) {
Ok(t) => t,
Err(()) => {
self.type_error_message(ex.span, |actual| {
format!("cannot apply unary operator `{}` to type `{}`",
op_str, actual)
}, operand_ty);
let actual = self.resolve_type_vars_if_possible(&operand_ty);
if !actual.references_error() {
struct_span_err!(self.tcx.sess, ex.span, E0600,
"cannot apply unary operator `{}` to type `{}`",
op_str, actual).emit();
}
self.tcx.types.err
}
}

View file

@ -4052,6 +4052,49 @@ x.chocolate(); // error: no method named `chocolate` found for type `Mouth`
```
"##,
E0600: r##"
An unary operator was used on a type which doesn't implement it.
Example of erroneous code:
```compile_fail,E0600
enum Question {
Yes,
No,
}
!Question::Yes; // error: cannot apply unary operator `!` to type `Question`
```
In this case, `Question` would need to implement the `std::ops::Not` trait in
order to be able to use `!` on it. Let's implement it:
```
use std::ops::Not;
enum Question {
Yes,
No,
}
// We implement the `Not` trait on the enum.
impl Not for Question {
type Output = bool;
fn not(self) -> bool {
match self {
Question::Yes => false, // If the `Answer` is `Yes`, then it
// returns false.
Question::No => true, // And here we do the opposite.
}
}
}
assert_eq!(!Question::Yes, false);
assert_eq!(!Question::No, true);
```
"##,
}
register_diagnostics! {

View file

@ -0,0 +1,13 @@
// 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 main() {
!"a"; //~ ERROR E0600
}

View file

@ -1,4 +1,4 @@
error: cannot apply unary operator `!` to type `&'static str`
error[E0600]: cannot apply unary operator `!` to type `&'static str`
--> $DIR/issue-28308.rs:12:5
|
12 | assert!("foo");

View file

@ -1,4 +1,4 @@
error: cannot apply unary operator `!` to type `!`
error[E0600]: cannot apply unary operator `!` to type `!`
--> $DIR/expr_unary.rs:18:16
|
18 | let x: ! = ! { return; 22 };