1
Fork 0

replace fileline_{help,note} with {help,note}

The extra filename and line was mainly there to keep the indentation
relative to the main snippet; now that this doesn't include
filename/line-number as a prefix, it is distracted.
This commit is contained in:
Niko Matsakis 2016-04-20 14:49:16 -04:00
parent 1ff1887cc9
commit 489a6c95bf
25 changed files with 172 additions and 260 deletions

View file

@ -682,8 +682,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
E0309, E0309,
"{} may not live long enough", "{} may not live long enough",
labeled_user_string); labeled_user_string);
err.fileline_help(origin.span(), err.help(&format!("consider adding an explicit lifetime bound `{}: {}`...",
&format!("consider adding an explicit lifetime bound `{}: {}`...",
bound_kind, bound_kind,
sub)); sub));
err err
@ -696,8 +695,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
E0310, E0310,
"{} may not live long enough", "{} may not live long enough",
labeled_user_string); labeled_user_string);
err.fileline_help(origin.span(), err.help(&format!("consider adding an explicit lifetime \
&format!("consider adding an explicit lifetime \
bound `{}: 'static`...", bound `{}: 'static`...",
bound_kind)); bound_kind));
err err
@ -710,8 +708,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
E0311, E0311,
"{} may not live long enough", "{} may not live long enough",
labeled_user_string); labeled_user_string);
err.fileline_help(origin.span(), err.help(&format!("consider adding an explicit lifetime bound for `{}`",
&format!("consider adding an explicit lifetime bound for `{}`",
bound_kind)); bound_kind));
self.tcx.note_and_explain_region( self.tcx.note_and_explain_region(
&mut err, &mut err,

View file

@ -456,17 +456,13 @@ pub fn raw_struct_lint<'a>(sess: &'a Session,
it will become a hard error in a future release!"); it will become a hard error in a future release!");
let citation = format!("for more information, see {}", let citation = format!("for more information, see {}",
future_incompatible.reference); future_incompatible.reference);
if let Some(sp) = span {
err.fileline_warn(sp, &explanation);
err.fileline_note(sp, &citation);
} else {
err.warn(&explanation); err.warn(&explanation);
err.note(&citation); err.note(&citation);
} }
}
if let Some(span) = def { if let Some(span) = def {
err.span_note(span, "lint level defined here"); let explanation = "lint level defined here";
err = err.span_label(span, &explanation);
} }
err err
@ -542,7 +538,7 @@ pub trait LintContext: Sized {
let mut err = self.lookup(lint, Some(span), msg); let mut err = self.lookup(lint, Some(span), msg);
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.note(note);
} else { } else {
err.span_note(note_span, note); err.span_note(note_span, note);
} }

View file

