about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2019-09-11 08:08:04 -0700
committerAlex Crichton <alex@alexcrichton.com>2019-09-23 12:29:51 -0700
commit50c57d8c80b1fab4c1e9087756fb9fae396d5218 (patch)
treeff339d08c069bf82aba5da45609a8c32065f07d9
parent5d531aeaf46451f999aea0f7c9ba08016b9ee3eb (diff)
downloadrust-50c57d8c80b1fab4c1e9087756fb9fae396d5218.tar.gz
rust-50c57d8c80b1fab4c1e9087756fb9fae396d5218.zip
rustc: Fix mixing crates with different `share_generics`
This commit addresses #64319 by removing the `dylib` crate type from the
list of crate type that exports generic symbols. The bug in #64319
arises because a `dylib` crate type was trying to export a symbol in an
uptream crate but it miscalculated the symbol name of the uptream
symbol. This isn't really necessary, though, since `dylib` crates aren't
that heavily used, so we can just conservatively say that the `dylib`
crate type never exports generic symbols, forcibly removing them from
the exported symbol lists if were to otherwise find them.

The fix here happens in two places:

* First is in the `local_crate_exports_generics` method, indicating that
  it's now `false` for the `Dylib` crate type. Only rlibs actually
  export generics at this point.

* Next is when we load exported symbols from upstream crate. If, for our
  compilation session, the crate may be included from a dynamic library,
  then its generic symbols are removed. When the crate was linked into a
  dynamic library its symbols weren't exported, so we can't consider
  them a candidate to link against.

Overally this should avoid situations where we incorrectly calculate the
upstream symbol names in the face of differnet `share_generics` options,
ultimately...

Closes #64319
-rw-r--r--src/librustc/query/mod.rs4
-rw-r--r--src/librustc/ty/context.rs4
-rw-r--r--src/librustc_codegen_ssa/back/symbol_export.rs2
-rw-r--r--src/librustc_metadata/cstore_impl.rs27
-rw-r--r--src/librustc_metadata/dependency_format.rs1
-rw-r--r--src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs1
-rw-r--r--src/test/codegen-units/partitioning/shared-generics.rs1
-rw-r--r--src/test/compile-fail/two-panic-runtimes.rs1
-rw-r--r--src/test/run-make-fulldeps/issue-64319/Makefile39
-rw-r--r--src/test/run-make-fulldeps/issue-64319/bar.rs5
-rw-r--r--src/test/run-make-fulldeps/issue-64319/foo.rs9
-rw-r--r--src/test/run-make-fulldeps/symbol-visibility/Makefile4
-rw-r--r--src/test/ui/panic-runtime/transitive-link-a-bunch.rs3
-rw-r--r--src/test/ui/panic-runtime/want-unwind-got-abort.rs3
-rw-r--r--src/test/ui/panic-runtime/want-unwind-got-abort2.rs3
15 files changed, 93 insertions, 14 deletions
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 4a9fa57f345..fd99995480a 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -631,7 +631,9 @@ rustc_queries! {
             desc { "dylib dependency formats of crate" }
         }
 
