Skip to content

Commit 95dc9b9

Browse files
committed
ast: normalize ForeignItemKind::Ty & AssocItemKind::TyAlias.
1 parent e2ae717 commit 95dc9b9

File tree

18 files changed

+192
-37
lines changed

18 files changed

+192
-37
lines changed

src/librustc_ast_lowering/item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
682682
let ty = self.lower_ty(t, ImplTraitContext::disallowed());
683683
hir::ForeignItemKind::Static(ty, m)
684684
}
685-
ForeignItemKind::Ty => hir::ForeignItemKind::Type,
685+
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
686686
ForeignItemKind::Macro(_) => panic!("macro shouldn't exist here"),
687687
},
688688
vis: self.lower_visibility(&i.vis, None),

src/librustc_ast_passes/ast_validation.rs

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ use syntax::expand::is_proc_macro_attr;
2222
use syntax::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
2323
use syntax::walk_list;
2424

25+
const MORE_EXTERN: &str =
26+
"for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
27+
2528
/// Is `self` allowed semantically as the first parameter in an `FnDecl`?
2629
enum SelfSemantic {
2730
Yes,
@@ -423,14 +426,59 @@ impl<'a> AstValidator<'a> {
423426
}
424427
}
425428

426-
fn check_impl_assoc_type_no_bounds(&self, bounds: &[GenericBound]) {
429+
fn check_type_no_bounds(&self, bounds: &[GenericBound], ctx: &str) {
427430
let span = match bounds {
428431
[] => return,
429432
[b0] => b0.span(),
430433
[b0, .., bl] => b0.span().to(bl.span()),
431434
};
432435
self.err_handler()
433-
.struct_span_err(span, "bounds on associated `type`s in `impl`s have no effect")
436+
.struct_span_err(span, &format!("bounds on `type`s in {} have no effect", ctx))
437+
.emit();
438+
}
439+
440+
fn check_foreign_ty_genericless(&self, generics: &Generics) {
441+
let cannot_have = |span, descr, remove_descr| {
442+
self.err_handler()
443+
.struct_span_err(
444+
span,
445+
&format!("`type`s inside `extern` blocks cannot have {}", descr),
446+
)
447+
.span_suggestion(
448+
span,
449+
&format!("remove the {}", remove_descr),
450+
String::new(),
451+
Applicability::MaybeIncorrect,
452+
)
453+
.span_label(self.current_extern_span(), "`extern` block begins here")
454+
.note(MORE_EXTERN)
455+
.emit();
456+
};
457+
458+
if !generics.params.is_empty() {
459+
cannot_have(generics.span, "generic parameters", "generic parameters");
460+
}
461+
462+
if !generics.where_clause.predicates.is_empty() {
463+
cannot_have(generics.where_clause.span, "`where` clauses", "`where` clause");
464+
}
465+
}
466+
467+
fn check_foreign_ty_bodyless(&self, ident: Ident, body: Option<&Ty>) {
468+
let body = match body {
469+
None => return,
470+
Some(body) => body,
471+
};
472+
self.err_handler()
473+
.struct_span_err(ident.span, "incorrect `type` inside `extern` block")
474+
.span_label(ident.span, "cannot have a body")
475+
.span_label(body.span, "the invalid body")
476+
.span_label(
477+
self.current_extern_span(),
478+
"`extern` blocks define existing foreign types and types \
479+
inside of them cannot have a body",
480+
)
481+
.note(MORE_EXTERN)
434482
.emit();
435483
}
436484

@@ -458,7 +506,7 @@ impl<'a> AstValidator<'a> {
458506
"`extern` blocks define existing foreign functions and functions \
459507
inside of them cannot have a body",
460508
)
461-
.note("for more information, visit https://doc.rust-lang.org/std/keyword.extern.html")
509+
.note(MORE_EXTERN)
462510
.emit();
463511
}
464512

@@ -912,7 +960,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
912960
self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
913961
self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header);
914962
}
915-
ForeignItemKind::Static(..) | ForeignItemKind::Ty | ForeignItemKind::Macro(..) => {}
963+
ForeignItemKind::TyAlias(generics, bounds, body) => {
964+
self.check_foreign_ty_bodyless(fi.ident, body.as_deref());
965+
self.check_type_no_bounds(bounds, "`extern` blocks");
966+
self.check_foreign_ty_genericless(generics);
967+
}
968+
ForeignItemKind::Static(..) | ForeignItemKind::Macro(..) => {}
916969
}
917970

918971
visit::walk_foreign_item(self, fi)
@@ -1159,7 +1212,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11591212
}
11601213
AssocItemKind::TyAlias(_, bounds, body) => {
11611214
self.check_impl_item_provided(item.span, body, "type", " = <type>;");
1162-
self.check_impl_assoc_type_no_bounds(bounds);
1215+
self.check_type_no_bounds(bounds, "`impl`s");
11631216
}
11641217
_ => {}
11651218
}

