Skip to content

Commit abe0d2e

Browse files
committed
Initial support for dynamically linked crates
1 parent 820bfff commit abe0d2e

File tree

87 files changed

+1975
-193
lines changed

Some content is hidden

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

87 files changed

+1975
-193
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4033,6 +4033,7 @@ dependencies = [
40334033
"rustc_fs_util",
40344034
"rustc_hir",
40354035
"rustc_hir_analysis",
4036+
"rustc_hir_pretty",
40364037
"rustc_hir_typeck",
40374038
"rustc_incremental",
40384039
"rustc_lint",

compiler/rustc_ast/src/ast.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3192,6 +3192,7 @@ impl Item {
31923192
pub fn opt_generics(&self) -> Option<&Generics> {
31933193
match &self.kind {
31943194
ItemKind::ExternCrate(_)
3195+
| ItemKind::ExternDynCrate(_)
31953196
| ItemKind::Use(_)
31963197
| ItemKind::Mod(_, _)
31973198
| ItemKind::ForeignMod(_)
@@ -3407,6 +3408,10 @@ pub enum ItemKind {
34073408
///
34083409
/// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
34093410
ExternCrate(Option<Symbol>),
3411+
/// An extern crate with a stable interface.
3412+
///
3413+
/// E.g., `extern dyn crate foo` or `extern dyn crate foo_bar as foo`.
3414+
ExternDynCrate(Option<Symbol>),
34103415
/// A use declaration item (`use`).
34113416
///
34123417
/// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
@@ -3488,13 +3493,19 @@ impl ItemKind {
34883493
Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
34893494
| Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
34903495
| Delegation(..) | DelegationMac(..) => "a",
3491-
ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
3496+
ExternCrate(..)
3497+
| ExternDynCrate(..)
3498+
| ForeignMod(..)
3499+
| MacCall(..)
3500+
| Enum(..)
3501+
| Impl { .. } => "an",
34923502
}
34933503
}
34943504

34953505
pub fn descr(&self) -> &'static str {
34963506
match self {
34973507
ItemKind::ExternCrate(..) => "extern crate",
3508+
ItemKind::ExternDynCrate(..) => "extern dyn crate",
34983509
ItemKind::Use(..) => "`use` import",
34993510
ItemKind::Static(..) => "static item",
35003511
ItemKind::Const(..) => "constant item",

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1219,7 +1219,7 @@ impl WalkItemKind for ItemKind {
12191219
vis: &mut impl MutVisitor,
12201220
) {
12211221
match self {
1222-
ItemKind::ExternCrate(_orig_name) => {}
1222+
ItemKind::ExternCrate(_orig_name) | ItemKind::ExternDynCrate(_orig_name) => {}
12231223
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
12241224
ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
12251225
vis.visit_ty(ty);

compiler/rustc_ast/src/visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ impl WalkItemKind for ItemKind {
366366
visitor: &mut V,
367367
) -> V::Result {
368368
match self {
369-
ItemKind::ExternCrate(_rename) => {}
369+
ItemKind::ExternCrate(_rename) | ItemKind::ExternDynCrate(_rename) => {}
370370
ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, id, false)),
371371
ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
372372
try_visit!(visitor.visit_ty(ty));

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
180180
i: &ItemKind,
181181
) -> hir::ItemKind<'hir> {
182182
match i {
183-
ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(*orig_name),
183+
ItemKind::ExternCrate(orig_name) | ItemKind::ExternDynCrate(orig_name) => {
184+
hir::ItemKind::ExternCrate(*orig_name)
185+
}
184186
ItemKind::Use(use_tree) => {
185187
// Start with an empty prefix.
186188
let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None };
@@ -1176,7 +1178,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11761178
// create a fake body so that the entire rest of the compiler doesn't have to deal with
11771179
// this as a special case.
11781180
return self.lower_fn_body(decl, |this| {
1179-
if attrs.iter().any(|a| a.name_or_empty() == sym::rustc_intrinsic) {
1181+
if attrs.iter().any(|a| a.name_or_empty() == sym::rustc_intrinsic) || this.tcx.is_interface_build() {
11801182
let span = this.lower_span(span);
11811183
let empty_block = hir::Block {
11821184
hir_id: this.next_id(),

compiler/rustc_ast_passes/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,6 @@ ast_passes_where_clause_before_type_alias = where clauses are not allowed before
273273
.note = see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
274274
.remove_suggestion = remove this `where`
275275
.move_suggestion = move it to the end of the type declaration
276+
277+
ast_passes_wrong_mangling_scheme_for_extern_dyn =
278+
`extern dyn` annotation is only allowed with `v0` mangling scheme

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use rustc_errors::DiagCtxtHandle;
2929
use rustc_feature::Features;
3030
use rustc_parse::validate_attr;
3131
use rustc_session::Session;
32+
use rustc_session::config::SymbolManglingVersion;
3233
use rustc_session::lint::builtin::{
3334
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, MISSING_UNSAFE_ON_EXTERN,
3435
PATTERNS_IN_FNS_WITHOUT_BODY,
@@ -82,6 +83,8 @@ struct AstValidator<'a> {
8283
/// Used to ban explicit safety on foreign items when the extern block is not marked as unsafe.
8384
extern_mod_safety: Option<Safety>,
8485

86+
is_interface: bool,
87+
8588
lint_buffer: &'a mut LintBuffer,
8689
}
8790

@@ -922,7 +925,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
922925

923926
let is_intrinsic =
924927
item.attrs.iter().any(|a| a.name_or_empty() == sym::rustc_intrinsic);
925-
if body.is_none() && !is_intrinsic {
928+
if body.is_none() && !is_intrinsic && !self.is_interface {
926929
self.dcx().emit_err(errors::FnWithoutBody {
927930
span: item.span,
928931
replace_span: self.ending_semi_or_hi(item.span),
@@ -1110,6 +1113,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11101113
});
11111114
}
11121115
}
1116+
ItemKind::ExternDynCrate(_) => {
1117+
if self.sess.opts.get_symbol_mangling_version() != SymbolManglingVersion::V0 {
1118+
self.dcx()
1119+
.emit_err(errors::WrongManglingSchemeForExternDyn { span: item.span });
1120+
}
1121+
}
11131122
_ => {}
11141123
}
11151124

@@ -1419,7 +1428,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14191428
});
14201429
}
14211430
AssocItemKind::Fn(box Fn { body, .. }) => {
1422-
if body.is_none() {
1431+
if body.is_none() && !self.is_interface {
14231432
self.dcx().emit_err(errors::AssocFnWithoutBody {
14241433
span: item.span,
14251434
replace_span: self.ending_semi_or_hi(item.span),
@@ -1669,6 +1678,7 @@ pub fn check_crate(
16691678
sess: &Session,
16701679
features: &Features,
16711680
krate: &Crate,
1681+
is_interface: bool,
16721682
lints: &mut LintBuffer,
16731683
) -> bool {
16741684
let mut validator = AstValidator {
@@ -1680,6 +1690,7 @@ pub fn check_crate(
16801690
outer_impl_trait: None,
16811691
disallow_tilde_const: Some(TildeConstReason::Item),
16821692
extern_mod_safety: None,
1693+
is_interface,
16831694
lint_buffer: lints,
16841695
};
16851696
visit::walk_crate(&mut validator, krate);

compiler/rustc_ast_passes/src/errors.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,3 +824,10 @@ pub(crate) struct DuplicatePreciseCapturing {
824824
#[label]
825825
pub bound2: Span,
826826
}
827+
828+
#[derive(Diagnostic)]
829+
#[diag(ast_passes_wrong_mangling_scheme_for_extern_dyn)]
830+
pub(crate) struct WrongManglingSchemeForExternDyn {
831+
#[primary_span]
832+
pub span: Span,
833+
}

compiler/rustc_ast_pretty/src/pprust/state/item.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use itertools::{Itertools, Position};
33
use rustc_ast as ast;
44
use rustc_ast::ModKind;
55
use rustc_ast::ptr::P;
6-
use rustc_span::Ident;
6+
use rustc_span::{Ident, Symbol};
77

88
use crate::pp::Breaks::Inconsistent;
99
use crate::pprust::state::fixup::FixupContext;
@@ -148,6 +148,26 @@ impl<'a> State<'a> {
148148
self.end(); // end outer head-block
149149
}
150150

151+
fn print_extern_crate(
152+
&mut self,
153+
vis: &ast::Visibility,
154+
head: &str,
155+
ident: Ident,
156+
orig_name: Option<Symbol>,
157+
) {
158+
self.head(visibility_qualified(vis, head));
159+
if let Some(orig_name) = orig_name {
160+
self.print_name(orig_name);
161+
self.space();
162+
self.word("as");
163+
self.space();
164+
}
165+
self.print_ident(ident);
166+
self.word(";");
167+
self.end(); // end inner head-block
168+
self.end(); // end outer head-block
169+
}
170+
151171
/// Pretty-prints an item.
152172
pub(crate) fn print_item(&mut self, item: &ast::Item) {
153173
self.hardbreak_if_not_bol();
@@ -156,17 +176,10 @@ impl<'a> State<'a> {
156176
self.ann.pre(self, AnnNode::Item(item));
157177
match &item.kind {
158178
ast::ItemKind::ExternCrate(orig_name) => {
159-
self.head(visibility_qualified(&item.vis, "extern crate"));
160-
if let &Some(orig_name) = orig_name {
161-
self.print_name(orig_name);
162-
self.space();
163-
self.word("as");
164-
self.space();
165-
}
166-
self.print_ident(item.ident);
167-
self.word(";");
168-
self.end(); // end inner head-block
169-
self.end(); // end outer head-block
179+
self.print_extern_crate(&item.vis, "extern crate", item.ident, *orig_name);
180+
}
181+
ast::ItemKind::ExternDynCrate(orig_name) => {
182+
self.print_extern_crate(&item.vis, "extern dyn crate", item.ident, *orig_name);
170183
}
171184
ast::ItemKind::Use(tree) => {
172185
self.print_visibility(&item.vis);

compiler/rustc_codegen_llvm/src/back/lto.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ fn crate_type_allows_lto(crate_type: CrateType) -> bool {
4040
| CrateType::Dylib
4141
| CrateType::Staticlib
4242
| CrateType::Cdylib
43-
| CrateType::ProcMacro => true,
43+
| CrateType::ProcMacro
44+
| CrateType::Sdylib => true,
4445
CrateType::Rlib => false,
4546
}
4647
}

0 commit comments

Comments
 (0)