Skip to content

Commit f6403c6

Browse files
committed
Use Option in ImplItemKind::Method.
1 parent 73557fa commit f6403c6

File tree

17 files changed

+149
-73
lines changed

17 files changed

+149
-73
lines changed

src/librustc/hir/lowering.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,7 +1211,7 @@ impl<'a> LoweringContext<'a> {
12111211
let ct = self.with_new_scopes(|this| {
12121212
hir::AnonConst {
12131213
hir_id: this.lower_node_id(node_id),
1214-
body: this.lower_const_body(&path_expr),
1214+
body: this.lower_const_body(path_expr.span, Some(&path_expr)),
12151215
}
12161216
});
12171217
return GenericArg::Const(ConstArg {
@@ -3003,7 +3003,7 @@ impl<'a> LoweringContext<'a> {
30033003
self.with_new_scopes(|this| {
30043004
hir::AnonConst {
30053005
hir_id: this.lower_node_id(c.id),
3006-
body: this.lower_const_body(&c.value),
3006+
body: this.lower_const_body(c.value.span, Some(&c.value)),
30073007
}
30083008
})
30093009
}

src/librustc/hir/lowering/item.rs

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ impl LoweringContext<'_> {
250250
return None;
251251
}
252252

253-
let kind = self.lower_item_kind(i.id, &mut ident, &attrs, &mut vis, &i.kind);
253+
let kind = self.lower_item_kind(i.span, i.id, &mut ident, &attrs, &mut vis, &i.kind);
254254

255255
Some(hir::Item {
256256
hir_id: self.lower_node_id(i.id),
@@ -264,6 +264,7 @@ impl LoweringContext<'_> {
264264

265265
fn lower_item_kind(
266266
&mut self,
267+
span: Span,
267268
id: NodeId,
268269
ident: &mut Ident,
269270
attrs: &hir::HirVec<Attribute>,
@@ -292,7 +293,7 @@ impl LoweringContext<'_> {
292293
}
293294
),
294295
m,
295-
self.lower_const_body(e),
296+
self.lower_const_body(span, Some(e)),
296297
)
297298
}
298299
ItemKind::Const(ref t, ref e) => {
@@ -305,7 +306,7 @@ impl LoweringContext<'_> {
305306
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
306307
}
307308
),
308-
self.lower_const_body(e)
309+
self.lower_const_body(span, Some(e))
309310
)
310311
}
311312
ItemKind::Fn(FnSig { ref decl, header }, ref generics, ref body) => {
@@ -317,7 +318,12 @@ impl LoweringContext<'_> {
317318
// `impl Future<Output = T>` here because lower_body
318319
// only cares about the input argument patterns in the function
319320
// declaration (decl), not the return types.
320-
let body_id = this.lower_maybe_async_body(&decl, header.asyncness.node, body);
321+
let body_id = this.lower_maybe_async_body(
322+
span,
323+
&decl,
324+
header.asyncness.node,
325+
Some(body),
326+
);
321327

322328
let (generics, decl) = this.add_in_band_defs(
323329
generics,
@@ -817,7 +823,7 @@ impl LoweringContext<'_> {
817823
self.lower_ty(ty, ImplTraitContext::disallowed()),
818824
default
819825
.as_ref()
820-
.map(|x| self.lower_const_body(x)),
826+
.map(|x| self.lower_const_body(i.span, Some(x))),
821827
),
822828
),
823829
TraitItemKind::Method(ref sig, None) => {
@@ -832,7 +838,7 @@ impl LoweringContext<'_> {
832838
(generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Required(names)))
833839
}
834840
TraitItemKind::Method(ref sig, Some(ref body)) => {
835-
let body_id = self.lower_fn_body_block(&sig.decl, body);
841+
let body_id = self.lower_fn_body_block(i.span, &sig.decl, Some(body));
836842
let (generics, sig) = self.lower_method_sig(
837843
&i.generics,
838844
sig,
@@ -891,6 +897,11 @@ impl LoweringContext<'_> {
891897
}
892898
}
893899

