Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New error codes #42614

Merged
merged 6 commits into from
Jun 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 35 additions & 41 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2921,8 +2921,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {

if let Some((did, field_ty)) = private_candidate {
let struct_path = self.tcx().item_path_str(did);
let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
"field `{}` of struct `{}` is private",
field.node, struct_path);
// Also check if an accessible method exists, which is often what is meant.
if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
Expand All @@ -2933,10 +2934,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
} else if field.node == keywords::Invalid.name() {
self.tcx().types.err
} else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
self.type_error_struct(field.span, |actual| {
format!("attempted to take value of method `{}` on type \
`{}`", field.node, actual)
}, expr_t)
type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
"attempted to take value of method `{}` on type `{}`",
field.node, expr_t)
.help("maybe a `()` to call it is missing? \
If not, try an anonymous function")
.emit();
Expand Down Expand Up @@ -3051,27 +3051,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {

if let Some((did, field_ty)) = private_candidate {
let struct_path = self.tcx().item_path_str(did);
let msg = format!("field `{}` of struct `{}` is private", idx.node, struct_path);
self.tcx().sess.span_err(expr.span, &msg);
struct_span_err!(self.tcx().sess, expr.span, E0611,
"field `{}` of tuple-struct `{}` is private",
idx.node, struct_path).emit();
return field_ty;
}

self.type_error_message(
expr.span,
|actual| {
if tuple_like {
format!("attempted out-of-bounds tuple index `{}` on \
type `{}`",
idx.node,
actual)
} else {
format!("attempted tuple index `{}` on type `{}`, but the \
type was not a tuple or tuple struct",
idx.node,
actual)
}
},
expr_t);
if tuple_like {
type_error_struct!(self.tcx().sess, expr.span, expr_t, E0612,
"attempted out-of-bounds tuple index `{}` on type `{}`",
idx.node, expr_t).emit();
} else {
type_error_struct!(self.tcx().sess, expr.span, expr_t, E0613,
"attempted to access tuple index `{}` on type `{}`, but the type \
was not a tuple or tuple struct",
idx.node, expr_t).emit();
}

self.tcx().types.err
}
Expand Down Expand Up @@ -3172,10 +3167,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
field_type_hint = tcx.types.err;
if let Some(_) = variant.find_field_named(field.name.node) {
let mut err = struct_span_err!(self.tcx.sess,
field.name.span,
E0062,
"field `{}` specified more than once",
field.name.node);
field.name.span,
E0062,
"field `{}` specified more than once",
field.name.node);

err.span_label(field.name.span, "used more than once");

Expand Down Expand Up @@ -3222,15 +3217,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
.join(", ");

struct_span_err!(tcx.sess, span, E0063,
"missing field{} {}{} in initializer of `{}`",
if remaining_fields.len() == 1 {""} else {"s"},
remaining_fields_names,
truncated_fields_error,
adt_ty)
.span_label(span, format!("missing {}{}",
remaining_fields_names,
truncated_fields_error))
.emit();
"missing field{} {}{} in initializer of `{}`",
if remaining_fields.len() == 1 { "" } else { "s" },
remaining_fields_names,
truncated_fields_error,
adt_ty)
.span_label(span, format!("missing {}{}",
remaining_fields_names,
truncated_fields_error))
.emit();
}
}

Expand Down Expand Up @@ -3463,10 +3458,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
self.write_method_call(expr.id, method);
} else {
self.type_error_message(expr.span, |actual| {
format!("type `{}` cannot be \
dereferenced", actual)
}, oprnd_t);
type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
"type `{}` cannot be dereferenced",
oprnd_t).emit();
oprnd_t = tcx.types.err;
}
}
Expand Down
247 changes: 247 additions & 0 deletions src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4152,6 +4152,253 @@ println!("x: {}, y: {}", variable.x, variable.y);
For more information see The Rust Book: https://doc.rust-lang.org/book/
"##,

E0611: r##"
Attempted to access a private field on a tuple-struct.

Erroneous code example:

```compile_fail,E0611
mod some_module {
pub struct Foo(u32);

impl Foo {
pub fn new() -> Foo { Foo(0) }
}
}

let y = some_module::Foo::new();
println!("{}", y.0); // error: field `0` of tuple-struct `some_module::Foo`
// is private
```

Since the field is private, you have two solutions:

1) Make the field public:

```
mod some_module {
pub struct Foo(pub u32); // The field is now public.

impl Foo {
pub fn new() -> Foo { Foo(0) }
}
}

let y = some_module::Foo::new();
println!("{}", y.0); // So we can access it directly.
```

2) Add a getter function to keep the field private but allow for accessing its
value:

```
mod some_module {
pub struct Foo(u32);

impl Foo {
pub fn new() -> Foo { Foo(0) }

// We add the getter function.
pub fn get(&self) -> &u32 { &self.0 }
}
}

let y = some_module::Foo::new();
println!("{}", y.get()); // So we can get the value through the function.
```
"##,