@ -206,18 +206,17 @@ fn find_similar_impl_candidates<'a, 'tcx>(
impl_candidates impl_candidates
} }
fn report_similar_impl_candidates(span: Span, fn report_similar_impl_candidates(err: &mut DiagnosticBuilder,
err: &mut DiagnosticBuilder,
impl_candidates: &[ty::TraitRef]) impl_candidates: &[ty::TraitRef])
{ {
err.fileline_help(span, &format!("the following implementations were found:")); err.help(&format!("the following implementations were found:"));
let end = cmp::min(4, impl_candidates.len()); let end = cmp::min(4, impl_candidates.len());
for candidate in &impl_candidates[0..end] { for candidate in &impl_candidates[0..end] {
err.fileline_help(span, &format!(" {:?}", candidate)); err.help(&format!(" {:?}", candidate));
} }
if impl_candidates.len() > 4 { if impl_candidates.len() > 4 {
err.fileline_help(span, &format!("and {} others", impl_candidates.len()-4)); err.help(&format!("and {} others", impl_candidates.len()-4));
} }
} }
@ -240,7 +239,7 @@ pub fn report_overflow_error<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
predicate); predicate);
if suggest_increasing_limit { if suggest_increasing_limit {
suggest_new_overflow_limit(infcx.tcx, &mut err, obligation.cause.span); suggest_new_overflow_limit(infcx.tcx, &mut err);
} }
note_obligation_cause(infcx, &mut err, obligation); note_obligation_cause(infcx, &mut err, obligation);
@ -353,17 +352,13 @@ pub fn try_report_overflow_error_type_of_infinite_size<'a, 'tcx>(
let mut err = recursive_type_with_infinite_size_error(tcx, main_def_id); let mut err = recursive_type_with_infinite_size_error(tcx, main_def_id);
let len = struct_enum_tys.len(); let len = struct_enum_tys.len();
if len > 2 { if len > 2 {
let span = tcx.map.span_if_local(main_def_id).unwrap(); err.note(&format!("type `{}` is embedded within `{}`...",
err.fileline_note(span,
&format!("type `{}` is embedded within `{}`...",
struct_enum_tys[0], struct_enum_tys[0],
struct_enum_tys[1])); struct_enum_tys[1]));
for &next_ty in &struct_enum_tys[1..len-1] { for &next_ty in &struct_enum_tys[1..len-1] {
err.fileline_note(span, err.note(&format!("...which in turn is embedded within `{}`...", next_ty));
&format!("...which in turn is embedded within `{}`...", next_ty));
} }
err.fileline_note(span, err.note(&format!("...which in turn is embedded within `{}`, \
&format!("...which in turn is embedded within `{}`, \
completing the cycle.", completing the cycle.",
struct_enum_tys[len-1])); struct_enum_tys[len-1]));
} }
@ -380,7 +375,7 @@ pub fn recursive_type_with_infinite_size_error<'tcx>(tcx: &TyCtxt<'tcx>,
let span = tcx.map.span_if_local(type_def_id).unwrap(); let span = tcx.map.span_if_local(type_def_id).unwrap();
let mut err = struct_span_err!(tcx.sess, span, E0072, "recursive type `{}` has infinite size", let mut err = struct_span_err!(tcx.sess, span, E0072, "recursive type `{}` has infinite size",
tcx.item_path_str(type_def_id)); tcx.item_path_str(type_def_id));
err.fileline_help(span, &format!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \ err.help(&format!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \
at some point to make `{}` representable", at some point to make `{}` representable",
tcx.item_path_str(type_def_id))); tcx.item_path_str(type_def_id)));
err err
@ -423,15 +418,14 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
// these notes will often be of the form // these notes will often be of the form
// "the type `T` can't be frobnicated" // "the type `T` can't be frobnicated"
// which is somewhat confusing. // which is somewhat confusing.
err.fileline_help(obligation.cause.span, &format!( err.help(&format!("consider adding a `where {}` bound",
"consider adding a `where {}` bound",
trait_ref.to_predicate() trait_ref.to_predicate()
)); ));
} else if let Some(s) = on_unimplemented_note(infcx, trait_ref, } else if let Some(s) = on_unimplemented_note(infcx, trait_ref,
obligation.cause.span) { obligation.cause.span) {
// Otherwise, if there is an on-unimplemented note, // Otherwise, if there is an on-unimplemented note,
// display it. // display it.
err.fileline_note(obligation.cause.span, &s); err.note(&s);
} else { } else {
// If we can't show anything useful, try to find // If we can't show anything useful, try to find
// similar impls. // similar impls.
@ -439,8 +433,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
let impl_candidates = let impl_candidates =
find_similar_impl_candidates(infcx, trait_ref); find_similar_impl_candidates(infcx, trait_ref);
if impl_candidates.len() > 0 { if impl_candidates.len() > 0 {
report_similar_impl_candidates(obligation.cause.span, report_similar_impl_candidates(&mut err, &impl_candidates);
&mut err, &impl_candidates);
} }
} }
note_obligation_cause(infcx, &mut err, obligation); note_obligation_cause(infcx, &mut err, obligation);
@ -499,7 +492,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
let found_kind = infcx.closure_kind(closure_def_id).unwrap(); let found_kind = infcx.closure_kind(closure_def_id).unwrap();
let closure_span = infcx.tcx.map.span_if_local(closure_def_id).unwrap(); let closure_span = infcx.tcx.map.span_if_local(closure_def_id).unwrap();
let mut err = struct_span_err!( let mut err = struct_span_err!(
infcx.tcx.sess, closure_span, E0524, infcx.tcx.sess, closure_span, E0525,
"expected a closure that implements the `{}` trait, but this closure \ "expected a closure that implements the `{}` trait, but this closure \
only implements `{}`", only implements `{}`",
kind, kind,
@ -570,40 +563,30 @@ pub fn report_object_safety_error<'tcx>(tcx: &TyCtxt<'tcx>,
} }
match violation { match violation {
ObjectSafetyViolation::SizedSelf => { ObjectSafetyViolation::SizedSelf => {
err.fileline_note( err.note("the trait cannot require that `Self : Sized`");
span,
"the trait cannot require that `Self : Sized`");
} }
ObjectSafetyViolation::SupertraitSelf => { ObjectSafetyViolation::SupertraitSelf => {
err.fileline_note( err.note("the trait cannot use `Self` as a type parameter \
span,
"the trait cannot use `Self` as a type parameter \
in the supertrait listing"); in the supertrait listing");
} }
ObjectSafetyViolation::Method(method, ObjectSafetyViolation::Method(method,
MethodViolationCode::StaticMethod) => { MethodViolationCode::StaticMethod) => {
err.fileline_note( err.note(&format!("method `{}` has no receiver",
span,
&format!("method `{}` has no receiver",
method.name)); method.name));
} }
ObjectSafetyViolation::Method(method, ObjectSafetyViolation::Method(method,
MethodViolationCode::ReferencesSelf) => { MethodViolationCode::ReferencesSelf) => {
err.fileline_note( err.note(&format!("method `{}` references the `Self` type \
span,
&format!("method `{}` references the `Self` type \
in its arguments or return type", in its arguments or return type",
method.name)); method.name));
} }
ObjectSafetyViolation::Method(method, ObjectSafetyViolation::Method(method,
MethodViolationCode::Generic) => { MethodViolationCode::Generic) => {
err.fileline_note( err.note(&format!("method `{}` has generic type parameters",
span,
&format!("method `{}` has generic type parameters",
method.name)); method.name));
} }
} }
@ -766,14 +749,12 @@ fn note_obligation_cause<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
note_obligation_cause_code(infcx, note_obligation_cause_code(infcx,
err, err,
&obligation.predicate, &obligation.predicate,
obligation.cause.span,
&obligation.cause.code); &obligation.cause.code);
} }
fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
err: &mut DiagnosticBuilder, err: &mut DiagnosticBuilder,
predicate: &T, predicate: &T,
cause_span: Span,
cause_code: &ObligationCauseCode<'tcx>) cause_code: &ObligationCauseCode<'tcx>)
where T: fmt::Display where T: fmt::Display
{ {
@ -781,101 +762,71 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
match *cause_code { match *cause_code {
ObligationCauseCode::MiscObligation => { } ObligationCauseCode::MiscObligation => { }
ObligationCauseCode::SliceOrArrayElem => { ObligationCauseCode::SliceOrArrayElem => {
err.fileline_note( err.note("slice and array elements must have `Sized` type");
cause_span,
"slice and array elements must have `Sized` type");
} }
ObligationCauseCode::ProjectionWf(data) => { ObligationCauseCode::ProjectionWf(data) => {
err.fileline_note( err.note(&format!("required so that the projection `{}` is well-formed",
cause_span,
&format!("required so that the projection `{}` is well-formed",
data)); data));
} }
ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => { ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => {
err.fileline_note( err.note(&format!("required so that reference `{}` does not outlive its referent",
cause_span,
&format!("required so that reference `{}` does not outlive its referent",
ref_ty)); ref_ty));
} }
ObligationCauseCode::ItemObligation(item_def_id) => { ObligationCauseCode::ItemObligation(item_def_id) => {
let item_name = tcx.item_path_str(item_def_id); let item_name = tcx.item_path_str(item_def_id);
err.fileline_note( err.note(&format!("required by `{}`", item_name));
cause_span,
&format!("required by `{}`", item_name));
} }
ObligationCauseCode::ObjectCastObligation(object_ty) => { ObligationCauseCode::ObjectCastObligation(object_ty) => {
err.fileline_note( err.note(&format!("required for the cast to the object type `{}`",
cause_span,
&format!(
"required for the cast to the object type `{}`",
infcx.ty_to_string(object_ty))); infcx.ty_to_string(object_ty)));
} }
ObligationCauseCode::RepeatVec => { ObligationCauseCode::RepeatVec => {
err.fileline_note( err.note("the `Copy` trait is required because the \
cause_span,
"the `Copy` trait is required because the \
repeated element will be copied"); repeated element will be copied");
} }
ObligationCauseCode::VariableType(_) => { ObligationCauseCode::VariableType(_) => {
err.fileline_note( err.note("all local variables must have a statically known size");
cause_span,
"all local variables must have a statically known size");
} }
ObligationCauseCode::ReturnType => { ObligationCauseCode::ReturnType => {
err.fileline_note( err.note("the return type of a function must have a \
cause_span,
"the return type of a function must have a \
statically known size"); statically known size");
} }
ObligationCauseCode::AssignmentLhsSized => { ObligationCauseCode::AssignmentLhsSized => {
err.fileline_note( err.note("the left-hand-side of an assignment must have a statically known size");
cause_span,
"the left-hand-side of an assignment must have a statically known size");
} }
ObligationCauseCode::StructInitializerSized => { ObligationCauseCode::StructInitializerSized => {
err.fileline_note( err.note("structs must have a statically known size to be initialized");
cause_span,
"structs must have a statically known size to be initialized");
} }
ObligationCauseCode::ClosureCapture(var_id, _, builtin_bound) => { ObligationCauseCode::ClosureCapture(var_id, _, builtin_bound) => {
let def_id = tcx.lang_items.from_builtin_kind(builtin_bound).unwrap(); let def_id = tcx.lang_items.from_builtin_kind(builtin_bound).unwrap();
let trait_name = tcx.item_path_str(def_id); let trait_name = tcx.item_path_str(def_id);
let name = tcx.local_var_name_str(var_id); let name = tcx.local_var_name_str(var_id);
err.fileline_note( err.note(
cause_span,
&format!("the closure that captures `{}` requires that all captured variables \ &format!("the closure that captures `{}` requires that all captured variables \
implement the trait `{}`", implement the trait `{}`",
name, name,
trait_name)); trait_name));
} }
ObligationCauseCode::FieldSized => { ObligationCauseCode::FieldSized => {
err.fileline_note( err.note("only the last field of a struct or enum variant \
cause_span,
"only the last field of a struct or enum variant \
may have a dynamically sized type"); may have a dynamically sized type");
} }
ObligationCauseCode::SharedStatic => { ObligationCauseCode::SharedStatic => {
err.fileline_note( err.note("shared static variables must have a type that implements `Sync`");
cause_span,
"shared static variables must have a type that implements `Sync`");
} }
ObligationCauseCode::BuiltinDerivedObligation(ref data) => { ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
let parent_trait_ref = infcx.resolve_type_vars_if_possible(&data.parent_trait_ref); let parent_trait_ref = infcx.resolve_type_vars_if_possible(&data.parent_trait_ref);
err.fileline_note( err.note(&format!("required because it appears within the type `{}`",
cause_span,
&format!("required because it appears within the type `{}`",
parent_trait_ref.0.self_ty())); parent_trait_ref.0.self_ty()));
let parent_predicate = parent_trait_ref.to_predicate(); let parent_predicate = parent_trait_ref.to_predicate();
note_obligation_cause_code(infcx, note_obligation_cause_code(infcx,
err, err,
&parent_predicate, &parent_predicate,
cause_span,
&data.parent_code); &data.parent_code);
} }
ObligationCauseCode::ImplDerivedObligation(ref data) => { ObligationCauseCode::ImplDerivedObligation(ref data) => {
let parent_trait_ref = infcx.resolve_type_vars_if_possible(&data.parent_trait_ref); let parent_trait_ref = infcx.resolve_type_vars_if_possible(&data.parent_trait_ref);
err.fileline_note( err.note(
cause_span,
&format!("required because of the requirements on the impl of `{}` for `{}`", &format!("required because of the requirements on the impl of `{}` for `{}`",
parent_trait_ref, parent_trait_ref,
parent_trait_ref.0.self_ty())); parent_trait_ref.0.self_ty()));
@ -883,12 +834,10 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
note_obligation_cause_code(infcx, note_obligation_cause_code(infcx,
err, err,
&parent_predicate, &parent_predicate,
cause_span,
&data.parent_code); &data.parent_code);
} }
ObligationCauseCode::CompareImplMethodObligation => { ObligationCauseCode::CompareImplMethodObligation => {
err.fileline_note( err.note(
cause_span,
&format!("the requirement `{}` appears on the impl method \ &format!("the requirement `{}` appears on the impl method \
but not on the corresponding trait method", but not on the corresponding trait method",
predicate)); predicate));
@ -896,12 +845,10 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
} }
} }
fn suggest_new_overflow_limit(tcx: &TyCtxt, err:&mut DiagnosticBuilder, span: Span) { fn suggest_new_overflow_limit(tcx: &TyCtxt, err:&mut DiagnosticBuilder) {
let current_limit = tcx.sess.recursion_limit.get(); let current_limit = tcx.sess.recursion_limit.get();
let suggested_limit = current_limit * 2; let suggested_limit = current_limit * 2;
err.fileline_note( err.note(&format!(
span,
&format!(
"consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate", "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
suggested_limit)); suggested_limit));
} }

View file

@ -167,8 +167,7 @@ fn note_move_destination(err: &mut DiagnosticBuilder,
err.span_note( err.span_note(
move_to_span, move_to_span,
"attempting to move value to here"); "attempting to move value to here");
err.fileline_help( err.help(
move_to_span,
&format!("to prevent the move, \ &format!("to prevent the move, \
use `ref {0}` or `ref mut {0}` to capture value by \ use `ref {0}` or `ref mut {0}` to capture value by \
reference", reference",

View file

@ -912,8 +912,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}; };
if is_closure { if is_closure {
err.fileline_help(span, err.help("closures behind references must be called via `&mut`");
"closures behind references must be called via `&mut`");
} }
err.emit(); err.emit();
} }

View file

@ -255,7 +255,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
"pattern binding `{}` is named the same as one \ "pattern binding `{}` is named the same as one \
of the variants of the type `{}`", of the variants of the type `{}`",
ident.node, ty_path); ident.node, ty_path);
fileline_help!(err, p.span, help!(err,
"if you meant to match on a variant, \ "if you meant to match on a variant, \
consider making the path in the pattern qualified: `{}::{}`", consider making the path in the pattern qualified: `{}::{}`",
ty_path, ident.node); ty_path, ident.node);