900+
/// Construct `ExprKind::Err` for the given `span`.
901+
fn expr_err(&mut self, span: Span) -> hir::Expr {
902+
self.expr(span, hir::ExprKind::Err, ThinVec::new())
903+
}
904+
894905
fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
895906
let impl_item_def_id = self.resolver.definitions().local_def_id(i.id);
896907

@@ -899,19 +910,16 @@ impl LoweringContext<'_> {
899910
self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
900911
hir::ImplItemKind::Const(
901912
self.lower_ty(ty, ImplTraitContext::disallowed()),
902-
match expr {
903-
Some(expr) => self.lower_const_body(expr),
904-
None => self.lower_body(|this| (
905-
hir_vec![],
906-
this.expr(i.span, hir::ExprKind::Err, ThinVec::new()),
907-
)),
908-
}
913+
self.lower_const_body(i.span, expr.as_deref()),
909914
),
910915
),
911916
ImplItemKind::Method(ref sig, ref body) => {
912917
self.current_item = Some(i.span);
913918
let body_id = self.lower_maybe_async_body(
914-
&sig.decl, sig.header.asyncness.node, body
919+
i.span,
920+
&sig.decl,
921+
sig.header.asyncness.node,
922+
body.as_deref(),
915923
);
916924
let impl_trait_return_allow = !self.is_in_trait_impl;
917925
let (generics, sig) = self.lower_method_sig(
@@ -1069,23 +1077,39 @@ impl LoweringContext<'_> {
10691077
))
10701078
}
10711079

1072-
fn lower_fn_body_block(&mut self, decl: &FnDecl, body: &Block) -> hir::BodyId {
1073-
self.lower_fn_body(decl, |this| this.lower_block_expr(body))
1080+
fn lower_fn_body_block(
1081+
&mut self,
1082+
span: Span,
1083+
decl: &FnDecl,
1084+
body: Option<&Block>,
1085+
) -> hir::BodyId {
1086+
self.lower_fn_body(decl, |this| this.lower_block_expr_opt(span, body))
1087+
}
1088+
1089+
fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr {
1090+
match block {
1091+
Some(block) => self.lower_block_expr(block),
1092+
None => self.expr_err(span),
1093+
}
10741094
}
10751095

1076-
pub(super) fn lower_const_body(&mut self, expr: &Expr) -> hir::BodyId {
1077-
self.lower_body(|this| (hir_vec![], this.lower_expr(expr)))
1096+
pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
1097+
self.lower_body(|this| (hir_vec![], match expr {
1098+
Some(expr) => this.lower_expr(expr),
1099+
None => this.expr_err(span),
1100+
}))
10781101
}
10791102

10801103
fn lower_maybe_async_body(
10811104
&mut self,
1105+
span: Span,
10821106
decl: &FnDecl,
10831107
asyncness: IsAsync,
1084-
body: &Block,
1108+
body: Option<&Block>,
10851109
) -> hir::BodyId {
10861110
let closure_id = match asyncness {
10871111
IsAsync::Async { closure_id, .. } => closure_id,
1088-
IsAsync::NotAsync => return self.lower_fn_body_block(decl, body),
1112+
IsAsync::NotAsync => return self.lower_fn_body_block(span, decl, body),
10891113
};
10901114

10911115
self.lower_body(|this| {
@@ -1219,15 +1243,16 @@ impl LoweringContext<'_> {
12191243
parameters.push(new_parameter);
12201244
}
12211245

1246+
let body_span = body.map_or(span, |b| b.span);
12221247
let async_expr = this.make_async_expr(
12231248
CaptureBy::Value,
12241249
closure_id,
12251250
None,
1226-
body.span,
1251+
body_span,
12271252
hir::AsyncGeneratorKind::Fn,
12281253
|this| {
12291254
// Create a block from the user's function body:
1230-
let user_body = this.lower_block_expr(body);
1255+
let user_body = this.lower_block_expr_opt(body_span, body);
12311256

12321257
// Transform into `drop-temps { <user-body> }`, an expression:
12331258
let desugared_span = this.mark_span_with_reason(
@@ -1257,7 +1282,7 @@ impl LoweringContext<'_> {
12571282
);
12581283
this.expr_block(P(body), ThinVec::new())
12591284
});
1260-
(HirVec::from(parameters), this.expr(body.span, async_expr, ThinVec::new()))
1285+
(HirVec::from(parameters), this.expr(body_span, async_expr, ThinVec::new()))
12611286
})
12621287
}
12631288

