Refactoring
This commit is contained in:
parent
95dc7efad0
commit
aaa02b3ff9
13 changed files with 238 additions and 226 deletions
|
@ -368,7 +368,7 @@ pub fn raw_emit_lint(sess: &Session,
|
||||||
lvlsrc: LevelSource,
|
lvlsrc: LevelSource,
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
msg: &str) {
|
msg: &str) {
|
||||||
raw_struct_lint(sess, lint, lvlsrc, span, msg).map(|mut e| e.emit());
|
raw_struct_lint(sess, lint, lvlsrc, span, msg).emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn raw_struct_lint<'a>(sess: &'a Session,
|
pub fn raw_struct_lint<'a>(sess: &'a Session,
|
||||||
|
@ -376,10 +376,10 @@ pub fn raw_struct_lint<'a>(sess: &'a Session,
|
||||||
lvlsrc: LevelSource,
|
lvlsrc: LevelSource,
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
msg: &str)
|
msg: &str)
|
||||||
-> Option<DiagnosticBuilder<'a>> {
|
-> DiagnosticBuilder<'a> {
|
||||||
let (mut level, source) = lvlsrc;
|
let (mut level, source) = lvlsrc;
|
||||||
if level == Allow {
|
if level == Allow {
|
||||||
return None;
|
return sess.diagnostic().struct_dummy();
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = lint.name_lower();
|
let name = lint.name_lower();
|
||||||
|
@ -416,7 +416,8 @@ pub fn raw_struct_lint<'a>(sess: &'a Session,
|
||||||
if let Some(span) = def {
|
if let Some(span) = def {
|
||||||
err.span_note(span, "lint level defined here");
|
err.span_note(span, "lint level defined here");
|
||||||
}
|
}
|
||||||
Some(err)
|
|
||||||
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait LintContext: Sized {
|
pub trait LintContext: Sized {
|
||||||
|
@ -456,9 +457,9 @@ pub trait LintContext: Sized {
|
||||||
lint: &'static Lint,
|
lint: &'static Lint,
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
msg: &str)
|
msg: &str)
|
||||||
-> Option<DiagnosticBuilder> {
|
-> DiagnosticBuilder {
|
||||||
let (level, src) = match self.level_src(lint) {
|
let (level, src) = match self.level_src(lint) {
|
||||||
None => return None,
|
None => return self.sess().diagnostic().struct_dummy(),
|
||||||
Some(pair) => pair,
|
Some(pair) => pair,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -474,17 +475,14 @@ pub trait LintContext: Sized {
|
||||||
lint: &'static Lint,
|
lint: &'static Lint,
|
||||||
span: Span,
|
span: Span,
|
||||||
msg: &str)
|
msg: &str)
|
||||||
-> Option<DiagnosticBuilder> {
|
-> DiagnosticBuilder {
|
||||||
self.lookup(lint, Some(span), msg)
|
self.lookup(lint, Some(span), msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emit a lint and note at the appropriate level, for a particular span.
|
/// Emit a lint and note at the appropriate level, for a particular span.
|
||||||
fn span_lint_note(&self, lint: &'static Lint, span: Span, msg: &str,
|
fn span_lint_note(&self, lint: &'static Lint, span: Span, msg: &str,
|
||||||
note_span: Span, note: &str) {
|
note_span: Span, note: &str) {
|
||||||
let mut err = match self.lookup(lint, Some(span), msg) {
|
let mut err = self.lookup(lint, Some(span), msg);
|
||||||
Some(e) => e,
|
|
||||||
None => return
|
|
||||||
};
|
|
||||||
if self.current_level(lint) != Level::Allow {
|
if self.current_level(lint) != Level::Allow {
|
||||||
if note_span == span {
|
if note_span == span {
|
||||||
err.fileline_note(note_span, note);
|
err.fileline_note(note_span, note);
|
||||||
|
@ -498,10 +496,7 @@ pub trait LintContext: Sized {
|
||||||
/// Emit a lint and help at the appropriate level, for a particular span.
|
/// Emit a lint and help at the appropriate level, for a particular span.
|
||||||
fn span_lint_help(&self, lint: &'static Lint, span: Span,
|
fn span_lint_help(&self, lint: &'static Lint, span: Span,
|
||||||
msg: &str, help: &str) {
|
msg: &str, help: &str) {
|
||||||
let mut err = match self.lookup(lint, Some(span), msg) {
|
let mut err = self.lookup(lint, Some(span), msg);
|
||||||
Some(e) => e,
|
|
||||||
None => return
|
|
||||||
};
|
|
||||||
self.span_lint(lint, span, msg);
|
self.span_lint(lint, span, msg);
|
||||||
if self.current_level(lint) != Level::Allow {
|
if self.current_level(lint) != Level::Allow {
|
||||||
err.span_help(span, help);
|
err.span_help(span, help);
|
||||||
|
|
|
@ -237,7 +237,7 @@ pub trait ErrorReporting<'tcx> {
|
||||||
fn report_type_error(&self,
|
fn report_type_error(&self,
|
||||||
trace: TypeTrace<'tcx>,
|
trace: TypeTrace<'tcx>,
|
||||||
terr: &TypeError<'tcx>)
|
terr: &TypeError<'tcx>)
|
||||||
-> Option<DiagnosticBuilder<'tcx>>;
|
-> DiagnosticBuilder<'tcx>;
|
||||||
|
|
||||||
fn check_and_note_conflicting_crates(&self,
|
fn check_and_note_conflicting_crates(&self,
|
||||||
err: &mut DiagnosticBuilder,
|
err: &mut DiagnosticBuilder,
|
||||||
|
@ -478,11 +478,11 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
fn report_type_error(&self,
|
fn report_type_error(&self,
|
||||||
trace: TypeTrace<'tcx>,
|
trace: TypeTrace<'tcx>,
|
||||||
terr: &TypeError<'tcx>)
|
terr: &TypeError<'tcx>)
|
||||||
-> Option<DiagnosticBuilder<'tcx>> {
|
-> DiagnosticBuilder<'tcx> {
|
||||||
let expected_found_str = match self.values_str(&trace.values) {
|
let expected_found_str = match self.values_str(&trace.values) {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => {
|
None => {
|
||||||
return None; /* derived error */
|
return self.tcx.sess.diagnostic().struct_dummy(); /* derived error */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -507,7 +507,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
Some(err)
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a note if the types come from similarly named crates
|
/// Adds a note if the types come from similarly named crates
|
||||||
|
@ -560,11 +560,9 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
trace: TypeTrace<'tcx>,
|
trace: TypeTrace<'tcx>,
|
||||||
terr: &TypeError<'tcx>) {
|
terr: &TypeError<'tcx>) {
|
||||||
let span = trace.origin.span();
|
let span = trace.origin.span();
|
||||||
let err = self.report_type_error(trace, terr);
|
let mut err = self.report_type_error(trace, terr);
|
||||||
err.map(|mut err| {
|
|
||||||
self.tcx.note_and_explain_type_err(&mut err, terr, span);
|
self.tcx.note_and_explain_type_err(&mut err, terr, span);
|
||||||
err.emit();
|
err.emit();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a string of the form "expected `{}`, found `{}`", or None if this is a derived
|
/// Returns a string of the form "expected `{}`, found `{}`", or None if this is a derived
|
||||||
|
|
|
@ -1281,7 +1281,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
mk_msg: M,
|
mk_msg: M,
|
||||||
actual_ty: String,
|
actual_ty: String,
|
||||||
err: Option<&TypeError<'tcx>>)
|
err: Option<&TypeError<'tcx>>)
|
||||||
-> Option<DiagnosticBuilder<'tcx>>
|
-> DiagnosticBuilder<'tcx>
|
||||||
where M: FnOnce(Option<String>, String) -> String,
|
where M: FnOnce(Option<String>, String) -> String,
|
||||||
{
|
{
|
||||||
self.type_error_struct_str_with_expected(sp, mk_msg, None, actual_ty, err)
|
self.type_error_struct_str_with_expected(sp, mk_msg, None, actual_ty, err)
|
||||||
|
@ -1296,7 +1296,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
where M: FnOnce(Option<String>, String) -> String,
|
where M: FnOnce(Option<String>, String) -> String,
|
||||||
{
|
{
|
||||||
self.type_error_struct_str_with_expected(sp, mk_msg, expected_ty, actual_ty, err)
|
self.type_error_struct_str_with_expected(sp, mk_msg, expected_ty, actual_ty, err)
|
||||||
.map(|mut e| e.emit());
|
.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_error_struct_str_with_expected<M>(&self,
|
pub fn type_error_struct_str_with_expected<M>(&self,
|
||||||
|
@ -1305,7 +1305,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
expected_ty: Option<Ty<'tcx>>,
|
expected_ty: Option<Ty<'tcx>>,
|
||||||
actual_ty: String,
|
actual_ty: String,
|
||||||
err: Option<&TypeError<'tcx>>)
|
err: Option<&TypeError<'tcx>>)
|
||||||
-> Option<DiagnosticBuilder<'tcx>>
|
-> DiagnosticBuilder<'tcx>
|
||||||
where M: FnOnce(Option<String>, String) -> String,
|
where M: FnOnce(Option<String>, String) -> String,
|
||||||
{
|
{
|
||||||
debug!("hi! expected_ty = {:?}, actual_ty = {}", expected_ty, actual_ty);
|
debug!("hi! expected_ty = {:?}, actual_ty = {}", expected_ty, actual_ty);
|
||||||
|
@ -1324,9 +1324,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
if let Some(err) = err {
|
if let Some(err) = err {
|
||||||
self.tcx.note_and_explain_type_err(&mut db, err, sp);
|
self.tcx.note_and_explain_type_err(&mut db, err, sp);
|
||||||
}
|
}
|
||||||
Some(db)
|
db
|
||||||
} else {
|
} else {
|
||||||
None
|
self.tcx.sess.diagnostic().struct_dummy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1337,7 +1337,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
err: Option<&TypeError<'tcx>>)
|
err: Option<&TypeError<'tcx>>)
|
||||||
where M: FnOnce(String) -> String,
|
where M: FnOnce(String) -> String,
|
||||||
{
|
{
|
||||||
self.type_error_struct(sp, mk_msg, actual_ty, err).map(|mut e| e.emit());
|
self.type_error_struct(sp, mk_msg, actual_ty, err).emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_error_struct<M>(&self,
|
pub fn type_error_struct<M>(&self,
|
||||||
|
@ -1345,14 +1345,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
mk_msg: M,
|
mk_msg: M,
|
||||||
actual_ty: Ty<'tcx>,
|
actual_ty: Ty<'tcx>,
|
||||||
err: Option<&TypeError<'tcx>>)
|
err: Option<&TypeError<'tcx>>)
|
||||||
-> Option<DiagnosticBuilder<'tcx>>
|
-> DiagnosticBuilder<'tcx>
|
||||||
where M: FnOnce(String) -> String,
|
where M: FnOnce(String) -> String,
|
||||||
{
|
{
|
||||||
let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
|
let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
|
||||||
|
|
||||||
// Don't report an error if actual type is TyError.
|
// Don't report an error if actual type is TyError.
|
||||||
if actual_ty.references_error() {
|
if actual_ty.references_error() {
|
||||||
return None;
|
return self.tcx.sess.diagnostic().struct_dummy();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.type_error_struct_str(sp,
|
self.type_error_struct_str(sp,
|
||||||
|
|
|
@ -60,7 +60,7 @@ struct ExpectErrorEmitter {
|
||||||
fn remove_message(e: &mut ExpectErrorEmitter, msg: &str, lvl: Level) {
|
fn remove_message(e: &mut ExpectErrorEmitter, msg: &str, lvl: Level) {
|
||||||
match lvl {
|
match lvl {
|
||||||
Level::Bug | Level::Fatal | Level::Error => {}
|
Level::Bug | Level::Fatal | Level::Error => {}
|
||||||
Level::Warning | Level::Note | Level::Help => {
|
_ => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -754,18 +754,17 @@ impl LateLintPass for UnconditionalRecursion {
|
||||||
if !reached_exit_without_self_call && !self_call_spans.is_empty() {
|
if !reached_exit_without_self_call && !self_call_spans.is_empty() {
|
||||||
let mut db = cx.struct_span_lint(UNCONDITIONAL_RECURSION, sp,
|
let mut db = cx.struct_span_lint(UNCONDITIONAL_RECURSION, sp,
|
||||||
"function cannot return without recurring");
|
"function cannot return without recurring");
|
||||||
let mut db = db.as_mut();
|
|
||||||
|
|
||||||
// FIXME #19668: these could be span_lint_note's instead of this manual guard.
|
// FIXME #19668: these could be span_lint_note's instead of this manual guard.
|
||||||
if cx.current_level(UNCONDITIONAL_RECURSION) != Level::Allow {
|
if cx.current_level(UNCONDITIONAL_RECURSION) != Level::Allow {
|
||||||
// offer some help to the programmer.
|
// offer some help to the programmer.
|
||||||
for call in &self_call_spans {
|
for call in &self_call_spans {
|
||||||
db = db.map(|db| db.span_note(*call, "recursive call site"));
|
db.span_note(*call, "recursive call site");
|
||||||
}
|
}
|
||||||
db = db.map(|db| db.fileline_help(sp, "a `loop` may express intention \
|
db.fileline_help(sp, "a `loop` may express intention \
|
||||||
better if this is on purpose"));
|
better if this is on purpose");
|
||||||
}
|
}
|
||||||
db.map(|db| db.emit());
|
db.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// all done
|
// all done
|
||||||
|
|
|
@ -144,9 +144,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||||
|
|
||||||
if let Some(sp) = child[ns].span() {
|
if let Some(sp) = child[ns].span() {
|
||||||
let note = format!("first definition of {} `{}` here", ns_str, name);
|
let note = format!("first definition of {} `{}` here", ns_str, name);
|
||||||
err.as_mut().map(|mut e| e.span_note(sp, ¬e));
|
err.span_note(sp, ¬e);
|
||||||
}
|
}
|
||||||
err.as_mut().map(|mut e| e.emit());
|
err.emit();
|
||||||
child
|
child
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,10 +261,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||||
mod_spans[0],
|
mod_spans[0],
|
||||||
ResolutionError::SelfImportCanOnlyAppearOnceInTheList);
|
ResolutionError::SelfImportCanOnlyAppearOnceInTheList);
|
||||||
for other_span in mod_spans.iter().skip(1) {
|
for other_span in mod_spans.iter().skip(1) {
|
||||||
e.as_mut().map(|mut e| e.span_note(*other_span,
|
e.span_note(*other_span, "another `self` import appears here");
|
||||||
"another `self` import appears here"));
|
|
||||||
}
|
}
|
||||||
e.as_mut().map(|mut e| e.emit());
|
e.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
for source_item in source_items {
|
for source_item in source_items {
|
||||||
|
|
|
@ -216,18 +216,18 @@ pub enum UnresolvedNameContext {
|
||||||
fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
|
fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
|
||||||
span: syntax::codemap::Span,
|
span: syntax::codemap::Span,
|
||||||
resolution_error: ResolutionError<'b>) {
|
resolution_error: ResolutionError<'b>) {
|
||||||
resolve_struct_error(resolver, span, resolution_error).map(|mut e| e.emit());
|
resolve_struct_error(resolver, span, resolution_error).emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
|
fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
|
||||||
span: syntax::codemap::Span,
|
span: syntax::codemap::Span,
|
||||||
resolution_error: ResolutionError<'b>)
|
resolution_error: ResolutionError<'b>)
|
||||||
-> Option<DiagnosticBuilder<'a>> {
|
-> DiagnosticBuilder<'a> {
|
||||||
if !resolver.emit_errors {
|
if !resolver.emit_errors {
|
||||||
return None;
|
return resolver.session.diagnostic().struct_dummy();
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(match resolution_error {
|
match resolution_error {
|
||||||
ResolutionError::TypeParametersFromOuterFunction => {
|
ResolutionError::TypeParametersFromOuterFunction => {
|
||||||
struct_span_err!(resolver.session,
|
struct_span_err!(resolver.session,
|
||||||
span,
|
span,
|
||||||
|
@ -532,7 +532,7 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
|
||||||
E0435,
|
E0435,
|
||||||
"attempt to use a non-constant value in a constant")
|
"attempt to use a non-constant value in a constant")
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -2202,10 +2202,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
|
|
||||||
// If it's a typedef, give a note
|
// If it's a typedef, give a note
|
||||||
if let DefTy(..) = path_res.base_def {
|
if let DefTy(..) = path_res.base_def {
|
||||||
err.as_mut().map(|mut e| e.span_note(trait_path.span,
|
err.span_note(trait_path.span,
|
||||||
"`type` aliases cannot be used for traits"));
|
"`type` aliases cannot be used for traits");
|
||||||
}
|
}
|
||||||
err.as_mut().map(|mut e| e.emit());
|
err.emit();
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -3493,11 +3493,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
|
let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
|
||||||
path_name);
|
path_name);
|
||||||
if self.emit_errors {
|
if self.emit_errors {
|
||||||
err.as_mut().map(|mut e| e.fileline_help(expr.span, &msg));
|
err.fileline_help(expr.span, &msg);
|
||||||
} else {
|
} else {
|
||||||
err.as_mut().map(|mut e| e.span_help(expr.span, &msg));
|
err.span_help(expr.span, &msg);
|
||||||
}
|
}
|
||||||
err.as_mut().map(|mut e| e.emit());
|
err.emit();
|
||||||
self.record_def(expr.id, err_path_resolution());
|
self.record_def(expr.id, err_path_resolution());
|
||||||
} else {
|
} else {
|
||||||
// Write the result into the def map.
|
// Write the result into the def map.
|
||||||
|
@ -3534,11 +3534,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
|
let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
|
||||||
path_name);
|
path_name);
|
||||||
if self.emit_errors {
|
if self.emit_errors {
|
||||||
err.as_mut().map(|mut e| e.fileline_help(expr.span, &msg));
|
err.fileline_help(expr.span, &msg);
|
||||||
} else {
|
} else {
|
||||||
err.as_mut().map(|mut e| e.span_help(expr.span, &msg));
|
err.span_help(expr.span, &msg);
|
||||||
}
|
}
|
||||||
err.as_mut().map(|mut e| e.emit());
|
err.emit();
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Keep reporting some errors even if they're ignored above.
|
// Keep reporting some errors even if they're ignored above.
|
||||||
|
|
|
@ -2213,11 +2213,9 @@ fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &hir::EnumDef, sp: Span,
|
||||||
&format!("enum variant is more than three times larger ({} bytes) \
|
&format!("enum variant is more than three times larger ({} bytes) \
|
||||||
than the next largest (ignoring padding)",
|
than the next largest (ignoring padding)",
|
||||||
largest))
|
largest))
|
||||||
.map(|mut e| {
|
.span_note(enum_def.variants[largest_index].span,
|
||||||
e.span_note(enum_def.variants[largest_index].span,
|
|
||||||
"this variant is the largest")
|
"this variant is the largest")
|
||||||
.emit();
|
.emit();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -232,20 +232,19 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
||||||
let mut err = fcx.type_error_struct(call_expr.span, |actual| {
|
let mut err = fcx.type_error_struct(call_expr.span, |actual| {
|
||||||
format!("expected function, found `{}`", actual)
|
format!("expected function, found `{}`", actual)
|
||||||
}, callee_ty, None);
|
}, callee_ty, None);
|
||||||
let mut err = err.as_mut();
|
|
||||||
|
|
||||||
if let hir::ExprCall(ref expr, _) = call_expr.node {
|
if let hir::ExprCall(ref expr, _) = call_expr.node {
|
||||||
let tcx = fcx.tcx();
|
let tcx = fcx.tcx();
|
||||||
if let Some(pr) = tcx.def_map.borrow().get(&expr.id) {
|
if let Some(pr) = tcx.def_map.borrow().get(&expr.id) {
|
||||||
if pr.depth == 0 && pr.base_def != def::DefErr {
|
if pr.depth == 0 && pr.base_def != def::DefErr {
|
||||||
if let Some(span) = tcx.map.span_if_local(pr.def_id()) {
|
if let Some(span) = tcx.map.span_if_local(pr.def_id()) {
|
||||||
err = err.map(|e| e.span_note(span, "defined here"));
|
err.span_note(span, "defined here");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err.map(|e| e.emit());
|
err.emit();
|
||||||
|
|
||||||
// This is the "default" function signature, used in case of error.
|
// This is the "default" function signature, used in case of error.
|
||||||
// In that case, we check each argument against "error" in order to
|
// In that case, we check each argument against "error" in order to
|
||||||
|
|
|
@ -132,17 +132,15 @@ impl<'tcx> CastCheck<'tcx> {
|
||||||
actual,
|
actual,
|
||||||
fcx.infcx().ty_to_string(self.cast_ty))
|
fcx.infcx().ty_to_string(self.cast_ty))
|
||||||
}, self.expr_ty, None)
|
}, self.expr_ty, None)
|
||||||
.map(|mut err| {
|
.fileline_help(self.span,
|
||||||
err.fileline_help(self.span,
|
|
||||||
&format!("cast through {} first", match e {
|
&format!("cast through {} first", match e {
|
||||||
CastError::NeedViaPtr => "a raw pointer",
|
CastError::NeedViaPtr => "a raw pointer",
|
||||||
CastError::NeedViaThinPtr => "a thin pointer",
|
CastError::NeedViaThinPtr => "a thin pointer",
|
||||||
CastError::NeedViaInt => "an integer",
|
CastError::NeedViaInt => "an integer",
|
||||||
CastError::NeedViaUsize => "a usize",
|
CastError::NeedViaUsize => "a usize",
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
}));
|
}))
|
||||||
err.emit();
|
.emit();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
CastError::CastToBool => {
|
CastError::CastToBool => {
|
||||||
struct_span_err!(fcx.tcx().sess, self.span, E0054, "cannot cast as `bool`")
|
struct_span_err!(fcx.tcx().sess, self.span, E0054, "cannot cast as `bool`")
|
||||||
|
@ -174,10 +172,8 @@ impl<'tcx> CastCheck<'tcx> {
|
||||||
actual,
|
actual,
|
||||||
fcx.infcx().ty_to_string(self.cast_ty))
|
fcx.infcx().ty_to_string(self.cast_ty))
|
||||||
}, self.expr_ty, None)
|
}, self.expr_ty, None)
|
||||||
.map(|mut err| {
|
.fileline_note(self.span, "vtable kinds may not match")
|
||||||
err.fileline_note(self.span, "vtable kinds may not match");
|
.emit();
|
||||||
err.emit();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,6 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
rcvr_ty,
|
rcvr_ty,
|
||||||
None);
|
None);
|
||||||
|
|
||||||
if let Some(ref mut err) = err {
|
|
||||||
// If the item has the name of a field, give a help note
|
// If the item has the name of a field, give a help note
|
||||||
if let (&ty::TyStruct(def, substs), Some(expr)) = (&rcvr_ty.sty, rcvr_expr) {
|
if let (&ty::TyStruct(def, substs), Some(expr)) = (&rcvr_ty.sty, rcvr_expr) {
|
||||||
if let Some(field) = def.struct_variant().find_field_named(item_name) {
|
if let Some(field) = def.struct_variant().find_field_named(item_name) {
|
||||||
|
@ -144,7 +143,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
span,
|
span,
|
||||||
"found defined static methods, maybe a `self` is missing?");
|
"found defined static methods, maybe a `self` is missing?");
|
||||||
|
|
||||||
report_candidates(fcx, err, span, item_name, static_sources);
|
report_candidates(fcx, &mut err, span, item_name, static_sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !unsatisfied_predicates.is_empty() {
|
if !unsatisfied_predicates.is_empty() {
|
||||||
|
@ -162,11 +161,10 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
bound_list));
|
bound_list));
|
||||||
}
|
}
|
||||||
|
|
||||||
suggest_traits_to_import(fcx, err, span, rcvr_ty, item_name,
|
suggest_traits_to_import(fcx, &mut err, span, rcvr_ty, item_name,
|
||||||
rcvr_expr, out_of_scope_traits);
|
rcvr_expr, out_of_scope_traits);
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MethodError::Ambiguity(sources) => {
|
MethodError::Ambiguity(sources) => {
|
||||||
let mut err = struct_span_err!(fcx.sess(), span, E0034,
|
let mut err = struct_span_err!(fcx.sess(), span, E0034,
|
||||||
|
|
|
@ -1051,16 +1051,16 @@ fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
if t_cast.is_trait() {
|
if t_cast.is_trait() {
|
||||||
match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
|
match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
err.as_mut().unwrap().span_suggestion(t_span,
|
err.span_suggestion(t_span,
|
||||||
"try casting to a reference instead:",
|
"try casting to a reference instead:",
|
||||||
format!("&{}{}", mtstr, s));
|
format!("&{}{}", mtstr, s));
|
||||||
},
|
},
|
||||||
Err(_) =>
|
Err(_) =>
|
||||||
span_help!(err.as_mut().unwrap(), t_span,
|
span_help!(err, t_span,
|
||||||
"did you mean `&{}{}`?", mtstr, tstr),
|
"did you mean `&{}{}`?", mtstr, tstr),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
span_help!(err.as_mut().unwrap(), span,
|
span_help!(err, span,
|
||||||
"consider using an implicit coercion to `&{}{}` instead",
|
"consider using an implicit coercion to `&{}{}` instead",
|
||||||
mtstr, tstr);
|
mtstr, tstr);
|
||||||
}
|
}
|
||||||
|
@ -1068,20 +1068,20 @@ fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
ty::TyBox(..) => {
|
ty::TyBox(..) => {
|
||||||
match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
|
match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
err.as_mut().unwrap().span_suggestion(t_span,
|
err.span_suggestion(t_span,
|
||||||
"try casting to a `Box` instead:",
|
"try casting to a `Box` instead:",
|
||||||
format!("Box<{}>", s));
|
format!("Box<{}>", s));
|
||||||
},
|
},
|
||||||
Err(_) =>
|
Err(_) =>
|
||||||
span_help!(err.as_mut().unwrap(), t_span, "did you mean `Box<{}>`?", tstr),
|
span_help!(err, t_span, "did you mean `Box<{}>`?", tstr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
span_help!(err.as_mut().unwrap(), e_span,
|
span_help!(err, e_span,
|
||||||
"consider using a box or reference as appropriate");
|
"consider using a box or reference as appropriate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err.map(|mut e| e.emit());
|
err.emit();
|
||||||
fcx.write_error(id);
|
fcx.write_error(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1630,7 +1630,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
mk_msg: M,
|
mk_msg: M,
|
||||||
actual_ty: Ty<'tcx>,
|
actual_ty: Ty<'tcx>,
|
||||||
err: Option<&TypeError<'tcx>>)
|
err: Option<&TypeError<'tcx>>)
|
||||||
-> Option<DiagnosticBuilder<'tcx>>
|
-> DiagnosticBuilder<'tcx>
|
||||||
where M: FnOnce(String) -> String,
|
where M: FnOnce(String) -> String,
|
||||||
{
|
{
|
||||||
self.infcx().type_error_struct(sp, mk_msg, actual_ty, err)
|
self.infcx().type_error_struct(sp, mk_msg, actual_ty, err)
|
||||||
|
@ -2966,13 +2966,12 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
`{}`", field.node, actual)
|
`{}`", field.node, actual)
|
||||||
},
|
},
|
||||||
expr_t, None)
|
expr_t, None)
|
||||||
.unwrap()
|
|
||||||
.fileline_help(field.span,
|
.fileline_help(field.span,
|
||||||
"maybe a `()` to call it is missing? \
|
"maybe a `()` to call it is missing? \
|
||||||
If not, try an anonymous function")
|
If not, try an anonymous function")
|
||||||
.emit();
|
.emit();
|
||||||
} else {
|
} else {
|
||||||
fcx.type_error_struct(
|
let mut err = fcx.type_error_struct(
|
||||||
expr.span,
|
expr.span,
|
||||||
|actual| {
|
|actual| {
|
||||||
format!("attempted access of field `{}` on \
|
format!("attempted access of field `{}` on \
|
||||||
|
@ -2981,13 +2980,11 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
field.node,
|
field.node,
|
||||||
actual)
|
actual)
|
||||||
},
|
},
|
||||||
expr_t, None)
|
expr_t, None);
|
||||||
.map(|mut e| {
|
|
||||||
if let ty::TyStruct(def, _) = expr_t.sty {
|
if let ty::TyStruct(def, _) = expr_t.sty {
|
||||||
suggest_field_names(&mut e, def.struct_variant(), field, vec![]);
|
suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
|
||||||
}
|
}
|
||||||
e.emit();
|
err.emit();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fcx.write_error(expr.id);
|
fcx.write_error(expr.id);
|
||||||
|
@ -3089,7 +3086,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
variant: ty::VariantDef<'tcx>,
|
variant: ty::VariantDef<'tcx>,
|
||||||
field: &hir::Field,
|
field: &hir::Field,
|
||||||
skip_fields: &[hir::Field]) {
|
skip_fields: &[hir::Field]) {
|
||||||
fcx.type_error_struct(
|
let mut err = fcx.type_error_struct(
|
||||||
field.name.span,
|
field.name.span,
|
||||||
|actual| if let ty::TyEnum(..) = ty.sty {
|
|actual| if let ty::TyEnum(..) = ty.sty {
|
||||||
format!("struct variant `{}::{}` has no field named `{}`",
|
format!("struct variant `{}::{}` has no field named `{}`",
|
||||||
|
@ -3099,13 +3096,11 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
actual, field.name.node)
|
actual, field.name.node)
|
||||||
},
|
},
|
||||||
ty,
|
ty,
|
||||||
None)
|
None);
|
||||||
.map(|mut e| {
|
|
||||||
// prevent all specified fields from being suggested
|
// prevent all specified fields from being suggested
|
||||||
let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
|
let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
|
||||||
suggest_field_names(&mut e, variant, &field.name, skip_fields.collect());
|
suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
|
||||||
e.emit();
|
err.emit();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
|
|
|
@ -107,7 +107,6 @@ pub struct DiagnosticBuilder<'a> {
|
||||||
code: Option<String>,
|
code: Option<String>,
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
children: Vec<SubDiagnostic>,
|
children: Vec<SubDiagnostic>,
|
||||||
cancelled: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For example a note attached to an error.
|
// For example a note attached to an error.
|
||||||
|
@ -121,12 +120,12 @@ struct SubDiagnostic {
|
||||||
impl<'a> DiagnosticBuilder<'a> {
|
impl<'a> DiagnosticBuilder<'a> {
|
||||||
// Emit the diagnostic.
|
// Emit the diagnostic.
|
||||||
pub fn emit(&mut self) {
|
pub fn emit(&mut self) {
|
||||||
if self.cancelled {
|
if self.cancelled() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.cancel();
|
|
||||||
self.emitter.borrow_mut().emit_struct(&self);
|
self.emitter.borrow_mut().emit_struct(&self);
|
||||||
|
self.cancel();
|
||||||
|
|
||||||
// if self.is_fatal() {
|
// if self.is_fatal() {
|
||||||
// panic!(FatalError);
|
// panic!(FatalError);
|
||||||
|
@ -135,8 +134,15 @@ impl<'a> DiagnosticBuilder<'a> {
|
||||||
|
|
||||||
// Cancel the diagnostic (a structured diagnostic must either be emitted or
|
// Cancel the diagnostic (a structured diagnostic must either be emitted or
|
||||||
// cancelled or it will panic when dropped).
|
// cancelled or it will panic when dropped).
|
||||||
|
// BEWARE: if this DiagnosticBuilder is an error, then creating it will
|
||||||
|
// bump the error count on the Handler and cancelling it won't undo that.
|
||||||
|
// If you want to decrement the error count you should use `Handler::cancel`.
|
||||||
pub fn cancel(&mut self) {
|
pub fn cancel(&mut self) {
|
||||||
self.cancelled = true;
|
self.level = Level::Cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cancelled(&self) -> bool {
|
||||||
|
self.level == Level::Cancelled
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_fatal(&self) -> bool {
|
pub fn is_fatal(&self) -> bool {
|
||||||
|
@ -204,21 +210,28 @@ impl<'a> DiagnosticBuilder<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn span(&mut self, sp: Span) -> &mut Self {
|
||||||
|
self.span = Some(sp);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn code(&mut self, s: String) -> &mut Self {
|
||||||
|
self.code = Some(s);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
// Convenience function for internal use, clients should use one of the
|
// Convenience function for internal use, clients should use one of the
|
||||||
// struct_* methods on Handler.
|
// struct_* methods on Handler.
|
||||||
fn new(emitter: &'a RefCell<Box<Emitter>>,
|
fn new(emitter: &'a RefCell<Box<Emitter>>,
|
||||||
level: Level,
|
level: Level,
|
||||||
message: &str,
|
message: &str) -> DiagnosticBuilder<'a> {
|
||||||
code: Option<String>,
|
|
||||||
span: Option<Span>) -> DiagnosticBuilder<'a> {
|
|
||||||
DiagnosticBuilder {
|
DiagnosticBuilder {
|
||||||
emitter: emitter,
|
emitter: emitter,
|
||||||
level: level,
|
level: level,
|
||||||
message: message.to_owned(),
|
message: message.to_owned(),
|
||||||
code: code,
|
code: None,
|
||||||
span: span,
|
span: None,
|
||||||
children: vec![],
|
children: vec![],
|
||||||
cancelled: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +262,7 @@ impl<'a> fmt::Debug for DiagnosticBuilder<'a> {
|
||||||
// we emit a bug.
|
// we emit a bug.
|
||||||
impl<'a> Drop for DiagnosticBuilder<'a> {
|
impl<'a> Drop for DiagnosticBuilder<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if !self.cancelled {
|
if !self.cancelled() {
|
||||||
self.emitter.borrow_mut().emit(None, "Error constructed but not emitted", None, Bug);
|
self.emitter.borrow_mut().emit(None, "Error constructed but not emitted", None, Bug);
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
|
@ -290,11 +303,16 @@ impl Handler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn struct_dummy<'a>(&'a self) -> DiagnosticBuilder<'a> {
|
||||||
|
DiagnosticBuilder::new(&self.emit, Level::Cancelled, "")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn struct_span_warn<'a>(&'a self,
|
pub fn struct_span_warn<'a>(&'a self,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
msg: &str)
|
msg: &str)
|
||||||
-> DiagnosticBuilder<'a> {
|
-> DiagnosticBuilder<'a> {
|
||||||
let mut result = DiagnosticBuilder::new(&self.emit, Level::Warning, msg, None, Some(sp));
|
let mut result = DiagnosticBuilder::new(&self.emit, Level::Warning, msg);
|
||||||
|
result.span(sp);
|
||||||
if !self.can_emit_warnings {
|
if !self.can_emit_warnings {
|
||||||
result.cancel();
|
result.cancel();
|
||||||
}
|
}
|
||||||
|
@ -305,18 +323,16 @@ impl Handler {
|
||||||
msg: &str,
|
msg: &str,
|
||||||
code: &str)
|
code: &str)
|
||||||
-> DiagnosticBuilder<'a> {
|
-> DiagnosticBuilder<'a> {
|
||||||
let mut result = DiagnosticBuilder::new(&self.emit,
|
let mut result = DiagnosticBuilder::new(&self.emit, Level::Warning, msg);
|
||||||
Level::Warning,
|
result.span(sp);
|
||||||
msg,
|
result.code(code.to_owned());
|
||||||
Some(code.to_owned()),
|
|
||||||
Some(sp));
|
|
||||||
if !self.can_emit_warnings {
|
if !self.can_emit_warnings {
|
||||||
result.cancel();
|
result.cancel();
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
|
pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
|
||||||
let mut result = DiagnosticBuilder::new(&self.emit, Level::Warning, msg, None, None);
|
let mut result = DiagnosticBuilder::new(&self.emit, Level::Warning, msg);
|
||||||
if !self.can_emit_warnings {
|
if !self.can_emit_warnings {
|
||||||
result.cancel();
|
result.cancel();
|
||||||
}
|
}
|
||||||
|
@ -327,28 +343,33 @@ impl Handler {
|
||||||
msg: &str)
|
msg: &str)
|
||||||
-> DiagnosticBuilder<'a> {
|
-> DiagnosticBuilder<'a> {
|
||||||
self.bump_err_count();
|
self.bump_err_count();
|
||||||
DiagnosticBuilder::new(&self.emit, Level::Error, msg, None, Some(sp))
|
let mut result = DiagnosticBuilder::new(&self.emit, Level::Error, msg);
|
||||||
|
result.span(sp);
|
||||||
|
result
|
||||||
}
|
}
|
||||||
pub fn struct_span_err_with_code<'a>(&'a self,
|
pub fn struct_span_err_with_code<'a>(&'a self,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
msg: &str,
|
msg: &str,
|
||||||
code: &str)
|
code: &str)
|
||||||
-> DiagnosticBuilder<'a> {
|
-> DiagnosticBuilder<'a> {
|
||||||
// FIXME (and below) this is potentially inaccurate, since the DiagnosticBuilder
|
|
||||||
// might be cancelled.
|
|
||||||
self.bump_err_count();
|
self.bump_err_count();
|
||||||
DiagnosticBuilder::new(&self.emit, Level::Error, msg, Some(code.to_owned()), Some(sp))
|
let mut result = DiagnosticBuilder::new(&self.emit, Level::Error, msg);
|
||||||
|
result.span(sp);
|
||||||
|
result.code(code.to_owned());
|
||||||
|
result
|
||||||
}
|
}
|
||||||
pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
|
pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
|
||||||
self.bump_err_count();
|
self.bump_err_count();
|
||||||
DiagnosticBuilder::new(&self.emit, Level::Error, msg, None, None)
|
DiagnosticBuilder::new(&self.emit, Level::Error, msg)
|
||||||
}
|
}
|
||||||
pub fn struct_span_fatal<'a>(&'a self,
|
pub fn struct_span_fatal<'a>(&'a self,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
msg: &str)
|
msg: &str)
|
||||||
-> DiagnosticBuilder<'a> {
|
-> DiagnosticBuilder<'a> {
|
||||||
self.bump_err_count();
|
self.bump_err_count();
|
||||||
DiagnosticBuilder::new(&self.emit, Level::Fatal, msg, None, Some(sp))
|
let mut result = DiagnosticBuilder::new(&self.emit, Level::Fatal, msg);
|
||||||
|
result.span(sp);
|
||||||
|
result
|
||||||
}
|
}
|
||||||
pub fn struct_span_fatal_with_code<'a>(&'a self,
|
pub fn struct_span_fatal_with_code<'a>(&'a self,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
|
@ -356,11 +377,22 @@ impl Handler {
|
||||||
code: &str)
|
code: &str)
|
||||||
-> DiagnosticBuilder<'a> {
|
-> DiagnosticBuilder<'a> {
|
||||||
self.bump_err_count();
|
self.bump_err_count();
|
||||||
DiagnosticBuilder::new(&self.emit, Level::Fatal, msg, Some(code.to_owned()), Some(sp))
|
let mut result = DiagnosticBuilder::new(&self.emit, Level::Fatal, msg);
|
||||||
|
result.span(sp);
|
||||||
|
result.code(code.to_owned());
|
||||||
|
result
|
||||||
}
|
}
|
||||||
pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
|
pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
|
||||||
self.bump_err_count();
|
self.bump_err_count();
|
||||||
DiagnosticBuilder::new(&self.emit, Level::Fatal, msg, None, None)
|
DiagnosticBuilder::new(&self.emit, Level::Fatal, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cancel(&mut self, err: &mut DiagnosticBuilder) {
|
||||||
|
if err.level == Level::Error || err.level == Level::Fatal {
|
||||||
|
assert!(self.has_errors());
|
||||||
|
self.err_count.set(self.err_count.get() + 1);
|
||||||
|
}
|
||||||
|
err.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn span_fatal(&self, sp: Span, msg: &str) -> FatalError {
|
pub fn span_fatal(&self, sp: Span, msg: &str) -> FatalError {
|
||||||
|
@ -514,6 +546,7 @@ pub enum Level {
|
||||||
Warning,
|
Warning,
|
||||||
Note,
|
Note,
|
||||||
Help,
|
Help,
|
||||||
|
Cancelled,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Level {
|
impl fmt::Display for Level {
|
||||||
|
@ -526,6 +559,7 @@ impl fmt::Display for Level {
|
||||||
Warning => "warning".fmt(f),
|
Warning => "warning".fmt(f),
|
||||||
Note => "note".fmt(f),
|
Note => "note".fmt(f),
|
||||||
Help => "help".fmt(f),
|
Help => "help".fmt(f),
|
||||||
|
Cancelled => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -537,6 +571,7 @@ impl Level {
|
||||||
Warning => term::color::BRIGHT_YELLOW,
|
Warning => term::color::BRIGHT_YELLOW,
|
||||||
Note => term::color::BRIGHT_GREEN,
|
Note => term::color::BRIGHT_GREEN,
|
||||||
Help => term::color::BRIGHT_CYAN,
|
Help => term::color::BRIGHT_CYAN,
|
||||||
|
Cancelled => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue