Skip to content

Commit

Permalink
Rollup merge of #105500 - oli-obk:unhide_unknown_spans, r=estebank
Browse files Browse the repository at this point in the history
Make some diagnostics not depend on the source of what they reference being available

r? `@estebank`

follow up to #104449
  • Loading branch information
matthiaskrgr committed Dec 13, 2022
2 parents dcdbbd0 + 82ce70a commit 15b9e20
Show file tree
Hide file tree
Showing 246 changed files with 381 additions and 1,666 deletions.
24 changes: 16 additions & 8 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1059,17 +1059,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
if self.fn_self_span_reported.insert(fn_span) {
err.span_note(
// Check whether the source is accessible
if self.infcx.tcx.sess.source_map().is_span_accessible(self_arg.span) {
self_arg.span
} else {
fn_call_span
},
self_arg.span,
"calling this operator moves the left-hand side",
);
}
}
CallKind::Normal { self_arg, desugaring, is_option_or_result } => {
CallKind::Normal { self_arg, desugaring, method_did } => {
let self_arg = self_arg.unwrap();
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
let ty = moved_place.ty(self.body, self.infcx.tcx).ty;
Expand Down Expand Up @@ -1139,14 +1134,27 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
),
);
}
let tcx = self.infcx.tcx;
// Avoid pointing to the same function in multiple different
// error messages.
if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span) {
let func = tcx.def_path_str(method_did);
err.span_note(
self_arg.span,
&format!("this function takes ownership of the receiver `self`, which moves {}", place_name)
&format!("`{func}` takes ownership of the receiver `self`, which moves {place_name}")
);
}
let parent_did = tcx.parent(method_did);
let parent_self_ty = (tcx.def_kind(parent_did)
== rustc_hir::def::DefKind::Impl)
.then_some(parent_did)
.and_then(|did| match tcx.type_of(did).kind() {
ty::Adt(def, ..) => Some(def.did()),
_ => None,
});
let is_option_or_result = parent_self_ty.map_or(false, |def_id| {
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
});
if is_option_or_result && maybe_reinitialized_locations_is_empty {
err.span_label(
var_span,
Expand Down
18 changes: 3 additions & 15 deletions compiler/rustc_const_eval/src/util/call_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use rustc_hir::def_id::DefId;
use rustc_hir::{lang_items, LangItem};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, AssocItemContainer, DefIdTree, Instance, ParamEnv, Ty, TyCtxt};
use rustc_middle::ty::{AssocItemContainer, Instance, ParamEnv, Ty, TyCtxt};
use rustc_span::symbol::Ident;
use rustc_span::{sym, DesugaringKind, Span};

Expand Down Expand Up @@ -39,9 +39,7 @@ pub enum CallKind<'tcx> {
Normal {
self_arg: Option<Ident>,
desugaring: Option<(CallDesugaringKind, Ty<'tcx>)>,
/// Whether the self type of the method call has an `.as_ref()` method.
/// Used for better diagnostics.
is_option_or_result: bool,
method_did: DefId,
},
/// A call to `Fn(..)::call(..)`, desugared from `my_closure(a, b, c)`
FnCall { fn_trait_id: DefId, self_ty: Ty<'tcx> },
Expand Down Expand Up @@ -133,16 +131,6 @@ pub fn call_kind<'tcx>(
} else {
None
};
let parent_did = tcx.parent(method_did);
let parent_self_ty = (tcx.def_kind(parent_did) == rustc_hir::def::DefKind::Impl)
.then_some(parent_did)
.and_then(|did| match tcx.type_of(did).kind() {
ty::Adt(def, ..) => Some(def.did()),
_ => None,
});
let is_option_or_result = parent_self_ty.map_or(false, |def_id| {
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
});
CallKind::Normal { self_arg, desugaring, is_option_or_result }
CallKind::Normal { self_arg, desugaring, method_did }
})
}
79 changes: 44 additions & 35 deletions compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1408,49 +1408,58 @@ impl EmitterWriter {
if !sm.ensure_source_file_source_present(annotated_file.file.clone()) {
if !self.short_message {
// We'll just print an unannotated message.
for (annotation_id, line) in annotated_file.lines.into_iter().enumerate() {
for (annotation_id, line) in annotated_file.lines.iter().enumerate() {
let mut annotations = line.annotations.clone();
annotations.sort_by_key(|a| Reverse(a.start_col));
let mut line_idx = buffer.num_lines();
buffer.append(
line_idx,
&format!(
"{}:{}:{}",
sm.filename_for_diagnostics(&annotated_file.file.name),
sm.doctest_offset_line(&annotated_file.file.name, line.line_index),
annotations[0].start_col + 1,
),
Style::LineAndColumn,
);
if annotation_id == 0 {
buffer.prepend(line_idx, "--> ", Style::LineNumber);

let labels: Vec<_> = annotations
.iter()
.filter_map(|a| Some((a.label.as_ref()?, a.is_primary)))
.filter(|(l, _)| !l.is_empty())
.collect();

if annotation_id == 0 || !labels.is_empty() {
buffer.append(
line_idx,
&format!(
"{}:{}:{}",
sm.filename_for_diagnostics(&annotated_file.file.name),
sm.doctest_offset_line(
&annotated_file.file.name,
line.line_index
),
annotations[0].start_col + 1,
),
Style::LineAndColumn,
);
if annotation_id == 0 {
buffer.prepend(line_idx, "--> ", Style::LineNumber);
} else {
buffer.prepend(line_idx, "::: ", Style::LineNumber);
}
for _ in 0..max_line_num_len {
buffer.prepend(line_idx, " ", Style::NoStyle);
}
line_idx += 1;
};
for (i, annotation) in annotations.into_iter().enumerate() {
if let Some(label) = &annotation.label {
let style = if annotation.is_primary {
Style::LabelPrimary
} else {
Style::LabelSecondary
};
if annotation_id == 0 {
buffer.prepend(line_idx, " |", Style::LineNumber);
for _ in 0..max_line_num_len {
buffer.prepend(line_idx, " ", Style::NoStyle);
}
line_idx += 1;
buffer.append(line_idx + i, " = note: ", style);
for _ in 0..max_line_num_len {
buffer.prepend(line_idx, " ", Style::NoStyle);
}
} else {
buffer.append(line_idx + i, ": ", style);
}
buffer.append(line_idx + i, label, style);
}
for (label, is_primary) in labels.into_iter() {
let style = if is_primary {
Style::LabelPrimary
} else {
Style::LabelSecondary
};
buffer.prepend(line_idx, " |", Style::LineNumber);
for _ in 0..max_line_num_len {
buffer.prepend(line_idx, " ", Style::NoStyle);
}
line_idx += 1;
buffer.append(line_idx, " = note: ", style);
for _ in 0..max_line_num_len {
buffer.prepend(line_idx, " ", Style::NoStyle);
}
buffer.append(line_idx, label, style);
line_idx += 1;
}
}
}
Expand Down
23 changes: 18 additions & 5 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1853,7 +1853,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
)],
) {
let mut derives = Vec::<(String, Span, Symbol)>::new();
let mut traits = Vec::<Span>::new();
let mut traits = Vec::new();
for (pred, _, _) in unsatisfied_predicates {
let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = pred.kind().skip_binder() else { continue };
let adt = match trait_pred.self_ty().ty_adt_def() {
Expand Down Expand Up @@ -1892,10 +1892,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
derives.push((self_name, self_span, diagnostic_name));
} else {
traits.push(self.tcx.def_span(trait_pred.def_id()));
traits.push(trait_pred.def_id());
}
} else {
traits.push(self.tcx.def_span(trait_pred.def_id()));
traits.push(trait_pred.def_id());
}
}
traits.sort();
Expand All @@ -1918,10 +1918,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let len = traits.len();
if len > 0 {
let span: MultiSpan = traits.into();
let span =
MultiSpan::from_spans(traits.iter().map(|&did| self.tcx.def_span(did)).collect());
let mut names = format!("`{}`", self.tcx.def_path_str(traits[0]));
for (i, &did) in traits.iter().enumerate().skip(1) {
if len > 2 {
names.push_str(", ");
}
if i == len - 1 {
names.push_str(" and ");
}
names.push('`');
names.push_str(&self.tcx.def_path_str(did));
names.push('`');
}
err.span_note(
span,
&format!("the following trait{} must be implemented", pluralize!(len),),
&format!("the trait{} {} must be implemented", pluralize!(len), names),
);
}

Expand Down
16 changes: 9 additions & 7 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1527,13 +1527,15 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
if let Some(virtual_dir) = &sess.opts.unstable_opts.simulate_remapped_rust_src_base
{
if let Some(real_dir) = &sess.opts.real_rust_source_base_dir {
if let rustc_span::FileName::Real(ref mut old_name) = name {
if let rustc_span::RealFileName::LocalPath(local) = old_name {
if let Ok(rest) = local.strip_prefix(real_dir) {
*old_name = rustc_span::RealFileName::Remapped {
local_path: None,
virtual_name: virtual_dir.join(rest),
};
for subdir in ["library", "compiler"] {
if let rustc_span::FileName::Real(ref mut old_name) = name {
if let rustc_span::RealFileName::LocalPath(local) = old_name {
if let Ok(rest) = local.strip_prefix(real_dir.join(subdir)) {
*old_name = rustc_span::RealFileName::Remapped {
local_path: None,
virtual_name: virtual_dir.join(subdir).join(rest),
};
}
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1308,15 +1308,15 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
let is_local_static =
if let DefKind::Static(_) = kind { def_id.is_local() } else { false };
if !self.item_is_accessible(def_id) && !is_local_static {
let sess = self.tcx.sess;
let sm = sess.source_map();
let name = match qpath {
hir::QPath::Resolved(..) | hir::QPath::LangItem(..) => {
sm.span_to_snippet(qpath.span()).ok()
let name = match *qpath {
hir::QPath::LangItem(it, ..) => {
self.tcx.lang_items().get(it).map(|did| self.tcx.def_path_str(did))
}
hir::QPath::Resolved(_, path) => Some(self.tcx.def_path_str(path.res.def_id())),
hir::QPath::TypeRelative(_, segment) => Some(segment.ident.to_string()),
};
let kind = kind.descr(def_id);
let sess = self.tcx.sess;
let _ = match name {
Some(name) => {
sess.emit_err(ItemIsPrivate { span, kind, descr: (&name).into() })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2179,15 +2179,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
format!("does not implement `{}`", trait_pred.print_modifiers_and_trait_path())
};

let mut explain_yield = |interior_span: Span,
yield_span: Span,
scope_span: Option<Span>| {
let mut span = MultiSpan::from_span(yield_span);
if let Ok(snippet) = source_map.span_to_snippet(interior_span) {
// #70935: If snippet contains newlines, display "the value" instead
// so that we do not emit complex diagnostics.
let snippet = &format!("`{}`", snippet);
let snippet = if snippet.contains('\n') { "the value" } else { snippet };
let mut explain_yield =
|interior_span: Span, yield_span: Span, scope_span: Option<Span>| {
let mut span = MultiSpan::from_span(yield_span);
let snippet = match source_map.span_to_snippet(interior_span) {
// #70935: If snippet contains newlines, display "the value" instead
// so that we do not emit complex diagnostics.
Ok(snippet) if !snippet.contains('\n') => format!("`{}`", snippet),
_ => "the value".to_string(),
};
// note: future is not `Send` as this value is used across an await
// --> $DIR/issue-70935-complex-spans.rs:13:9
// |
Expand All @@ -2212,17 +2212,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
interior_span,
format!("has type `{}` which {}", target_ty, trait_explanation),
);
// If available, use the scope span to annotate the drop location.
let mut scope_note = None;
if let Some(scope_span) = scope_span {
let scope_span = source_map.end_point(scope_span);

let msg = format!("{} is later dropped here", snippet);
if source_map.is_multiline(yield_span.between(scope_span)) {
span.push_span_label(scope_span, msg);
} else {
scope_note = Some((scope_span, msg));
}
span.push_span_label(scope_span, msg);
}
err.span_note(
span,
Expand All @@ -2231,11 +2225,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
future_or_generator, trait_explanation, an_await_or_yield
),
);
if let Some((span, msg)) = scope_note {
err.span_note(span, &msg);
}
}
};
};
match interior_or_upvar_span {
GeneratorInteriorOrUpvar::Interior(interior_span, interior_extra_info) => {
if let Some((scope_span, yield_span, expr, from_awaited_ty)) = interior_extra_info {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -660,10 +660,7 @@ LL | #[derive(Diagnostic)]
= help: normalized in stderr
note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg`
--> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:LL:CC
|
LL | arg: impl IntoDiagnosticArg,
| ^^^^^^^^^^^^^^^^^ required by this bound in `DiagnosticBuilder::<'a, G>::set_arg`
= note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the derive macro `Diagnostic` which comes from the expansion of the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 83 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ LL | | }
= note: struct `core::alloc::Layout` and struct `Layout` have similar names, but are actually distinct types
note: struct `core::alloc::Layout` is defined in crate `core`
--> $SRC_DIR/core/src/alloc/layout.rs:LL:COL
|
LL | pub struct Layout {
| ^^^^^^^^^^^^^^^^^
note: struct `Layout` is defined in the current crate
--> $DIR/alloc-error-handler-bad-signature-2.rs:7:1
|
Expand Down
3 changes: 0 additions & 3 deletions src/test/ui/associated-type-bounds/issue-99828.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ LL | fn get_iter(vec: &[i32]) -> impl Iterator<Item = {}> + '_ {
|
note: associated type defined here
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
LL | type Item;
| ^^^^^^^^^

error: aborting due to 2 previous errors

Expand Down
3 changes: 0 additions & 3 deletions src/test/ui/associated-types/defaults-wf.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ LL | type Ty = Vec<[u8]>;
= help: the trait `Sized` is not implemented for `[u8]`
note: required by a bound in `Vec`
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
| ^ required by this bound in `Vec`

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ LL | trait ArithmeticOps: Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self>
|
note: required by a bound in `Add`
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
|
LL | pub trait Add<Rhs = Self> {
| ^^^^^^^^^^ required by this bound in `Add`
help: consider further restricting `Self`
|
LL | trait ArithmeticOps: Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + Div<Output=Self> + Sized {}
Expand Down
Loading

0 comments on commit 15b9e20

Please sign in to comment.