src/librustc_parse/parser/item.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -705,9 +705,7 @@ impl<'a> Parser<'a> {
705705
// FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
706706
(Ident::invalid(), ast::ImplItemKind::Macro(mac), Generics::default())
707707
} else {
708-
let (name, inner_attrs, generics, kind) = self.parse_impl_method(at_end)?;
709-
attrs.extend(inner_attrs);
710-
(name, kind, generics)
708+
self.parse_impl_method(at_end, &mut attrs)?
711709
};
712710

713711
Ok(ImplItem {
@@ -1842,11 +1840,11 @@ impl<'a> Parser<'a> {
18421840
fn parse_impl_method(
18431841
&mut self,
18441842
at_end: &mut bool,
1845-
) -> PResult<'a, (Ident, Vec<Attribute>, Generics, ImplItemKind)> {
1843+
attrs: &mut Vec<Attribute>,
1844+
) -> PResult<'a, (Ident, ImplItemKind, Generics)> {
18461845
let (ident, sig, generics) = self.parse_method_sig(|_| true)?;
1847-
*at_end = true;
1848-
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
1849-
Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(sig, body)))
1846+
let body = self.parse_trait_method_body(at_end, attrs)?;
1847+
Ok((ident, ast::ImplItemKind::Method(sig, body), generics))
18501848
}
18511849

18521850
fn parse_trait_item_method(

src/librustc_passes/ast_validation.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,22 @@ impl<'a> AstValidator<'a> {
279279
.emit();
280280
}
281281
}
282+
283+
fn check_impl_item_provided<T>(&self, sp: Span, body: &Option<T>, ctx: &str, sugg: &str) {
284+
if body.is_some() {
285+
return;
286+
}
287+
288+
self.err_handler()
289+
.struct_span_err(sp, &format!("associated {} in `impl` without body", ctx))
290+
.span_suggestion(
291+
self.session.source_map().end_point(sp),
292+
&format!("provide a definition for the {}", ctx),
293+
sugg.to_string(),
294+
Applicability::HasPlaceholders,
295+
)
296+
.emit();
297+
}
282298
}
283299

