Skip to content

Commit 1d17b6a

Browse files
authored
Rollup merge of rust-lang#109082 - estebank:macro-spans, r=oli-obk
Do not provide suggestions when the spans come from expanded code that doesn't point at user code Hide invalid proc-macro suggestions and track spans coming from proc-macros pointing at attribute. Effectively, unless the proc-macro keeps user spans, suggestions will not be produced for the code they produce. r? `@ghost` Fix rust-lang#107113, fix rust-lang#107976, fix rust-lang#107977, fix rust-lang#108748, fix rust-lang#106720, fix rust-lang#90557. Could potentially address rust-lang#50141, rust-lang#67373, rust-lang#55146, rust-lang#78862, rust-lang#74043, rust-lang#88514, rust-lang#83320, rust-lang#91520, rust-lang#104071. CC rust-lang#50122, rust-lang#76360.
2 parents 3182334 + 019556d commit 1d17b6a

File tree

78 files changed

+3198
-2771
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+3198
-2771
lines changed

compiler/rustc_ast_lowering/src/path.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
286286
segment_ident_span.find_ancestor_inside(path_span).unwrap_or(path_span)
287287
} else if generic_args.is_empty() {
288288
// If there are brackets, but not generic arguments, then use the opening bracket
289-
generic_args.span.with_hi(generic_args.span.lo() + BytePos(1))
289+
self.tcx
290+
.mark_span_for_resize(generic_args.span)
291+
.with_hi(generic_args.span.lo() + BytePos(1))
290292
} else {
291293
// Else use an empty span right after the opening bracket.
292-
generic_args.span.with_lo(generic_args.span.lo() + BytePos(1)).shrink_to_lo()
294+
self.tcx
295+
.mark_span_for_resize(generic_args.span)
296+
.with_lo(generic_args.span.lo() + BytePos(1))
297+
.shrink_to_lo()
293298
};
294299

