Skip to content

Commit d5ba3ef

Browse files
committed
Auto merge of #75465 - Aaron1011:feature/short-fn-def-span, r=estebank
Use smaller def span for functions Currently, the def span of a function encompasses the entire function signature and body. However, this is usually unnecessarily verbose - when we are pointing at an entire function in a diagnostic, we almost always want to point at the signature. The actual contents of the body tends to be irrelevant to the diagnostic we are emitting, and just takes up additional screen space. This commit changes the `def_span` of all function items (freestanding functions, `impl`-block methods, and `trait`-block methods) to be the span of the signature. For example, the function ```rust pub fn foo<T>(val: T) -> T { val } ``` now has a `def_span` corresponding to `pub fn foo<T>(val: T) -> T` (everything before the opening curly brace). Trait methods without a body have a `def_span` which includes the trailing semicolon. For example: ```rust trait Foo { fn bar(); } ``` the function definition `Foo::bar` has a `def_span` of `fn bar();` This makes our diagnostic output much shorter, and emphasizes information that is relevant to whatever diagnostic we are reporting. We continue to use the full span (including the body) in a few of places: * MIR building uses the full span when building source scopes. * 'Outlives suggestions' use the full span to sort the diagnostics being emitted. * The `#[rustc_on_unimplemented(enclosing_scope="in this scope")]` attribute points the entire scope body. All of these cases work only with local items, so we don't need to add anything extra to crate metadata.
2 parents d5abc8d + e3cd43e commit d5ba3ef

File tree

107 files changed

+345
-576
lines changed

Some content is hidden

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

107 files changed

+345
-576
lines changed

src/librustc_ast/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,6 +1671,7 @@ pub struct MutTy {
16711671
pub struct FnSig {
16721672
pub header: FnHeader,
16731673
pub decl: P<FnDecl>,
1674+
pub span: Span,
16741675
}
16751676

16761677
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]

src/librustc_ast/mut_visit.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,10 @@ pub fn visit_bounds<T: MutVisitor>(bounds: &mut GenericBounds, vis: &mut T) {
363363
}
364364

365365
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
366-
pub fn visit_fn_sig<T: MutVisitor>(FnSig { header, decl }: &mut FnSig, vis: &mut T) {
366+
pub fn visit_fn_sig<T: MutVisitor>(FnSig { header, decl, span }: &mut FnSig, vis: &mut T) {
367367
vis.visit_fn_header(header);
368368
vis.visit_fn_decl(decl);
369+
vis.visit_span(span);
369370
}
370371

371372
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.

src/librustc_ast_lowering/item.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
263263
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
264264
hir::ItemKind::Const(ty, body_id)
265265
}
266-
ItemKind::Fn(_, FnSig { ref decl, header }, ref generics, ref body) => {
266+
ItemKind::Fn(
267+
_,
268+
FnSig { ref decl, header, span: fn_sig_span },
269+
ref generics,
270+
ref body,
271+
) => {
267272
let fn_def_id = self.resolver.local_def_id(id);
268273
self.with_new_scopes(|this| {
269274
this.current_item = Some(ident.span);
@@ -290,7 +295,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
290295
)
291296
},
292297
);
293-
let sig = hir::FnSig { decl, header: this.lower_fn_header(header) };
298+
let sig = hir::FnSig {
299+
decl,
300+
header: this.lower_fn_header(header),
301+
span: fn_sig_span,
302+
};
294303
hir::ItemKind::Fn(sig, generics, body_id)
295304
})
296305
}
@@ -1243,7 +1252,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12431252
)
12441253
},
12451254
);
1246-
(generics, hir::FnSig { header, decl })
1255+
(generics, hir::FnSig { header, decl, span: sig.span })
12471256
}
12481257