284300
enum GenericPosition {
@@ -747,18 +763,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
747763

748764
fn visit_impl_item(&mut self, ii: &'a ImplItem) {
749765
match &ii.kind {
750-
ImplItemKind::Const(ty, None) => {
751-
self.err_handler()
752-
.struct_span_err(ii.span, "associated constant in `impl` without body")
753-
.span_suggestion(
754-
ii.span,
755-
"provide a definition for the constant",
756-
format!("const {}: {} = <expr>;", ii.ident, pprust::ty_to_string(ty)),
757-
Applicability::HasPlaceholders,
758-
)
759-
.emit();
766+
ImplItemKind::Const(_, body) => {
767+
self.check_impl_item_provided(ii.span, body, "constant", " = <expr>;");
760768
}
761-
ImplItemKind::Method(sig, _) => {
769+
ImplItemKind::Method(sig, body) => {
770+
self.check_impl_item_provided(ii.span, body, "function", " { <body> }");
762771
self.check_fn_decl(&sig.decl);
763772
}
764773
_ => {}

src/librustc_resolve/def_collector.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ impl<'a> DefCollector<'a> {
5050
header: &FnHeader,
5151
generics: &'a Generics,
5252
decl: &'a FnDecl,
53-
body: &'a Block,
53+
body: Option<&'a Block>,
5454
) {
5555
let (closure_id, return_impl_trait_id) = match header.asyncness.node {
5656
IsAsync::Async {
@@ -74,7 +74,9 @@ impl<'a> DefCollector<'a> {
7474
closure_id, DefPathData::ClosureExpr, span,
7575
);
7676
this.with_parent(closure_def, |this| {
77-
visit::walk_block(this, body);
77+
if let Some(body) = body {
78+
visit::walk_block(this, body);
79+
}
7880
})
7981
})
8082
}
@@ -123,7 +125,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
123125
&sig.header,
124126
generics,
125127
&sig.decl,
126-
body,
128+
Some(body),
127129
)
128130
}
129131
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
@@ -237,7 +239,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
237239
header,
238240
&ii.generics,
239241
decl,
240-
body,
242+
body.as_deref(),
241243
)
242244
}
243245
ImplItemKind::Method(..) |

src/librustc_save_analysis/dump_visitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
11191119
ast::ImplItemKind::Method(ref sig, ref body) => {
11201120
self.process_method(
11211121
sig,
1122-
Some(body),
1122+
body.as_deref(),
11231123
impl_item.id,
11241124
impl_item.ident,
11251125
&impl_item.generics,

src/libsyntax/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1637,7 +1637,7 @@ pub struct ImplItem<K = ImplItemKind> {
16371637
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
16381638
pub enum ImplItemKind {
16391639
Const(P<Ty>, Option<P<Expr>>),
1640-
Method(FnSig, P<Block>),
1640+
Method(FnSig, Option<P<Block>>),
16411641
TyAlias(P<Ty>),
16421642
Macro(Mac),
16431643
}

src/libsyntax/mut_visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
985985
}
986986
ImplItemKind::Method(sig, body) => {
987987
visit_fn_sig(sig, visitor);
988-
visitor.visit_block(body);
988+
visit_opt(body, |body| visitor.visit_block(body));
989989
}
990990
ImplItemKind::TyAlias(ty) => visitor.visit_ty(ty),
991991
ImplItemKind::Macro(mac) => visitor.visit_mac(mac),

src/libsyntax/print/pprust.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,23 +1553,13 @@ impl<'a> State<'a> {
15531553
self.print_defaultness(ti.defaultness);
15541554
match ti.kind {
15551555
ast::TraitItemKind::Const(ref ty, ref default) => {
1556-
self.print_associated_const(
1557-
ti.ident,
1558-
ty,
1559-
default.as_ref().map(|expr| &**expr),
1560-
&source_map::respan(ti.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
1561-
);
1556+
self.print_associated_const(ti.ident, ty, default.as_deref(), &ti.vis);
15621557
}
15631558
ast::TraitItemKind::Method(ref sig, ref body) => {
15641559
if body.is_some() {
15651560
self.head("");
15661561
}
1567-
self.print_method_sig(
1568-
ti.ident,
1569-
&ti.generics,
1570-
sig,
1571-
&source_map::respan(ti.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
1572-
);
1562+
self.print_method_sig(ti.ident, &ti.generics, sig, &ti.vis);
15731563
if let Some(ref body) = *body {
15741564
self.nbsp();
15751565
self.print_block_with_attrs(body, &ti.attrs);
@@ -1602,10 +1592,16 @@ impl<'a> State<'a> {
16021592
self.print_associated_const(ii.ident, ty, expr.as_deref(), &ii.vis);
16031593
}
16041594
ast::ImplItemKind::Method(ref sig, ref body) => {
1605-
self.head("");
1595+
if body.is_some() {
1596+
self.head("");
1597+
}
16061598
self.print_method_sig(ii.ident, &ii.generics, sig, &ii.vis);
1607-
self.nbsp();
1608-
self.print_block_with_attrs(body, &ii.attrs);
1599+
if let Some(body) = body {
1600+
self.nbsp();
1601+
self.print_block_with_attrs(body, &ii.attrs);
1602+
} else {
1603+
self.s.word(";");
1604+
}
16091605
}
16101606
ast::ImplItemKind::TyAlias(ref ty) => {
16111607
self.print_associated_type(ii.ident, None, Some(ty));

0 commit comments

Comments
 (0)