295300
generic_args.args.insert_many(

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,12 +2073,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
20732073
Ok(string) => {
20742074
if string.starts_with("async ") {
20752075
let pos = args_span.lo() + BytePos(6);
2076-
(args_span.with_lo(pos).with_hi(pos), "move ")
2076+
(
2077+
self.infcx.tcx.mark_span_for_resize(args_span).with_lo(pos).with_hi(pos),
2078+
"move ",
2079+
)
20772080
} else if string.starts_with("async|") {
20782081
let pos = args_span.lo() + BytePos(5);
2079-
(args_span.with_lo(pos).with_hi(pos), " move")
2082+
(
2083+
self.infcx.tcx.mark_span_for_resize(args_span).with_lo(pos).with_hi(pos),
2084+
" move",
2085+
)
20802086
} else {
2081-
(args_span.shrink_to_lo(), "move ")
2087+
(self.infcx.tcx.mark_span_for_resize(args_span).shrink_to_lo(), "move ")
20822088
}
20832089
}
20842090
Err(_) => (args_span, "move |<args>| <body>"),

compiler/rustc_borrowck/src/diagnostics/move_errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,15 +457,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
457457
match self.infcx.tcx.sess.source_map().span_to_snippet(span) {
458458
Ok(snippet) if snippet.starts_with('*') => {
459459
err.span_suggestion_verbose(
460-
span.with_hi(span.lo() + BytePos(1)),
460+
self.infcx.tcx.mark_span_for_resize(span).with_hi(span.lo() + BytePos(1)),
461461
"consider removing the dereference here",
462462
String::new(),
463463
Applicability::MaybeIncorrect,
464464
);
465465
}
466466
_ => {
467467
err.span_suggestion_verbose(
468-
span.shrink_to_lo(),
468+
self.infcx.tcx.mark_span_for_resize(span).shrink_to_lo(),
469469
"consider borrowing here",
470470
'&',
471471
Applicability::MaybeIncorrect,

compiler/rustc_builtin_macros/src/alloc_error_handler.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ pub fn expand(
2020

2121
// Allow using `#[alloc_error_handler]` on an item statement
2222
// FIXME - if we get deref patterns, use them to reduce duplication here
23-
let (item, is_stmt, sig_span) =
23+
let (item, is_stmt, sig) =
2424
if let Annotatable::Item(item) = &item
2525
&& let ItemKind::Fn(fn_kind) = &item.kind
2626
{
27-
(item, false, ecx.with_def_site_ctxt(fn_kind.sig.span))
27+
(item, false, &fn_kind.sig)
2828
} else if let Annotatable::Stmt(stmt) = &item
2929
&& let StmtKind::Item(item) = &stmt.kind
3030
&& let ItemKind::Fn(fn_kind) = &item.kind
3131
{
32-
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
32+
(item, true, &fn_kind.sig)
3333
} else {
3434
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "alloc_error_handler must be a function");
3535
return vec![orig_item];
@@ -39,10 +39,10 @@ pub fn expand(
3939
let span = ecx.with_def_site_ctxt(item.span);
4040

4141
// Generate item statements for the allocator methods.
42-
let stmts = thin_vec![generate_handler(ecx, item.ident, span, sig_span)];
42+
let stmts = thin_vec![generate_handler(ecx, item.ident, span, sig)];
4343

4444
// Generate anonymous constant serving as container for the allocator methods.
45-
let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new()));
45+
let const_ty = ecx.ty(ecx.with_def_site_ctxt(sig.span), TyKind::Tup(ThinVec::new()));
4646
let const_body = ecx.expr_block(ecx.block(span, stmts));
4747
let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
4848
let const_item = if is_stmt {
@@ -59,27 +59,31 @@ pub fn expand(
5959
// unsafe fn __rg_oom(size: usize, align: usize) -> ! {
6060
// handler(core::alloc::Layout::from_size_align_unchecked(size, align))
6161
// }
62-
fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt {
62+
fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig: &FnSig) -> Stmt {
6363
let usize = cx.path_ident(span, Ident::new(sym::usize, span));
6464
let ty_usize = cx.ty_path(usize);
6565
let size = Ident::from_str_and_span("size", span);
6666
let align = Ident::from_str_and_span("align", span);
6767

68+
let sig_span = cx.with_def_site_ctxt(sig.span);
69+
let ret_sp = cx.with_def_site_ctxt(sig.decl.output.span());
70+
71+
// core::alloc::Layout::from_size_align_unchecked(size, align)
6872
let layout_new = cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]);
6973
let layout_new = cx.expr_path(cx.path(span, layout_new));
7074
let layout = cx.expr_call(
71-
span,
75+
cx.with_def_site_ctxt(sig.decl.inputs.get(0).map_or(span, |p| p.span)),
7276
layout_new,
7377
thin_vec![cx.expr_ident(span, size), cx.expr_ident(span, align)],
7478
);
75-
76-
let call = cx.expr_call_ident(sig_span, handler, thin_vec![layout]);
79+
let call =
80+
cx.expr(ret_sp, ast::ExprKind::Call(cx.expr_ident(span, handler), thin_vec![layout]));
7781

7882
let never = ast::FnRetTy::Ty(cx.ty(span, TyKind::Never));
7983
let params = thin_vec![cx.param(span, size, ty_usize.clone()), cx.param(span, align, ty_usize)];
8084
let decl = cx.fn_decl(params, never);
8185
let header = FnHeader { unsafety: Unsafe::Yes(span), ..FnHeader::default() };
82-
let sig = FnSig { decl, header, span: span };
86+
let sig = FnSig { decl, header, span };
8387

8488
let body = Some(cx.block_expr(call));
8589
let kind = ItemKind::Fn(Box::new(Fn {

compiler/rustc_builtin_macros/src/derive.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ fn report_unexpected_meta_item_lit(sess: &Session, lit: &ast::MetaItemLit) {
138138
}
139139
_ => "for example, write `#[derive(Debug)]` for `Debug`".to_string(),
140140
};
141-
struct_span_err!(sess, lit.span, E0777, "expected path to a trait, found literal",)
141+
struct_span_err!(sess, lit.span, E0777, "expected path to a trait, found literal")
142142
.span_label(lit.span, "not a trait")
143143
.help(&help_msg)
144144
.emit();

compiler/rustc_const_eval/src/transform/check_consts/ops.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,17 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
256256
{
257257
let rhs_pos =
258258
span.lo() + BytePos::from_usize(eq_idx + 2 + rhs_idx);
259-
let rhs_span = span.with_lo(rhs_pos).with_hi(rhs_pos);
259+
let rhs_span = tcx
260+
.mark_span_for_resize(span)
261+
.with_lo(rhs_pos)
262+
.with_hi(rhs_pos);
260263
err.multipart_suggestion(
261264
"consider dereferencing here",
262265
vec![
263-
(span.shrink_to_lo(), deref.clone()),
266+
(
267+
tcx.mark_span_for_resize(span).shrink_to_lo(),
268+
deref.clone(),
269+
),
264270
(rhs_span, deref),
265271
],
266272
Applicability::MachineApplicable,

compiler/rustc_errors/src/diagnostic.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,10 @@ impl Diagnostic {
621621
.map(|(span, snippet)| SubstitutionPart { snippet, span })
622622
.collect::<Vec<_>>();
623623

624+
if !parts.iter().all(|sub| sub.span.can_be_used_for_suggestions()) {
625+
return self;
626+
}
627+
624628
parts.sort_unstable_by_key(|part| part.span);
625629

626630
assert!(!parts.is_empty());
@@ -711,6 +715,9 @@ impl Diagnostic {
711715
!(sp.is_empty() && suggestion.to_string().is_empty()),
712716
"Span must not be empty and have no suggestion"
713717
);
718+
if !sp.can_be_used_for_suggestions() {
719+
return self;
720+
}
714721
self.push_suggestion(CodeSuggestion {
715722
substitutions: vec![Substitution {
716723
parts: vec![SubstitutionPart { snippet: suggestion.to_string(), span: sp }],
@@ -774,6 +781,9 @@ impl Diagnostic {
774781
!(sp.is_empty() && suggestions.iter().any(|suggestion| suggestion.is_empty())),
775782
"Span must not be empty and have no suggestion"
776783
);
784+
if !sp.can_be_used_for_suggestions() {
785+
return self;
786+
}
777787

778788
let substitutions = suggestions
779789
.into_iter()
@@ -799,12 +809,16 @@ impl Diagnostic {
799809
) -> &mut Self {
800810
let substitutions = suggestions
801811
.into_iter()
802-
.map(|sugg| {
812+
.filter_map(|sugg| {
803813
let mut parts = sugg
804814
.into_iter()
805815
.map(|(span, snippet)| SubstitutionPart { snippet, span })
806816
.collect::<Vec<_>>();
807817

818+
if !parts.iter().all(|sub| sub.span.can_be_used_for_suggestions()) {
819+
return None;
820+
}
821+
808822
parts.sort_unstable_by_key(|part| part.span);
809823

810824
assert!(!parts.is_empty());
@@ -819,7 +833,7 @@ impl Diagnostic {
819833
"suggestion must not have overlapping parts",
820834
);
821835

822-
Substitution { parts }
836+
Some(Substitution { parts })
823837
})
824838
.collect();
825839

compiler/rustc_errors/src/emitter.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use Destination::*;
1111

1212
use rustc_span::source_map::SourceMap;
13-
use rustc_span::{FileLines, SourceFile, Span};
13+
use rustc_span::{DesugaringKind, FileLines, SourceFile, Span};
1414

1515
use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Style, StyledString};
1616
use crate::styled_buffer::StyledBuffer;
@@ -400,12 +400,13 @@ pub trait Emitter: Translate {
400400
// entries we don't want to print, to make sure the indices being
401401
// printed are contiguous (or omitted if there's only one entry).
402402
let macro_backtrace: Vec<_> = sp.macro_backtrace().collect();
403-
for (i, trace) in macro_backtrace.iter().rev().enumerate() {
404-
if trace.def_site.is_dummy() {
405-
continue;
406-
}
407-
408-
if always_backtrace && !matches!(trace.kind, ExpnKind::Inlined) {
403+
for (i, trace) in macro_backtrace.iter().rev().enumerate().filter(|(_, trace)| {
404+
!matches!(
405+
trace.kind,
406+
ExpnKind::Inlined | ExpnKind::Desugaring(DesugaringKind::Resize)
407+
) && !trace.def_site.is_dummy()
408+
}) {
409+
if always_backtrace {
409410
new_labels.push((
410411
trace.def_site,
411412
format!(

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,7 +1351,8 @@ fn compare_number_of_method_arguments<'tcx>(
13511351
if pos == 0 {
13521352
arg.span
13531353
} else {
1354-
arg.span.with_lo(trait_m_sig.decl.inputs[0].span.lo())
1354+
tcx.mark_span_for_resize(arg.span)
1355+
.with_lo(trait_m_sig.decl.inputs[0].span.lo())
13551356
}
13561357
})
13571358
})
@@ -1367,7 +1368,7 @@ fn compare_number_of_method_arguments<'tcx>(
13671368
if pos == 0 {
13681369
arg.span
13691370
} else {
1370-
arg.span.with_lo(impl_m_sig.decl.inputs[0].span.lo())
1371+
tcx.mark_span_for_resize(arg.span).with_lo(impl_m_sig.decl.inputs[0].span.lo())
13711372
}
13721373
})
13731374
.unwrap_or_else(|| tcx.def_span(impl_m.def_id));
@@ -1464,7 +1465,9 @@ fn compare_synthetic_generics<'tcx>(
14641465

14651466
// in case there are no generics, take the spot between the function name
14661467
// and the opening paren of the argument list
1467-
let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi();
1468+
let new_generics_span = tcx
1469+
.mark_span_for_resize(tcx.def_ident_span(impl_def_id)?)
1470+
.shrink_to_hi();
14681471
// in case there are generics, just replace them
14691472
let generics_span =
14701473
impl_m.generics.span.substitute_dummy(new_generics_span);

compiler/rustc_hir_analysis/src/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ fn missing_items_err(
220220
let hi = full_impl_span.hi() - BytePos(1);
221221
// Point at the place right before the closing brace of the relevant `impl` to suggest
222222
// adding the associated item at the end of its body.
223-
let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
223+
let sugg_sp = tcx.mark_span_for_resize(full_impl_span).with_lo(hi).with_hi(hi);
224224
// Obtain the level of indentation ending in `sugg_sp`.
225225
let padding =
226226
tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new());

compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
594594

595595
match self.angle_brackets {
596596
AngleBrackets::Missing => {
597-
let span = self.path_segment.ident.span;
597+
let span = self.tcx.mark_span_for_resize(self.path_segment.ident.span);
598598

599599
// insert a suggestion of the form "Y<'a, 'b>"
600600
let sugg = format!("<{}>", suggested_args);
@@ -610,11 +610,23 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
610610

611611
AngleBrackets::Available => {
612612
let (sugg_span, is_first) = if self.num_provided_lifetime_args() == 0 {
613-
(self.gen_args.span().unwrap().shrink_to_lo(), true)
613+
(
614+
self.tcx.mark_span_for_resize(self.gen_args.span().unwrap()).shrink_to_lo(),
615+
true,
616+
)
614617
} else {
615618
let last_lt = &self.gen_args.args[self.num_provided_lifetime_args() - 1];
616-
(last_lt.span().shrink_to_hi(), false)
619+
(self.tcx.mark_span_for_resize(last_lt.span()).shrink_to_hi(), false)
617620
};
621+
let path_sp = self.path_segment.ident.span.peel_ctxt();
622+
if !self.gen_args.args.iter().all(|arg| {
623+
arg.span().can_be_used_for_suggestions()
624+
&& arg.span().peel_ctxt().ctxt() == path_sp.ctxt()
625+
}) || !path_sp.can_be_used_for_suggestions()
626+
{
627+
// Do not suggest syntax when macros are involved. (#90557)
628+
return;
629+
}
618630
let has_non_lt_args = self.num_provided_type_or_const_args() != 0;
619631
let has_bindings = !self.gen_args.bindings.is_empty();
620632

@@ -644,7 +656,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
644656

645657
match self.angle_brackets {
646658
AngleBrackets::Missing | AngleBrackets::Implied => {
647-
let span = self.path_segment.ident.span;
659+
let span = self.tcx.mark_span_for_resize(self.path_segment.ident.span);
648660

649661
// insert a suggestion of the form "Y<T, U>"
650662
let sugg = format!("<{}>", suggested_args);
@@ -658,14 +670,24 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
658670
);
659671
}
660672
AngleBrackets::Available => {
661-
let gen_args_span = self.gen_args.span().unwrap();
673+
let path_sp = self.path_segment.ident.span.peel_ctxt();
674+
if !self.gen_args.args.iter().all(|arg| {
675+
arg.span().can_be_used_for_suggestions()
676+
&& arg.span().peel_ctxt().ctxt() == path_sp.ctxt()
677+
}) || !path_sp.can_be_used_for_suggestions()
678+
{
679+
// Do not suggest syntax when macros are involved. (#90557)
680+
return;
681+
}
682+
let gen_args_span = self.tcx.mark_span_for_resize(self.gen_args.span().unwrap());
662683
let sugg_offset =
663684
self.get_lifetime_args_offset() + self.num_provided_type_or_const_args();
664685

665686
let (sugg_span, is_first) = if sugg_offset == 0 {
666-
(gen_args_span.shrink_to_lo(), true)
687+
(self.tcx.mark_span_for_resize(gen_args_span).shrink_to_lo(), true)
667688
} else {
668-
let arg_span = self.gen_args.args[sugg_offset - 1].span();
689+
let arg_span =
690+
self.tcx.mark_span_for_resize(self.gen_args.args[sugg_offset - 1].span());
669691
// If we came here then inferred lifetime's spans can only point
670692
// to either the opening bracket or to the space right after.
671693
// Both of these spans have an `hi` lower than or equal to the span
@@ -770,7 +792,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
770792
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
771793
let sugg = vec![
772794
(self.path_segment.ident.span, format!("{}::{}", snippet, self.path_segment.ident)),
773-
(span.with_lo(self.path_segment.ident.span.hi()), "".to_owned())
795+
(self.tcx.mark_span_for_resize(span).with_lo(self.path_segment.ident.span.hi()), "".to_owned())
774796
];
775797

776798
err.multipart_suggestion(
@@ -953,11 +975,8 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
953975
}
954976
} else if remove_entire_generics {
955977
let span = self
956-
.path_segment
957-
.args
958-
.unwrap()
959-
.span_ext()
960-
.unwrap()
978+
.tcx
979+
.mark_span_for_resize(self.path_segment.args.unwrap().span_ext().unwrap())
961980
.with_lo(self.path_segment.ident.span.hi());
962981

963982
let msg = format!(

0 commit comments

Comments
 (0)