Skip to content

Commit bd62230

Browse files
committed
Auto merge of #42614 - GuillaumeGomez:new-error-codes, r=pnkfelix
New error codes Part of #42229. cc @Susurrus @frewsxcv @QuietMisdreavus
2 parents ab5bec2 + ee60064 commit bd62230

File tree

11 files changed

+401
-46
lines changed

11 files changed

+401
-46
lines changed

src/librustc_typeck/check/mod.rs

+35-41
Original file line numberDiff line numberDiff line change
@@ -2950,8 +2950,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
29502950

29512951
if let Some((did, field_ty)) = private_candidate {
29522952
let struct_path = self.tcx().item_path_str(did);
2953-
let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
2954-
let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
2953+
let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
2954+
"field `{}` of struct `{}` is private",
2955+
field.node, struct_path);
29552956
// Also check if an accessible method exists, which is often what is meant.
29562957
if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
29572958
err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
@@ -2962,10 +2963,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
29622963
} else if field.node == keywords::Invalid.name() {
29632964
self.tcx().types.err
29642965
} else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
2965-
self.type_error_struct(field.span, |actual| {
2966-
format!("attempted to take value of method `{}` on type \
2967-
`{}`", field.node, actual)
2968-
}, expr_t)
2966+
type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
2967+
"attempted to take value of method `{}` on type `{}`",
2968+
field.node, expr_t)
29692969
.help("maybe a `()` to call it is missing? \
29702970
If not, try an anonymous function")
29712971
.emit();
@@ -3080,27 +3080,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
30803080

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

3088-
self.type_error_message(
3089-
expr.span,
3090-
|actual| {
3091-
if tuple_like {
3092-
format!("attempted out-of-bounds tuple index `{}` on \
3093-
type `{}`",
3094-
idx.node,
3095-
actual)
3096-
} else {
3097-
format!("attempted tuple index `{}` on type `{}`, but the \
3098-
type was not a tuple or tuple struct",
3099-
idx.node,
3100-
actual)
3101-
}
3102-
},
3103-
expr_t);
3089+
if tuple_like {
3090+
type_error_struct!(self.tcx().sess, expr.span, expr_t, E0612,
3091+
"attempted out-of-bounds tuple index `{}` on type `{}`",
3092+
idx.node, expr_t).emit();
3093+
} else {
3094+
type_error_struct!(self.tcx().sess, expr.span, expr_t, E0613,
3095+
"attempted to access tuple index `{}` on type `{}`, but the type \
3096+
was not a tuple or tuple struct",
3097+
idx.node, expr_t).emit();
3098+
}
31043099

31053100
self.tcx().types.err
31063101
}
@@ -3201,10 +3196,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
32013196
field_type_hint = tcx.types.err;
32023197
if let Some(_) = variant.find_field_named(field.name.node) {
32033198
let mut err = struct_span_err!(self.tcx.sess,
3204-
field.name.span,
3205-
E0062,
3206-
"field `{}` specified more than once",
3207-
field.name.node);
3199+
field.name.span,
3200+
E0062,
3201+
"field `{}` specified more than once",
3202+
field.name.node);
32083203

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

@@ -3251,15 +3246,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
32513246
.join(", ");
32523247

32533248
struct_span_err!(tcx.sess, span, E0063,
3254-
"missing field{} {}{} in initializer of `{}`",
3255-
if remaining_fields.len() == 1 {""} else {"s"},
3256-
remaining_fields_names,
3257-
truncated_fields_error,
3258-
adt_ty)
3259-
.span_label(span, format!("missing {}{}",
3260-
remaining_fields_names,
3261-
truncated_fields_error))
3262-
.emit();
3249+
"missing field{} {}{} in initializer of `{}`",
3250+
if remaining_fields.len() == 1 { "" } else { "s" },
3251+
remaining_fields_names,
3252+
truncated_fields_error,
3253+
adt_ty)
3254+
.span_label(span, format!("missing {}{}",
3255+
remaining_fields_names,
3256+
truncated_fields_error))
3257+
.emit();
32633258
}
32643259
}
32653260

