Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parse: fuse associated and extern items up to defaultness #69194

Merged
merged 16 commits into from
Feb 19, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 19 additions & 18 deletions src/librustc_ast_lowering/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,26 +269,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs)
}
ItemKind::Static(ref t, m, ref e) => {
let ty = self.lower_ty(
t,
if self.sess.features_untracked().impl_trait_in_bindings {
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)
} else {
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
},
);
hir::ItemKind::Static(ty, m, self.lower_const_body(span, Some(e)))
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
hir::ItemKind::Static(ty, m, body_id)
}
ItemKind::Const(ref t, ref e) => {
let ty = self.lower_ty(
t,
if self.sess.features_untracked().impl_trait_in_bindings {
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)
} else {
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
},
);
hir::ItemKind::Const(ty, self.lower_const_body(span, Some(e)))
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
hir::ItemKind::Const(ty, body_id)
}
ItemKind::Fn(FnSig { ref decl, header }, ref generics, ref body) => {
let fn_def_id = self.resolver.definitions().local_def_id(id);
Expand Down Expand Up @@ -457,6 +443,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
// not cause an assertion failure inside the `lower_defaultness` function.
}

fn lower_const_item(
&mut self,
ty: &Ty,
span: Span,
body: Option<&Expr>,
) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
let itctx = if self.sess.features_untracked().impl_trait_in_bindings {
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)
} else {
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
};
let ty = self.lower_ty(ty, itctx);
(ty, self.lower_const_body(span, body))
}

fn lower_use_tree(
&mut self,
tree: &UseTree,
Expand Down
8 changes: 8 additions & 0 deletions src/librustc_ast_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.err_handler().span_err(item.span, "unions cannot have zero fields");
}
}
ItemKind::Const(.., None) => {
let msg = "free constant item without body";
self.error_item_without_body(item.span, "constant", msg, " = <expr>;");
}
ItemKind::Static(.., None) => {
let msg = "free static item without body";
self.error_item_without_body(item.span, "static", msg, " = <expr>;");
}
_ => {}
}