12491258
fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {

src/librustc_builtin_macros/deriving/generic/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,7 @@ impl<'a> MethodDef<'a> {
924924
let sig = ast::FnSig {
925925
header: ast::FnHeader { unsafety, ext: ast::Extern::None, ..ast::FnHeader::default() },
926926
decl: fn_decl,
927+
span: trait_.span,
927928
};
928929
let def = ast::Defaultness::Final;
929930

src/librustc_builtin_macros/global_allocator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl AllocFnFactory<'_, '_> {
6767
let (output_ty, output_expr) = self.ret_ty(&method.output, result);
6868
let decl = self.cx.fn_decl(abi_args, ast::FnRetTy::Ty(output_ty));
6969
let header = FnHeader { unsafety: Unsafe::Yes(self.span), ..FnHeader::default() };
70-
let sig = FnSig { decl, header };
70+
let sig = FnSig { decl, header, span: self.span };
7171
let block = Some(self.cx.block_expr(output_expr));
7272
let kind = ItemKind::Fn(ast::Defaultness::Final, sig, Generics::default(), block);
7373
let item = self.cx.item(

src/librustc_builtin_macros/test_harness.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
318318
};
319319

320320
let decl = ecx.fn_decl(vec![], ast::FnRetTy::Ty(main_ret_ty));
321-
let sig = ast::FnSig { decl, header: ast::FnHeader::default() };
321+
let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp };
322322
let def = ast::Defaultness::Final;
323323
let main = ast::ItemKind::Fn(def, sig, ast::Generics::default(), Some(main_body));
324324

src/librustc_hir/hir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,6 +1851,7 @@ pub struct MutTy<'hir> {
18511851
pub struct FnSig<'hir> {
18521852
pub header: FnHeader,
18531853
pub decl: &'hir FnDecl<'hir>,
1854+
pub span: Span,
18541855
}
18551856

18561857
// The bodies for items are stored "out of line", in a separate

src/librustc_middle/hir/map/mod.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -828,13 +828,24 @@ impl<'hir> Map<'hir> {
828828
attrs.unwrap_or(&[])
829829
}
830830

831+
/// Gets the span of the definition of the specified HIR node.
832+
/// This is used by `tcx.get_span`
831833
pub fn span(&self, hir_id: HirId) -> Span {
832834
match self.find_entry(hir_id).map(|entry| entry.node) {
833835
Some(Node::Param(param)) => param.span,
834-
Some(Node::Item(item)) => item.span,
836+
Some(Node::Item(item)) => match &item.kind {
837+
ItemKind::Fn(sig, _, _) => sig.span,
838+
_ => item.span,
839+
},
835840
Some(Node::ForeignItem(foreign_item)) => foreign_item.span,
836-
Some(Node::TraitItem(trait_method)) => trait_method.span,
837-
Some(Node::ImplItem(impl_item)) => impl_item.span,
841+
Some(Node::TraitItem(trait_item)) => match &trait_item.kind {
842+
TraitItemKind::Fn(sig, _) => sig.span,
843+
_ => trait_item.span,
844+
},
845+
Some(Node::ImplItem(impl_item)) => match &impl_item.kind {
846+
ImplItemKind::Fn(sig, _) => sig.span,
847+
_ => impl_item.span,
848+
},
838849
Some(Node::Variant(variant)) => variant.span,
839850
Some(Node::Field(field)) => field.span,
840851
Some(Node::AnonConst(constant)) => self.body(constant.body).value.span,
@@ -866,6 +877,18 @@ impl<'hir> Map<'hir> {
866877
}
867878
}
868879

880+
/// Like `hir.span()`, but includes the body of function items
881+
/// (instead of just the function header)
882+
pub fn span_with_body(&self, hir_id: HirId) -> Span {
883+
match self.find_entry(hir_id).map(|entry| entry.node) {
884+
Some(Node::TraitItem(item)) => item.span,
885+
Some(Node::ImplItem(impl_item)) => impl_item.span,
886+
Some(Node::Item(item)) => item.span,
887+
Some(_) => self.span(hir_id),
888+
_ => bug!("hir::map::Map::span_with_body: id not in map: {:?}", hir_id),
889+
}
890+
}
891+
869892
pub fn span_if_local(&self, id: DefId) -> Option<Span> {
870893
id.as_local().map(|id| self.span(self.local_def_id_to_hir_id(id)))
871894
}

src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ impl OutlivesSuggestionBuilder {
257257
};
258258

259259
// We want this message to appear after other messages on the mir def.
260-
let mir_span = mbcx.infcx.tcx.def_span(mbcx.mir_def_id);
260+
let mir_span = mbcx.body.span;
261261
diag.sort_span = mir_span.shrink_to_hi();
262262

263263
// Buffer the diagnostic

src/librustc_mir_build/build/mod.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,29 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
3737
let id = tcx.hir().local_def_id_to_hir_id(def.did);
3838

3939
// Figure out what primary body this item has.
40-
let (body_id, return_ty_span) = match tcx.hir().get(id) {
40+
let (body_id, return_ty_span, span_with_body) = match tcx.hir().get(id) {
4141
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, decl, body_id, _, _), .. }) => {
42-
(*body_id, decl.output.span())
42+
(*body_id, decl.output.span(), None)
4343
}
4444
Node::Item(hir::Item {
4545
kind: hir::ItemKind::Fn(hir::FnSig { decl, .. }, _, body_id),
46+
span,
4647
..
4748
})
4849
| Node::ImplItem(hir::ImplItem {
4950
kind: hir::ImplItemKind::Fn(hir::FnSig { decl, .. }, body_id),
51+
span,
5052
..
5153
})
5254
| Node::TraitItem(hir::TraitItem {
5355
kind: hir::TraitItemKind::Fn(hir::FnSig { decl, .. }, hir::TraitFn::Provided(body_id)),
56+
span,
5457
..
55-
}) => (*body_id, decl.output.span()),
58+
}) => {
59+
// Use the `Span` of the `Item/ImplItem/TraitItem` as the body span,
60+
// since the def span of a function does not include the body
61+
(*body_id, decl.output.span(), Some(*span))
62+
}
5663
Node::Item(hir::Item {
5764
kind: hir::ItemKind::Static(ty, _, body_id) | hir::ItemKind::Const(ty, body_id),
5865
..
@@ -61,12 +68,16 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
6168
| Node::TraitItem(hir::TraitItem {
6269
kind: hir::TraitItemKind::Const(ty, Some(body_id)),
6370
..
64-
}) => (*body_id, ty.span),
65-
Node::AnonConst(hir::AnonConst { body, hir_id, .. }) => (*body, tcx.hir().span(*hir_id)),
71+
}) => (*body_id, ty.span, None),
72+
Node::AnonConst(hir::AnonConst { body, hir_id, .. }) => (*body, tcx.hir().span(*hir_id), None),
6673