E0612: r##"
Attempted out-of-bounds tuple index.

Erroneous code example:

```compile_fail,E0612
struct Foo(u32);

let y = Foo(0);
println!("{}", y.1); // error: attempted out-of-bounds tuple index `1`
// on type `Foo`
```

If a tuple/tuple-struct type has n fields, you can only try to access these n
fields from 0 to (n - 1). So in this case, you can only index `0`. Example:

```
struct Foo(u32);

let y = Foo(0);
println!("{}", y.0); // ok!
```
"##,

E0613: r##"
Attempted tuple index on a type which isn't a tuple nor a tuple-struct.

Erroneous code example:

```compile_fail,E0613
struct Foo;

let y = Foo;
println!("{}", y.1); // error: attempted to access tuple index `1` on type
// `Foo`, but the type was not a tuple or tuple
// struct
```

Only tuple and tuple-struct types can be indexed this way. Example:

```
// Let's create a tuple first:
let x: (u32, u32, u32, u32) = (0, 1, 1, 2);
// You can index its fields this way:
println!("({}, {}, {}, {})", x.0, x.1, x.2, x.3);

// Now let's declare a tuple-struct:
struct TupleStruct(u32, u32, u32, u32);
// Let's instantiate it:
let x = TupleStruct(0, 1, 1, 2);
// And just like the tuple:
println!("({}, {}, {}, {})", x.0, x.1, x.2, x.3);
```

If you want to index into an array, use `[]` instead:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

index into a slice

would this be more accurate?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to include both Vec and slices.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the context of Rust, when I see the term "array" I often think of fixed-length arrays [T; n]. But I don't have a better term on hand that covers the cases here, so this is fine with me.


```
let x = &[0, 1, 1, 2];
println!("[{}, {}, {}, {}]", x[0], x[1], x[2], x[3]);
```

If you want to access a field of a struct, check the field's name wasn't
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to access a field of a struct, ensure the field's name is spelled correctly

this sounds better to me, but i don't feel strongly

misspelled:

```
struct SomeStruct {
x: u32,
y: i32,
}

let s = SomeStruct {
x: 0,
y: -1,
};
println!("x: {} y: {}", s.x, s.y);
```
"##,

E0614: r##"
Attempted to dereference a variable which cannot be dereferenced.

Erroneous code example:

```compile_fail,E0614
let y = 0u32;
*y; // error: type `u32` cannot be dereferenced
```

Only types implementing `std::ops::Deref` can be dereferenced (such as `&T`).
Example:

```
let y = 0u32;
let x = &y;
// So here, `x` is a `&u32`, so we can dereference it:
*x; // ok!
```
"##,

E0615: r##"
Attempted to access a method like a field.

Erroneous code example:

```compile_fail,E0615
struct Foo {
x: u32,
}

impl Foo {
fn method(&self) {}
}

let f = Foo { x: 0 };
f.method; // error: attempted to take value of method `method` on type `Foo`
```

If you want to use a method, add `()` after it:

```ignore
f.method();
```

However, if you wanted to access a field of a struct check that the field name
is spelled correctly. Example:

```ignore
println!("{}", f.x);
```
"##,

E0616: r##"
Attempted to access a private field on a struct.

Erroneous code example:

```compile_fail,E0616
mod some_module {
pub struct Foo {
x: u32, // So `x` is private in here.
}

impl Foo {
pub fn new() -> Foo { Foo { x: 0 } }
}
}

let f = some_module::Foo::new();
println!("{}", f.x); // error: field `x` of struct `some_module::Foo` is private
```

If you want to access this field, you have two options:

1) Set the field public:

```
mod some_module {
pub struct Foo {
pub x: u32, // `x` is now public.
}

impl Foo {
pub fn new() -> Foo { Foo { x: 0 } }
}
}

let f = some_module::Foo::new();
println!("{}", f.x); // ok!
```

2) Add a getter function:

```
mod some_module {
pub struct Foo {
x: u32, // So `x` is still private in here.
}

impl Foo {
pub fn new() -> Foo { Foo { x: 0 } }

// We create the getter function here:
pub fn get_x(&self) -> &u32 { &self.x }
}
}

let f = some_module::Foo::new();
println!("{}", f.get_x()); // ok!
```
"##,

E0617: r##"
Attempted to pass an invalid type of variable into a variadic function.

Expand Down
22 changes: 22 additions & 0 deletions src/test/compile-fail/E0611.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// 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.

mod a {
pub struct Foo(u32);

impl Foo {
pub fn new() -> Foo { Foo(0) }
}
}

fn main() {
let y = a::Foo::new();
y.0; //~ ERROR E0611
}
Loading