Expand Down
14 changes: 8 additions & 6 deletions src/librustc_ast_pretty/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1124,9 +1124,10 @@ impl<'a> State<'a> {
self.print_type(ty);
self.s.space();
self.end(); // end the head-ibox

self.word_space("=");
self.print_expr(expr);
if let Some(expr) = expr {
self.word_space("=");
self.print_expr(expr);
}
self.s.word(";");
self.end(); // end the outer cbox
}
Expand All @@ -1137,9 +1138,10 @@ impl<'a> State<'a> {
self.print_type(ty);
self.s.space();
self.end(); // end the head-ibox

self.word_space("=");
self.print_expr(expr);
if let Some(expr) = expr {
self.word_space("=");
self.print_expr(expr);
}
self.s.word(";");
self.end(); // end the outer cbox
}
Expand Down
148 changes: 76 additions & 72 deletions src/librustc_builtin_macros/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,81 +186,85 @@ pub fn expand_test_or_bench(
ast::ItemKind::Const(
cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
// test::TestDescAndFn {
cx.expr_struct(
sp,
test_path("TestDescAndFn"),
vec![
// desc: test::TestDesc {
field(
"desc",
cx.expr_struct(
sp,
test_path("TestDesc"),
vec![
// name: "path::to::test"
field(
"name",
cx.expr_call(
sp,
cx.expr_path(test_path("StaticTestName")),
vec![cx.expr_str(
sp,
Symbol::intern(&item_path(
// skip the name of the root module
&cx.current_expansion.module.mod_path[1..],
&item.ident,
)),
)],
),
),
// ignore: true | false
field("ignore", cx.expr_bool(sp, should_ignore(&item))),
// allow_fail: true | false
field("allow_fail", cx.expr_bool(sp, should_fail(&item))),
// should_panic: ...
field(
"should_panic",
match should_panic(cx, &item) {
// test::ShouldPanic::No
ShouldPanic::No => cx.expr_path(should_panic_path("No")),
// test::ShouldPanic::Yes
ShouldPanic::Yes(None) => {
cx.expr_path(should_panic_path("Yes"))
}
// test::ShouldPanic::YesWithMessage("...")
ShouldPanic::Yes(Some(sym)) => cx.expr_call(
Some(
cx.expr_struct(
sp,
test_path("TestDescAndFn"),
vec![
// desc: test::TestDesc {
field(
"desc",
cx.expr_struct(
sp,
test_path("TestDesc"),
vec![
// name: "path::to::test"
field(
"name",
cx.expr_call(
sp,
cx.expr_path(should_panic_path("YesWithMessage")),
vec![cx.expr_str(sp, sym)],
cx.expr_path(test_path("StaticTestName")),
vec![cx.expr_str(
sp,
Symbol::intern(&item_path(
// skip the name of the root module
&cx.current_expansion.module.mod_path[1..],
&item.ident,
)),
)],
),
},
),
// test_type: ...
field(
"test_type",
match test_type(cx) {
// test::TestType::UnitTest
TestType::UnitTest => {
cx.expr_path(test_type_path("UnitTest"))
}
// test::TestType::IntegrationTest
TestType::IntegrationTest => {
cx.expr_path(test_type_path("IntegrationTest"))
}
// test::TestPath::Unknown
TestType::Unknown => {
cx.expr_path(test_type_path("Unknown"))
}
},
),
// },
],
),
// ignore: true | false
field("ignore", cx.expr_bool(sp, should_ignore(&item))),
// allow_fail: true | false
field("allow_fail", cx.expr_bool(sp, should_fail(&item))),
// should_panic: ...
field(
"should_panic",
match should_panic(cx, &item) {
// test::ShouldPanic::No
ShouldPanic::No => {
cx.expr_path(should_panic_path("No"))
}
// test::ShouldPanic::Yes
ShouldPanic::Yes(None) => {
cx.expr_path(should_panic_path("Yes"))
}
// test::ShouldPanic::YesWithMessage("...")
ShouldPanic::Yes(Some(sym)) => cx.expr_call(
sp,
cx.expr_path(should_panic_path("YesWithMessage")),
vec![cx.expr_str(sp, sym)],
),
},
),
// test_type: ...
field(
"test_type",
match test_type(cx) {
// test::TestType::UnitTest
TestType::UnitTest => {
cx.expr_path(test_type_path("UnitTest"))
}
// test::TestType::IntegrationTest
TestType::IntegrationTest => {
cx.expr_path(test_type_path("IntegrationTest"))
}
// test::TestPath::Unknown
TestType::Unknown => {
cx.expr_path(test_type_path("Unknown"))
}
},
),
// },
],
),
),
),
// testfn: test::StaticTestFn(...) | test::StaticBenchFn(...)
field("testfn", test_fn), // }
],
), // }
// testfn: test::StaticTestFn(...) | test::StaticBenchFn(...)
field("testfn", test_fn), // }
],
), // }
),
),
);
test_const = test_const.map(|mut tc| {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_expand/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ impl<'a> ExtCtxt<'a> {
mutbl: ast::Mutability,
expr: P<ast::Expr>,
) -> P<ast::Item> {
self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, expr))
self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr)))
}