6774
_ => span_bug!(tcx.hir().span(id), "can't build MIR for {:?}", def.did),
6875
};
6976

77+
// If we don't have a specialized span for the body, just use the
78+
// normal def span.
79+
let span_with_body = span_with_body.unwrap_or_else(|| tcx.hir().span(id));
80+
7081
tcx.infer_ctxt().enter(|infcx| {
7182
let cx = Cx::new(&infcx, def, id);
7283
let body = if let Some(ErrorReported) = cx.typeck_results().tainted_by_errors {
@@ -167,6 +178,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
167178
return_ty,
168179
return_ty_span,
169180
body,
181+
span_with_body
170182
);
171183
mir.yield_ty = yield_ty;
172184
mir
@@ -571,6 +583,7 @@ fn construct_fn<'a, 'tcx, A>(
571583
return_ty: Ty<'tcx>,
572584
return_ty_span: Span,
573585
body: &'tcx hir::Body<'tcx>,
586+
span_with_body: Span
574587
) -> Body<'tcx>
575588
where
576589
A: Iterator<Item = ArgInfo<'tcx>>,
@@ -585,7 +598,7 @@ where
585598

586599
let mut builder = Builder::new(
587600
hir,
588-
span,
601+
span_with_body,
589602
arguments.len(),
590603
safety,
591604
return_ty,
@@ -628,7 +641,7 @@ where
628641
)
629642
);
630643
// Attribute epilogue to function's closing brace
631-
let fn_end = span.shrink_to_hi();
644+
let fn_end = span_with_body.shrink_to_hi();
632645
let source_info = builder.source_info(fn_end);
633646
let return_block = builder.return_block();
634647
builder.cfg.goto(block, source_info, return_block);

0 commit comments

Comments
 (0)