@@ -3492,10 +3487,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
34923487
oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
34933488
self.write_method_call(expr.id, method);
34943489
} else {
3495-
self.type_error_message(expr.span, |actual| {
3496-
format!("type `{}` cannot be \
3497-
dereferenced", actual)
3498-
}, oprnd_t);
3490+
type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
3491+
"type `{}` cannot be dereferenced",
3492+
oprnd_t).emit();
34993493
oprnd_t = tcx.types.err;
35003494
}
35013495
}

src/librustc_typeck/diagnostics.rs

+247
Original file line numberDiff line numberDiff line change
@@ -4174,6 +4174,253 @@ println!("x: {}, y: {}", variable.x, variable.y);
41744174
For more information see The Rust Book: https://doc.rust-lang.org/book/
41754175
"##,
41764176

4177+
E0611: r##"
4178+
Attempted to access a private field on a tuple-struct.
4179+
4180+
Erroneous code example:
4181+
4182+
```compile_fail,E0611
4183+
mod some_module {
4184+
pub struct Foo(u32);
4185+
4186+
impl Foo {
4187+
pub fn new() -> Foo { Foo(0) }
4188+
}
4189+
}
4190+
4191+
let y = some_module::Foo::new();
4192+
println!("{}", y.0); // error: field `0` of tuple-struct `some_module::Foo`
4193+
// is private
4194+
```
4195+
4196+
Since the field is private, you have two solutions:
4197+
4198+
1) Make the field public:
4199+
4200+
```
4201+
mod some_module {
4202+
pub struct Foo(pub u32); // The field is now public.
4203+
4204+
impl Foo {
4205+
pub fn new() -> Foo { Foo(0) }
4206+
}
4207+
}
4208+
4209+
let y = some_module::Foo::new();
4210+
println!("{}", y.0); // So we can access it directly.
4211+
```
4212+
4213+
2) Add a getter function to keep the field private but allow for accessing its
4214+
value:
4215+
4216+
```
4217+
mod some_module {
4218+
pub struct Foo(u32);
4219+
4220+
impl Foo {
4221+
pub fn new() -> Foo { Foo(0) }
4222+
4223+
// We add the getter function.
4224+
pub fn get(&self) -> &u32 { &self.0 }
4225+
}
4226+
}
4227+
4228+
let y = some_module::Foo::new();
4229+
println!("{}", y.get()); // So we can get the value through the function.
4230+
```
4231+
"##,
4232+
4233+
E0612: r##"
4234+
Attempted out-of-bounds tuple index.
4235+
4236+
Erroneous code example:
4237+
4238+
```compile_fail,E0612
4239+
struct Foo(u32);
4240+
4241+
let y = Foo(0);
4242+
println!("{}", y.1); // error: attempted out-of-bounds tuple index `1`
4243+
// on type `Foo`
4244+
```
4245+
4246+
If a tuple/tuple-struct type has n fields, you can only try to access these n
4247+
fields from 0 to (n - 1). So in this case, you can only index `0`. Example:
4248+
4249+
```
4250+
struct Foo(u32);
4251+
4252+
let y = Foo(0);
4253+
println!("{}", y.0); // ok!
4254+
```
4255+
"##,
4256+
4257+
E0613: r##"
4258+
Attempted tuple index on a type which isn't a tuple nor a tuple-struct.
4259+
4260+
Erroneous code example:
4261+
4262+
```compile_fail,E0613
4263+
struct Foo;
4264+
4265+
let y = Foo;
4266+
println!("{}", y.1); // error: attempted to access tuple index `1` on type
4267+
// `Foo`, but the type was not a tuple or tuple
4268+
// struct
4269+
```
4270+
4271+
Only tuple and tuple-struct types can be indexed this way. Example:
4272+
4273+
```
4274+
// Let's create a tuple first:
4275+
let x: (u32, u32, u32, u32) = (0, 1, 1, 2);
4276+
// You can index its fields this way:
4277+
println!("({}, {}, {}, {})", x.0, x.1, x.2, x.3);
4278+
4279+
// Now let's declare a tuple-struct:
4280+
struct TupleStruct(u32, u32, u32, u32);
4281+
// Let's instantiate it:
4282+
let x = TupleStruct(0, 1, 1, 2);
4283+
// And just like the tuple:
4284+
println!("({}, {}, {}, {})", x.0, x.1, x.2, x.3);
4285+
```
4286+
4287+
If you want to index into an array, use `[]` instead:
4288+
4289+
```
4290+
let x = &[0, 1, 1, 2];
4291+
println!("[{}, {}, {}, {}]", x[0], x[1], x[2], x[3]);
4292+
```
4293+
4294+
If you want to access a field of a struct, check the field's name wasn't
4295+
misspelled:
4296+
4297+
```
4298+
struct SomeStruct {
4299+
x: u32,
4300+
y: i32,
4301+
}
4302+
4303+
let s = SomeStruct {
4304+
x: 0,
4305+
y: -1,
4306+
};
4307+
println!("x: {} y: {}", s.x, s.y);
4308+
```
4309+
"##,
4310+
4311+
E0614: r##"
4312+
Attempted to dereference a variable which cannot be dereferenced.
4313+
4314+
Erroneous code example:
4315+
4316+
```compile_fail,E0614
4317+
let y = 0u32;
4318+
*y; // error: type `u32` cannot be dereferenced
4319+
```
4320+
4321+
Only types implementing `std::ops::Deref` can be dereferenced (such as `&T`).
4322+
Example:
4323+
4324+
```
4325+
let y = 0u32;
4326+
let x = &y;
4327+
// So here, `x` is a `&u32`, so we can dereference it:
4328+
*x; // ok!
4329+
```
4330+
"##,
4331+
4332+
E0615: r##"
4333+
Attempted to access a method like a field.
4334+
4335+
Erroneous code example:
4336+
4337+
```compile_fail,E0615
4338+
struct Foo {
4339+
x: u32,
4340+
}
4341+
4342+
impl Foo {
4343+
fn method(&self) {}
4344+
}
4345+
4346+
let f = Foo { x: 0 };
4347+
f.method; // error: attempted to take value of method `method` on type `Foo`
4348+
```
4349+
4350+
If you want to use a method, add `()` after it:
4351+
4352+
```ignore
4353+
f.method();
4354+
```
4355+
4356+
However, if you wanted to access a field of a struct check that the field name
4357+
is spelled correctly. Example:
4358+
4359+
```ignore
4360+
println!("{}", f.x);
4361+
```
4362+
"##,
4363+
4364+
E0616: r##"
4365+
Attempted to access a private field on a struct.
4366+
4367+
Erroneous code example:
4368+
4369+
```compile_fail,E0616
4370+
mod some_module {
4371+
pub struct Foo {
4372+
x: u32, // So `x` is private in here.
4373+
}
4374+
4375+
impl Foo {
4376+
pub fn new() -> Foo { Foo { x: 0 } }
4377+
}
4378+
}
4379+
4380+
let f = some_module::Foo::new();
4381+
println!("{}", f.x); // error: field `x` of struct `some_module::Foo` is private
4382+
```
4383+
4384+
If you want to access this field, you have two options:
4385+
4386+
1) Set the field public:
4387+
4388+
```
4389+
mod some_module {
4390+
pub struct Foo {
4391+
pub x: u32, // `x` is now public.
4392+
}
4393+
4394+
impl Foo {
4395+
pub fn new() -> Foo { Foo { x: 0 } }
4396+
}
4397+
}
4398+
4399+
let f = some_module::Foo::new();
4400+
println!("{}", f.x); // ok!
4401+
```
4402+
4403+
2) Add a getter function:
4404+
4405+
```
4406+
mod some_module {
4407+
pub struct Foo {
4408+
x: u32, // So `x` is still private in here.
4409+
}
4410+
4411+
impl Foo {
4412+
pub fn new() -> Foo { Foo { x: 0 } }
4413+
4414+
// We create the getter function here:
4415+
pub fn get_x(&self) -> &u32 { &self.x }
4416+
}
4417+
}
4418+
4419+
let f = some_module::Foo::new();
4420+
println!("{}", f.get_x()); // ok!
4421+
```
4422+
"##,
4423+
41774424
E0617: r##"
41784425
Attempted to pass an invalid type of variable into a variadic function.
41794426

src/test/compile-fail/E0611.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
mod a {
12+
pub struct Foo(u32);
13+
14+
impl Foo {
15+
pub fn new() -> Foo { Foo(0) }
16+
}
17+
}
18+
19+
fn main() {
20+
let y = a::Foo::new();
21+
y.0; //~ ERROR E0611
22+
}

0 commit comments

Comments
 (0)