src/librustc_ast_passes/feature_gate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
397397
);
398398
}
399399
}
400-
ast::ForeignItemKind::Ty => {
400+
ast::ForeignItemKind::TyAlias(..) => {
401401
gate_feature_post!(&self, extern_types, i.span, "extern types are experimental");
402402
}
403403
ast::ForeignItemKind::Macro(..) => {}

src/librustc_ast_pretty/pprust.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,13 +1019,13 @@ impl<'a> State<'a> {
10191019
self.hardbreak_if_not_bol();
10201020
self.maybe_print_comment(item.span.lo());
10211021
self.print_outer_attributes(&item.attrs);
1022-
match item.kind {
1023-
ast::ForeignItemKind::Fn(ref sig, ref gen, ref body) => {
1022+
match &item.kind {
1023+
ast::ForeignItemKind::Fn(sig, gen, body) => {
10241024
self.print_fn_full(sig, item.ident, gen, &item.vis, body.as_deref(), &item.attrs);
10251025
}
1026-
ast::ForeignItemKind::Static(ref t, m) => {
1026+
ast::ForeignItemKind::Static(t, m) => {
10271027
self.head(visibility_qualified(&item.vis, "static"));
1028-
if m == ast::Mutability::Mut {
1028+
if *m == ast::Mutability::Mut {
10291029
self.word_space("mut");
10301030
}
10311031
self.print_ident(item.ident);
@@ -1035,14 +1035,10 @@ impl<'a> State<'a> {
10351035
self.end(); // end the head-ibox
10361036
self.end(); // end the outer cbox
10371037
}
1038-
ast::ForeignItemKind::Ty => {
1039-
self.head(visibility_qualified(&item.vis, "type"));
1040-
self.print_ident(item.ident);
1041-
self.s.word(";");
1042-
self.end(); // end the head-ibox
1043-
self.end(); // end the outer cbox
1038+
ast::ForeignItemKind::TyAlias(generics, bounds, ty) => {
1039+
self.print_associated_type(item.ident, generics, bounds, ty.as_deref());
10441040
}
1045-
ast::ForeignItemKind::Macro(ref m) => {
1041+
ast::ForeignItemKind::Macro(m) => {
10461042
self.print_mac(m);
10471043
if m.args.need_semicolon() {
10481044
self.s.word(";");

src/librustc_parse/parser/item.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ impl<'a> Parser<'a> {
876876
let lo = self.token.span;
877877
let vis = self.parse_visibility(FollowedByType::No)?;
878878

879-
let (ident, kind) = if self.check_keyword(kw::Type) {
879+
let (ident, kind) = if self.eat_keyword(kw::Type) {
880880
// FOREIGN TYPE ITEM
881881
self.parse_item_foreign_type()?
882882
} else if self.check_fn_front_matter() {
@@ -925,10 +925,12 @@ impl<'a> Parser<'a> {
925925

926926
/// Parses a type from a foreign module.
927927
fn parse_item_foreign_type(&mut self) -> PResult<'a, (Ident, ForeignItemKind)> {
928-
self.expect_keyword(kw::Type)?;
929-
let ident = self.parse_ident()?;
930-
self.expect_semi()?;
931-
Ok((ident, ForeignItemKind::Ty))
928+
let (ident, kind) = self.parse_assoc_ty()?;
929+
let kind = match kind {
930+
AssocItemKind::TyAlias(g, b, d) => ForeignItemKind::TyAlias(g, b, d),
931+
_ => unreachable!(),
932+
};
933+
Ok((ident, kind))
932934
}
933935

934936
fn is_static_global(&mut self) -> bool {

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
829829
ForeignItemKind::Static(..) => {
830830
(Res::Def(DefKind::Static, self.r.definitions.local_def_id(item.id)), ValueNS)
831831
}
832-
ForeignItemKind::Ty => {
832+
ForeignItemKind::TyAlias(..) => {
833833
(Res::Def(DefKind::ForeignTy, self.r.definitions.local_def_id(item.id)), TypeNS)
834834
}
835835
ForeignItemKind::Macro(_) => unreachable!(),

src/librustc_resolve/late.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,8 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
437437
}
438438
fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
439439
match foreign_item.kind {
440-
ForeignItemKind::Fn(_, ref generics, _) => {
440+
ForeignItemKind::Fn(_, ref generics, _)
441+
| ForeignItemKind::TyAlias(ref generics, ..) => {
441442
self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
442443
visit::walk_foreign_item(this, foreign_item);
443444
});
@@ -447,7 +448,7 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
447448
visit::walk_foreign_item(this, foreign_item);
448449
});
449450
}
450-
ForeignItemKind::Ty | ForeignItemKind::Macro(..) => {
451+
ForeignItemKind::Macro(..) => {
451452
visit::walk_foreign_item(self, foreign_item);
452453
}
453454
}

src/librustc_save_analysis/dump_visitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
15401540

15411541
self.visit_ty(ty);
15421542
}
1543-
ast::ForeignItemKind::Ty => {
1543+
ast::ForeignItemKind::TyAlias(..) => {
15441544
if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) {
15451545
down_cast_data!(var_data, DefData, item.span);
15461546
self.dumper.dump_def(&access, var_data);

src/librustc_save_analysis/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
173173
}))
174174
}
175175
// FIXME(plietar): needs a new DefKind in rls-data
176-
ast::ForeignItemKind::Ty => None,
176+
ast::ForeignItemKind::TyAlias(..) => None,
177177
ast::ForeignItemKind::Macro(..) => None,
178178
}
179179
}

src/librustc_save_analysis/sig.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ impl Sig for ast::ForeignItem {
773773

774774
Ok(extend_sig(ty_sig, text, defs, vec![]))
775775
}
776-
ast::ForeignItemKind::Ty => {
776+
ast::ForeignItemKind::TyAlias(..) => {
777777
let mut text = "type ".to_owned();
778778
let name = self.ident.to_string();
779779
let defs = vec![SigElement {

0 commit comments

Comments
 (0)