Skip to content

Add 9 more error explanations, improve some error messages. #25688

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

Merged
merged 5 commits into from
May 27, 2015
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
55 changes: 51 additions & 4 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,54 @@ enum Method { GET, POST }
```
"##,

E0261: r##"
When using a lifetime like `'a` in a type, it must be declared before being
used.

These two examples illustrate the problem:

```
// error, use of undeclared lifetime name `'a`
fn foo(x: &'a str) { }

struct Foo {
// error, use of undeclared lifetime name `'a`
x: &'a str,
}
```

These can be fixed by declaring lifetime parameters:

```
fn foo<'a>(x: &'a str) { }

struct Foo<'a> {
x: &'a str,
}
```
"##,

E0262: r##"
Declaring certain lifetime names in parameters is disallowed. For example,
because the `'static` lifetime is a special built-in lifetime name denoting
the lifetime of the entire program, this is an error:

```
// error, illegal lifetime parameter name `'static`
fn foo<'static>(x: &'static str) { }
```
"##,

E0263: r##"
A lifetime name cannot be declared more than once in the same scope. For
example:

```
// error, lifetime name `'a` declared twice in the same scope
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { }
```
"##,

E0265: r##"
This error indicates that a static or constant references itself.
All statics and constants need to resolve to a value in an acyclic manner.
Expand Down Expand Up @@ -814,9 +862,6 @@ register_diagnostics! {
E0136,
E0138,
E0139,
E0261, // use of undeclared lifetime name
E0262, // illegal lifetime parameter name
E0263, // lifetime name declared twice in same scope
E0264, // unknown external lang item
E0266, // expected item
E0269, // not all control paths return a value
Expand Down Expand Up @@ -846,5 +891,7 @@ register_diagnostics! {
E0315, // cannot invoke closure outside of its lifetime
E0316, // nested quantification of lifetimes
E0370, // discriminant overflow
E0378 // method calls limited to constant inherent methods
E0378, // method calls limited to constant inherent methods
E0394 // cannot refer to other statics by value, use the address-of
// operator or a constant instead
}
6 changes: 3 additions & 3 deletions src/librustc/middle/check_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -762,9 +762,9 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'tcx> {
// statics cannot be consumed by value at any time, that would imply
// that they're an initializer (what a const is for) or kept in sync
// over time (not feasible), so deny it outright.
self.tcx.sess.span_err(consume_span,
"cannot refer to other statics by value, use the \
address-of operator or a constant instead");
span_err!(self.tcx.sess, consume_span, E0394,
"cannot refer to other statics by value, use the \
address-of operator or a constant instead");
}
break;
}
Expand Down
71 changes: 33 additions & 38 deletions src/librustc_borrowck/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,11 +603,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {

let (ol, moved_lp_msg) = match the_move.kind {
move_data::Declared => {
self.tcx.sess.span_err(
use_span,
&format!("{} of possibly uninitialized variable: `{}`",
verb,
self.loan_path_to_string(lp)));
span_err!(
self.tcx.sess, use_span, E0381,
"{} of possibly uninitialized variable: `{}`",
verb,
self.loan_path_to_string(lp));

(self.loan_path_to_string(moved_lp),
String::new())
}
Expand Down Expand Up @@ -644,12 +645,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
let msg = if !has_fork && partial { "partially " }
else if has_fork && !has_common { "collaterally "}
else { "" };
self.tcx.sess.span_err(
use_span,
&format!("{} of {}moved value: `{}`",
verb,
msg,
nl));
span_err!(
self.tcx.sess, use_span, E0382,
"{} of {}moved value: `{}`",
verb, msg, nl);
(ol, moved_lp_msg)
}
};
Expand Down Expand Up @@ -762,23 +761,21 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
&self,
span: Span,
lp: &LoanPath<'tcx>) {
self.tcx
.sess
.span_err(span,
&format!("partial reinitialization of uninitialized \
structure `{}`",
self.loan_path_to_string(lp)));
span_err!(
self.tcx.sess, span, E0383,
"partial reinitialization of uninitialized structure `{}`",
self.loan_path_to_string(lp));
}

pub fn report_reassigned_immutable_variable(&self,
span: Span,
lp: &LoanPath<'tcx>,
assign:
&move_data::Assignment) {
self.tcx.sess.span_err(
span,
&format!("re-assignment of immutable variable `{}`",
self.loan_path_to_string(lp)));
span_err!(
self.tcx.sess, span, E0384,
"re-assignment of immutable variable `{}`",
self.loan_path_to_string(lp));
self.tcx.sess.span_note(assign.span, "prior assignment occurs here");
}

Expand Down Expand Up @@ -896,21 +893,19 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {

match cause {
mc::AliasableOther => {
self.tcx.sess.span_err(
span,
&format!("{} in an aliasable location",
prefix));
span_err!(
self.tcx.sess, span, E0385,
"{} in an aliasable location", prefix);
}
mc::AliasableReason::UnaliasableImmutable => {
self.tcx.sess.span_err(
span,
&format!("{} in an immutable container",
prefix));
span_err!(
self.tcx.sess, span, E0386,
"{} in an immutable container", prefix);
}
mc::AliasableClosure(id) => {
self.tcx.sess.span_err(span,
&format!("{} in a captured outer \
variable in an `Fn` closure", prefix));
span_err!(
self.tcx.sess, span, E0387,
"{} in a captured outer variable in an `Fn` closure", prefix);
if let BorrowViolation(euv::ClosureCapture(_)) = kind {
// The aliasability violation with closure captures can
// happen for nested closures, so we know the enclosing
Expand All @@ -925,14 +920,14 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}
mc::AliasableStatic(..) |
mc::AliasableStaticMut(..) => {
self.tcx.sess.span_err(
span,
&format!("{} in a static location", prefix));
span_err!(
self.tcx.sess, span, E0388,
"{} in a static location", prefix);
}
mc::AliasableBorrowed => {
self.tcx.sess.span_err(
span,
&format!("{} in a `&` reference", prefix));
span_err!(
self.tcx.sess, span, E0389,
"{} in a `&` reference", prefix);
}
}

Expand Down
27 changes: 26 additions & 1 deletion src/librustc_borrowck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@

#![allow(non_snake_case)]

register_long_diagnostics! {

E0381: r##"
It is not allowed to use or capture an uninitialized variable. For example:

```
fn main() {
let x: i32;
let y = x; // error, use of possibly uninitialized variable
```

To fix this, ensure that any declared variables are initialized before being
used.
"##

}

register_diagnostics! {
E0373 // closure may outlive current fn, but it borrows {}, which is owned by current fn
E0373, // closure may outlive current fn, but it borrows {}, which is owned by current fn
E0382, // use of partially/collaterally moved value
E0383, // partial reinitialization of uninitialized structure
E0384, // reassignment of immutable variable
E0385, // {} in an aliasable location
E0386, // {} in an immutable container
E0387, // {} in a captured outer variable in an `Fn` closure
E0388, // {} in a static location
E0389 // {} in a `&` reference
}
13 changes: 6 additions & 7 deletions src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,13 +437,12 @@ fn create_substs_for_ast_path<'tcx>(
// defaults. This will lead to an ICE if we are not
// careful!
if self_ty.is_none() && ty::type_has_self(default) {
tcx.sess.span_err(
span,
&format!("the type parameter `{}` must be explicitly specified \
in an object type because its default value `{}` references \
the type `Self`",
param.name.user_string(tcx),
default.user_string(tcx)));
span_err!(tcx.sess, span, E0393,
"the type parameter `{}` must be explicitly specified \
in an object type because its default value `{}` references \
the type `Self`",
param.name.user_string(tcx),
default.user_string(tcx));
substs.types.push(TypeSpace, tcx.types.err);
} else {
// This is a default type parameter.
Expand Down
33 changes: 22 additions & 11 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4688,9 +4688,12 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
} else if i == type_count {
span_err!(fcx.tcx().sess, typ.span, E0087,
"too many type parameters provided: \
expected at most {} parameter(s), \
found {} parameter(s)",
type_count, data.types.len());
expected at most {} parameter{}, \
found {} parameter{}",
type_count,
if type_count == 1 {""} else {"s"},
data.types.len(),
if data.types.len() == 1 {""} else {"s"});
substs.types.truncate(space, 0);
break;
}
Expand All @@ -4713,9 +4716,11 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
} else if i == region_count {
span_err!(fcx.tcx().sess, lifetime.span, E0088,
"too many lifetime parameters provided: \
expected {} parameter(s), found {} parameter(s)",
expected {} parameter{}, found {} parameter{}",
region_count,
data.lifetimes.len());
if region_count == 1 {""} else {"s"},
data.lifetimes.len(),
if data.lifetimes.len() == 1 {""} else {"s"});
substs.mut_regions().truncate(space, 0);
break;
}
Expand Down Expand Up @@ -4805,9 +4810,12 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
let qualifier =
if desired.len() != required_len { "at least " } else { "" };
span_err!(fcx.tcx().sess, span, E0089,
"too few type parameters provided: expected {}{} parameter(s) \
, found {} parameter(s)",
qualifier, required_len, provided_len);
"too few type parameters provided: expected {}{} parameter{}, \
found {} parameter{}",
qualifier, required_len,
if required_len == 1 {""} else {"s"},
provided_len,
if provided_len == 1 {""} else {"s"});
substs.types.replace(space, repeat(fcx.tcx().types.err).take(desired.len()).collect());
return;
}
Expand Down Expand Up @@ -4858,9 +4866,12 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// Otherwise, too few were provided. Report an error and then
// use inference variables.
span_err!(fcx.tcx().sess, span, E0090,
"too few lifetime parameters provided: expected {} parameter(s), \
found {} parameter(s)",
desired.len(), provided_len);
"too few lifetime parameters provided: expected {} parameter{}, \
found {} parameter{}",
desired.len(),
if desired.len() == 1 {""} else {"s"},
provided_len,
if provided_len == 1 {""} else {"s"});

substs.mut_regions().replace(
space,
Expand Down
13 changes: 5 additions & 8 deletions src/librustc_typeck/check/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,9 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
reject_non_type_param_bounds(ccx.tcx, item.span, &trait_predicates);
if ty::trait_has_default_impl(ccx.tcx, local_def(item.id)) {
if !items.is_empty() {
ccx.tcx.sess.span_err(
item.span,
"traits with default impls (`e.g. unsafe impl Trait for ..`) must \
have no methods or associated items")
span_err!(ccx.tcx.sess, item.span, E0380,
"traits with default impls (`e.g. unsafe impl \
Trait for ..`) must have no methods or associated items")
}
}
}
Expand Down Expand Up @@ -353,10 +352,8 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
span: Span,
param_name: ast::Name)
{
self.tcx().sess.span_err(
span,
&format!("parameter `{}` is never used",
param_name.user_string(self.tcx())));
span_err!(self.tcx().sess, span, E0392,
"parameter `{}` is never used", param_name.user_string(self.tcx()));

let suggested_marker_id = self.tcx().lang_items.phantom_data();
match suggested_marker_id {
Expand Down
7 changes: 3 additions & 4 deletions src/librustc_typeck/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
match lang_def_id {
Some(lang_def_id) if lang_def_id == impl_def_id => { /* OK */ },
_ => {
self.tcx.sess.span_err(
span,
&format!("only a single inherent implementation marked with `#[lang = \"{}\"]` \
is allowed for the `{}` primitive", lang, ty));
span_err!(self.tcx.sess, span, E0390,
"only a single inherent implementation marked with `#[lang = \"{}\"]` \
is allowed for the `{}` primitive", lang, ty);
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,8 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
assert!(!cycle.is_empty());
let tcx = self.tcx;

tcx.sess.span_err(
span,
&format!("unsupported cyclic reference between types/traits detected"));
span_err!(tcx.sess, span, E0391,
"unsupported cyclic reference between types/traits detected");

match cycle[0] {
AstConvRequest::GetItemTypeScheme(def_id) |
Expand Down
Loading