View file

@ -764,7 +764,7 @@ impl LateLintPass for UnconditionalRecursion {
for call in &self_call_spans { for call in &self_call_spans {
db.span_note(*call, "recursive call site"); db.span_note(*call, "recursive call site");
} }
db.fileline_help(sp, "a `loop` may express intention \ db.help("a `loop` may express intention \
better if this is on purpose"); better if this is on purpose");
} }
db.emit(); db.emit();

View file

@ -241,7 +241,7 @@ impl<'a> CrateReader<'a> {
crate_rustc_version crate_rustc_version
.as_ref().map(|s| &**s) .as_ref().map(|s| &**s)
.unwrap_or("an old version of rustc")); .unwrap_or("an old version of rustc"));
err.fileline_help(span, "consider removing the compiled binaries and recompiling \ err.help("consider removing the compiled binaries and recompiling \
with your current version of rustc"); with your current version of rustc");
err.emit(); err.emit();
} }

View file

@ -346,38 +346,32 @@ impl<'a> Context<'a> {
if !self.rejected_via_triple.is_empty() { if !self.rejected_via_triple.is_empty() {
let mismatches = self.rejected_via_triple.iter(); let mismatches = self.rejected_via_triple.iter();
for (i, &CrateMismatch{ ref path, ref got }) in mismatches.enumerate() { for (i, &CrateMismatch{ ref path, ref got }) in mismatches.enumerate() {
err.fileline_note(self.span, err.note(&format!("crate `{}`, path #{}, triple {}: {}",
&format!("crate `{}`, path #{}, triple {}: {}",
self.ident, i+1, got, path.display())); self.ident, i+1, got, path.display()));
} }
} }
if !self.rejected_via_hash.is_empty() { if !self.rejected_via_hash.is_empty() {
err.span_note(self.span, "perhaps this crate needs \ err.note("perhaps this crate needs to be recompiled?");
to be recompiled?");
let mismatches = self.rejected_via_hash.iter(); let mismatches = self.rejected_via_hash.iter();
for (i, &CrateMismatch{ ref path, .. }) in mismatches.enumerate() { for (i, &CrateMismatch{ ref path, .. }) in mismatches.enumerate() {
err.fileline_note(self.span, err.note(&format!("crate `{}` path #{}: {}",
&format!("crate `{}` path #{}: {}",
self.ident, i+1, path.display())); self.ident, i+1, path.display()));
} }
match self.root { match self.root {
&None => {} &None => {}
&Some(ref r) => { &Some(ref r) => {
for (i, path) in r.paths().iter().enumerate() { for (i, path) in r.paths().iter().enumerate() {
err.fileline_note(self.span, err.note(&format!("crate `{}` path #{}: {}",
&format!("crate `{}` path #{}: {}",
r.ident, i+1, path.display())); r.ident, i+1, path.display()));
} }
} }
} }
} }
if !self.rejected_via_kind.is_empty() { if !self.rejected_via_kind.is_empty() {
err.fileline_help(self.span, "please recompile this crate using \ err.help("please recompile this crate using --crate-type lib");
--crate-type lib");
let mismatches = self.rejected_via_kind.iter(); let mismatches = self.rejected_via_kind.iter();
for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() { for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() {
err.fileline_note(self.span, err.note(&format!("crate `{}` path #{}: {}",
&format!("crate `{}` path #{}: {}",
self.ident, i+1, path.display())); self.ident, i+1, path.display()));
} }
} }

View file

@ -198,9 +198,8 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
let mut err = self.tcx.sess.struct_span_err( let mut err = self.tcx.sess.struct_span_err(
expr.span, expr.span,
"const fns are an unstable feature"); "const fns are an unstable feature");
fileline_help!( help!(
&mut err, &mut err,
expr.span,
"in Nightly builds, add `#![feature(const_fn)]` to the crate \ "in Nightly builds, add `#![feature(const_fn)]` to the crate \
attributes to enable"); attributes to enable");
err.emit(); err.emit();

View file

@ -244,7 +244,7 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
E0405, E0405,
"trait `{}` is not in scope", "trait `{}` is not in scope",
name); name);
show_candidates(&mut err, span, &candidates); show_candidates(&mut err, &candidates);
err err
} }
ResolutionError::UndeclaredAssociatedType => { ResolutionError::UndeclaredAssociatedType => {
@ -312,7 +312,7 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
"{} `{}` is undefined or not in scope", "{} `{}` is undefined or not in scope",
kind, kind,
name); name);
show_candidates(&mut err, span, &candidates); show_candidates(&mut err, &candidates);
err err
} }
ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(name) => { ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(name) => {
@ -420,7 +420,7 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
match context { match context {
UnresolvedNameContext::Other => { } // no help available UnresolvedNameContext::Other => { } // no help available
UnresolvedNameContext::PathIsMod(parent) => { UnresolvedNameContext::PathIsMod(parent) => {
err.fileline_help(span, &match parent.map(|parent| &parent.node) { err.help(&match parent.map(|parent| &parent.node) {
Some(&ExprField(_, ident)) => { Some(&ExprField(_, ident)) => {
format!("To reference an item from the `{module}` module, \ format!("To reference an item from the `{module}` module, \
use `{module}::{ident}`", use `{module}::{ident}`",
@ -1784,7 +1784,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// If it's a typedef, give a note // If it's a typedef, give a note
if let Def::TyAlias(..) = path_res.base_def { if let Def::TyAlias(..) = path_res.base_def {
err.fileline_note(trait_path.span, err.note(trait_path.span,
"`type` aliases cannot be used for traits"); "`type` aliases cannot be used for traits");
let definition_site = { let definition_site = {
@ -2880,7 +2880,7 @@ 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.fileline_help(expr.span, &msg); err.help(&msg);
} else { } else {
err.span_help(expr.span, &msg); err.span_help(expr.span, &msg);
} }
@ -2922,7 +2922,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
path_name); path_name);
if self.emit_errors { if self.emit_errors {
err.fileline_help(expr.span, &msg); err.help(&msg);
} else { } else {
err.span_help(expr.span, &msg); err.span_help(expr.span, &msg);
} }
@ -3420,7 +3420,6 @@ fn path_names_to_string(path: &Path, depth: usize) -> String {
/// entities with that name in all crates. This method allows outputting the /// entities with that name in all crates. This method allows outputting the
/// results of this search in a programmer-friendly way /// results of this search in a programmer-friendly way
fn show_candidates(session: &mut DiagnosticBuilder, fn show_candidates(session: &mut DiagnosticBuilder,
span: syntax::codemap::Span,
candidates: &SuggestedCandidates) { candidates: &SuggestedCandidates) {
let paths = &candidates.candidates; let paths = &candidates.candidates;
@ -3440,26 +3439,23 @@ fn show_candidates(session: &mut DiagnosticBuilder,
// behave differently based on how many candidates we have: // behave differently based on how many candidates we have:
if !paths.is_empty() { if !paths.is_empty() {
if paths.len() == 1 { if paths.len() == 1 {
session.fileline_help( session.help(
span,
&format!("you can import it into scope: `use {};`.", &format!("you can import it into scope: `use {};`.",
&path_strings[0]), &path_strings[0]),
); );
} else { } else {
session.fileline_help(span, "you can import several candidates \ session.help("you can import several candidates \
into scope (`use ...;`):"); into scope (`use ...;`):");
let count = path_strings.len() as isize - MAX_CANDIDATES as isize + 1; let count = path_strings.len() as isize - MAX_CANDIDATES as isize + 1;
for (idx, path_string) in path_strings.iter().enumerate() { for (idx, path_string) in path_strings.iter().enumerate() {
if idx == MAX_CANDIDATES - 1 && count > 1 { if idx == MAX_CANDIDATES - 1 && count > 1 {
session.fileline_help( session.help(
span,
&format!(" and {} other candidates", count).to_string(), &format!(" and {} other candidates", count).to_string(),
); );
break; break;
} else { } else {
session.fileline_help( session.help(
span,
&format!(" `{}`", path_string).to_string(), &format!(" `{}`", path_string).to_string(),
); );
} }
@ -3468,8 +3464,7 @@ fn show_candidates(session: &mut DiagnosticBuilder,
} }
} else { } else {
// nothing found: // nothing found:
session.fileline_help( session.help(
span,
&format!("no candidates by the name of `{}` found in your \ &format!("no candidates by the name of `{}` found in your \
project; maybe you misspelled the name or forgot to import \ project; maybe you misspelled the name or forgot to import \
an external crate?", candidates.name.to_string()), an external crate?", candidates.name.to_string()),

View file

@ -206,7 +206,6 @@ pub fn ast_region_to_region(tcx: &TyCtxt, lifetime: &hir::Lifetime)
fn report_elision_failure( fn report_elision_failure(
db: &mut DiagnosticBuilder, db: &mut DiagnosticBuilder,
default_span: Span,
params: Vec<ElisionFailureInfo>) params: Vec<ElisionFailureInfo>)
{ {
let mut m = String::new(); let mut m = String::new();
@ -243,26 +242,26 @@ fn report_elision_failure(
} }
if len == 0 { if len == 0 {
fileline_help!(db, default_span, help!(db,
"this function's return type contains a borrowed value, but \ "this function's return type contains a borrowed value, but \
there is no value for it to be borrowed from"); there is no value for it to be borrowed from");
fileline_help!(db, default_span, help!(db,
"consider giving it a 'static lifetime"); "consider giving it a 'static lifetime");
} else if !any_lifetimes { } else if !any_lifetimes {
fileline_help!(db, default_span, help!(db,
"this function's return type contains a borrowed value with \ "this function's return type contains a borrowed value with \
an elided lifetime, but the lifetime cannot be derived from \ an elided lifetime, but the lifetime cannot be derived from \
the arguments"); the arguments");
fileline_help!(db, default_span, help!(db,
"consider giving it an explicit bounded or 'static \ "consider giving it an explicit bounded or 'static \
lifetime"); lifetime");
} else if len == 1 { } else if len == 1 {
fileline_help!(db, default_span, help!(db,
"this function's return type contains a borrowed value, but \ "this function's return type contains a borrowed value, but \
the signature does not say which {} it is borrowed from", the signature does not say which {} it is borrowed from",
m); m);
} else { } else {
fileline_help!(db, default_span, help!(db,
"this function's return type contains a borrowed value, but \ "this function's return type contains a borrowed value, but \
the signature does not say whether it is borrowed from {}", the signature does not say whether it is borrowed from {}",
m); m);
@ -286,7 +285,7 @@ pub fn opt_ast_region_to_region<'tcx>(
let mut err = struct_span_err!(this.tcx().sess, default_span, E0106, let mut err = struct_span_err!(this.tcx().sess, default_span, E0106,
"missing lifetime specifier"); "missing lifetime specifier");
if let Some(params) = params { if let Some(params) = params {
report_elision_failure(&mut err, default_span, params); report_elision_failure(&mut err, params);
} }
err.emit(); err.emit();
ty::ReStatic ty::ReStatic
@ -1087,7 +1086,7 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
} }
_ => { _ => {
fileline_help!(&mut err, ty.span, help!(&mut err,
"perhaps you forgot parentheses? (per RFC 438)"); "perhaps you forgot parentheses? (per RFC 438)");
} }
} }

View file

@ -64,7 +64,7 @@ pub fn check_legal_trait_for_method_call(ccx: &CrateCtxt, span: Span, trait_id:
struct_span_err!(tcx.sess, span, E0174, struct_span_err!(tcx.sess, span, E0174,
"explicit use of unboxed closure method `{}` is experimental", "explicit use of unboxed closure method `{}` is experimental",
method) method)
.fileline_help(span, "add `#![feature(unboxed_closures)]` to the crate \ .help("add `#![feature(unboxed_closures)]` to the crate \
attributes to enable") attributes to enable")
.emit(); .emit();
} }

View file

@ -155,8 +155,7 @@ 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)
.fileline_help(self.span, .help(&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",
@ -167,7 +166,7 @@ impl<'tcx> CastCheck<'tcx> {
} }
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`")
.fileline_help(self.span, "compare with zero instead") .help("compare with zero instead")
.emit(); .emit();
} }
CastError::CastToChar => { CastError::CastToChar => {
@ -202,7 +201,7 @@ 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)
.fileline_note(self.span, "vtable kinds may not match") .note("vtable kinds may not match")
.emit(); .emit();
} }
} }

View file

@ -148,9 +148,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
if is_fn_ty(&rcvr_ty, &fcx, span) { if is_fn_ty(&rcvr_ty, &fcx, span) {
macro_rules! report_function { macro_rules! report_function {
($span:expr, $name:expr) => { ($span:expr, $name:expr) => {
err.fileline_note( err.note(&format!("{} is a function, perhaps you wish to call it",
$span,
&format!("{} is a function, perhaps you wish to call it",
$name)); $name));
} }
} }
@ -172,8 +170,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
} }
if !static_sources.is_empty() { if !static_sources.is_empty() {
err.fileline_note( err.note(
span,
"found the following associated functions; to be used as \ "found the following associated functions; to be used as \
methods, functions must have a `self` parameter"); methods, functions must have a `self` parameter");
@ -187,8 +184,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
p)) p))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", "); .join(", ");
err.fileline_note( err.note(
span,
&format!("the method `{}` exists but the \ &format!("the method `{}` exists but the \
following trait bounds were not satisfied: {}", following trait bounds were not satisfied: {}",
item_name, item_name,
@ -306,11 +302,10 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
traits_are = if candidates.len() == 1 {"trait is"} else {"traits are"}, traits_are = if candidates.len() == 1 {"trait is"} else {"traits are"},
one_of_them = if candidates.len() == 1 {"it"} else {"one of them"}); one_of_them = if candidates.len() == 1 {"it"} else {"one of them"});
err.fileline_help(span, &msg[..]); err.help(&msg[..]);
for (i, trait_did) in candidates.iter().enumerate() { for (i, trait_did) in candidates.iter().enumerate() {
err.fileline_help(span, err.help(&format!("candidate #{}: `use {}`",
&format!("candidate #{}: `use {}`",
i + 1, i + 1,
fcx.tcx().item_path_str(*trait_did))); fcx.tcx().item_path_str(*trait_did)));
} }
@ -351,11 +346,10 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
one_of_them = if candidates.len() == 1 {"it"} else {"one of them"}, one_of_them = if candidates.len() == 1 {"it"} else {"one of them"},
name = item_name); name = item_name);
err.fileline_help(span, &msg[..]); err.help(&msg[..]);
for (i, trait_info) in candidates.iter().enumerate() { for (i, trait_info) in candidates.iter().enumerate() {
err.fileline_help(span, err.help(&format!("candidate #{}: `{}`",
&format!("candidate #{}: `{}`",
i + 1, i + 1,
fcx.tcx().item_path_str(trait_info.def_id))); fcx.tcx().item_path_str(trait_info.def_id)));
} }

View file

@ -2955,7 +2955,7 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
`{}`", field.node, actual) `{}`", field.node, actual)
}, },
expr_t, None) expr_t, None)
.fileline_help(field.span, .help(
"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();

View file

@ -501,8 +501,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
let suggested_marker_id = self.tcx().lang_items.phantom_data(); let suggested_marker_id = self.tcx().lang_items.phantom_data();
match suggested_marker_id { match suggested_marker_id {
Some(def_id) => { Some(def_id) => {
err.fileline_help( err.help(
span,
&format!("consider removing `{}` or using a marker such as `{}`", &format!("consider removing `{}` or using a marker such as `{}`",
param_name, param_name,
self.tcx().item_path_str(def_id))); self.tcx().item_path_str(def_id)));

View file

@ -510,8 +510,7 @@ fn enforce_trait_manually_implementable(tcx: &TyCtxt, sp: Span, trait_def_id: De
E0183, E0183,
"manual implementations of `{}` are experimental", "manual implementations of `{}` are experimental",
trait_name); trait_name);
fileline_help!(&mut err, sp, help!(&mut err, "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
"add `#![feature(unboxed_closures)]` to the crate attributes to enable");
err.emit(); err.emit();
} }

View file

@ -1258,7 +1258,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
it.span, it.span,
"the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \ "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
which traits can use parenthetical notation"); which traits can use parenthetical notation");
fileline_help!(&mut err, it.span, help!(&mut err,
"add `#![feature(unboxed_closures)]` to \ "add `#![feature(unboxed_closures)]` to \
the crate attributes to use it"); the crate attributes to use it");
err.emit(); err.emit();
@ -2196,8 +2196,7 @@ fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
&format!("use of SIMD type `{}` in FFI is highly experimental and \ &format!("use of SIMD type `{}` in FFI is highly experimental and \
may result in invalid code", may result in invalid code",
pprust::ty_to_string(ast_ty))) pprust::ty_to_string(ast_ty)))
.fileline_help(ast_ty.span, .help("add #![feature(simd_ffi)] to the crate attributes to enable")
"add #![feature(simd_ffi)] to the crate attributes to enable")
.emit(); .emit();
} }
}; };

View file

@ -101,9 +101,9 @@ macro_rules! span_help {
} }
#[macro_export] #[macro_export]
macro_rules! fileline_help { macro_rules! help {
($err:expr, $span:expr, $($message:tt)*) => ({ ($err:expr, $($message:tt)*) => ({
($err).fileline_help($span, &format!($($message)*)); ($err).help(&format!($($message)*));
}) })
} }

View file

@ -764,14 +764,13 @@ impl<'a> ExtCtxt<'a> {
pub fn suggest_macro_name(&mut self, pub fn suggest_macro_name(&mut self,
name: &str, name: &str,
span: Span,
err: &mut DiagnosticBuilder<'a>) { err: &mut DiagnosticBuilder<'a>) {
let names = &self.syntax_env.names; let names = &self.syntax_env.names;
if let Some(suggestion) = find_best_match_for_name(names.iter(), name, None) { if let Some(suggestion) = find_best_match_for_name(names.iter(), name, None) {
if suggestion != name { if suggestion != name {
err.fileline_help(span, &format!("did you mean `{}!`?", suggestion)); err.help(&format!("did you mean `{}!`?", suggestion));
} else { } else {
err.fileline_help(span, &format!("have you added the `#[macro_use]` on the \ err.help(&format!("have you added the `#[macro_use]` on the \
module/import?")); module/import?"));
} }
} }

View file

@ -770,7 +770,7 @@ pub fn emit_feature_err(diag: &Handler, feature: &str, span: Span, issue: GateIs
err.emit(); err.emit();
return; return;
} }
err.fileline_help(span, &format!("add #![feature({})] to the \ err.help(&format!("add #![feature({})] to the \
crate attributes to enable", crate attributes to enable",
feature)); feature));
err.emit(); err.emit();

View file

@ -69,8 +69,7 @@ impl<'a> Parser<'a> {
self.diagnostic() self.diagnostic()
.struct_span_err(span, .struct_span_err(span,
"an inner attribute is not permitted in this context") "an inner attribute is not permitted in this context")
.fileline_help(span, .help("place inner attribute at the top of the module or \
"place inner attribute at the top of the module or \
block") block")
.emit() .emit()
} }

View file

@ -445,11 +445,11 @@ fn filtered_float_lit(data: token::InternedString, suffix: Option<&str>,
if suf.len() >= 2 && looks_like_width_suffix(&['f'], suf) { if suf.len() >= 2 && looks_like_width_suffix(&['f'], suf) {
// if it looks like a width, lets try to be helpful. // if it looks like a width, lets try to be helpful.
sd.struct_span_err(sp, &format!("invalid width `{}` for float literal", &suf[1..])) sd.struct_span_err(sp, &format!("invalid width `{}` for float literal", &suf[1..]))
.fileline_help(sp, "valid widths are 32 and 64") .help("valid widths are 32 and 64")
.emit(); .emit();
} else { } else {
sd.struct_span_err(sp, &format!("invalid suffix `{}` for float literal", suf)) sd.struct_span_err(sp, &format!("invalid suffix `{}` for float literal", suf))
.fileline_help(sp, "valid suffixes are `f32` and `f64`") .help("valid suffixes are `f32` and `f64`")
.emit(); .emit();
} }
@ -621,11 +621,11 @@ pub fn integer_lit(s: &str,
if looks_like_width_suffix(&['i', 'u'], suf) { if looks_like_width_suffix(&['i', 'u'], suf) {
sd.struct_span_err(sp, &format!("invalid width `{}` for integer literal", sd.struct_span_err(sp, &format!("invalid width `{}` for integer literal",
&suf[1..])) &suf[1..]))
.fileline_help(sp, "valid widths are 8, 16, 32 and 64") .help("valid widths are 8, 16, 32 and 64")
.emit(); .emit();
} else { } else {
sd.struct_span_err(sp, &format!("invalid suffix `{}` for numeric literal", suf)) sd.struct_span_err(sp, &format!("invalid suffix `{}` for numeric literal", suf))
.fileline_help(sp, "the suffix must be one of the integral types \ .help("the suffix must be one of the integral types \
(`u32`, `isize`, etc)") (`u32`, `isize`, etc)")
.emit(); .emit();
} }

View file

@ -583,7 +583,7 @@ impl<'a> Parser<'a> {
let mut err = self.fatal(&format!("expected identifier, found `{}`", let mut err = self.fatal(&format!("expected identifier, found `{}`",
self.this_token_to_string())); self.this_token_to_string()));
if self.token == token::Underscore { if self.token == token::Underscore {
err.fileline_note(self.span, "`_` is a wildcard pattern, not an identifier"); err.note("`_` is a wildcard pattern, not an identifier");
} }
Err(err) Err(err)
} }
@ -1082,7 +1082,7 @@ impl<'a> Parser<'a> {
} }
pub fn span_fatal_help(&self, sp: Span, m: &str, help: &str) -> DiagnosticBuilder<'a> { pub fn span_fatal_help(&self, sp: Span, m: &str, help: &str) -> DiagnosticBuilder<'a> {
let mut err = self.sess.span_diagnostic.struct_span_fatal(sp, m); let mut err = self.sess.span_diagnostic.struct_span_fatal(sp, m);
err.fileline_help(sp, help); err.help(help);
err err
} }
pub fn bug(&self, m: &str) -> ! { pub fn bug(&self, m: &str) -> ! {
@ -2622,8 +2622,7 @@ impl<'a> Parser<'a> {
Some(f) => f, Some(f) => f,
None => continue, None => continue,
}; };
err.fileline_help(last_span, err.help(&format!("try parenthesizing the first index; e.g., `(foo.{}){}`",
&format!("try parenthesizing the first index; e.g., `(foo.{}){}`",
float.trunc() as usize, float.trunc() as usize,
format!(".{}", fstr.splitn(2, ".").last().unwrap()))); format!(".{}", fstr.splitn(2, ".").last().unwrap())));
} }
@ -3134,7 +3133,7 @@ impl<'a> Parser<'a> {
let mut err = self.diagnostic().struct_span_err(op_span, let mut err = self.diagnostic().struct_span_err(op_span,
"chained comparison operators require parentheses"); "chained comparison operators require parentheses");
if op.node == BinOpKind::Lt && *outer_op == AssocOp::Greater { if op.node == BinOpKind::Lt && *outer_op == AssocOp::Greater {
err.fileline_help(op_span, err.help(
"use `::<...>` instead of `<...>` if you meant to specify type arguments"); "use `::<...>` instead of `<...>` if you meant to specify type arguments");
} }
err.emit(); err.emit();
@ -4951,12 +4950,12 @@ impl<'a> Parser<'a> {
if is_macro_rules { if is_macro_rules {
self.diagnostic().struct_span_err(span, "can't qualify macro_rules \ self.diagnostic().struct_span_err(span, "can't qualify macro_rules \
invocation with `pub`") invocation with `pub`")
.fileline_help(span, "did you mean #[macro_export]?") .help("did you mean #[macro_export]?")
.emit(); .emit();
} else { } else {
self.diagnostic().struct_span_err(span, "can't qualify macro \ self.diagnostic().struct_span_err(span, "can't qualify macro \
invocation with `pub`") invocation with `pub`")
.fileline_help(span, "try adjusting the macro to put `pub` \ .help("try adjusting the macro to put `pub` \
inside the invocation") inside the invocation")
.emit(); .emit();
} }
@ -5857,7 +5856,7 @@ impl<'a> Parser<'a> {
if self.eat_keyword(keywords::Mut) { if self.eat_keyword(keywords::Mut) {
let last_span = self.last_span; let last_span = self.last_span;
self.diagnostic().struct_span_err(last_span, "const globals cannot be mutable") self.diagnostic().struct_span_err(last_span, "const globals cannot be mutable")
.fileline_help(last_span, "did you mean to declare a static?") .help("did you mean to declare a static?")
.emit(); .emit();
} }
let (ident, item_, extra_attrs) = self.parse_item_const(None)?; let (ident, item_, extra_attrs) = self.parse_item_const(None)?;