about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2023-03-17 09:23:46 +0800
committeryukang <moorekang@gmail.com>2023-03-19 11:23:19 +0800
commitd5558e67ef86bda546eca72778aeeeda24420926 (patch)
treefd82733ae7b4224df33be30836614288464359f8
parentc22f154e3fb6eca7dd1e83575564a5ea44d661bc (diff)
downloadrust-d5558e67ef86bda546eca72778aeeeda24420926.tar.gz
rust-d5558e67ef86bda546eca72778aeeeda24420926.zip
The name of NativeLib will be presented
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs19
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs2
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs75
-rw-r--r--compiler/rustc_session/src/cstore.rs7
-rw-r--r--compiler/rustc_session/src/utils.rs9
-rw-r--r--tests/ui/linkage-attr/issue-109144.rs4
-rw-r--r--tests/ui/linkage-attr/issue-109144.stderr9
8 files changed, 71 insertions, 56 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 8aa744ce935..64742bbb986 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -358,9 +358,9 @@ fn link_rlib<'a>(
             let (data, _) = create_wrapper_file(sess, b".bundled_lib".to_vec(), &src);
             let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str());
             packed_bundled_libs.push(wrapper_file);
-        } else if let Some(name) = lib.name {
+        } else {
             let path =
-                find_native_static_library(name.as_str(), lib.verbatim, &lib_search_paths, sess);
+                find_native_static_library(lib.name.as_str(), lib.verbatim, &lib_search_paths, sess);
             ab.add_archive(&path, Box::new(|_| false)).unwrap_or_else(|error| {
                 sess.emit_fatal(errors::AddNativeLibrary { library_path: path, error })});
         }
