mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Convert a first batch of diagnostics to have error codes
This commit is contained in:
parent
350f3aa856
commit
a5fe176e97
@ -16,3 +16,99 @@ register_diagnostic!(E0001, r##"
|
||||
This means that perhaps some of the preceeding patterns are too general, this
|
||||
one is too specific or the ordering is incorrect.
|
||||
"##)
|
||||
|
||||
register_diagnostics!(
|
||||
E0002,
|
||||
E0003,
|
||||
E0004,
|
||||
E0005,
|
||||
E0006,
|
||||
E0007,
|
||||
E0008,
|
||||
E0009,
|
||||
E0010,
|
||||
E0011,
|
||||
E0012,
|
||||
E0013,
|
||||
E0014,
|
||||
E0015,
|
||||
E0016,
|
||||
E0017,
|
||||
E0018,
|
||||
E0019,
|
||||
E0020,
|
||||
E0021,
|
||||
E0022,
|
||||
E0023,
|
||||
E0024,
|
||||
E0025,
|
||||
E0026,
|
||||
E0027,
|
||||
E0028,
|
||||
E0029,
|
||||
E0030,
|
||||
E0031,
|
||||
E0032,
|
||||
E0033,
|
||||
E0034,
|
||||
E0035,
|
||||
E0036,
|
||||
E0037,
|
||||
E0038,
|
||||
E0039,
|
||||
E0040,
|
||||
E0041,
|
||||
E0042,
|
||||
E0043,
|
||||
E0044,
|
||||
E0045,
|
||||
E0046,
|
||||
E0047,
|
||||
E0048,
|
||||
E0049,
|
||||
E0050,
|
||||
E0051,
|
||||
E0052,
|
||||
E0053,
|
||||
E0054,
|
||||
E0055,
|
||||
E0056,
|
||||
E0057,
|
||||
E0058,
|
||||
E0059,
|
||||
E0060,
|
||||
E0061,
|
||||
E0062,
|
||||
E0063,
|
||||
E0064,
|
||||
E0065,
|
||||
E0066,
|
||||
E0067,
|
||||
E0068,
|
||||
E0069,
|
||||
E0070,
|
||||
E0071,
|
||||
E0072,
|
||||
E0073,
|
||||
E0074,
|
||||
E0075,
|
||||
E0076,
|
||||
E0077,
|
||||
E0078,
|
||||
E0079,
|
||||
E0080,
|
||||
E0081,
|
||||
E0082,
|
||||
E0083,
|
||||
E0084,
|
||||
E0085,
|
||||
E0086,
|
||||
E0087,
|
||||
E0088,
|
||||
E0089,
|
||||
E0090,
|
||||
E0091,
|
||||
E0092,
|
||||
E0093,
|
||||
E0094
|
||||
)
|
||||
|
@ -85,6 +85,9 @@ impl Session {
|
||||
pub fn span_warn(&self, sp: Span, msg: &str) {
|
||||
self.diagnostic().span_warn(sp, msg)
|
||||
}
|
||||
pub fn span_warn_with_code(&self, sp: Span, msg: &str, code: &str) {
|
||||
self.diagnostic().span_warn_with_code(sp, msg, code)
|
||||
}
|
||||
pub fn warn(&self, msg: &str) {
|
||||
self.diagnostic().handler().warn(msg)
|
||||
}
|
||||
|
@ -87,28 +87,25 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
|
||||
match e.node {
|
||||
ExprUnary(UnDeref, _) => { }
|
||||
ExprUnary(UnBox, _) | ExprUnary(UnUniq, _) => {
|
||||
v.tcx.sess.span_err(e.span,
|
||||
"cannot do allocations in constant expressions");
|
||||
span_err!(v.tcx.sess, e.span, E0010, "cannot do allocations in constant expressions");
|
||||
return;
|
||||
}
|
||||
ExprLit(lit) if ast_util::lit_is_str(lit) => {}
|
||||
ExprBinary(..) | ExprUnary(..) => {
|
||||
let method_call = typeck::MethodCall::expr(e.id);
|
||||
if v.tcx.method_map.borrow().contains_key(&method_call) {
|
||||
v.tcx.sess.span_err(e.span, "user-defined operators are not \
|
||||
allowed in constant expressions");
|
||||
span_err!(v.tcx.sess, e.span, E0011,
|
||||
"user-defined operators are not allowed in constant expressions");
|
||||
}
|
||||
}
|
||||
ExprLit(_) => (),
|
||||
ExprCast(_, _) => {
|
||||
let ety = ty::expr_ty(v.tcx, e);
|
||||
if !ty::type_is_numeric(ety) && !ty::type_is_unsafe_ptr(ety) {
|
||||
v.tcx
|
||||
.sess
|
||||
.span_err(e.span,
|
||||
format!("can not cast to `{}` in a constant \
|
||||
expression",
|
||||
ppaux::ty_to_string(v.tcx, ety)).as_slice())
|
||||
span_err!(v.tcx.sess, e.span, E0012,
|
||||
"can not cast to `{}` in a constant expression",
|
||||
ppaux::ty_to_string(v.tcx, ety)
|
||||
);
|
||||
}
|
||||
}
|
||||
ExprPath(ref pth) => {
|
||||
@ -117,9 +114,8 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
|
||||
// foo::<bar> in a const. Currently that is only done on
|
||||
// a path in trans::callee that only works in block contexts.
|
||||
if !pth.segments.iter().all(|segment| segment.types.is_empty()) {
|
||||
v.tcx.sess.span_err(e.span,
|
||||
"paths in constants may only refer to \
|
||||
items without type parameters");
|
||||
span_err!(v.tcx.sess, e.span, E0013,
|
||||
"paths in constants may only refer to items without type parameters");
|
||||
}
|
||||
match v.tcx.def_map.borrow().find(&e.id) {
|
||||
Some(&DefStatic(..)) |
|
||||
@ -129,9 +125,8 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
|
||||
|
||||
Some(&def) => {
|
||||
debug!("(checking const) found bad def: {:?}", def);
|
||||
v.tcx.sess.span_err(e.span,
|
||||
"paths in constants may only refer to \
|
||||
constants or functions");
|
||||
span_err!(v.tcx.sess, e.span, E0014,
|
||||
"paths in constants may only refer to constants or functions");
|
||||
}
|
||||
None => {
|
||||
v.tcx.sess.span_bug(e.span, "unbound path in const?!");
|
||||
@ -143,9 +138,8 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
|
||||
Some(&DefStruct(..)) => {} // OK.
|
||||
Some(&DefVariant(..)) => {} // OK.
|
||||
_ => {
|
||||
v.tcx.sess.span_err(e.span,
|
||||
"function calls in constants are limited to \
|
||||
struct and enum constructors");
|
||||
span_err!(v.tcx.sess, e.span, E0015,
|
||||
"function calls in constants are limited to struct and enum constructors");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -153,9 +147,8 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
|
||||
// Check all statements in the block
|
||||
for stmt in block.stmts.iter() {
|
||||
let block_span_err = |span|
|
||||
v.tcx.sess.span_err(span,
|
||||
"blocks in constants are limited to \
|
||||
items and tail expressions");
|
||||
span_err!(v.tcx.sess, span, E0016,
|
||||
"blocks in constants are limited to items and tail expressions");
|
||||
match stmt.node {
|
||||
StmtDecl(ref span, _) => {
|
||||
match span.node {
|
||||
@ -187,18 +180,18 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
|
||||
ExprRepeat(..) |
|
||||
ExprStruct(..) => { }
|
||||
ExprAddrOf(..) => {
|
||||
v.tcx.sess.span_err(e.span,
|
||||
"references in constants may only refer to \
|
||||
immutable values");
|
||||
span_err!(v.tcx.sess, e.span, E0017,
|
||||
"references in constants may only refer to immutable values");
|
||||
},
|
||||
ExprVstore(_, ExprVstoreUniq) => {
|
||||
v.tcx.sess.span_err(e.span, "cannot allocate vectors in constant expressions")
|
||||
span_err!(v.tcx.sess, e.span, E0018,
|
||||
"cannot allocate vectors in constant expressions");
|
||||
},
|
||||
|
||||
_ => {
|
||||
v.tcx.sess.span_err(e.span,
|
||||
"constant contains unimplemented expression type");
|
||||
return;
|
||||
span_err!(v.tcx.sess, e.span, E0019,
|
||||
"constant contains unimplemented expression type");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,15 +142,16 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &Expr) {
|
||||
// Finally, check if the whole match expression is exhaustive.
|
||||
// Check for empty enum, because is_useful only works on inhabited types.
|
||||
let pat_ty = node_id_to_type(cx.tcx, scrut.id);
|
||||
if (*arms).is_empty() {
|
||||
if !type_is_empty(cx.tcx, pat_ty) {
|
||||
// We know the type is inhabited, so this must be wrong
|
||||
cx.tcx.sess.span_err(ex.span, format!("non-exhaustive patterns: \
|
||||
type {} is non-empty",
|
||||
ty_to_string(cx.tcx, pat_ty)).as_slice());
|
||||
}
|
||||
// If the type *is* empty, it's vacuously exhaustive
|
||||
return;
|
||||
if arms.is_empty() {
|
||||
if !type_is_empty(cx.tcx, pat_ty) {
|
||||
// We know the type is inhabited, so this must be wrong
|
||||
span_err!(cx.tcx.sess, ex.span, E0002,
|
||||
"non-exhaustive patterns: type {} is non-empty",
|
||||
ty_to_string(cx.tcx, pat_ty)
|
||||
);
|
||||
}
|
||||
// If the type *is* empty, it's vacuously exhaustive
|
||||
return;
|
||||
}
|
||||
let m: Matrix = Matrix(arms
|
||||
.iter()
|
||||
@ -186,8 +187,9 @@ fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm]) {
|
||||
|
||||
walk_pat(&**pat, |p| {
|
||||
if pat_matches_nan(p) {
|
||||
cx.tcx.sess.span_warn(p.span, "unmatchable NaN in pattern, \
|
||||
use the is_nan method in a guard instead");
|
||||
span_warn!(cx.tcx.sess, p.span, E0003,
|
||||
"unmatchable NaN in pattern, use the is_nan method in a guard instead"
|
||||
);
|
||||
}
|
||||
true
|
||||
});
|
||||
@ -222,9 +224,10 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, m: &Matrix) {
|
||||
[] => wild(),
|
||||
_ => unreachable!()
|
||||
};
|
||||
let msg = format!("non-exhaustive patterns: `{0}` not covered",
|
||||
pat_to_string(&*witness));
|
||||
cx.tcx.sess.span_err(sp, msg.as_slice());
|
||||
span_err!(cx.tcx.sess, sp, E0004,
|
||||
"non-exhaustive patterns: `{}` not covered",
|
||||
pat_to_string(&*witness)
|
||||
);
|
||||
}
|
||||
NotUseful => {
|
||||
// This is good, wildcard pattern isn't reachable
|
||||
@ -779,11 +782,10 @@ fn check_local(cx: &mut MatchCheckCtxt, loc: &Local) {
|
||||
|
||||
match is_refutable(cx, loc.pat) {
|
||||
Some(pat) => {
|
||||
let msg = format!(
|
||||
span_err!(cx.tcx.sess, loc.pat.span, E0005,
|
||||
"refutable pattern in {} binding: `{}` not covered",
|
||||
name, pat_to_string(&*pat)
|
||||
);
|
||||
cx.tcx.sess.span_err(loc.pat.span, msg.as_slice());
|
||||
},
|
||||
None => ()
|
||||
}
|
||||
@ -801,11 +803,10 @@ fn check_fn(cx: &mut MatchCheckCtxt,
|
||||
for input in decl.inputs.iter() {
|
||||
match is_refutable(cx, input.pat) {
|
||||
Some(pat) => {
|
||||
let msg = format!(
|
||||
span_err!(cx.tcx.sess, input.pat.span, E0006,
|
||||
"refutable pattern in function argument: `{}` not covered",
|
||||
pat_to_string(&*pat)
|
||||
);
|
||||
cx.tcx.sess.span_err(input.pat.span, msg.as_slice());
|
||||
},
|
||||
None => ()
|
||||
}
|
||||
@ -850,21 +851,13 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
|
||||
|
||||
// x @ Foo(..) is legal, but x @ Foo(y) isn't.
|
||||
if sub.map_or(false, |p| pat_contains_bindings(def_map, &*p)) {
|
||||
tcx.sess.span_err(
|
||||
p.span,
|
||||
"cannot bind by-move with sub-bindings");
|
||||
span_err!(cx.tcx.sess, p.span, E0007, "cannot bind by-move with sub-bindings");
|
||||
} else if has_guard {
|
||||
tcx.sess.span_err(
|
||||
p.span,
|
||||
"cannot bind by-move into a pattern guard");
|
||||
span_err!(cx.tcx.sess, p.span, E0008, "cannot bind by-move into a pattern guard");
|
||||
} else if by_ref_span.is_some() {
|
||||
tcx.sess.span_err(
|
||||
p.span,
|
||||
"cannot bind by-move and by-ref \
|
||||
in the same pattern");
|
||||
tcx.sess.span_note(
|
||||
by_ref_span.unwrap(),
|
||||
"by-ref binding occurs here");
|
||||
span_err!(cx.tcx.sess, p.span, E0009,
|
||||
"cannot bind by-move and by-ref in the same pattern");
|
||||
span_note!(cx.tcx.sess, by_ref_span.unwrap(), "by-ref binding occurs here");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -112,18 +112,18 @@ impl<'a> Visitor<bool> for CheckStaticVisitor<'a> {
|
||||
visit::walk_expr(self, e, is_const);
|
||||
}
|
||||
ast::ExprVstore(_, ast::ExprVstoreMutSlice) => {
|
||||
self.tcx.sess.span_err(e.span,
|
||||
"static items are not allowed to have mutable slices");
|
||||
span_err!(self.tcx.sess, e.span, E0020,
|
||||
"static items are not allowed to have mutable slices");
|
||||
},
|
||||
ast::ExprUnary(ast::UnBox, _) => {
|
||||
self.tcx.sess.span_err(e.span,
|
||||
"static items are not allowed to have managed pointers");
|
||||
span_err!(self.tcx.sess, e.span, E0021,
|
||||
"static items are not allowed to have managed pointers");
|
||||
}
|
||||
ast::ExprBox(..) |
|
||||
ast::ExprUnary(ast::UnUniq, _) |
|
||||
ast::ExprVstore(_, ast::ExprVstoreUniq) => {
|
||||
self.tcx.sess.span_err(e.span,
|
||||
"static items are not allowed to have custom pointers");
|
||||
span_err!(self.tcx.sess, e.span, E0022,
|
||||
"static items are not allowed to have custom pointers");
|
||||
}
|
||||
_ => {
|
||||
let node_ty = ty::node_id_to_type(self.tcx, e.id);
|
||||
|
@ -253,14 +253,10 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path,
|
||||
if arg_len > 0 {
|
||||
// N-ary variant.
|
||||
if arg_len != subpats_len {
|
||||
let s = format!("this pattern has {} field{}, \
|
||||
but the corresponding {} has {} field{}",
|
||||
subpats_len,
|
||||
if subpats_len == 1 {""} else {"s"},
|
||||
kind_name,
|
||||
arg_len,
|
||||
if arg_len == 1 {""} else {"s"});
|
||||
tcx.sess.span_err(pat.span, s.as_slice());
|
||||
span_err!(tcx.sess, pat.span, E0023,
|
||||
"this pattern has {} field{}, but the corresponding {} has {} field{}",
|
||||
subpats_len, if subpats_len == 1 {""} else {"s"},
|
||||
kind_name, arg_len, if arg_len == 1 {""} else {"s"});
|
||||
error_happened = true;
|
||||
}
|
||||
|
||||
@ -272,12 +268,10 @@ pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path,
|
||||
}
|
||||
}
|
||||
} else if subpats_len > 0 {
|
||||
tcx.sess.span_err(pat.span,
|
||||
format!("this pattern has {} field{}, \
|
||||
but the corresponding {} has no fields",
|
||||
subpats_len,
|
||||
if subpats_len == 1 {""} else {"s"},
|
||||
kind_name).as_slice());
|
||||
span_err!(tcx.sess, pat.span, E0024,
|
||||
"this pattern has {} field{}, but the corresponding {} has no fields",
|
||||
subpats_len, if subpats_len == 1 {""} else {"s"},
|
||||
kind_name);
|
||||
error_happened = true;
|
||||
}
|
||||
|
||||
@ -321,9 +315,9 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
|
||||
// Check the pattern anyway, so that attempts to look
|
||||
// up its type won't fail
|
||||
check_pat(pcx, &*field.pat, ty::mk_err());
|
||||
tcx.sess.span_err(span,
|
||||
format!("field `{}` bound twice in pattern",
|
||||
token::get_ident(field.ident)).as_slice());
|
||||
span_err!(tcx.sess, span, E0025,
|
||||
"field `{}` bound twice in pattern",
|
||||
token::get_ident(field.ident));
|
||||
}
|
||||
Some(&(index, ref mut used)) => {
|
||||
*used = true;
|
||||
@ -339,10 +333,10 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
|
||||
// Check the pattern anyway, so that attempts to look
|
||||
// up its type won't fail
|
||||
check_pat(pcx, &*field.pat, ty::mk_err());
|
||||
tcx.sess.span_err(span,
|
||||
format!("struct `{}` does not have a field named `{}`",
|
||||
ty::item_path_str(tcx, class_id),
|
||||
token::get_ident(field.ident)).as_slice());
|
||||
span_err!(tcx.sess, span, E0026,
|
||||
"struct `{}` does not have a field named `{}`",
|
||||
ty::item_path_str(tcx, class_id),
|
||||
token::get_ident(field.ident));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -353,11 +347,9 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
|
||||
if found_fields.contains(&i) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tcx.sess
|
||||
.span_err(span,
|
||||
format!("pattern does not mention field `{}`",
|
||||
token::get_name(field.name)).as_slice());
|
||||
span_err!(tcx.sess, span, E0027,
|
||||
"pattern does not mention field `{}`",
|
||||
token::get_name(field.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -400,11 +392,9 @@ pub fn check_struct_like_enum_variant_pat(pcx: &pat_ctxt,
|
||||
}
|
||||
Some(&def::DefStruct(..)) | Some(&def::DefVariant(..)) => {
|
||||
let name = pprust::path_to_string(path);
|
||||
tcx.sess.span_err(span,
|
||||
format!("mismatched types: expected `{}` but \
|
||||
found `{}`",
|
||||
fcx.infcx().ty_to_string(expected),
|
||||
name).as_slice());
|
||||
span_err!(tcx.sess, span, E0028,
|
||||
"mismatched types: expected `{}` but found `{}`",
|
||||
fcx.infcx().ty_to_string(expected), name);
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_bug(span, "resolve didn't write in variant");
|
||||
@ -441,16 +431,16 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
|
||||
{
|
||||
// no-op
|
||||
} else if !ty::type_is_numeric(b_ty) && !ty::type_is_char(b_ty) {
|
||||
tcx.sess.span_err(pat.span,
|
||||
span_err!(tcx.sess, begin.span, E0029,
|
||||
"only char and numeric types are allowed in range");
|
||||
} else {
|
||||
match valid_range_bounds(fcx.ccx, &**begin, &**end) {
|
||||
Some(false) => {
|
||||
tcx.sess.span_err(begin.span,
|
||||
span_err!(tcx.sess, begin.span, E0030,
|
||||
"lower range bound must be less than upper");
|
||||
},
|
||||
None => {
|
||||
tcx.sess.span_err(begin.span,
|
||||
span_err!(tcx.sess, begin.span, E0031,
|
||||
"mismatched types in range");
|
||||
},
|
||||
_ => { },
|
||||
@ -521,13 +511,10 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
|
||||
ty::ty_to_def_id(
|
||||
ty::lookup_item_type(tcx, item_did).ty).unwrap();
|
||||
if struct_did != cid {
|
||||
tcx.sess
|
||||
.span_err(path.span,
|
||||
format!("`{}` does not name the \
|
||||
structure `{}`",
|
||||
pprust::path_to_string(path),
|
||||
fcx.infcx()
|
||||
.ty_to_string(expected)).as_slice())
|
||||
span_err!(tcx.sess, pat.span, E0032,
|
||||
"`{}` does not name the structure `{}`",
|
||||
pprust::path_to_string(path),
|
||||
fcx.infcx().ty_to_string(expected));
|
||||
}
|
||||
|
||||
check_struct_pat(pcx, pat.id, pat.span, expected, path,
|
||||
@ -744,10 +731,9 @@ fn check_pointer_pat(pcx: &pat_ctxt,
|
||||
// This is "x = SomeTrait" being reduced from
|
||||
// "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
|
||||
check_pat(pcx, inner, ty::mk_err());
|
||||
tcx.sess.span_err(
|
||||
span,
|
||||
format!("type `{}` cannot be dereferenced",
|
||||
fcx.infcx().ty_to_string(expected)).as_slice());
|
||||
span_err!(tcx.sess, span, E0033,
|
||||
"type `{}` cannot be dereferenced",
|
||||
fcx.infcx().ty_to_string(expected));
|
||||
fcx.write_error(pat_id);
|
||||
}
|
||||
_ => {
|
||||
|
@ -1041,8 +1041,7 @@ impl<'a> LookupContext<'a> {
|
||||
}
|
||||
|
||||
if relevant_candidates.len() > 1 {
|
||||
self.tcx().sess.span_err(
|
||||
self.span,
|
||||
span_err!(self.tcx().sess, self.span, E0034,
|
||||
"multiple applicable methods in scope");
|
||||
for (idx, candidate) in relevant_candidates.iter().enumerate() {
|
||||
self.report_candidate(idx, &candidate.origin);
|
||||
@ -1112,13 +1111,11 @@ impl<'a> LookupContext<'a> {
|
||||
if num_supplied_tps == 0u {
|
||||
self.fcx.infcx().next_ty_vars(num_method_tps)
|
||||
} else if num_method_tps == 0u {
|
||||
tcx.sess.span_err(
|
||||
self.span,
|
||||
"this method does not take type parameters");
|
||||
span_err!(tcx.sess, self.span, E0035,
|
||||
"does not take type parameters");
|
||||
self.fcx.infcx().next_ty_vars(num_method_tps)
|
||||
} else if num_supplied_tps != num_method_tps {
|
||||
tcx.sess.span_err(
|
||||
self.span,
|
||||
span_err!(tcx.sess, self.span, E0036,
|
||||
"incorrect number of type parameters given for this method");
|
||||
self.fcx.infcx().next_ty_vars(num_method_tps)
|
||||
} else {
|
||||
@ -1221,10 +1218,8 @@ impl<'a> LookupContext<'a> {
|
||||
|
||||
match candidate.method_ty.explicit_self {
|
||||
ast::SelfStatic => { // reason (a) above
|
||||
self.tcx().sess.span_err(
|
||||
self.span,
|
||||
"cannot call a method without a receiver \
|
||||
through an object");
|
||||
span_err!(self.tcx().sess, self.span, E0037,
|
||||
"cannot call a method without a receiver through an object");
|
||||
}
|
||||
|
||||
ast::SelfValue(_) | ast::SelfRegion(..) | ast::SelfUniq(_) => {}
|
||||
@ -1233,8 +1228,7 @@ impl<'a> LookupContext<'a> {
|
||||
// reason (a) above
|
||||
let check_for_self_ty = |ty| {
|
||||
if ty::type_has_self(ty) {
|
||||
self.tcx().sess.span_err(
|
||||
self.span,
|
||||
span_err!(self.tcx().sess, self.span, E0038,
|
||||
"cannot call a method whose type contains a \
|
||||
self-type through an object");
|
||||
true
|
||||
@ -1256,8 +1250,7 @@ impl<'a> LookupContext<'a> {
|
||||
|
||||
if candidate.method_ty.generics.has_type_params(subst::FnSpace) {
|
||||
// reason (b) above
|
||||
self.tcx().sess.span_err(
|
||||
self.span,
|
||||
span_err!(self.tcx().sess, self.span, E0039,
|
||||
"cannot call a generic method through an object");
|
||||
}
|
||||
}
|
||||
@ -1279,8 +1272,8 @@ impl<'a> LookupContext<'a> {
|
||||
}
|
||||
|
||||
if bad {
|
||||
self.tcx().sess.span_err(self.span,
|
||||
"explicit call to destructor");
|
||||
span_err!(self.tcx().sess, self.span, E0040,
|
||||
"explicit call to destructor");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1425,28 +1418,22 @@ impl<'a> LookupContext<'a> {
|
||||
} else {
|
||||
self.span
|
||||
};
|
||||
self.tcx().sess.span_note(
|
||||
span,
|
||||
format!("candidate #{} is `{}`",
|
||||
idx + 1u,
|
||||
ty::item_path_str(self.tcx(), did)).as_slice());
|
||||
span_note!(self.tcx().sess, span,
|
||||
"candidate #{} is `{}`",
|
||||
idx + 1u, ty::item_path_str(self.tcx(), did));
|
||||
}
|
||||
|
||||
fn report_param_candidate(&self, idx: uint, did: DefId) {
|
||||
self.tcx().sess.span_note(
|
||||
self.span,
|
||||
format!("candidate #{} derives from the bound `{}`",
|
||||
idx + 1u,
|
||||
ty::item_path_str(self.tcx(), did)).as_slice());
|
||||
span_note!(self.tcx().sess, self.span,
|
||||
"candidate #{} derives from the bound `{}`",
|
||||
idx + 1u, ty::item_path_str(self.tcx(), did));
|
||||
}
|
||||
|
||||
fn report_trait_candidate(&self, idx: uint, did: DefId) {
|
||||
self.tcx().sess.span_note(
|
||||
self.span,
|
||||
format!("candidate #{} derives from the type of the receiver, \
|
||||
which is the trait `{}`",
|
||||
idx + 1u,
|
||||
ty::item_path_str(self.tcx(), did)).as_slice());
|
||||
span_note!(self.tcx().sess, self.span,
|
||||
"candidate #{} derives from the type of the receiver, \
|
||||
which is the trait `{}`",
|
||||
idx + 1u, ty::item_path_str(self.tcx(), did));
|
||||
}
|
||||
|
||||
fn infcx(&'a self) -> &'a infer::InferCtxt<'a> {
|
||||
|
@ -569,11 +569,10 @@ fn check_for_field_shadowing(tcx: &ty::ctxt,
|
||||
for f in fields.iter() {
|
||||
match super_fields.iter().find(|sf| f.name == sf.name) {
|
||||
Some(prev_field) => {
|
||||
tcx.sess.span_err(span_for_field(tcx, f, id),
|
||||
format!("field `{}` hides field declared in \
|
||||
super-struct",
|
||||
token::get_name(f.name)).as_slice());
|
||||
tcx.sess.span_note(span_for_field(tcx, prev_field, parent_id),
|
||||
span_err!(tcx.sess, span_for_field(tcx, f, id), E0041,
|
||||
"field `{}` hides field declared in super-struct",
|
||||
token::get_name(f.name));
|
||||
span_note!(tcx.sess, span_for_field(tcx, prev_field, parent_id),
|
||||
"previously declared here");
|
||||
},
|
||||
None => {}
|
||||
@ -595,16 +594,16 @@ fn check_fields_sized(tcx: &ty::ctxt,
|
||||
if !ty::type_is_sized(tcx, t) {
|
||||
match f.node.kind {
|
||||
ast::NamedField(ident, _) => {
|
||||
tcx.sess.span_err(
|
||||
f.span,
|
||||
format!("type `{}` is dynamically sized. \
|
||||
dynamically sized types may only \
|
||||
appear as the type of the final \
|
||||
field in a struct",
|
||||
token::get_ident(ident)).as_slice());
|
||||
span_err!(tcx.sess, f.span, E0042,
|
||||
"type `{}` is dynamically sized. \
|
||||
dynamically sized types may only \
|
||||
appear as the type of the final \
|
||||
field in a struct",
|
||||
token::get_ident(ident));
|
||||
}
|
||||
ast::UnnamedField(_) => {
|
||||
tcx.sess.span_err(f.span, "dynamically sized type in field");
|
||||
span_err!(tcx.sess, f.span, E0043,
|
||||
"dynamically sized type in field");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -719,14 +718,15 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
|
||||
for item in m.items.iter() {
|
||||
let pty = ty::lookup_item_type(ccx.tcx, local_def(item.id));
|
||||
if !pty.generics.types.is_empty() {
|
||||
ccx.tcx.sess.span_err(item.span, "foreign items may not have type parameters");
|
||||
span_err!(ccx.tcx.sess, item.span, E0044,
|
||||
"foreign items may not have type parameters");
|
||||
}
|
||||
|
||||
match item.node {
|
||||
ast::ForeignItemFn(ref fn_decl, _) => {
|
||||
if fn_decl.variadic && m.abi != abi::C {
|
||||
ccx.tcx.sess.span_err(
|
||||
item.span, "variadic function must have C calling convention");
|
||||
span_err!(ccx.tcx.sess, item.span, E0045,
|
||||
"variadic function must have C calling convention");
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -826,10 +826,9 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
|
||||
}
|
||||
|
||||
if !missing_methods.is_empty() {
|
||||
tcx.sess.span_err(
|
||||
impl_span,
|
||||
format!("not all trait methods implemented, missing: {}",
|
||||
missing_methods.connect(", ")).as_slice());
|
||||
span_err!(tcx.sess, impl_span, E0046,
|
||||
"not all trait methods implemented, missing: {}",
|
||||
missing_methods.connect(", "));
|
||||
}
|
||||
}
|
||||
|
||||
@ -865,23 +864,17 @@ fn compare_impl_method(tcx: &ty::ctxt,
|
||||
match (&trait_m.explicit_self, &impl_m.explicit_self) {
|
||||
(&ast::SelfStatic, &ast::SelfStatic) => {}
|
||||
(&ast::SelfStatic, _) => {
|
||||
tcx.sess.span_err(
|
||||
impl_m_span,
|
||||
format!("method `{}` has a `{}` declaration in the impl, \
|
||||
but not in the trait",
|
||||
token::get_ident(trait_m.ident),
|
||||
pprust::explicit_self_to_string(
|
||||
impl_m.explicit_self)).as_slice());
|
||||
span_err!(tcx.sess, impl_m_span, E0047,
|
||||
"method `{}` has a `{}` declaration in the impl, but not in the trait",
|
||||
token::get_ident(trait_m.ident),
|
||||
pprust::explicit_self_to_string(impl_m.explicit_self));
|
||||
return;
|
||||
}
|
||||
(_, &ast::SelfStatic) => {
|
||||
tcx.sess.span_err(
|
||||
impl_m_span,
|
||||
format!("method `{}` has a `{}` declaration in the trait, \
|
||||
but not in the impl",
|
||||
token::get_ident(trait_m.ident),
|
||||
pprust::explicit_self_to_string(
|
||||
trait_m.explicit_self)).as_slice());
|
||||
span_err!(tcx.sess, impl_m_span, E0048,
|
||||
"method `{}` has a `{}` declaration in the trait, but not in the impl",
|
||||
token::get_ident(trait_m.ident),
|
||||
pprust::explicit_self_to_string(trait_m.explicit_self));
|
||||
return;
|
||||
}
|
||||
_ => {
|
||||
@ -892,28 +885,26 @@ fn compare_impl_method(tcx: &ty::ctxt,
|
||||
let num_impl_m_type_params = impl_m.generics.types.len(subst::FnSpace);
|
||||
let num_trait_m_type_params = trait_m.generics.types.len(subst::FnSpace);
|
||||
if num_impl_m_type_params != num_trait_m_type_params {
|
||||
tcx.sess.span_err(
|
||||
impl_m_span,
|
||||
format!("method `{}` has {} type parameter{} \
|
||||
but its trait declaration has {} type parameter{}",
|
||||
token::get_ident(trait_m.ident),
|
||||
num_impl_m_type_params,
|
||||
if num_impl_m_type_params == 1 {""} else {"s"},
|
||||
num_trait_m_type_params,
|
||||
if num_trait_m_type_params == 1 {""} else {"s"}).as_slice());
|
||||
span_err!(tcx.sess, impl_m_span, E0049,
|
||||
"method `{}` has {} type parameter{} \
|
||||
but its trait declaration has {} type parameter{}",
|
||||
token::get_ident(trait_m.ident),
|
||||
num_impl_m_type_params,
|
||||
if num_impl_m_type_params == 1 {""} else {"s"},
|
||||
num_trait_m_type_params,
|
||||
if num_trait_m_type_params == 1 {""} else {"s"});
|
||||
return;
|
||||
}
|
||||
|
||||
if impl_m.fty.sig.inputs.len() != trait_m.fty.sig.inputs.len() {
|
||||
tcx.sess.span_err(
|
||||
impl_m_span,
|
||||
format!("method `{}` has {} parameter{} \
|
||||
but the declaration in trait `{}` has {}",
|
||||
token::get_ident(trait_m.ident),
|
||||
impl_m.fty.sig.inputs.len(),
|
||||
if impl_m.fty.sig.inputs.len() == 1 {""} else {"s"},
|
||||
ty::item_path_str(tcx, trait_m.def_id),
|
||||
trait_m.fty.sig.inputs.len()).as_slice());
|
||||
span_err!(tcx.sess, impl_m_span, E0050,
|
||||
"method `{}` has {} parameter{} \
|
||||
but the declaration in trait `{}` has {}",
|
||||
token::get_ident(trait_m.ident),
|
||||
impl_m.fty.sig.inputs.len(),
|
||||
if impl_m.fty.sig.inputs.len() == 1 {""} else {"s"},
|
||||
ty::item_path_str(tcx, trait_m.def_id),
|
||||
trait_m.fty.sig.inputs.len());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1002,16 +993,13 @@ fn compare_impl_method(tcx: &ty::ctxt,
|
||||
impl_param_def.bounds.builtin_bounds -
|
||||
trait_param_def.bounds.builtin_bounds;
|
||||
if !extra_bounds.is_empty() {
|
||||
tcx.sess.span_err(
|
||||
impl_m_span,
|
||||
format!("in method `{}`, \
|
||||
type parameter {} requires `{}`, \
|
||||
which is not required by \
|
||||
the corresponding type parameter \
|
||||
in the trait declaration",
|
||||
token::get_ident(trait_m.ident),
|
||||
i,
|
||||
extra_bounds.user_string(tcx)).as_slice());
|
||||
span_err!(tcx.sess, impl_m_span, E0051,
|
||||
"in method `{}`, type parameter {} requires `{}`, \
|
||||
which is not required by the corresponding type parameter \
|
||||
in the trait declaration",
|
||||
token::get_ident(trait_m.ident),
|
||||
i,
|
||||
extra_bounds.user_string(tcx));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1043,17 +1031,12 @@ fn compare_impl_method(tcx: &ty::ctxt,
|
||||
}
|
||||
|
||||
if !ok {
|
||||
tcx.sess.span_err(impl_m_span,
|
||||
format!("in method `{}`, type parameter {} \
|
||||
requires bound `{}`, which is not \
|
||||
required by the corresponding \
|
||||
type parameter in the trait \
|
||||
declaration",
|
||||
token::get_ident(trait_m.ident),
|
||||
i,
|
||||
ppaux::trait_ref_to_string(
|
||||
tcx,
|
||||
&*impl_trait_bound)).as_slice())
|
||||
span_err!(tcx.sess, impl_m_span, E0052,
|
||||
"in method `{}`, type parameter {} requires bound `{}`, which is not \
|
||||
required by the corresponding type parameter in the trait declaration",
|
||||
token::get_ident(trait_m.ident),
|
||||
i,
|
||||
ppaux::trait_ref_to_string(tcx, &*impl_trait_bound));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1071,11 +1054,10 @@ fn compare_impl_method(tcx: &ty::ctxt,
|
||||
impl_fty, trait_fty) {
|
||||
Ok(()) => {}
|
||||
Err(ref terr) => {
|
||||
tcx.sess.span_err(
|
||||
impl_m_span,
|
||||
format!("method `{}` has an incompatible type for trait: {}",
|
||||
token::get_ident(trait_m.ident),
|
||||
ty::type_err_to_str(tcx, terr)).as_slice());
|
||||
span_err!(tcx.sess, impl_m_span, E0053,
|
||||
"method `{}` has an incompatible type for trait: {}",
|
||||
token::get_ident(trait_m.ident),
|
||||
ty::type_err_to_str(tcx, terr));
|
||||
ty::note_and_explain_type_err(tcx, terr);
|
||||
}
|
||||
}
|
||||
@ -1162,10 +1144,8 @@ fn check_cast(fcx: &FnCtxt,
|
||||
}, t_e, None);
|
||||
}
|
||||
} else if ty::get(t_1).sty == ty::ty_bool {
|
||||
fcx.tcx()
|
||||
.sess
|
||||
.span_err(span,
|
||||
"cannot cast as `bool`, compare with zero instead");
|
||||
span_err!(fcx.tcx().sess, span, E0054,
|
||||
"cannot cast as `bool`, compare with zero instead");
|
||||
} else if ty::type_is_region_ptr(t_e) && ty::type_is_unsafe_ptr(t_1) {
|
||||
fn types_compatible(fcx: &FnCtxt, sp: Span,
|
||||
t1: ty::t, t2: ty::t) -> bool {
|
||||
@ -1533,9 +1513,9 @@ pub fn autoderef<T>(fcx: &FnCtxt, sp: Span, base_ty: ty::t,
|
||||
}
|
||||
|
||||
// We've reached the recursion limit, error gracefully.
|
||||
fcx.tcx().sess.span_err(sp,
|
||||
format!("reached the recursion limit while auto-dereferencing {}",
|
||||
base_ty.repr(fcx.tcx())).as_slice());
|
||||
span_err!(fcx.tcx().sess, sp, E0055,
|
||||
"reached the recursion limit while auto-dereferencing {}",
|
||||
base_ty.repr(fcx.tcx()));
|
||||
(ty::mk_err(), 0, None)
|
||||
}
|
||||
|
||||
@ -1581,11 +1561,11 @@ fn try_overloaded_call(fcx: &FnCtxt,
|
||||
write_call(fcx, call_expression, output_type);
|
||||
|
||||
if !fcx.tcx().sess.features.overloaded_calls.get() {
|
||||
fcx.tcx().sess.span_err(call_expression.span,
|
||||
"overloaded calls are experimental");
|
||||
fcx.tcx().sess.span_note(call_expression.span,
|
||||
"add `#[feature(overloaded_calls)]` to \
|
||||
the crate attributes to enable");
|
||||
span_err!(fcx.tcx().sess, call_expression.span, E0056,
|
||||
"overloaded calls are experimental");
|
||||
span_note!(fcx.tcx().sess, call_expression.span,
|
||||
"add `#[feature(overloaded_calls)]` to \
|
||||
the crate attributes to enable");
|
||||
}
|
||||
|
||||
return true
|
||||
@ -1783,14 +1763,12 @@ fn check_argument_types(fcx: &FnCtxt,
|
||||
match ty::get(tuple_type).sty {
|
||||
ty::ty_tup(ref arg_types) => {
|
||||
if arg_types.len() != args.len() {
|
||||
let msg = format!(
|
||||
"this function takes {} parameter{} \
|
||||
but {} parameter{} supplied",
|
||||
arg_types.len(),
|
||||
if arg_types.len() == 1 {""} else {"s"},
|
||||
args.len(),
|
||||
if args.len() == 1 {" was"} else {"s were"});
|
||||
tcx.sess.span_err(sp, msg.as_slice());
|
||||
span_err!(tcx.sess, sp, E0057,
|
||||
"this function takes {} parameter{} but {} parameter{} supplied",
|
||||
arg_types.len(),
|
||||
if arg_types.len() == 1 {""} else {"s"},
|
||||
args.len(),
|
||||
if args.len() == 1 {" was"} else {"s were"});
|
||||
err_args(args.len())
|
||||
} else {
|
||||
(*arg_types).clone()
|
||||
@ -1798,21 +1776,17 @@ fn check_argument_types(fcx: &FnCtxt,
|
||||
}
|
||||
ty::ty_nil => {
|
||||
if args.len() != 0 {
|
||||
let msg = format!(
|
||||
"this function takes 0 parameters \
|
||||
but {} parameter{} supplied",
|
||||
args.len(),
|
||||
if args.len() == 1 {" was"} else {"s were"});
|
||||
tcx.sess.span_err(sp, msg.as_slice());
|
||||
span_err!(tcx.sess, sp, E0058,
|
||||
"this function takes 0 parameters but {} parameter{} supplied",
|
||||
args.len(),
|
||||
if args.len() == 1 {" was"} else {"s were"});
|
||||
}
|
||||
Vec::new()
|
||||
}
|
||||
_ => {
|
||||
tcx.sess
|
||||
.span_err(sp,
|
||||
"cannot use call notation; the first type \
|
||||
parameter for the function trait is neither a \
|
||||
tuple nor unit");
|
||||
span_err!(tcx.sess, sp, E0059,
|
||||
"cannot use call notation; the first type parameter \
|
||||
for the function trait is neither a tuple nor unit");
|
||||
err_args(supplied_arg_count)
|
||||
}
|
||||
}
|
||||
@ -1822,29 +1796,22 @@ fn check_argument_types(fcx: &FnCtxt,
|
||||
if supplied_arg_count >= expected_arg_count {
|
||||
fn_inputs.iter().map(|a| *a).collect()
|
||||
} else {
|
||||
let msg = format!(
|
||||
span_err!(tcx.sess, sp, E0060,
|
||||
"this function takes at least {} parameter{} \
|
||||
but {} parameter{} supplied",
|
||||
expected_arg_count,
|
||||
if expected_arg_count == 1 {""} else {"s"},
|
||||
supplied_arg_count,
|
||||
if supplied_arg_count == 1 {" was"} else {"s were"});
|
||||
|
||||
tcx.sess.span_err(sp, msg.as_slice());
|
||||
|
||||
expected_arg_count,
|
||||
if expected_arg_count == 1 {""} else {"s"},
|
||||
supplied_arg_count,
|
||||
if supplied_arg_count == 1 {" was"} else {"s were"});
|
||||
err_args(supplied_arg_count)
|
||||
}
|
||||
} else {
|
||||
let msg = format!(
|
||||
"this function takes {} parameter{} \
|
||||
but {} parameter{} supplied",
|
||||
expected_arg_count,
|
||||
if expected_arg_count == 1 {""} else {"s"},
|
||||
supplied_arg_count,
|
||||
if supplied_arg_count == 1 {" was"} else {"s were"});
|
||||
|
||||
tcx.sess.span_err(sp, msg.as_slice());
|
||||
|
||||
span_err!(tcx.sess, sp, E0061,
|
||||
"this function takes {} parameter{} but {} parameter{} supplied",
|
||||
expected_arg_count,
|
||||
if expected_arg_count == 1 {""} else {"s"},
|
||||
supplied_arg_count,
|
||||
if supplied_arg_count == 1 {" was"} else {"s were"});
|
||||
err_args(supplied_arg_count)
|
||||
};
|
||||
|
||||
@ -2730,11 +2697,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
error_happened = true;
|
||||
}
|
||||
Some((_, true)) => {
|
||||
tcx.sess.span_err(
|
||||
field.ident.span,
|
||||
format!("field `{}` specified more than once",
|
||||
token::get_ident(field.ident
|
||||
.node)).as_slice());
|
||||
span_err!(fcx.tcx().sess, field.ident.span, E0062,
|
||||
"field `{}` specified more than once",
|
||||
token::get_ident(field.ident.node));
|
||||
error_happened = true;
|
||||
}
|
||||
Some((field_id, false)) => {
|
||||
@ -2772,11 +2737,10 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
}
|
||||
}
|
||||
|
||||
tcx.sess.span_err(span,
|
||||
format!(
|
||||
"missing field{}: {fields}",
|
||||
if missing_fields.len() == 1 {""} else {"s"},
|
||||
fields = missing_fields.connect(", ")).as_slice());
|
||||
span_err!(tcx.sess, span, E0063,
|
||||
"missing field{}: {}",
|
||||
if missing_fields.len() == 1 {""} else {"s"},
|
||||
missing_fields.connect(", "));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2938,12 +2902,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
}
|
||||
}
|
||||
ast::ExprLit(_) => {
|
||||
let error = if vst == ast::ExprVstoreSlice {
|
||||
"`&\"string\"` has been removed; use `\"string\"` instead"
|
||||
if vst == ast::ExprVstoreSlice {
|
||||
span_err!(tcx.sess, expr.span, E0064,
|
||||
"`&\"string\"` has been removed; use `\"string\"` instead");
|
||||
} else {
|
||||
"`box \"string\"` has been removed; use `\"string\".to_string()` instead"
|
||||
};
|
||||
tcx.sess.span_err(expr.span, error);
|
||||
span_err!(tcx.sess, expr.span, E0065,
|
||||
"`box \"string\"` has been removed; use \
|
||||
`\"string\".to_string()` instead");
|
||||
}
|
||||
ty::mk_err()
|
||||
}
|
||||
_ => tcx.sess.span_bug(expr.span, "vstore modifier on non-sequence"),
|
||||
@ -2977,9 +2943,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
}
|
||||
|
||||
if !checked {
|
||||
tcx.sess.span_err(expr.span,
|
||||
"only the managed heap and exchange heap are \
|
||||
currently supported");
|
||||
span_err!(tcx.sess, expr.span, E0066,
|
||||
"only the managed heap and exchange heap are currently supported");
|
||||
fcx.write_ty(id, ty::mk_err());
|
||||
}
|
||||
}
|
||||
@ -3011,7 +2976,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
|
||||
let tcx = fcx.tcx();
|
||||
if !ty::expr_is_lval(tcx, &**lhs) {
|
||||
tcx.sess.span_err(lhs.span, "illegal left-hand side expression");
|
||||
span_err!(tcx.sess, lhs.span, E0067, "illegal left-hand side expression");
|
||||
}
|
||||
|
||||
// Overwrite result of check_binop...this preserves existing behavior
|
||||
@ -3077,7 +3042,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
};
|
||||
if is_newtype {
|
||||
// This is an obsolete struct deref
|
||||
tcx.sess.span_err(expr.span,
|
||||
span_err!(tcx.sess, expr.span, E0068,
|
||||
"single-field tuple-structs can \
|
||||
no longer be dereferenced");
|
||||
} else {
|
||||
@ -3181,8 +3146,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
ret_ty, ty::mk_nil()) {
|
||||
Ok(_) => { /* fall through */ }
|
||||
Err(_) => {
|
||||
tcx.sess.span_err(
|
||||
expr.span,
|
||||
span_err!(tcx.sess, expr.span, E0069,
|
||||
"`return;` in function returning non-nil");
|
||||
}
|
||||
},
|
||||
@ -3201,7 +3165,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
|
||||
let tcx = fcx.tcx();
|
||||
if !ty::expr_is_lval(tcx, &**lhs) {
|
||||
tcx.sess.span_err(lhs.span, "illegal left-hand side expression");
|
||||
span_err!(tcx.sess, expr.span, E0070,
|
||||
"illegal left-hand side expression");
|
||||
}
|
||||
|
||||
let lhs_ty = fcx.expr_ty(&**lhs);
|
||||
@ -3390,11 +3355,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
base_expr);
|
||||
}
|
||||
_ => {
|
||||
tcx.sess
|
||||
.span_err(path.span,
|
||||
format!("`{}` does not name a structure",
|
||||
pprust::path_to_string(
|
||||
path)).as_slice())
|
||||
span_err!(tcx.sess, path.span, E0071,
|
||||
"`{}` does not name a structure",
|
||||
pprust::path_to_string(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3766,10 +3729,10 @@ pub fn check_representable(tcx: &ty::ctxt,
|
||||
// caught by case 1.
|
||||
match ty::is_type_representable(tcx, sp, rty) {
|
||||
ty::SelfRecursive => {
|
||||
tcx.sess.span_err(
|
||||
sp, format!("illegal recursive {} type; \
|
||||
wrap the inner value in a box to make it representable",
|
||||
designation).as_slice());
|
||||
span_err!(tcx.sess, sp, E0072,
|
||||
"illegal recursive {} type; \
|
||||
wrap the inner value in a box to make it representable",
|
||||
designation);
|
||||
return false
|
||||
}
|
||||
ty::Representable | ty::ContainsRecursive => (),
|
||||
@ -3794,12 +3757,10 @@ pub fn check_instantiable(tcx: &ty::ctxt,
|
||||
-> bool {
|
||||
let item_ty = ty::node_id_to_type(tcx, item_id);
|
||||
if !ty::is_instantiable(tcx, item_ty) {
|
||||
tcx.sess
|
||||
.span_err(sp,
|
||||
format!("this type cannot be instantiated without an \
|
||||
instance of itself; consider using \
|
||||
`Option<{}>`",
|
||||
ppaux::ty_to_string(tcx, item_ty)).as_slice());
|
||||
span_err!(tcx.sess, sp, E0073,
|
||||
"this type cannot be instantiated without an \
|
||||
instance of itself; consider using `Option<{}>`",
|
||||
ppaux::ty_to_string(tcx, item_ty));
|
||||
false
|
||||
} else {
|
||||
true
|
||||
@ -3809,25 +3770,25 @@ pub fn check_instantiable(tcx: &ty::ctxt,
|
||||
pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
|
||||
let t = ty::node_id_to_type(tcx, id);
|
||||
if ty::type_needs_subst(t) {
|
||||
tcx.sess.span_err(sp, "SIMD vector cannot be generic");
|
||||
span_err!(tcx.sess, sp, E0074, "SIMD vector cannot be generic");
|
||||
return;
|
||||
}
|
||||
match ty::get(t).sty {
|
||||
ty::ty_struct(did, ref substs) => {
|
||||
let fields = ty::lookup_struct_fields(tcx, did);
|
||||
if fields.is_empty() {
|
||||
tcx.sess.span_err(sp, "SIMD vector cannot be empty");
|
||||
span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
|
||||
return;
|
||||
}
|
||||
let e = ty::lookup_field_type(tcx, did, fields.get(0).id, substs);
|
||||
if !fields.iter().all(
|
||||
|f| ty::lookup_field_type(tcx, did, f.id, substs) == e) {
|
||||
tcx.sess.span_err(sp, "SIMD vector should be homogeneous");
|
||||
span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
|
||||
return;
|
||||
}
|
||||
if !ty::type_is_machine(e) {
|
||||
tcx.sess.span_err(sp, "SIMD vector element type should be \
|
||||
machine type");
|
||||
span_err!(tcx.sess, sp, E0077,
|
||||
"SIMD vector element type should be machine type");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -3852,16 +3813,10 @@ pub fn check_enum_variants_sized(ccx: &CrateCtxt,
|
||||
// A struct value with an unsized final field is itself
|
||||
// unsized and we must track this in the type system.
|
||||
if !ty::type_is_sized(ccx.tcx, *t) {
|
||||
ccx.tcx
|
||||
.sess
|
||||
.span_err(
|
||||
args.get(i).ty.span,
|
||||
format!("type `{}` is dynamically sized. \
|
||||
dynamically sized types may only \
|
||||
appear as the final type in a \
|
||||
variant",
|
||||
ppaux::ty_to_string(ccx.tcx,
|
||||
*t)).as_slice());
|
||||
span_err!(ccx.tcx.sess, args.get(i).ty.span, E0078,
|
||||
"type `{}` is dynamically sized. dynamically sized types may only \
|
||||
appear as the final type in a variant",
|
||||
ppaux::ty_to_string(ccx.tcx, *t));
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3947,14 +3902,12 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
|
||||
Ok(const_eval::const_int(val)) => current_disr_val = val as Disr,
|
||||
Ok(const_eval::const_uint(val)) => current_disr_val = val as Disr,
|
||||
Ok(_) => {
|
||||
ccx.tcx.sess.span_err(e.span, "expected signed integer constant");
|
||||
span_err!(ccx.tcx.sess, e.span, E0079,
|
||||
"expected signed integer constant");
|
||||
}
|
||||
Err(ref err) => {
|
||||
ccx.tcx
|
||||
.sess
|
||||
.span_err(e.span,
|
||||
format!("expected constant: {}",
|
||||
*err).as_slice());
|
||||
span_err!(ccx.tcx.sess, e.span, E0080,
|
||||
"expected constant: {}", *err);
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3963,16 +3916,18 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
|
||||
|
||||
// Check for duplicate discriminant values
|
||||
if disr_vals.contains(¤t_disr_val) {
|
||||
ccx.tcx.sess.span_err(v.span, "discriminant value already exists");
|
||||
span_err!(ccx.tcx.sess, v.span, E0081,
|
||||
"discriminant value already exists");
|
||||
}
|
||||
// Check for unrepresentable discriminant values
|
||||
match hint {
|
||||
attr::ReprAny | attr::ReprExtern => (),
|
||||
attr::ReprInt(sp, ity) => {
|
||||
if !disr_in_range(ccx, ity, current_disr_val) {
|
||||
ccx.tcx.sess.span_err(v.span,
|
||||
"discriminant value outside specified type");
|
||||
ccx.tcx.sess.span_note(sp, "discriminant type specified here");
|
||||
span_err!(ccx.tcx.sess, v.span, E0082,
|
||||
"discriminant value outside specified type");
|
||||
span_note!(ccx.tcx.sess, sp,
|
||||
"discriminant type specified here");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3990,12 +3945,13 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
|
||||
|
||||
let hint = ty::lookup_repr_hint(ccx.tcx, ast::DefId { krate: ast::LOCAL_CRATE, node: id });
|
||||
if hint != attr::ReprAny && vs.len() <= 1 {
|
||||
let msg = if vs.len() == 1 {
|
||||
"unsupported representation for univariant enum"
|
||||
if vs.len() == 1 {
|
||||
span_err!(ccx.tcx.sess, sp, E0083,
|
||||
"unsupported representation for univariant enum");
|
||||
} else {
|
||||
"unsupported representation for zero-variant enum"
|
||||
span_err!(ccx.tcx.sess, sp, E0084,
|
||||
"unsupported representation for zero-variant enum");
|
||||
};
|
||||
ccx.tcx.sess.span_err(sp, msg)
|
||||
}
|
||||
|
||||
let variants = do_check(ccx, vs, id, hint);
|
||||
@ -4241,15 +4197,13 @@ pub fn instantiate_path(fcx: &FnCtxt,
|
||||
segment: &ast::PathSegment)
|
||||
{
|
||||
for typ in segment.types.iter() {
|
||||
fcx.tcx().sess.span_err(
|
||||
typ.span,
|
||||
span_err!(fcx.tcx().sess, typ.span, E0085,
|
||||
"type parameters may not appear here");
|
||||
break;
|
||||
}
|
||||
|
||||
for lifetime in segment.lifetimes.iter() {
|
||||
fcx.tcx().sess.span_err(
|
||||
lifetime.span,
|
||||
span_err!(fcx.tcx().sess, lifetime.span, E0086,
|
||||
"lifetime parameters may not appear here");
|
||||
break;
|
||||
}
|
||||
@ -4288,14 +4242,11 @@ pub fn instantiate_path(fcx: &FnCtxt,
|
||||
if i < type_count {
|
||||
substs.types.push(space, t);
|
||||
} else if i == type_count {
|
||||
fcx.tcx().sess.span_err(
|
||||
typ.span,
|
||||
format!(
|
||||
"too many type parameters provided: \
|
||||
expected at most {} parameter(s) \
|
||||
but found {} parameter(s)",
|
||||
type_count,
|
||||
segment.types.len()).as_slice());
|
||||
span_err!(fcx.tcx().sess, typ.span, E0087,
|
||||
"too many type parameters provided: \
|
||||
expected at most {} parameter(s) \
|
||||
but found {} parameter(s)",
|
||||
type_count, segment.types.len());
|
||||
substs.types.truncate(space, 0);
|
||||
}
|
||||
}
|
||||
@ -4309,13 +4260,11 @@ pub fn instantiate_path(fcx: &FnCtxt,
|
||||
if i < region_count {
|
||||
substs.mut_regions().push(space, r);
|
||||
} else if i == region_count {
|
||||
fcx.tcx().sess.span_err(
|
||||
lifetime.span,
|
||||
format!(
|
||||
"too many lifetime parameters provided: \
|
||||
expected {} parameter(s) but found {} parameter(s)",
|
||||
region_count,
|
||||
segment.lifetimes.len()).as_slice());
|
||||
span_err!(fcx.tcx().sess, lifetime.span, E0088,
|
||||
"too many lifetime parameters provided: \
|
||||
expected {} parameter(s) but found {} parameter(s)",
|
||||
region_count,
|
||||
segment.lifetimes.len());
|
||||
substs.mut_regions().truncate(space, 0);
|
||||
}
|
||||
}
|
||||
@ -4360,14 +4309,10 @@ pub fn instantiate_path(fcx: &FnCtxt,
|
||||
if provided_len < required_len {
|
||||
let qualifier =
|
||||
if desired.len() != required_len { "at least " } else { "" };
|
||||
fcx.tcx().sess.span_err(
|
||||
span,
|
||||
format!("too few type parameters provided: \
|
||||
expected {}{} parameter(s) \
|
||||
but found {} parameter(s)",
|
||||
qualifier,
|
||||
required_len,
|
||||
provided_len).as_slice());
|
||||
span_err!(fcx.tcx().sess, span, E0089,
|
||||
"too few type parameters provided: expected {}{} parameter(s) \
|
||||
but found {} parameter(s)",
|
||||
qualifier, required_len, provided_len);
|
||||
substs.types.replace(space,
|
||||
Vec::from_elem(desired.len(), ty::mk_err()));
|
||||
return;
|
||||
@ -4418,14 +4363,10 @@ pub fn instantiate_path(fcx: &FnCtxt,
|
||||
|
||||
// Otherwise, too few were provided. Report an error and then
|
||||
// use inference variables.
|
||||
fcx.tcx().sess.span_err(
|
||||
span,
|
||||
format!(
|
||||
"too few lifetime parameters provided: \
|
||||
expected {} parameter(s) \
|
||||
but found {} parameter(s)",
|
||||
desired.len(),
|
||||
provided_len).as_slice());
|
||||
span_err!(fcx.tcx().sess, span, E0090,
|
||||
"too few lifetime parameters provided: expected {} parameter(s) \
|
||||
but found {} parameter(s)",
|
||||
desired.len(), provided_len);
|
||||
|
||||
substs.mut_regions().replace(
|
||||
space,
|
||||
@ -4547,10 +4488,9 @@ pub fn check_bounds_are_used(ccx: &CrateCtxt,
|
||||
|
||||
for (i, b) in tps_used.iter().enumerate() {
|
||||
if !*b {
|
||||
ccx.tcx.sess.span_err(
|
||||
span,
|
||||
format!("type parameter `{}` is unused",
|
||||
token::get_ident(tps.get(i).ident)).as_slice());
|
||||
span_err!(ccx.tcx.sess, span, E0091,
|
||||
"type parameter `{}` is unused",
|
||||
token::get_ident(tps.get(i).ident));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4586,10 +4526,8 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
|
||||
(0, Vec::new(), ty::mk_nil())
|
||||
}
|
||||
op => {
|
||||
tcx.sess.span_err(it.span,
|
||||
format!("unrecognized atomic operation \
|
||||
function: `{}`",
|
||||
op).as_slice());
|
||||
span_err!(tcx.sess, it.span, E0092,
|
||||
"unrecognized atomic operation function: `{}`", op);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -4813,9 +4751,8 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
|
||||
ty::mk_tup(tcx, vec!(ty::mk_u64(), ty::mk_bool()))),
|
||||
|
||||
ref other => {
|
||||
tcx.sess.span_err(it.span,
|
||||
format!("unrecognized intrinsic function: `{}`",
|
||||
*other).as_slice());
|
||||
span_err!(tcx.sess, it.span, E0093,
|
||||
"unrecognized intrinsic function: `{}`", *other);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -4833,11 +4770,10 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
|
||||
let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id));
|
||||
let i_n_tps = i_ty.generics.types.len(subst::FnSpace);
|
||||
if i_n_tps != n_tps {
|
||||
tcx.sess.span_err(it.span,
|
||||
format!("intrinsic has wrong number of type \
|
||||
parameters: found {}, expected {}",
|
||||
i_n_tps,
|
||||
n_tps).as_slice());
|
||||
span_err!(tcx.sess, it.span, E0094,
|
||||
"intrinsic has wrong number of type \
|
||||
parameters: found {}, expected {}",
|
||||
i_n_tps, n_tps);
|
||||
} else {
|
||||
require_same_types(tcx,
|
||||
None,
|
||||
|
@ -98,6 +98,9 @@ impl SpanHandler {
|
||||
pub fn span_warn(&self, sp: Span, msg: &str) {
|
||||
self.handler.emit(Some((&self.cm, sp)), msg, Warning);
|
||||
}
|
||||
pub fn span_warn_with_code(&self, sp: Span, msg: &str, code: &str) {
|
||||
self.handler.emit_with_code(Some((&self.cm, sp)), msg, code, Warning);
|
||||
}
|
||||
pub fn span_note(&self, sp: Span, msg: &str) {
|
||||
self.handler.emit(Some((&self.cm, sp)), msg, Note);
|
||||
}
|
||||
|
@ -49,3 +49,25 @@ macro_rules! span_err(
|
||||
($session).span_err_with_code($span, format!($($arg),*).as_slice(), stringify!($code))
|
||||
})
|
||||
)
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! span_warn(
|
||||
($session:expr, $span:expr, $code:ident, $($arg:expr),*) => ({
|
||||
__diagnostic_used!($code);
|
||||
($session).span_warn_with_code($span, format!($($arg),*).as_slice(), stringify!($code))
|
||||
})
|
||||
)
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! span_note(
|
||||
($session:expr, $span:expr, $($arg:expr),*) => ({
|
||||
($session).span_note($span, format!($($arg),*).as_slice())
|
||||
})
|
||||
)
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! register_diagnostics(
|
||||
($($code:tt),*) => (
|
||||
$(register_diagnostic!($code))*
|
||||
)
|
||||
)
|
||||
|
@ -54,7 +54,8 @@ pub fn expand_diagnostic_used(ecx: &mut ExtCtxt, span: Span,
|
||||
with_registered_diagnostics(|diagnostics| {
|
||||
if !diagnostics.contains_key(&code.name) {
|
||||
ecx.span_err(span, format!(
|
||||
"unknown diagnostic code {}", token::get_ident(code).get()
|
||||
"unknown diagnostic code {}; add to librustc/diagnostics.rs",
|
||||
token::get_ident(code).get()
|
||||
).as_slice());
|
||||
}
|
||||
()
|
||||
|
Loading…
Reference in New Issue
Block a user