pub fn item_const(
Expand All @@ -644,7 +644,7 @@ impl<'a> ExtCtxt<'a> {
ty: P<ast::Ty>,
expr: P<ast::Expr>,
) -> P<ast::Item> {
self.item(span, name, Vec::new(), ast::ItemKind::Const(ty, expr))
self.item(span, name, Vec::new(), ast::ItemKind::Const(ty, Some(expr)))
}

pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_lint/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ impl EarlyLintPass for UnusedParens {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
use ast::ItemKind::*;

if let Const(.., ref expr) | Static(.., ref expr) = item.kind {
if let Const(.., Some(expr)) | Static(.., Some(expr)) = &item.kind {
self.check_unused_parens_expr(cx, expr, "assigned value", false, None, None);
}
}
Expand Down
19 changes: 8 additions & 11 deletions src/librustc_parse/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,7 @@ impl<'a> Parser<'a> {
}
}

/// Parse `["const" | ("static" "mut"?)] $ident ":" $ty = $expr` with
/// Parse `["const" | ("static" "mut"?)] $ident ":" $ty (= $expr)?` with
/// `["const" | ("static" "mut"?)]` already parsed and stored in `m`.
///
/// When `m` is `"const"`, `$ident` may also be `"_"`.
Expand All @@ -975,25 +975,22 @@ impl<'a> Parser<'a> {

// Parse the type of a `const` or `static mut?` item.
// That is, the `":" $ty` fragment.
let ty = if self.token == token::Eq {
self.recover_missing_const_type(id, m)
} else {
// Not `=` so expect `":"" $ty` as usual.
self.expect(&token::Colon)?;
let ty = if self.eat(&token::Colon) {
self.parse_ty()?
} else {
self.recover_missing_const_type(id, m)
};

self.expect(&token::Eq)?;
let e = self.parse_expr()?;
let expr = if self.eat(&token::Eq) { Some(self.parse_expr()?) } else { None };
self.expect_semi()?;
let item = match m {
Some(m) => ItemKind::Static(ty, m, e),
None => ItemKind::Const(ty, e),
Some(m) => ItemKind::Static(ty, m, expr),
None => ItemKind::Const(ty, expr),
};
Ok((id, item))
}

/// We were supposed to parse `:` but instead, we're already at `=`.
/// We were supposed to parse `:` but the `:` was missing.
/// This means that the type is missing.
fn recover_missing_const_type(&mut self, id: Ident, m: Option<Mutability>) -> P<Ty> {
// Construct the error and stash it away with the hope
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_resolve/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -881,9 +881,9 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
debug!("resolve_item ItemKind::Const");
self.with_item_rib(HasGenericParams::No, |this| {
this.visit_ty(ty);
this.with_constant_rib(|this| {
this.visit_expr(expr);
});
if let Some(expr) = expr {
this.with_constant_rib(|this| this.visit_expr(expr));
}
});
}

Expand Down
8 changes: 4 additions & 4 deletions src/librustc_save_analysis/dump_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
&mut self,
item: &'l ast::Item,
typ: &'l ast::Ty,
expr: &'l ast::Expr,
expr: Option<&'l ast::Expr>,
) {
let hir_id = self.tcx.hir().node_to_hir_id(item.id);
self.nest_tables(item.id, |v| {
Expand All @@ -409,7 +409,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
v.dumper.dump_def(&access_from!(v.save_ctxt, item, hir_id), var_data);
}
v.visit_ty(&typ);
v.visit_expr(expr);
walk_list!(v, visit_expr, expr);
});
}

Expand Down Expand Up @@ -1293,8 +1293,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
Fn(ref sig, ref ty_params, ref body) => {
self.process_fn(item, &sig.decl, &sig.header, ty_params, body.as_deref())
}
Static(ref typ, _, ref expr) => self.process_static_or_const_item(item, typ, expr),
Const(ref typ, ref expr) => self.process_static_or_const_item(item, &typ, &expr),
Static(ref typ, _, ref e) => self.process_static_or_const_item(item, typ, e.as_deref()),
Const(ref typ, ref e) => self.process_static_or_const_item(item, typ, e.as_deref()),
Struct(ref def, ref ty_params) | Union(ref def, ref ty_params) => {
self.process_struct(item, def, ty_params)
}
Expand Down
18 changes: 12 additions & 6 deletions src/librustc_save_analysis/sig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,10 +334,13 @@ impl Sig for ast::Item {

let ty = ty.make(offset + text.len(), id, scx)?;
text.push_str(&ty.text);
text.push_str(" = ");

let expr = pprust::expr_to_string(expr).replace('\n', " ");
text.push_str(&expr);
if let Some(expr) = expr {
text.push_str(" = ");
let expr = pprust::expr_to_string(expr).replace('\n', " ");
text.push_str(&expr);
}

text.push(';');

Ok(extend_sig(ty, text, defs, vec![]))
Expand All @@ -355,10 +358,13 @@ impl Sig for ast::Item {

let ty = ty.make(offset + text.len(), id, scx)?;
text.push_str(&ty.text);
text.push_str(" = ");

let expr = pprust::expr_to_string(expr).replace('\n', " ");
text.push_str(&expr);
if let Some(expr) = expr {
text.push_str(" = ");
let expr = pprust::expr_to_string(expr).replace('\n', " ");
text.push_str(&expr);
}

text.push(';');

Ok(extend_sig(ty, text, defs, vec![]))
Expand Down
Loading