diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 17b16b3cfe2d9..d1c4b51eee4a3 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -224,7 +224,7 @@ impl<'tcx> Collector<'tcx> { let dll_imports = match attr.kind { NativeLibKind::RawDylib { .. } => foreign_items .iter() - .map(|&child_item| { + .filter_map(|&child_item| { self.build_dll_import( abi, attr.import_name_type.map(|(import_name_type, _)| import_name_type), @@ -388,7 +388,7 @@ impl<'tcx> Collector<'tcx> { abi: ExternAbi, import_name_type: Option, item: DefId, - ) -> DllImport { + ) -> Option { let span = self.tcx.def_span(item); // This `extern` block should have been checked for general ABI support before, but let's @@ -465,6 +465,8 @@ impl<'tcx> Collector<'tcx> { } else { DllImportSymbolType::Static } + } else if def_kind == DefKind::ForeignTy { + return None; } else { bug!("Unexpected type for raw-dylib: {}", def_kind.descr(item)); }; @@ -482,6 +484,6 @@ impl<'tcx> Collector<'tcx> { } }; - DllImport { name, import_name_type, calling_convention, span, symbol_type, size } + Some(DllImport { name, import_name_type, calling_convention, span, symbol_type, size }) } } diff --git a/tests/run-make/raw-dylib-elf-extern-types/bin.rs b/tests/run-make/raw-dylib-elf-extern-types/bin.rs new file mode 100644 index 0000000000000..a62445af4f9ca --- /dev/null +++ b/tests/run-make/raw-dylib-elf-extern-types/bin.rs @@ -0,0 +1,21 @@ +#![feature(extern_types)] +#![feature(raw_dylib_elf)] + +use std::ffi::c_char; + +#[link(name = "extern", kind = "raw-dylib")] +unsafe extern "C" { + type FOO; + fn create_foo() -> *const FOO; + fn get_foo(foo: *const FOO) -> c_char; + fn set_foo(foo: *const FOO, value: c_char); +} + +pub fn main() { + let value = unsafe { + let foo = create_foo(); + set_foo(foo, 42); + get_foo(foo) + }; + println!("{}", value); +} diff --git a/tests/run-make/raw-dylib-elf-extern-types/extern.c b/tests/run-make/raw-dylib-elf-extern-types/extern.c new file mode 100644 index 0000000000000..0201cd3348ff9 --- /dev/null +++ b/tests/run-make/raw-dylib-elf-extern-types/extern.c @@ -0,0 +1,16 @@ +typedef struct FOO { + char val; +} FOO; + +FOO* create_foo() { + static FOO foo; + return &foo; +} + +void set_foo(FOO* foo, char val) { + foo->val = val; +} + +char get_foo(FOO* foo) { + return foo->val; +} diff --git a/tests/run-make/raw-dylib-elf-extern-types/output.txt b/tests/run-make/raw-dylib-elf-extern-types/output.txt new file mode 100644 index 0000000000000..d81cc0710eb6c --- /dev/null +++ b/tests/run-make/raw-dylib-elf-extern-types/output.txt @@ -0,0 +1 @@ +42 diff --git a/tests/run-make/raw-dylib-elf-extern-types/rmake.rs b/tests/run-make/raw-dylib-elf-extern-types/rmake.rs new file mode 100644 index 0000000000000..410982548ca1c --- /dev/null +++ b/tests/run-make/raw-dylib-elf-extern-types/rmake.rs @@ -0,0 +1,18 @@ +//@ only-elf +//@ ignore-cross-compile: Runs a binary. +//@ needs-dynamic-linking +// FIXME(raw_dylib_elf): Debug the failures on other targets. +//@ only-gnu +//@ only-x86_64 + +//@ ignore-rustc-debug-assertions + +use run_make_support::{build_native_dynamic_lib, diff, run, rustc}; + +fn main() { + rustc().crate_type("bin").crate_name("raw_dylib_test").input("bin.rs").run(); + build_native_dynamic_lib("extern"); + + let out_raw = run("raw_dylib_test").stdout_utf8(); + diff().expected_file("output.txt").actual_text("actual", out_raw).normalize(r#"\r"#, "").run(); +}