-        query dependency_formats(_: CrateNum) -> Lrc<crate::middle::dependency_format::Dependencies> {
+        query dependency_formats(_: CrateNum)
+            -> Lrc<crate::middle::dependency_format::Dependencies>
+        {
             desc { "get the linkage format of all dependencies" }
         }
     }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 0155803e305..c03dbb2b1ed 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1510,9 +1510,9 @@ impl<'tcx> TyCtxt<'tcx> {
                 CrateType::Executable |
                 CrateType::Staticlib  |
                 CrateType::ProcMacro  |
+                CrateType::Dylib      |
                 CrateType::Cdylib     => false,
-                CrateType::Rlib       |
-                CrateType::Dylib      => true,
+                CrateType::Rlib       => true,
             }
         })
     }
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index 7e700e68194..3e4b7695447 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -298,7 +298,7 @@ fn upstream_monomorphizations_provider(
     };
 
     for &cnum in cnums.iter() {
-        for &(ref exported_symbol, _) in tcx.exported_symbols(cnum).iter() {
+        for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() {
             if let &ExportedSymbol::Generic(def_id, substs) = exported_symbol {
                 let substs_map = instances.entry(def_id).or_default();
 
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 4a81fd3b320..f18a98ffea7 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -10,6 +10,8 @@ use rustc::middle::cstore::{CrateStore, DepKind,
                             EncodedMetadata, NativeLibraryKind};
 use rustc::middle::exported_symbols::ExportedSymbol;
 use rustc::middle::stability::DeprecationEntry;
+use rustc::middle::dependency_format::Linkage;
+use rustc::session::config::CrateType;
 use rustc::hir::def;
 use rustc::hir;
 use rustc::session::{CrateDisambiguator, Session};
@@ -239,7 +241,30 @@ provide! { <'tcx> tcx, def_id, other, cdata,
 
     used_crate_source => { Lrc::new(cdata.source.clone()) }
 
-    exported_symbols => { Arc::new(cdata.exported_symbols(tcx)) }
+    exported_symbols => {
+        let mut syms = cdata.exported_symbols(tcx);
+
+        // When linked into a dylib crates don't export their generic symbols,
+        // so if that's happening then we can't load upstream monomorphizations
+        // from this crate. As a result, if we're creating a dylib or this crate
+        // is being included from a different dynamic library, then we filter
+        // out all `Generic` symbols here.
+        let formats = tcx.dependency_formats(LOCAL_CRATE);
+        let remove_generics = formats.iter().any(|(ty, list)| {
+            *ty == CrateType::Dylib ||
+                list.get(def_id.krate.as_usize() - 1) == Some(&Linkage::IncludedFromDylib)
+        });
+        if remove_generics {
+            syms.retain(|(sym, _threshold)| {
+                match sym {
+                    ExportedSymbol::Generic(..) => false,
+                    _ => return true,
+                }
+            });
+        }
+
+        Arc::new(syms)
+    }
 }
 
 pub fn provide(providers: &mut Providers<'_>) {
diff --git a/src/librustc_metadata/dependency_format.rs b/src/librustc_metadata/dependency_format.rs
index 9de326a67b4..9a30623b33d 100644
--- a/src/librustc_metadata/dependency_format.rs
+++ b/src/librustc_metadata/dependency_format.rs
@@ -368,4 +368,3 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
         }
     }
 }
-
diff --git a/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs b/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs
index d50a7910fe0..9050e8f1671 100644
--- a/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs
+++ b/src/test/codegen-units/partitioning/auxiliary/shared_generics_aux.rs
@@ -1,4 +1,5 @@
 // compile-flags:-Zshare-generics=yes
+// no-prefer-dynamic
 
 #![crate_type="rlib"]
 
diff --git a/src/test/codegen-units/partitioning/shared-generics.rs b/src/test/codegen-units/partitioning/shared-generics.rs
index 010412b8bae..58e485be003 100644
--- a/src/test/codegen-units/partitioning/shared-generics.rs
+++ b/src/test/codegen-units/partitioning/shared-generics.rs
@@ -1,4 +1,5 @@
 // ignore-tidy-linelength
+// no-prefer-dynamic
 // compile-flags:-Zprint-mono-items=eager -Zshare-generics=yes -Zincremental=tmp/partitioning-tests/shared-generics-exe
 
 #![crate_type="rlib"]
diff --git a/src/test/compile-fail/two-panic-runtimes.rs b/src/test/compile-fail/two-panic-runtimes.rs
index 66b184e521a..671d44564e6 100644
--- a/src/test/compile-fail/two-panic-runtimes.rs
+++ b/src/test/compile-fail/two-panic-runtimes.rs
@@ -5,6 +5,7 @@
 // aux-build:panic-runtime-lang-items.rs
 
 #![no_std]
+#![no_main]
 
 extern crate panic_runtime_unwind;
 extern crate panic_runtime_unwind2;
diff --git a/src/test/run-make-fulldeps/issue-64319/Makefile b/src/test/run-make-fulldeps/issue-64319/Makefile
new file mode 100644
index 00000000000..b2c6b8b3cbb
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue-64319/Makefile
@@ -0,0 +1,39 @@
+-include ../tools.mk
+
+# Different optimization levels imply different values for `-Zshare-generics`,
+# so try out a whole bunch of combinations to make sure everything is compatible
+all:
+	# First up, try some defaults
+	$(RUSTC) --crate-type rlib foo.rs
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=3
+
+	# Next try mixing up some things explicitly
+	$(RUSTC) --crate-type rlib foo.rs -Z share-generics=no
+	$(RUSTC) --crate-type dylib bar.rs -Z share-generics=no
+	$(RUSTC) --crate-type rlib foo.rs -Z share-generics=no
+	$(RUSTC) --crate-type dylib bar.rs -Z share-generics=yes
+	$(RUSTC) --crate-type rlib foo.rs -Z share-generics=yes
+	$(RUSTC) --crate-type dylib bar.rs -Z share-generics=no
+	$(RUSTC) --crate-type rlib foo.rs -Z share-generics=yes
+	$(RUSTC) --crate-type dylib bar.rs -Z share-generics=yes
+
+	# Now combine a whole bunch of options together
+	$(RUSTC) --crate-type rlib foo.rs
+	$(RUSTC) --crate-type dylib bar.rs
+	$(RUSTC) --crate-type dylib bar.rs -Z share-generics=no
+	$(RUSTC) --crate-type dylib bar.rs -Z share-generics=yes
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=1
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=1 -Z share-generics=no
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=1 -Z share-generics=yes
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=2
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=2 -Z share-generics=no
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=2 -Z share-generics=yes
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=3
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=3 -Z share-generics=no
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=3 -Z share-generics=yes
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=s
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=s -Z share-generics=no
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=s -Z share-generics=yes
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=z
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=z -Z share-generics=no
+	$(RUSTC) --crate-type dylib bar.rs -C opt-level=z -Z share-generics=yes
diff --git a/src/test/run-make-fulldeps/issue-64319/bar.rs b/src/test/run-make-fulldeps/issue-64319/bar.rs
new file mode 100644
index 00000000000..3895c0b6cdb
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue-64319/bar.rs
@@ -0,0 +1,5 @@
+extern crate foo;
+
+pub fn bar() {
+    foo::foo();
+}
diff --git a/src/test/run-make-fulldeps/issue-64319/foo.rs b/src/test/run-make-fulldeps/issue-64319/foo.rs
new file mode 100644
index 00000000000..c54a238e9ad
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue-64319/foo.rs
@@ -0,0 +1,9 @@
+pub fn foo() {
+    bar::<usize>();
+}
+
+pub fn bar<T>() {
+    baz();
+}
+
+fn baz() {}
diff --git a/src/test/run-make-fulldeps/symbol-visibility/Makefile b/src/test/run-make-fulldeps/symbol-visibility/Makefile
index 7901866015b..840fe801a95 100644
--- a/src/test/run-make-fulldeps/symbol-visibility/Makefile
+++ b/src/test/run-make-fulldeps/symbol-visibility/Makefile
@@ -79,12 +79,12 @@ all:
 	# Check that a Rust dylib exports its monomorphic functions, including generics this time
 	[ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_c_function_from_rust_dylib)" -eq "1" ]
 	[ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_rust_function_from_rust_dylib)" -eq "1" ]
-	[ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_generic_function_from_rust_dylib)" -eq "1" ]
+	[ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_generic_function_from_rust_dylib)" -eq "0" ]
 
 	# Check that a Rust dylib exports the monomorphic functions from its dependencies
 	[ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_c_function_from_rlib)" -eq "1" ]
 	[ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_rust_function_from_rlib)" -eq "1" ]
-	[ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_generic_function_from_rlib)" -eq "1" ]
+	[ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -c public_generic_function_from_rlib)" -eq "0" ]
 
 	# Check that an executable does not export any dynamic symbols
 	[ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -c public_c_function_from_rlib)" -eq "0" ]
diff --git a/src/test/ui/panic-runtime/transitive-link-a-bunch.rs b/src/test/ui/panic-runtime/transitive-link-a-bunch.rs
index 9b083a640a6..5d72771c2dc 100644
--- a/src/test/ui/panic-runtime/transitive-link-a-bunch.rs
+++ b/src/test/ui/panic-runtime/transitive-link-a-bunch.rs
@@ -7,9 +7,8 @@
 // ignore-wasm32-bare compiled with panic=abort by default
 
 #![no_std]
+#![no_main]
 
 extern crate wants_panic_runtime_unwind;
 extern crate wants_panic_runtime_abort;
 extern crate panic_runtime_lang_items;
-
-fn main() {}
diff --git a/src/test/ui/panic-runtime/want-unwind-got-abort.rs b/src/test/ui/panic-runtime/want-unwind-got-abort.rs
index c9ee8a032a3..4c25c09d643 100644
--- a/src/test/ui/panic-runtime/want-unwind-got-abort.rs
+++ b/src/test/ui/panic-runtime/want-unwind-got-abort.rs
@@ -4,8 +4,7 @@
 // ignore-wasm32-bare compiled with panic=abort by default
 
 #![no_std]
+#![no_main]
 
 extern crate panic_runtime_abort;
 extern crate panic_runtime_lang_items;
-
-fn main() {}
diff --git a/src/test/ui/panic-runtime/want-unwind-got-abort2.rs b/src/test/ui/panic-runtime/want-unwind-got-abort2.rs
index 5219826eec6..478af451e7f 100644
--- a/src/test/ui/panic-runtime/want-unwind-got-abort2.rs
+++ b/src/test/ui/panic-runtime/want-unwind-got-abort2.rs
@@ -5,8 +5,7 @@
 // ignore-wasm32-bare compiled with panic=abort by default
 
 #![no_std]
+#![no_main]
 
 extern crate wants_panic_runtime_abort;
 extern crate panic_runtime_lang_items;
-
-fn main() {}