@@ -436,7 +436,7 @@ fn collate_raw_dylibs<'a, 'b>(
     for lib in used_libraries {
         if lib.kind == NativeLibKind::RawDylib {
             let ext = if lib.verbatim { "" } else { ".dll" };
-            let name = format!("{}{}", lib.name.expect("unnamed raw-dylib library"), ext);
+            let name = format!("{}{}", lib.name, ext);
             let imports = dylib_table.entry(name.clone()).or_default();
             for import in &lib.dll_imports {
                 if let Some(old_import) = imports.insert(import.name, import) {
@@ -1294,7 +1294,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
         .iter()
         .filter(|l| relevant_lib(sess, l))
         .filter_map(|lib| {
-            let name = lib.name?;
+            let name = lib.name;
             match lib.kind {
                 NativeLibKind::Static { bundle: Some(false), .. }
                 | NativeLibKind::Dylib { .. }
@@ -1315,6 +1315,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
                 // These are included, no need to print them
                 NativeLibKind::Static { bundle: None | Some(true), .. }
                 | NativeLibKind::LinkArg
+                | NativeLibKind::WasmImportModule
                 | NativeLibKind::RawDylib => None,
             }
         })
@@ -2273,21 +2274,18 @@ fn add_native_libs_from_crate(
 
     let mut last = (None, NativeLibKind::Unspecified, false);
     for lib in native_libs {
-        let Some(name) = lib.name else {
-            continue;
-        };
         if !relevant_lib(sess, lib) {
             continue;
         }
 
         // Skip if this library is the same as the last.
-        last = if (lib.name, lib.kind, lib.verbatim) == last {
+        last = if (Some(lib.name), lib.kind, lib.verbatim) == last {
             continue;
         } else {
-            (lib.name, lib.kind, lib.verbatim)
+            (Some(lib.name), lib.kind, lib.verbatim)
         };
 
-        let name = name.as_str();
+        let name = lib.name.as_str();
         let verbatim = lib.verbatim;
         match lib.kind {
             NativeLibKind::Static { bundle, whole_archive } => {
@@ -2344,6 +2342,7 @@ fn add_native_libs_from_crate(
             NativeLibKind::RawDylib => {
                 // Handled separately in `linker_with_args`.
             }
+            NativeLibKind::WasmImportModule => {}
             NativeLibKind::LinkArg => {
                 if link_static {
                     cmd.arg(name);
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 7b58e55dbe8..18d17b1a013 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -595,7 +595,7 @@ fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> FxHashMap<DefId, S
 
     let mut ret = FxHashMap::default();
     for (def_id, lib) in tcx.foreign_modules(cnum).iter() {
-        let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module);
+        let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module());
         let Some(module) = module else { continue };
         ret.extend(lib.foreign_items.iter().map(|id| {
             assert_eq!(id.krate, cnum);
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 8e721a84eaf..81227b04e8a 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -118,7 +118,7 @@ bitflags::bitflags! {
 #[derive(Clone, Debug, Encodable, Decodable, HashStable)]
 pub struct NativeLib {
     pub kind: NativeLibKind,
-    pub name: Option<Symbol>,
+    pub name: Symbol,
     pub filename: Option<Symbol>,
     pub cfg: Option<ast::MetaItem>,
     pub verbatim: bool,
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 6b6aa78575a..b855c8e4332 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -46,14 +46,13 @@ pub fn find_native_static_library(
 }
 
 fn find_bundled_library(
-    name: Option<Symbol>,
+    name: Symbol,
     verbatim: Option<bool>,
     kind: NativeLibKind,
     has_cfg: bool,
     sess: &Session,
 ) -> Option<Symbol> {
     if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind
-        && let Some(name) = name
         && sess.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::Staticlib))
         && (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true))
     {
@@ -337,10 +336,16 @@ impl<'tcx> Collector<'tcx> {
                 if name.is_some() || kind.is_some() || modifiers.is_some() || cfg.is_some() {
                     sess.emit_err(errors::IncompatibleWasmLink { span });
                 }
-            } else if name.is_none() {
-                sess.emit_err(errors::LinkRequiresName { span: m.span });
             }
 
+            if wasm_import_module.is_some() {
+                (name, kind) = (wasm_import_module, Some(NativeLibKind::WasmImportModule));
+            }
+            let Some((name, name_span)) = name else {
+                sess.emit_err(errors::LinkRequiresName { span: m.span });
+                continue;
+            };
+
             // Do this outside of the loop so that `import_name_type` can be specified before `kind`.
             if let Some((_, span)) = import_name_type {
                 if kind != Some(NativeLibKind::RawDylib) {
@@ -350,8 +355,8 @@ impl<'tcx> Collector<'tcx> {
 
             let dll_imports = match kind {
                 Some(NativeLibKind::RawDylib) => {
-                    if let Some((name, span)) = name && name.as_str().contains('\0') {
-                        sess.emit_err(errors::RawDylibNoNul { span });
+                    if name.as_str().contains('\0') {
+                        sess.emit_err(errors::RawDylibNoNul { span: name_span });
                     }
                     foreign_mod_items
                         .iter()
@@ -390,7 +395,6 @@ impl<'tcx> Collector<'tcx> {
                 }
             };
 
-            let name = name.map(|(name, _)| name);
             let kind = kind.unwrap_or(NativeLibKind::Unspecified);
             let filename = find_bundled_library(name, verbatim, kind, cfg.is_some(), sess);
             self.libs.push(NativeLib {
@@ -399,7 +403,6 @@ impl<'tcx> Collector<'tcx> {
                 kind,
                 cfg,
                 foreign_module: Some(it.owner_id.to_def_id()),
-                wasm_import_module: wasm_import_module.map(|(name, _)| name),
                 verbatim,
                 dll_imports,
             });
@@ -416,11 +419,7 @@ impl<'tcx> Collector<'tcx> {
                 self.tcx.sess.emit_err(errors::LibFrameworkApple);
             }
             if let Some(ref new_name) = lib.new_name {
-                let any_duplicate = self
-                    .libs
-                    .iter()
-                    .filter_map(|lib| lib.name.as_ref())
-                    .any(|n| n.as_str() == lib.name);
+                let any_duplicate = self.libs.iter().any(|n| n.name.as_str() == lib.name);
                 if new_name.is_empty() {
                     self.tcx.sess.emit_err(errors::EmptyRenamingTarget { lib_name: &lib.name });
                 } else if !any_duplicate {
@@ -445,33 +444,28 @@ impl<'tcx> Collector<'tcx> {
             let mut existing = self
                 .libs
                 .drain_filter(|lib| {
-                    if let Some(lib_name) = lib.name {
-                        if lib_name.as_str() == passed_lib.name {
-                            // FIXME: This whole logic is questionable, whether modifiers are
-                            // involved or not, library reordering and kind overriding without
-                            // explicit `:rename` in particular.
-                            if lib.has_modifiers() || passed_lib.has_modifiers() {
-                                match lib.foreign_module {
-                                    Some(def_id) => {
-                                        self.tcx.sess.emit_err(errors::NoLinkModOverride {
-                                            span: Some(self.tcx.def_span(def_id)),
-                                        })
-                                    }
-                                    None => self
-                                        .tcx
-                                        .sess
-                                        .emit_err(errors::NoLinkModOverride { span: None }),
-                                };
-                            }
-                            if passed_lib.kind != NativeLibKind::Unspecified {
-                                lib.kind = passed_lib.kind;
-                            }
-                            if let Some(new_name) = &passed_lib.new_name {
-                                lib.name = Some(Symbol::intern(new_name));
-                            }
-                            lib.verbatim = passed_lib.verbatim;
-                            return true;
+                    if lib.name.as_str() == passed_lib.name {
+                        // FIXME: This whole logic is questionable, whether modifiers are
+                        // involved or not, library reordering and kind overriding without
+                        // explicit `:rename` in particular.
+                        if lib.has_modifiers() || passed_lib.has_modifiers() {
+                            match lib.foreign_module {
+                                Some(def_id) => self.tcx.sess.emit_err(errors::NoLinkModOverride {
+                                    span: Some(self.tcx.def_span(def_id)),
+                                }),
+                                None => {
+                                    self.tcx.sess.emit_err(errors::NoLinkModOverride { span: None })
+                                }
+                            };
+                        }
+                        if passed_lib.kind != NativeLibKind::Unspecified {
+                            lib.kind = passed_lib.kind;
+                        }
+                        if let Some(new_name) = &passed_lib.new_name {
+                            lib.name = Symbol::intern(new_name);
                         }
+                        lib.verbatim = passed_lib.verbatim;
+                        return true;
                     }
                     false
                 })
@@ -479,7 +473,7 @@ impl<'tcx> Collector<'tcx> {
             if existing.is_empty() {
                 // Add if not found
                 let new_name: Option<&str> = passed_lib.new_name.as_deref();
-                let name = Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name)));
+                let name = Symbol::intern(new_name.unwrap_or(&passed_lib.name));
                 let sess = self.tcx.sess;
                 let filename =
                     find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, false, sess);
@@ -489,7 +483,6 @@ impl<'tcx> Collector<'tcx> {
                     kind: passed_lib.kind,
                     cfg: None,
                     foreign_module: None,
-                    wasm_import_module: None,
                     verbatim: passed_lib.verbatim,
                     dll_imports: Vec::new(),
                 });
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index 868ffdf0f1d..a262c06d91f 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -67,12 +67,11 @@ pub enum LinkagePreference {
 #[derive(Debug, Encodable, Decodable, HashStable_Generic)]
 pub struct NativeLib {
     pub kind: NativeLibKind,
-    pub name: Option<Symbol>,
+    pub name: Symbol,
     /// If packed_bundled_libs enabled, actual filename of library is stored.
     pub filename: Option<Symbol>,
     pub cfg: Option<ast::MetaItem>,
     pub foreign_module: Option<DefId>,
-    pub wasm_import_module: Option<Symbol>,
     pub verbatim: Option<bool>,
     pub dll_imports: Vec<DllImport>,
 }
@@ -81,6 +80,10 @@ impl NativeLib {
     pub fn has_modifiers(&self) -> bool {
         self.verbatim.is_some() || self.kind.has_modifiers()
     }
+
+    pub fn wasm_import_module(&self) -> Option<Symbol> {
+        if self.kind == NativeLibKind::WasmImportModule { Some(self.name) } else { None }
+    }
 }
 
 /// Different ways that the PE Format can decorate a symbol name.
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index b996d36a318..3b3d4ca5d6b 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -37,6 +37,10 @@ pub enum NativeLibKind {
     /// Argument which is passed to linker, relative order with libraries and other arguments
     /// is preserved
     LinkArg,
+
+    /// Module imported from WebAssembly
+    WasmImportModule,
+
     /// The library kind wasn't specified, `Dylib` is currently used as a default.
     Unspecified,
 }
@@ -50,7 +54,10 @@ impl NativeLibKind {
             NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } => {
                 as_needed.is_some()
             }
-            NativeLibKind::RawDylib | NativeLibKind::Unspecified | NativeLibKind::LinkArg => false,
+            NativeLibKind::RawDylib
+            | NativeLibKind::Unspecified
+            | NativeLibKind::LinkArg
+            | NativeLibKind::WasmImportModule => false,
         }
     }
 
diff --git a/tests/ui/linkage-attr/issue-109144.rs b/tests/ui/linkage-attr/issue-109144.rs
new file mode 100644
index 00000000000..2f740e55389
--- /dev/null
+++ b/tests/ui/linkage-attr/issue-109144.rs
@@ -0,0 +1,4 @@
+#![crate_type = "lib"]
+#[link(kind = "static", modifiers = "+whole-archive,+bundle")]
+//~^ ERROR `#[link]` attribute requires a `name = "string"` argument
+extern  {}
diff --git a/tests/ui/linkage-attr/issue-109144.stderr b/tests/ui/linkage-attr/issue-109144.stderr
new file mode 100644
index 00000000000..33187cfdbb6
--- /dev/null
+++ b/tests/ui/linkage-attr/issue-109144.stderr
@@ -0,0 +1,9 @@
+error[E0459]: `#[link]` attribute requires a `name = "string"` argument
+  --> $DIR/issue-109144.rs:2:1
+   |
+LL | #[link(kind = "static", modifiers = "+whole-archive,+bundle")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `name` argument
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0459`.