mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-15 05:26:47 +00:00
Auto merge of #76219 - Mark-Simulacrum:extern-require-abi, r=estebank
Add allow-by-default lint on implicit ABI in extern function pointers and items This adds a new lint, missing_abi, which lints on omitted ABIs on extern blocks, function declarations, and function pointers. It is currently not emitting the best possible diagnostics -- we need to track the span of "extern" at least or do some heuristic searching based on the available spans -- but seems good enough for an initial pass than can be expanded in future PRs. This is a pretty large PR, but mostly due to updating a large number of tests to include ABIs; I can split that into a separate PR if it would be helpful, but test updates are already in dedicated commits.
This commit is contained in:
commit
fd2df74902
@ -3896,6 +3896,7 @@ dependencies = [
|
||||
"rustc_macros",
|
||||
"rustc_serialize",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
@ -310,19 +310,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
let sig = hir::FnSig {
|
||||
decl,
|
||||
header: this.lower_fn_header(header),
|
||||
header: this.lower_fn_header(header, fn_sig_span, id),
|
||||
span: fn_sig_span,
|
||||
};
|
||||
hir::ItemKind::Fn(sig, generics, body_id)
|
||||
})
|
||||
}
|
||||
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
|
||||
ItemKind::ForeignMod(ref fm) => hir::ItemKind::ForeignMod {
|
||||
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
|
||||
items: self
|
||||
.arena
|
||||
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
|
||||
},
|
||||
ItemKind::ForeignMod(ref fm) => {
|
||||
if fm.abi.is_none() {
|
||||
self.maybe_lint_missing_abi(span, id, abi::Abi::C);
|
||||
}
|
||||
hir::ItemKind::ForeignMod {
|
||||
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
|
||||
items: self
|
||||
.arena
|
||||
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
|
||||
}
|
||||
}
|
||||
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
|
||||
ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => {
|
||||
// We lower
|
||||
@ -801,13 +806,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
AssocItemKind::Fn(_, ref sig, ref generics, None) => {
|
||||
let names = self.lower_fn_params_to_names(&sig.decl);
|
||||
let (generics, sig) =
|
||||
self.lower_method_sig(generics, sig, trait_item_def_id, false, None);
|
||||
self.lower_method_sig(generics, sig, trait_item_def_id, false, None, i.id);
|
||||
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)))
|
||||
}
|
||||
AssocItemKind::Fn(_, ref sig, ref generics, Some(ref body)) => {
|
||||
let body_id = self.lower_fn_body_block(i.span, &sig.decl, Some(body));
|
||||
let (generics, sig) =
|
||||
self.lower_method_sig(generics, sig, trait_item_def_id, false, None);
|
||||
self.lower_method_sig(generics, sig, trait_item_def_id, false, None, i.id);
|
||||
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)))
|
||||
}
|
||||
AssocItemKind::TyAlias(_, ref generics, ref bounds, ref default) => {
|
||||
@ -877,6 +882,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
impl_item_def_id,
|
||||
impl_trait_return_allow,
|
||||
asyncness.opt_return_id(),
|
||||
i.id,
|
||||
);
|
||||
|
||||
(generics, hir::ImplItemKind::Fn(sig, body_id))
|
||||
@ -1270,8 +1276,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
fn_def_id: LocalDefId,
|
||||
impl_trait_return_allow: bool,
|
||||
is_async: Option<NodeId>,
|
||||
id: NodeId,
|
||||
) -> (hir::Generics<'hir>, hir::FnSig<'hir>) {
|
||||
let header = self.lower_fn_header(sig.header);
|
||||
let header = self.lower_fn_header(sig.header, sig.span, id);
|
||||
let (generics, decl) = self.add_in_band_defs(
|
||||
generics,
|
||||
fn_def_id,
|
||||
@ -1288,12 +1295,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
(generics, hir::FnSig { header, decl, span: sig.span })
|
||||
}
|
||||
|
||||
fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
|
||||
fn lower_fn_header(&mut self, h: FnHeader, span: Span, id: NodeId) -> hir::FnHeader {
|
||||
hir::FnHeader {
|
||||
unsafety: self.lower_unsafety(h.unsafety),
|
||||
asyncness: self.lower_asyncness(h.asyncness),
|
||||
constness: self.lower_constness(h.constness),
|
||||
abi: self.lower_extern(h.ext),
|
||||
abi: self.lower_extern(h.ext, span, id),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1304,10 +1311,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn lower_extern(&mut self, ext: Extern) -> abi::Abi {
|
||||
pub(super) fn lower_extern(&mut self, ext: Extern, span: Span, id: NodeId) -> abi::Abi {
|
||||
match ext {
|
||||
Extern::None => abi::Abi::Rust,
|
||||
Extern::Implicit => abi::Abi::C,
|
||||
Extern::Implicit => {
|
||||
self.maybe_lint_missing_abi(span, id, abi::Abi::C);
|
||||
abi::Abi::C
|
||||
}
|
||||
Extern::Explicit(abi) => self.lower_abi(abi),
|
||||
}
|
||||
}
|
||||
|
@ -53,13 +53,15 @@ use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
|
||||
use rustc_hir::intravisit;
|
||||
use rustc_hir::{ConstArg, GenericArg, ParamName};
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_session::lint::{builtin::BARE_TRAIT_OBJECTS, BuiltinLintDiagnostics, LintBuffer};
|
||||
use rustc_session::lint::builtin::{BARE_TRAIT_OBJECTS, MISSING_ABI};
|
||||
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::hygiene::ExpnId;
|
||||
use rustc_span::source_map::{respan, DesugaringKind};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::collections::BTreeMap;
|
||||
@ -1288,6 +1290,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(&f.generic_params, |this| {
|
||||
this.with_anonymous_lifetime_mode(AnonymousLifetimeMode::PassThrough, |this| {
|
||||
let span = this.sess.source_map().next_point(t.span.shrink_to_lo());
|
||||
hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
|
||||
generic_params: this.lower_generic_params(
|
||||
&f.generic_params,
|
||||
@ -1295,7 +1298,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
ImplTraitContext::disallowed(),
|
||||
),
|
||||
unsafety: this.lower_unsafety(f.unsafety),
|
||||
abi: this.lower_extern(f.ext),
|
||||
abi: this.lower_extern(f.ext, span, t.id),
|
||||
decl: this.lower_fn_decl(&f.decl, None, false, None),
|
||||
param_names: this.lower_fn_params_to_names(&f.decl),
|
||||
}))
|
||||
@ -2777,6 +2780,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_lint_missing_abi(&mut self, span: Span, id: NodeId, default: Abi) {
|
||||
// FIXME(davidtwco): This is a hack to detect macros which produce spans of the
|
||||
// call site which do not have a macro backtrace. See #61963.
|
||||
let is_macro_callsite = self
|
||||
.sess
|
||||
.source_map()
|
||||
.span_to_snippet(span)
|
||||
.map(|snippet| snippet.starts_with("#["))
|
||||
.unwrap_or(true);
|
||||
if !is_macro_callsite {
|
||||
self.resolver.lint_buffer().buffer_lint_with_diagnostic(
|
||||
MISSING_ABI,
|
||||
id,
|
||||
span,
|
||||
"extern declarations without an explicit ABI are deprecated",
|
||||
BuiltinLintDiagnostics::MissingAbi(span, default),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body<'_>>) -> Vec<hir::BodyId> {
|
||||
|
@ -3,13 +3,13 @@ You cannot use type or const parameters on foreign items.
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0044
|
||||
extern { fn some_func<T>(x: T); }
|
||||
extern "C" { fn some_func<T>(x: T); }
|
||||
```
|
||||
|
||||
To fix this, replace the generic parameter with the specializations that you
|
||||
need:
|
||||
|
||||
```
|
||||
extern { fn some_func_i32(x: i32); }
|
||||
extern { fn some_func_i64(x: i64); }
|
||||
extern "C" { fn some_func_i32(x: i32); }
|
||||
extern "C" { fn some_func_i64(x: i64); }
|
||||
```
|
||||
|
@ -3,7 +3,7 @@ A pattern was declared as an argument in a foreign function declaration.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0130
|
||||
extern {
|
||||
extern "C" {
|
||||
fn foo((a, b): (u32, u32)); // error: patterns aren't allowed in foreign
|
||||
// function declarations
|
||||
}
|
||||
@ -17,7 +17,7 @@ struct SomeStruct {
|
||||
b: u32,
|
||||
}
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
fn foo(s: SomeStruct); // ok!
|
||||
}
|
||||
```
|
||||
@ -25,7 +25,7 @@ extern {
|
||||
Or:
|
||||
|
||||
```
|
||||
extern {
|
||||
extern "C" {
|
||||
fn foo(a: (u32, u32)); // ok!
|
||||
}
|
||||
```
|
||||
|
@ -3,7 +3,7 @@ A link name was given with an empty name.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0454
|
||||
#[link(name = "")] extern {}
|
||||
#[link(name = "")] extern "C" {}
|
||||
// error: `#[link(name = "")]` given with empty name
|
||||
```
|
||||
|
||||
@ -11,5 +11,5 @@ The rust compiler cannot link to an external library if you don't give it its
|
||||
name. Example:
|
||||
|
||||
```no_run
|
||||
#[link(name = "some_lib")] extern {} // ok!
|
||||
#[link(name = "some_lib")] extern "C" {} // ok!
|
||||
```
|
||||
|
@ -4,7 +4,7 @@ as frameworks are specific to that operating system.
|
||||
Erroneous code example:
|
||||
|
||||
```ignore (should-compile_fail-but-cannot-doctest-conditionally-without-macos)
|
||||
#[link(name = "FooCoreServices", kind = "framework")] extern {}
|
||||
#[link(name = "FooCoreServices", kind = "framework")] extern "C" {}
|
||||
// OS used to compile is Linux for example
|
||||
```
|
||||
|
||||
@ -12,7 +12,7 @@ To solve this error you can use conditional compilation:
|
||||
|
||||
```
|
||||
#[cfg_attr(target="macos", link(name = "FooCoreServices", kind = "framework"))]
|
||||
extern {}
|
||||
extern "C" {}
|
||||
```
|
||||
|
||||
Learn more in the [Conditional Compilation][conditional-compilation] section
|
||||
|
@ -3,7 +3,7 @@ An unknown "kind" was specified for a link attribute.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0458
|
||||
#[link(kind = "wonderful_unicorn")] extern {}
|
||||
#[link(kind = "wonderful_unicorn")] extern "C" {}
|
||||
// error: unknown kind: `wonderful_unicorn`
|
||||
```
|
||||
|
||||
|
@ -3,7 +3,7 @@ A link was used without a name parameter.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0459
|
||||
#[link(kind = "dylib")] extern {}
|
||||
#[link(kind = "dylib")] extern "C" {}
|
||||
// error: `#[link(...)]` specified without `name = "foo"`
|
||||
```
|
||||
|
||||
@ -11,5 +11,5 @@ Please add the name parameter to allow the rust compiler to find the library
|
||||
you want. Example:
|
||||
|
||||
```no_run
|
||||
#[link(kind = "dylib", name = "some_lib")] extern {} // ok!
|
||||
#[link(kind = "dylib", name = "some_lib")] extern "C" {} // ok!
|
||||
```
|
||||
|
@ -3,7 +3,7 @@ Attempted to pass an invalid type of variable into a variadic function.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0617
|
||||
extern {
|
||||
extern "C" {
|
||||
fn printf(c: *const i8, ...);
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ to import from `std::os::raw`).
|
||||
In this case, `c_double` has the same size as `f64` so we can use it directly:
|
||||
|
||||
```no_run
|
||||
# extern {
|
||||
# extern "C" {
|
||||
# fn printf(c: *const i8, ...);
|
||||
# }
|
||||
unsafe {
|
||||
|
@ -6,7 +6,7 @@ Erroneous code example:
|
||||
#![feature(unwind_attributes)]
|
||||
|
||||
#[unwind()] // error: expected one argument
|
||||
pub extern fn something() {}
|
||||
pub extern "C" fn something() {}
|
||||
|
||||
fn main() {}
|
||||
```
|
||||
|
@ -18,7 +18,7 @@ the function inside of an `extern` block.
|
||||
```
|
||||
#![feature(ffi_returns_twice)]
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
#[ffi_returns_twice] // ok!
|
||||
pub fn foo();
|
||||
}
|
||||
|
@ -600,6 +600,10 @@ pub trait LintContext: Sized {
|
||||
BuiltinLintDiagnostics::PatternsInFnsWithoutBody(span, ident) => {
|
||||
db.span_suggestion(span, "remove `mut` from the parameter", ident.to_string(), Applicability::MachineApplicable);
|
||||
}
|
||||
BuiltinLintDiagnostics::MissingAbi(span, default_abi) => {
|
||||
db.span_label(span, "ABI should be specified here");
|
||||
db.help(&format!("the default ABI is {}", default_abi.name()));
|
||||
}
|
||||
}
|
||||
// Rewrap `db`, and pass control to the user.
|
||||
decorate(LintDiagnosticBuilder::new(db));
|
||||
|
@ -11,3 +11,4 @@ rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_serialize = { path = "../rustc_serialize" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
|
@ -2917,6 +2917,7 @@ declare_lint_pass! {
|
||||
FUNCTION_ITEM_REFERENCES,
|
||||
USELESS_DEPRECATED,
|
||||
UNSUPPORTED_NAKED_FUNCTIONS,
|
||||
MISSING_ABI,
|
||||
]
|
||||
}
|
||||
|
||||
@ -2944,3 +2945,28 @@ declare_lint! {
|
||||
}
|
||||
|
||||
declare_lint_pass!(UnusedDocComment => [UNUSED_DOC_COMMENTS]);
|
||||
|
||||
declare_lint! {
|
||||
/// The `missing_abi` lint detects cases where the ABI is omitted from
|
||||
/// extern declarations.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust,compile_fail
|
||||
/// #![deny(missing_abi)]
|
||||
///
|
||||
/// extern fn foo() {}
|
||||
/// ```
|
||||
///
|
||||
/// {{produces}}
|
||||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// Historically, Rust implicitly selected C as the ABI for extern
|
||||
/// declarations. We expect to add new ABIs, like `C-unwind`, in the future,
|
||||
/// though this has not yet happened, and especially with their addition
|
||||
/// seeing the ABI easily will make code review easier.
|
||||
pub MISSING_ABI,
|
||||
Allow,
|
||||
"No declared ABI for extern declaration"
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use rustc_ast::node_id::{NodeId, NodeMap};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
pub mod builtin;
|
||||
|
||||
@ -252,6 +253,7 @@ pub enum BuiltinLintDiagnostics {
|
||||
UnusedImports(String, Vec<(Span, String)>),
|
||||
RedundantImport(Vec<(Span, bool)>, Ident),
|
||||
DeprecatedMacro(Option<Symbol>, Span),
|
||||
MissingAbi(Span, Abi),
|
||||
UnusedDocComment(Span),
|
||||
PatternsInFnsWithoutBody(Span, Ident),
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ pub fn initialize_available_targets() {
|
||||
($cfg:meta, $($method:ident),*) => { {
|
||||
#[cfg($cfg)]
|
||||
fn init() {
|
||||
extern {
|
||||
extern "C" {
|
||||
$(fn $method();)*
|
||||
}
|
||||
unsafe {
|
||||
|
@ -809,7 +809,7 @@ impl AtomicBool {
|
||||
/// ```ignore (extern-declaration)
|
||||
/// # fn main() {
|
||||
/// use std::sync::atomic::AtomicBool;
|
||||
/// extern {
|
||||
/// extern "C" {
|
||||
/// fn my_atomic_op(arg: *mut bool);
|
||||
/// }
|
||||
///
|
||||
@ -2068,7 +2068,7 @@ macro_rules! atomic_int {
|
||||
/// # fn main() {
|
||||
#[doc = concat!($extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";")]
|
||||
///
|
||||
/// extern {
|
||||
/// extern "C" {
|
||||
#[doc = concat!(" fn my_atomic_op(arg: *mut ", stringify!($int_type), ");")]
|
||||
/// }
|
||||
///
|
||||
|
@ -86,7 +86,7 @@ use crate::sys;
|
||||
/// use std::ffi::CString;
|
||||
/// use std::os::raw::c_char;
|
||||
///
|
||||
/// extern {
|
||||
/// extern "C" {
|
||||
/// fn my_printer(s: *const c_char);
|
||||
/// }
|
||||
///
|
||||
@ -144,7 +144,7 @@ pub struct CString {
|
||||
/// use std::ffi::CStr;
|
||||
/// use std::os::raw::c_char;
|
||||
///
|
||||
/// extern { fn my_string() -> *const c_char; }
|
||||
/// extern "C" { fn my_string() -> *const c_char; }
|
||||
///
|
||||
/// unsafe {
|
||||
/// let slice = CStr::from_ptr(my_string());
|
||||
@ -159,7 +159,7 @@ pub struct CString {
|
||||
/// use std::os::raw::c_char;
|
||||
///
|
||||
/// fn work(data: &CStr) {
|
||||
/// extern { fn work_with(data: *const c_char); }
|
||||
/// extern "C" { fn work_with(data: *const c_char); }
|
||||
///
|
||||
/// unsafe { work_with(data.as_ptr()) }
|
||||
/// }
|
||||
@ -174,7 +174,7 @@ pub struct CString {
|
||||
/// use std::ffi::CStr;
|
||||
/// use std::os::raw::c_char;
|
||||
///
|
||||
/// extern { fn my_string() -> *const c_char; }
|
||||
/// extern "C" { fn my_string() -> *const c_char; }
|
||||
///
|
||||
/// fn my_string_safe() -> String {
|
||||
/// unsafe {
|
||||
@ -359,7 +359,7 @@ impl CString {
|
||||
/// use std::ffi::CString;
|
||||
/// use std::os::raw::c_char;
|
||||
///
|
||||
/// extern { fn puts(s: *const c_char); }
|
||||
/// extern "C" { fn puts(s: *const c_char); }
|
||||
///
|
||||
/// let to_print = CString::new("Hello!").expect("CString::new failed");
|
||||
/// unsafe {
|
||||
@ -465,7 +465,7 @@ impl CString {
|
||||
/// use std::ffi::CString;
|
||||
/// use std::os::raw::c_char;
|
||||
///
|
||||
/// extern {
|
||||
/// extern "C" {
|
||||
/// fn some_extern_function(s: *mut c_char);
|
||||
/// }
|
||||
///
|
||||
@ -1147,7 +1147,7 @@ impl CStr {
|
||||
/// use std::ffi::CStr;
|
||||
/// use std::os::raw::c_char;
|
||||
///
|
||||
/// extern {
|
||||
/// extern "C" {
|
||||
/// fn my_string() -> *const c_char;
|
||||
/// }
|
||||
///
|
||||
|
@ -401,7 +401,7 @@ mod enum_keyword {}
|
||||
///
|
||||
/// ```rust
|
||||
/// #[no_mangle]
|
||||
/// pub extern fn callable_from_c(x: i32) -> bool {
|
||||
/// pub extern "C" fn callable_from_c(x: i32) -> bool {
|
||||
/// x % 3 == 0
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -28,7 +28,7 @@ use crate::sync::atomic::{self, AtomicUsize, Ordering};
|
||||
|
||||
macro_rules! weak {
|
||||
(fn $name:ident($($t:ty),*) -> $ret:ty) => (
|
||||
static $name: crate::sys::weak::Weak<unsafe extern fn($($t),*) -> $ret> =
|
||||
static $name: crate::sys::weak::Weak<unsafe extern "C" fn($($t),*) -> $ret> =
|
||||
crate::sys::weak::Weak::new(concat!(stringify!($name), '\0'));
|
||||
)
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ usage would be:
|
||||
#![feature(link_args)]
|
||||
|
||||
#[link_args = "-foo -bar -baz"]
|
||||
extern {}
|
||||
extern "C" {}
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
|
@ -13,7 +13,7 @@ impl Drop for A {
|
||||
}
|
||||
}
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
#[link_name = "llvm.sqrt.f32"]
|
||||
fn sqrt(x: f32) -> f32;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ struct A;
|
||||
|
||||
impl Drop for A {
|
||||
fn drop(&mut self) {
|
||||
extern { fn foo(); }
|
||||
extern "C" { fn foo(); }
|
||||
unsafe { foo(); }
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
fn giraffe();
|
||||
fn turtle();
|
||||
}
|
||||
|
@ -26,17 +26,17 @@ pub mod xyz {
|
||||
// CHECK: !DISubprogram(name: "e",
|
||||
// CHECK: linkageName:
|
||||
// CHECK-SAME: line: 29,
|
||||
pub extern fn e() {}
|
||||
pub extern "C" fn e() {}
|
||||
|
||||
// CHECK: !DISubprogram(name: "f",
|
||||
// CHECK-NOT: linkageName:
|
||||
// CHECK-SAME: line: 35,
|
||||
#[no_mangle]
|
||||
pub extern fn f() {}
|
||||
pub extern "C" fn f() {}
|
||||
|
||||
// CHECK: !DISubprogram(name: "g",
|
||||
// CHECK-NOT: linkageName:
|
||||
// CHECK-SAME: line: 41,
|
||||
#[export_name = "g"]
|
||||
pub extern fn g() {}
|
||||
pub extern "C" fn g() {}
|
||||
}
|
||||
|
@ -13,19 +13,19 @@ mod private {
|
||||
|
||||
// CHECK: void @a()
|
||||
#[no_mangle]
|
||||
pub extern fn a() {}
|
||||
pub extern "C" fn a() {}
|
||||
|
||||
// CHECK: void @b()
|
||||
#[export_name = "b"]
|
||||
extern fn b() {}
|
||||
extern "C" fn b() {}
|
||||
|
||||
// CHECK: void @c()
|
||||
#[export_name = "c"]
|
||||
#[inline]
|
||||
extern fn c() {}
|
||||
extern "C" fn c() {}
|
||||
|
||||
// CHECK: void @d()
|
||||
#[export_name = "d"]
|
||||
#[inline(always)]
|
||||
extern fn d() {}
|
||||
extern "C" fn d() {}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
pub fn bar() { unsafe { foo() } }
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
// CHECK-LABEL: declare void @foo()
|
||||
// CHECK-SAME: [[ATTRS:#[0-9]+]]
|
||||
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readnone{{.*}} }
|
||||
|
@ -11,7 +11,7 @@ struct S {
|
||||
f3: i32,
|
||||
}
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
fn foo(s: S);
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
pub fn bar() { unsafe { foo() } }
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
// CHECK-LABEL: declare void @foo()
|
||||
// CHECK-SAME: [[ATTRS:#[0-9]+]]
|
||||
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readonly{{.*}} }
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
pub fn bar() { unsafe { foo() } }
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
// CHECK-LABEL: declare void @foo()
|
||||
// CHECK-SAME: [[ATTRS:#[0-9]+]]
|
||||
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}returns_twice{{.*}} }
|
||||
|
@ -6,4 +6,4 @@ pub struct Foo(u64);
|
||||
|
||||
// CHECK: define {{.*}} @foo(
|
||||
#[no_mangle]
|
||||
pub extern fn foo(_: Foo) -> Foo { loop {} }
|
||||
pub extern "C" fn foo(_: Foo) -> Foo { loop {} }
|
||||
|
@ -36,19 +36,19 @@ pub enum TeBigS {
|
||||
|
||||
// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], %BigS* [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
|
||||
pub extern "C" fn test_BigS(_: BigS) -> BigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], %TsBigS* [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
|
||||
pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], %TuBigS* [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
|
||||
pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], %"TeBigS::Variant"* [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
|
||||
pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
|
||||
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
@ -72,16 +72,16 @@ pub enum TeBigU {
|
||||
|
||||
// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], %BigU* [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
|
||||
pub extern "C" fn test_BigU(_: BigU) -> BigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], %TsBigU* [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
|
||||
pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], %TuBigU* [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
|
||||
pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], %"TeBigU::Variant"* [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]])
|
||||
#[no_mangle]
|
||||
pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
|
||||
pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
|
||||
|
@ -19,21 +19,21 @@ pub struct F32(f32);
|
||||
|
||||
// CHECK: define float @test_F32(float %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_F32(_: F32) -> F32 { loop {} }
|
||||
pub extern "C" fn test_F32(_: F32) -> F32 { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Ptr(*mut u8);
|
||||
|
||||
// CHECK: define i8* @test_Ptr(i8* %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_Ptr(_: Ptr) -> Ptr { loop {} }
|
||||
pub extern "C" fn test_Ptr(_: Ptr) -> Ptr { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct WithZst(u64, Zst1);
|
||||
|
||||
// CHECK: define i64 @test_WithZst(i64 %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_WithZst(_: WithZst) -> WithZst { loop {} }
|
||||
pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct WithZeroSizedArray(*const f32, [i8; 0]);
|
||||
@ -41,14 +41,14 @@ pub struct WithZeroSizedArray(*const f32, [i8; 0]);
|
||||
// Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever.
|
||||
// CHECK: define i32* @test_WithZeroSizedArray(i32* %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} }
|
||||
pub extern "C" fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Generic<T>(T);
|
||||
|
||||
// CHECK: define double @test_Generic(double %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_Generic(_: Generic<f64>) -> Generic<f64> { loop {} }
|
||||
pub extern "C" fn test_Generic(_: Generic<f64>) -> Generic<f64> { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct GenericPlusZst<T>(T, Zst2);
|
||||
@ -58,14 +58,14 @@ pub enum Bool { True, False, FileNotFound }
|
||||
|
||||
// CHECK: define{{( zeroext)?}} i8 @test_Gpz(i8{{( zeroext)?}} %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> { loop {} }
|
||||
pub extern "C" fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>);
|
||||
|
||||
// CHECK: define i16* @test_LifetimePhantom(i16* %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_LifetimePhantom(_: LifetimePhantom<i16>) -> LifetimePhantom<i16> { loop {} }
|
||||
pub extern "C" fn test_LifetimePhantom(_: LifetimePhantom<i16>) -> LifetimePhantom<i16> { loop {} }
|
||||
|
||||
// This works despite current alignment resrictions because PhantomData is always align(1)
|
||||
#[repr(transparent)]
|
||||
@ -75,28 +75,28 @@ pub struct Px;
|
||||
|
||||
// CHECK: define float @test_UnitPhantom(float %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_UnitPhantom(_: UnitPhantom<f32, Px>) -> UnitPhantom<f32, Px> { loop {} }
|
||||
pub extern "C" fn test_UnitPhantom(_: UnitPhantom<f32, Px>) -> UnitPhantom<f32, Px> { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct TwoZsts(Zst1, i8, Zst2);
|
||||
|
||||
// CHECK: define{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} }
|
||||
pub extern "C" fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Nested1(Zst2, Generic<f64>);
|
||||
|
||||
// CHECK: define double @test_Nested1(double %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_Nested1(_: Nested1) -> Nested1 { loop {} }
|
||||
pub extern "C" fn test_Nested1(_: Nested1) -> Nested1 { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Nested2(Nested1, Zst1);
|
||||
|
||||
// CHECK: define double @test_Nested2(double %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_Nested2(_: Nested2) -> Nested2 { loop {} }
|
||||
pub extern "C" fn test_Nested2(_: Nested2) -> Nested2 { loop {} }
|
||||
|
||||
#[repr(simd)]
|
||||
struct f32x4(f32, f32, f32, f32);
|
||||
@ -106,7 +106,7 @@ pub struct Vector(f32x4);
|
||||
|
||||
// CHECK: define <4 x float> @test_Vector(<4 x float> %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_Vector(_: Vector) -> Vector { loop {} }
|
||||
pub extern "C" fn test_Vector(_: Vector) -> Vector { loop {} }
|
||||
|
||||
trait Mirror { type It: ?Sized; }
|
||||
impl<T: ?Sized> Mirror for T { type It = Self; }
|
||||
@ -116,7 +116,7 @@ pub struct StructWithProjection(<f32 as Mirror>::It);
|
||||
|
||||
// CHECK: define float @test_Projection(float %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} }
|
||||
pub extern "C" fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub enum EnumF32 {
|
||||
@ -125,7 +125,7 @@ pub enum EnumF32 {
|
||||
|
||||
// CHECK: define float @test_EnumF32(float %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_EnumF32(_: EnumF32) -> EnumF32 { loop {} }
|
||||
pub extern "C" fn test_EnumF32(_: EnumF32) -> EnumF32 { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub enum EnumF32WithZsts {
|
||||
@ -134,7 +134,7 @@ pub enum EnumF32WithZsts {
|
||||
|
||||
// CHECK: define float @test_EnumF32WithZsts(float %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { loop {} }
|
||||
pub extern "C" fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub union UnionF32 {
|
||||
@ -143,7 +143,7 @@ pub union UnionF32 {
|
||||
|
||||
// CHECK: define float @test_UnionF32(float %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} }
|
||||
pub extern "C" fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub union UnionF32WithZsts {
|
||||
@ -154,7 +154,7 @@ pub union UnionF32WithZsts {
|
||||
|
||||
// CHECK: define float @test_UnionF32WithZsts(float %_1)
|
||||
#[no_mangle]
|
||||
pub extern fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts { loop {} }
|
||||
pub extern "C" fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts { loop {} }
|
||||
|
||||
|
||||
// All that remains to be tested are aggregates. They are tested in separate files called repr-
|
||||
|
@ -13,7 +13,7 @@ impl Drop for A {
|
||||
}
|
||||
}
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
#[link_name = "llvm.sqrt.f32"]
|
||||
fn sqrt(x: f32) -> f32;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
// CHECK-LABEL: define {{.*}} @exported() {{.*}} #0
|
||||
#[no_mangle]
|
||||
pub extern fn exported() {
|
||||
pub extern "C" fn exported() {
|
||||
not_exported();
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
// "C" ABI
|
||||
// pub extern fn foo() {} // FIXME right now we don't abort-on-panic but add `nounwind` nevertheless
|
||||
#[unwind(allowed)]
|
||||
pub extern fn foo_allowed() {}
|
||||
pub extern "C" fn foo_allowed() {}
|
||||
|
||||
// "Rust"
|
||||
// (`extern "Rust"` could be removed as all `fn` get it implicitly; we leave it in for clarity.)
|
||||
|
@ -4,7 +4,7 @@
|
||||
#![crate_type = "lib"]
|
||||
#![feature(unwind_attributes)]
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
// CHECK: Function Attrs:{{.*}}nounwind
|
||||
// CHECK-NEXT: declare void @extern_fn
|
||||
fn extern_fn();
|
||||
|
@ -23,7 +23,6 @@
|
||||
// gdbg-check:type = struct Struct2
|
||||
// gdbr-check:type = type_names::mod1::Struct2
|
||||
|
||||
|
||||
// ENUMS
|
||||
// gdb-command:whatis simple_enum_1
|
||||
// gdbg-check:type = union Enum1
|
||||
@ -45,7 +44,6 @@
|
||||
// gdbg-check:type = union Enum3<type_names::Struct1>
|
||||
// gdbr-check:type = type_names::mod1::mod2::Enum3<type_names::Struct1>
|
||||
|
||||
|
||||
// TUPLES
|
||||
// gdb-command:whatis tuple1
|
||||
// gdbg-check:type = struct (u32, type_names::Struct1, type_names::mod1::mod2::Enum3<type_names::mod1::Struct2>)
|
||||
@ -55,7 +53,6 @@
|
||||
// gdbg-check:type = struct ((type_names::Struct1, type_names::mod1::mod2::Struct3), type_names::mod1::Enum2, char)
|
||||
// gdbr-check:type = ((type_names::Struct1, type_names::mod1::mod2::Struct3), type_names::mod1::Enum2, char)
|
||||
|
||||
|
||||
// BOX
|
||||
// gdb-command:whatis box1
|
||||
// gdbg-check:type = struct (alloc::boxed::Box<f32>, i32)
|
||||
@ -65,7 +62,6 @@
|
||||
// gdbg-check:type = struct (alloc::boxed::Box<type_names::mod1::mod2::Enum3<f32>>, i32)
|
||||
// gdbr-check:type = (alloc::boxed::Box<type_names::mod1::mod2::Enum3<f32>>, i32)
|
||||
|
||||
|
||||
// REFERENCES
|
||||
// gdb-command:whatis ref1
|
||||
// gdbg-check:type = struct (&type_names::Struct1, i32)
|
||||
@ -83,7 +79,6 @@
|
||||
// gdbg-check:type = struct (&mut type_names::GenericStruct<type_names::mod1::Enum2, f64>, i32)
|
||||
// gdbr-check:type = (&mut type_names::GenericStruct<type_names::mod1::Enum2, f64>, i32)
|
||||
|
||||
|
||||
// RAW POINTERS
|
||||
// gdb-command:whatis mut_ptr1
|
||||
// gdbg-check:type = struct (*mut type_names::Struct1, isize)
|
||||
@ -109,7 +104,6 @@
|
||||
// gdbg-check:type = struct (*const type_names::mod1::mod2::Enum3<type_names::Struct1>, isize)
|
||||
// gdbr-check:type = (*const type_names::mod1::mod2::Enum3<type_names::Struct1>, isize)
|
||||
|
||||
|
||||
// VECTORS
|
||||
// gdb-command:whatis fixed_size_vec1
|
||||
// gdbg-check:type = struct ([type_names::Struct1; 3], i16)
|
||||
@ -127,7 +121,6 @@
|
||||
// gdbg-check:type = struct &[type_names::mod1::Enum2]
|
||||
// gdbr-check:type = &[type_names::mod1::Enum2]
|
||||
|
||||
|
||||
// TRAITS
|
||||
// gdb-command:whatis box_trait
|
||||
// gdbg-check:type = struct Box<Trait1>
|
||||
@ -153,7 +146,6 @@
|
||||
// gdbg-check:type = struct &mut Trait2<type_names::mod1::mod2::Struct3, type_names::GenericStruct<usize, isize>>
|
||||
// gdbr-check:type = type_names::&mut Trait2<type_names::mod1::mod2::Struct3, type_names::GenericStruct<usize, isize>>
|
||||
|
||||
|
||||
// BARE FUNCTIONS
|
||||
// gdb-command:whatis rust_fn
|
||||
// gdbg-check:type = struct (fn(core::option::Option<isize>, core::option::Option<&type_names::mod1::Struct2>), usize)
|
||||
@ -199,7 +191,6 @@
|
||||
// gdbg-check:type = struct (unsafe extern "C" fn(*const u8, ...) -> isize, usize)
|
||||
// gdbr-check:type = (unsafe extern "C" fn(*const u8, ...) -> isize, usize)
|
||||
|
||||
|
||||
// CLOSURES
|
||||
// gdb-command:whatis closure1
|
||||
// gdbg-check:type = struct (closure, usize)
|
||||
@ -219,7 +210,7 @@ use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
|
||||
pub struct Struct1;
|
||||
struct GenericStruct<T1, T2>(PhantomData<(T1,T2)>);
|
||||
struct GenericStruct<T1, T2>(PhantomData<(T1, T2)>);
|
||||
|
||||
enum Enum1 {
|
||||
Variant1,
|
||||
@ -246,8 +237,12 @@ mod mod1 {
|
||||
}
|
||||
}
|
||||
|
||||
trait Trait1 { fn dummy(&self) { } }
|
||||
trait Trait2<T1, T2> { fn dummy(&self, _: T1, _:T2) { } }
|
||||
trait Trait1 {
|
||||
fn dummy(&self) {}
|
||||
}
|
||||
trait Trait2<T1, T2> {
|
||||
fn dummy(&self, _: T1, _: T2) {}
|
||||
}
|
||||
|
||||
impl Trait1 for isize {}
|
||||
impl<T1, T2> Trait2<T1, T2> for isize {}
|
||||
@ -257,16 +252,26 @@ extern "C" fn extern_c_fn(_: isize) {}
|
||||
unsafe fn unsafe_fn(_: Result<char, f64>) {}
|
||||
extern "stdcall" fn extern_stdcall_fn() {}
|
||||
|
||||
fn rust_fn_with_return_value(_: f64) -> usize { 4 }
|
||||
extern "C" fn extern_c_fn_with_return_value() -> Struct1 { Struct1 }
|
||||
unsafe fn unsafe_fn_with_return_value(_: GenericStruct<u16, u8>) -> mod1::Struct2 { mod1::Struct2 }
|
||||
extern "stdcall" fn extern_stdcall_fn_with_return_value(_: Box<isize>) -> usize { 0 }
|
||||
fn rust_fn_with_return_value(_: f64) -> usize {
|
||||
4
|
||||
}
|
||||
extern "C" fn extern_c_fn_with_return_value() -> Struct1 {
|
||||
Struct1
|
||||
}
|
||||
unsafe fn unsafe_fn_with_return_value(_: GenericStruct<u16, u8>) -> mod1::Struct2 {
|
||||
mod1::Struct2
|
||||
}
|
||||
extern "stdcall" fn extern_stdcall_fn_with_return_value(_: Box<isize>) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
fn generic_function<T>(x: T) -> T { x }
|
||||
fn generic_function<T>(x: T) -> T {
|
||||
x
|
||||
}
|
||||
|
||||
#[allow(improper_ctypes)]
|
||||
extern {
|
||||
fn printf(_:*const u8, ...) -> isize;
|
||||
extern "C" {
|
||||
fn printf(_: *const u8, ...) -> isize;
|
||||
}
|
||||
|
||||
// In many of the cases below, the type that is actually under test is wrapped
|
||||
@ -277,7 +282,6 @@ extern {
|
||||
// printed correctly, so the tests below just construct a tuple type that will
|
||||
// then *contain* the type name that we want to see.
|
||||
fn main() {
|
||||
|
||||
// Structs
|
||||
let simple_struct = Struct1;
|
||||
let generic_struct1: GenericStruct<mod1::Struct2, mod1::mod2::Struct3> =
|
||||
@ -336,11 +340,11 @@ fn main() {
|
||||
let mut_ref_trait = (&mut mut_int1) as &mut Trait1;
|
||||
|
||||
let generic_box_trait = (box 0_isize) as Box<Trait2<i32, mod1::Struct2>>;
|
||||
let generic_ref_trait = (&0_isize) as &Trait2<Struct1, Struct1>;
|
||||
let generic_ref_trait = (&0_isize) as &Trait2<Struct1, Struct1>;
|
||||
|
||||
let mut generic_mut_ref_trait_impl = 0_isize;
|
||||
let generic_mut_ref_trait = (&mut generic_mut_ref_trait_impl) as
|
||||
&mut Trait2<mod1::mod2::Struct3, GenericStruct<usize, isize>>;
|
||||
let generic_mut_ref_trait = (&mut generic_mut_ref_trait_impl)
|
||||
as &mut Trait2<mod1::mod2::Struct3, GenericStruct<usize, isize>>;
|
||||
|
||||
// Bare Functions
|
||||
let rust_fn = (rust_fn, 0_usize);
|
||||
@ -364,11 +368,13 @@ fn main() {
|
||||
// how that maps to rustc's internal representation of these forms.
|
||||
// Once closures have reached their 1.0 form, the tests below should
|
||||
// probably be expanded.
|
||||
let closure1 = (|x:isize| {}, 0_usize);
|
||||
let closure2 = (|x:i8, y: f32| { (x as f32) + y }, 0_usize);
|
||||
let closure1 = (|x: isize| {}, 0_usize);
|
||||
let closure2 = (|x: i8, y: f32| (x as f32) + y, 0_usize);
|
||||
|
||||
zzz(); // #break
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn zzz() { () }
|
||||
fn zzz() {
|
||||
()
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use std::ffi::CString;
|
||||
mod mlibc {
|
||||
use libc::{c_char, c_long, c_longlong};
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn atol(x: *const c_char) -> c_long;
|
||||
pub fn atoll(x: *const c_char) -> c_longlong;
|
||||
}
|
||||
@ -31,6 +31,8 @@ fn atoll(s: String) -> i64 {
|
||||
|
||||
pub fn main() {
|
||||
assert_eq!(atol("1024".to_string()) * 10, atol("10240".to_string()));
|
||||
assert_eq!((atoll("11111111111111111".to_string()) * 10),
|
||||
atoll("111111111111111110".to_string()));
|
||||
assert_eq!(
|
||||
(atoll("11111111111111111".to_string()) * 10),
|
||||
atoll("111111111111111110".to_string())
|
||||
);
|
||||
}
|
||||
|
@ -271,7 +271,7 @@ impl Foo {
|
||||
impl Foo {
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig,typeck")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub extern fn make_method_extern(&self) { }
|
||||
pub extern "C" fn make_method_extern(&self) { }
|
||||
}
|
||||
|
||||
|
||||
|
@ -312,7 +312,7 @@ trait TraitAddExternModifier {
|
||||
trait TraitAddExternModifier {
|
||||
#[rustc_dirty(label="hir_owner", cfg="cfail2")]
|
||||
#[rustc_clean(label="hir_owner", cfg="cfail3")]
|
||||
extern fn method();
|
||||
extern "C" fn method();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[link(name = "foo", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn foo();
|
||||
fn bar();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![crate_type = "dylib"]
|
||||
|
||||
#[link(name = "cfoo")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[link(name = "cfoo")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![crate_type = "dylib"]
|
||||
|
||||
#[link(name = "cfoo", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[link(name = "cfoo", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,11 @@
|
||||
extern crate bar;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn foo() {
|
||||
pub extern "C" fn foo() {
|
||||
bar::bar();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn bar(a: u32, b: u32) -> u32 {
|
||||
pub extern "C" fn bar(a: u32, b: u32) -> u32 {
|
||||
a + b
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![crate_type = "cdylib"]
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn foo() -> u32 {
|
||||
pub extern "C" fn foo() -> u32 {
|
||||
3
|
||||
}
|
||||
|
@ -3,11 +3,11 @@
|
||||
extern crate bar;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn foo() {
|
||||
pub extern "C" fn foo() {
|
||||
bar::bar();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn bar(a: u32, b: u32) -> u32 {
|
||||
pub extern "C" fn bar(a: u32, b: u32) -> u32 {
|
||||
a + b
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[link(name = "native", kind = "static")]
|
||||
extern {}
|
||||
extern "C" {}
|
||||
|
@ -1,6 +1,10 @@
|
||||
extern { fn foo(); }
|
||||
extern "C" {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe { foo(); }
|
||||
unsafe {
|
||||
foo();
|
||||
}
|
||||
assert_eq!(7f32.powi(3), 343f32);
|
||||
}
|
||||
|
@ -3,6 +3,6 @@
|
||||
extern crate upstream;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn bar() {
|
||||
pub extern "C" fn bar() {
|
||||
upstream::foo();
|
||||
}
|
||||
|
@ -1,22 +1,20 @@
|
||||
extern crate testcrate;
|
||||
|
||||
extern "C" fn bar<T>(ts: testcrate::TestStruct<T>) -> T { ts.y }
|
||||
extern "C" fn bar<T>(ts: testcrate::TestStruct<T>) -> T {
|
||||
ts.y
|
||||
}
|
||||
|
||||
#[link(name = "test", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn call(c: extern "C" fn(testcrate::TestStruct<i32>) -> i32) -> i32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Let's test calling it cross crate
|
||||
let back = unsafe {
|
||||
testcrate::call(testcrate::foo::<i32>)
|
||||
};
|
||||
let back = unsafe { testcrate::call(testcrate::foo::<i32>) };
|
||||
assert_eq!(3, back);
|
||||
|
||||
// And just within this crate
|
||||
let back = unsafe {
|
||||
call(bar::<i32>)
|
||||
};
|
||||
let back = unsafe { call(bar::<i32>) };
|
||||
assert_eq!(3, back);
|
||||
}
|
||||
|
@ -3,12 +3,14 @@
|
||||
#[repr(C)]
|
||||
pub struct TestStruct<T> {
|
||||
pub x: u8,
|
||||
pub y: T
|
||||
pub y: T,
|
||||
}
|
||||
|
||||
pub extern "C" fn foo<T>(ts: TestStruct<T>) -> T { ts.y }
|
||||
pub extern "C" fn foo<T>(ts: TestStruct<T>) -> T {
|
||||
ts.y
|
||||
}
|
||||
|
||||
#[link(name = "test", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn call(c: extern "C" fn(TestStruct<i32>) -> i32) -> i32;
|
||||
}
|
||||
|
@ -1,11 +1,15 @@
|
||||
#[no_mangle]
|
||||
pub extern "C" fn foo() -> i32 { 3 }
|
||||
pub extern "C" fn foo() -> i32 {
|
||||
3
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn bar() -> i32 { 5 }
|
||||
pub extern "C" fn bar() -> i32 {
|
||||
5
|
||||
}
|
||||
|
||||
#[link(name = "test", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn add() -> i32;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ struct Rect {
|
||||
a: i32,
|
||||
b: i32,
|
||||
c: i32,
|
||||
d: i32
|
||||
d: i32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
@ -15,7 +15,7 @@ struct Rect {
|
||||
struct BiggerRect {
|
||||
s: Rect,
|
||||
a: i32,
|
||||
b: i32
|
||||
b: i32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
@ -23,7 +23,7 @@ struct BiggerRect {
|
||||
struct FloatRect {
|
||||
a: i32,
|
||||
b: i32,
|
||||
c: f64
|
||||
c: f64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
@ -33,14 +33,14 @@ struct Huge {
|
||||
b: i32,
|
||||
c: i32,
|
||||
d: i32,
|
||||
e: i32
|
||||
e: i32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[repr(C)]
|
||||
struct FloatPoint {
|
||||
x: f64,
|
||||
y: f64
|
||||
y: f64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
@ -58,13 +58,22 @@ struct IntOdd {
|
||||
}
|
||||
|
||||
#[link(name = "test", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn byval_rect(a: i32, b: i32, c: i32, d: i32, e: i32, s: Rect);
|
||||
|
||||
fn byval_many_rect(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, s: Rect);
|
||||
|
||||
fn byval_rect_floats(a: f32, b: f32, c: f64, d: f32, e: f32,
|
||||
f: f32, g: f64, s: Rect, t: FloatRect);
|
||||
fn byval_rect_floats(
|
||||
a: f32,
|
||||
b: f32,
|
||||
c: f64,
|
||||
d: f32,
|
||||
e: f32,
|
||||
f: f32,
|
||||
g: f64,
|
||||
s: Rect,
|
||||
t: FloatRect,
|
||||
);
|
||||
|
||||
fn byval_rect_with_float(a: i32, b: i32, c: f32, d: i32, e: i32, f: i32, s: Rect);
|
||||
|
||||
@ -107,12 +116,7 @@ fn main() {
|
||||
byval_many_rect(1, 2, 3, 4, 5, 6, s);
|
||||
byval_rect_floats(1., 2., 3., 4., 5., 6., 7., s, u);
|
||||
byval_rect_with_float(1, 2, 3.0, 4, 5, 6, s);
|
||||
byval_rect_with_many_huge(v, v, v, v, v, v, Rect {
|
||||
a: 123,
|
||||
b: 456,
|
||||
c: 789,
|
||||
d: 420
|
||||
});
|
||||
byval_rect_with_many_huge(v, v, v, v, v, v, Rect { a: 123, b: 456, c: 789, d: 420 });
|
||||
split_rect(1, 2, s);
|
||||
split_rect_floats(1., 2., u);
|
||||
split_rect_with_floats(1, 2, 3.0, 4, 5.0, 6, s);
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![feature(extern_types)]
|
||||
|
||||
#[link(name = "ctest", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
type data;
|
||||
|
||||
fn data_create(magic: u32) -> *mut data;
|
||||
|
@ -3,11 +3,11 @@
|
||||
struct Foo {
|
||||
a: i8,
|
||||
b: i16,
|
||||
c: i8
|
||||
c: i8,
|
||||
}
|
||||
|
||||
#[link(name = "test", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn foo(f: Foo) -> Foo;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ extern crate testcrate;
|
||||
|
||||
use std::mem;
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
fn give_back(tu: testcrate::TestUnion) -> u64;
|
||||
}
|
||||
|
||||
@ -10,14 +10,10 @@ fn main() {
|
||||
let magic: u64 = 0xDEADBEEF;
|
||||
|
||||
// Let's test calling it cross crate
|
||||
let back = unsafe {
|
||||
testcrate::give_back(mem::transmute(magic))
|
||||
};
|
||||
let back = unsafe { testcrate::give_back(mem::transmute(magic)) };
|
||||
assert_eq!(magic, back);
|
||||
|
||||
// And just within this crate
|
||||
let back = unsafe {
|
||||
give_back(mem::transmute(magic))
|
||||
};
|
||||
let back = unsafe { give_back(mem::transmute(magic)) };
|
||||
assert_eq!(magic, back);
|
||||
}
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TestUnion {
|
||||
_val: u64
|
||||
_val: u64,
|
||||
}
|
||||
|
||||
#[link(name = "ctest", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn give_back(tu: TestUnion) -> u64;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#[no_mangle]
|
||||
pub extern fn args_check() {
|
||||
pub extern "C" fn args_check() {
|
||||
assert_ne!(std::env::args_os().count(), 0);
|
||||
}
|
||||
|
@ -3,10 +3,12 @@
|
||||
extern crate foo;
|
||||
|
||||
#[link(name = "bar", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn bar();
|
||||
}
|
||||
|
||||
pub fn doit() {
|
||||
unsafe { bar(); }
|
||||
unsafe {
|
||||
bar();
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[link(name = "foo", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
pub fn doit() {
|
||||
unsafe { foo(); }
|
||||
unsafe {
|
||||
foo();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[no_mangle]
|
||||
pub extern fn foo() {}
|
||||
pub extern "C" fn foo() {}
|
||||
|
||||
#[no_mangle]
|
||||
pub static FOO_STATIC: u8 = 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![crate_type = "dylib"]
|
||||
|
||||
#[link(name = "foo", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn foo();
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
#[link(name = "test", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn slice_len(s: &[u8]) -> usize;
|
||||
fn slice_elem(s: &[u8], idx: usize) -> u8;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let data = [1,2,3,4,5];
|
||||
let data = [1, 2, 3, 4, 5];
|
||||
|
||||
unsafe {
|
||||
assert_eq!(data.len(), slice_len(&data) as usize);
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[link(name = "a", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn a();
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
extern crate a;
|
||||
|
||||
#[link(name = "b", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn b();
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
unsafe { b(); }
|
||||
unsafe {
|
||||
b();
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,6 @@
|
||||
|
||||
#[link(name = "return1", cfg(foo))]
|
||||
#[link(name = "return3", kind = "static", cfg(bar))]
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn my_function() -> i32;
|
||||
}
|
||||
|
@ -3,6 +3,6 @@
|
||||
|
||||
#[link(name = "return1", cfg(foo))]
|
||||
#[link(name = "return2", cfg(bar))]
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn my_function() -> i32;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#[link(name = "return1", cfg(foo))]
|
||||
#[link(name = "return2", cfg(bar))]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn my_function() -> i32;
|
||||
}
|
||||
|
||||
|
@ -2,15 +2,13 @@
|
||||
|
||||
extern crate libc;
|
||||
|
||||
#[link(name="foo", kind = "static")]
|
||||
extern {
|
||||
#[link(name = "foo", kind = "static")]
|
||||
extern "C" {
|
||||
fn should_return_one() -> libc::c_int;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let result = unsafe {
|
||||
should_return_one()
|
||||
};
|
||||
let result = unsafe { should_return_one() };
|
||||
|
||||
if result != 1 {
|
||||
std::process::exit(255);
|
||||
|
@ -5,7 +5,7 @@
|
||||
static BAZ: i32 = 21;
|
||||
|
||||
#[link(name = "foo", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn what() -> i32;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ fn write_test_case(file: &Path, n: usize) -> HashSet<String> {
|
||||
writeln!(f, "#[link(name = \"S{}{}S\")]", prefix, i).unwrap();
|
||||
libs.insert(format!("{}{}", prefix, i));
|
||||
}
|
||||
writeln!(f, "extern {{}}\nfn main() {{}}").unwrap();
|
||||
writeln!(f, "extern \"C\" {{}}\nfn main() {{}}").unwrap();
|
||||
f.into_inner().unwrap();
|
||||
|
||||
libs
|
||||
|
@ -1,6 +1,6 @@
|
||||
#[link(name = "foo", kind = "static")]
|
||||
extern {
|
||||
fn test_start(f: extern fn());
|
||||
extern "C" {
|
||||
fn test_start(f: extern "C" fn());
|
||||
fn test_end();
|
||||
}
|
||||
|
||||
@ -13,11 +13,10 @@ fn main() {
|
||||
struct A;
|
||||
|
||||
impl Drop for A {
|
||||
fn drop(&mut self) {
|
||||
}
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
extern fn test_middle() {
|
||||
extern "C" fn test_middle() {
|
||||
let _a = A;
|
||||
foo();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[link(name = "foo", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn foo() -> i32;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
extern crate lib1;
|
||||
|
||||
#[link(name = "bar", kind = "static")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn foo() -> i32;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
fn bar();
|
||||
}
|
||||
|
||||
pub fn foo() {
|
||||
unsafe { bar(); }
|
||||
unsafe {
|
||||
bar();
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#[link(name = "foo")] // linker should drop this library, no symbols used
|
||||
#[link(name = "bar")] // symbol comes from this library
|
||||
#[link(name = "foo")] // now linker picks up `foo` b/c `bar` library needs it
|
||||
extern {
|
||||
extern "C" {
|
||||
fn bar();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[no_mangle]
|
||||
pub extern fn overflow() {
|
||||
pub extern "C" fn overflow() {
|
||||
let xs = [0, 1, 2, 3];
|
||||
let _y = unsafe { *xs.as_ptr().offset(4) };
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
extern {
|
||||
extern "C" {
|
||||
fn overflow();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[no_mangle]
|
||||
pub extern fn overflow() {
|
||||
pub extern "C" fn overflow() {
|
||||
let xs = [0, 1, 2, 3];
|
||||
let _y = unsafe { *xs.as_ptr().offset(4) };
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
extern {
|
||||
extern "C" {
|
||||
fn overflow();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[no_mangle]
|
||||
pub extern fn overflow() {
|
||||
pub extern "C" fn overflow() {
|
||||
let xs = [0, 1, 2, 3];
|
||||
let _y = unsafe { *xs.as_ptr().offset(4) };
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#[link(name = "library")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn overflow();
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![ crate_name = "test" ]
|
||||
#![crate_name = "test"]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
@ -9,11 +9,10 @@ extern crate krate2;
|
||||
extern crate krate2 as krate3;
|
||||
|
||||
use rustc_graphviz::RenderOption;
|
||||
use std::collections::{HashMap,HashSet};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::io::Write;
|
||||
|
||||
|
||||
use sub::sub2 as msalias;
|
||||
use sub::sub2;
|
||||
use sub::sub2::nested_struct as sub_struct;
|
||||
@ -30,7 +29,7 @@ static bob: Option<graphviz::RenderOption> = None;
|
||||
// buglink test - see issue #1337.
|
||||
|
||||
fn test_alias<I: Iterator>(i: Option<<I as Iterator>::Item>) {
|
||||
let s = sub_struct{ field2: 45u32, };
|
||||
let s = sub_struct { field2: 45u32 };
|
||||
|
||||
// import tests
|
||||
fn foo(x: &Write) {}
|
||||
@ -80,7 +79,7 @@ mod sub {
|
||||
|
||||
pub enum nested_enum {
|
||||
Nest2 = 2,
|
||||
Nest3 = 3
|
||||
Nest3 = 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -101,7 +100,9 @@ struct some_fields {
|
||||
type SF = some_fields;
|
||||
|
||||
trait SuperTrait {
|
||||
fn qux(&self) { panic!(); }
|
||||
fn qux(&self) {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
|
||||
trait SomeTrait: SuperTrait {
|
||||
@ -136,8 +137,7 @@ impl SomeTrait for some_fields {
|
||||
}
|
||||
}
|
||||
|
||||
impl SuperTrait for some_fields {
|
||||
}
|
||||
impl SuperTrait for some_fields {}
|
||||
|
||||
impl SubTrait for some_fields {}
|
||||
|
||||
@ -150,17 +150,14 @@ impl some_fields {
|
||||
42
|
||||
}
|
||||
|
||||
fn align_to<T>(&mut self) {
|
||||
|
||||
}
|
||||
fn align_to<T>(&mut self) {}
|
||||
|
||||
fn test(&mut self) {
|
||||
self.align_to::<bool>();
|
||||
}
|
||||
}
|
||||
|
||||
impl SuperTrait for nofields {
|
||||
}
|
||||
impl SuperTrait for nofields {}
|
||||
impl SomeTrait for nofields {
|
||||
fn Method(&self, x: u32) -> u32 {
|
||||
self.Method(x);
|
||||
@ -186,59 +183,70 @@ enum SomeEnum<'a> {
|
||||
Ints(isize, isize),
|
||||
Floats(f64, f64),
|
||||
Strings(&'a str, &'a str, &'a str),
|
||||
MyTypes(MyType, MyType)
|
||||
MyTypes(MyType, MyType),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum SomeOtherEnum {
|
||||
SomeConst1,
|
||||
SomeConst2,
|
||||
SomeConst3
|
||||
SomeConst3,
|
||||
}
|
||||
|
||||
enum SomeStructEnum {
|
||||
EnumStruct{a:isize, b:isize},
|
||||
EnumStruct2{f1:MyType, f2:MyType},
|
||||
EnumStruct3{f1:MyType, f2:MyType, f3:SomeEnum<'static>}
|
||||
EnumStruct { a: isize, b: isize },
|
||||
EnumStruct2 { f1: MyType, f2: MyType },
|
||||
EnumStruct3 { f1: MyType, f2: MyType, f3: SomeEnum<'static> },
|
||||
}
|
||||
|
||||
fn matchSomeEnum(val: SomeEnum) {
|
||||
match val {
|
||||
SomeEnum::Ints(int1, int2) => { println(&(int1+int2).to_string()); }
|
||||
SomeEnum::Floats(float1, float2) => { println(&(float2*float1).to_string()); }
|
||||
SomeEnum::Strings(.., s3) => { println(s3); }
|
||||
SomeEnum::MyTypes(mt1, mt2) => { println(&(mt1.field1 - mt2.field1).to_string()); }
|
||||
SomeEnum::Ints(int1, int2) => {
|
||||
println(&(int1 + int2).to_string());
|
||||
}
|
||||
SomeEnum::Floats(float1, float2) => {
|
||||
println(&(float2 * float1).to_string());
|
||||
}
|
||||
SomeEnum::Strings(.., s3) => {
|
||||
println(s3);
|
||||
}
|
||||
SomeEnum::MyTypes(mt1, mt2) => {
|
||||
println(&(mt1.field1 - mt2.field1).to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn matchSomeStructEnum(se: SomeStructEnum) {
|
||||
match se {
|
||||
SomeStructEnum::EnumStruct{a:a, ..} => println(&a.to_string()),
|
||||
SomeStructEnum::EnumStruct2{f1:f1, f2:f_2} => println(&f_2.field1.to_string()),
|
||||
SomeStructEnum::EnumStruct3{f1, ..} => println(&f1.field1.to_string()),
|
||||
SomeStructEnum::EnumStruct { a: a, .. } => println(&a.to_string()),
|
||||
SomeStructEnum::EnumStruct2 { f1: f1, f2: f_2 } => println(&f_2.field1.to_string()),
|
||||
SomeStructEnum::EnumStruct3 { f1, .. } => println(&f1.field1.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn matchSomeStructEnum2(se: SomeStructEnum) {
|
||||
use SomeStructEnum::*;
|
||||
match se {
|
||||
EnumStruct{a: ref aaa, ..} => println(&aaa.to_string()),
|
||||
EnumStruct2{f1, f2: f2} => println(&f1.field1.to_string()),
|
||||
EnumStruct3{f1, f3: SomeEnum::Ints(..), f2} => println(&f1.field1.to_string()),
|
||||
_ => {},
|
||||
EnumStruct { a: ref aaa, .. } => println(&aaa.to_string()),
|
||||
EnumStruct2 { f1, f2: f2 } => println(&f1.field1.to_string()),
|
||||
EnumStruct3 { f1, f3: SomeEnum::Ints(..), f2 } => println(&f1.field1.to_string()),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn matchSomeOtherEnum(val: SomeOtherEnum) {
|
||||
use SomeOtherEnum::{SomeConst2, SomeConst3};
|
||||
match val {
|
||||
SomeOtherEnum::SomeConst1 => { println("I'm const1."); }
|
||||
SomeConst2 | SomeConst3 => { println("I'm const2 or const3."); }
|
||||
SomeOtherEnum::SomeConst1 => {
|
||||
println("I'm const1.");
|
||||
}
|
||||
SomeConst2 | SomeConst3 => {
|
||||
println("I'm const2 or const3.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn hello<X: SomeTrait>((z, a) : (u32, String), ex: X) {
|
||||
fn hello<X: SomeTrait>((z, a): (u32, String), ex: X) {
|
||||
SameDir2::hello(43);
|
||||
|
||||
println(&yy.to_string());
|
||||
@ -253,8 +261,8 @@ fn hello<X: SomeTrait>((z, a) : (u32, String), ex: X) {
|
||||
let x = 32.0f32;
|
||||
let _ = (x + ((x * x) + 1.0).sqrt()).ln();
|
||||
|
||||
let s: Box<SomeTrait> = box some_fields {field1: 43};
|
||||
let s2: Box<some_fields> = box some_fields {field1: 43};
|
||||
let s: Box<SomeTrait> = box some_fields { field1: 43 };
|
||||
let s2: Box<some_fields> = box some_fields { field1: 43 };
|
||||
let s3 = box nofields;
|
||||
|
||||
s.Method(43);
|
||||
@ -307,8 +315,9 @@ mod macro_use_test {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { // foo
|
||||
let s = box some_fields {field1: 43};
|
||||
fn main() {
|
||||
// foo
|
||||
let s = box some_fields { field1: 43 };
|
||||
hello((43, "a".to_string()), *s);
|
||||
sub::sub2::hello();
|
||||
sub2::sub3::hello();
|
||||
@ -329,26 +338,24 @@ fn main() { // foo
|
||||
let vs = variable_str!(32);
|
||||
|
||||
let mut candidates: RefCell<HashMap<&'static str, &'static str>> = RefCell::new(HashMap::new());
|
||||
let _ = blah {
|
||||
used_link_args: RefCell::new([]),
|
||||
};
|
||||
let _ = blah { used_link_args: RefCell::new([]) };
|
||||
let s1 = nofields;
|
||||
let s2 = SF { field1: 55};
|
||||
let s3: some_fields = some_fields{ field1: 55};
|
||||
let s4: msalias::nested_struct = sub::sub2::nested_struct{ field2: 55};
|
||||
let s4: msalias::nested_struct = sub2::nested_struct{ field2: 55};
|
||||
let s2 = SF { field1: 55 };
|
||||
let s3: some_fields = some_fields { field1: 55 };
|
||||
let s4: msalias::nested_struct = sub::sub2::nested_struct { field2: 55 };
|
||||
let s4: msalias::nested_struct = sub2::nested_struct { field2: 55 };
|
||||
println(&s2.field1.to_string());
|
||||
let s5: MyType = box some_fields{ field1: 55};
|
||||
let s = SameDir::SameStruct{name: "Bob".to_string()};
|
||||
let s = SubDir::SubStruct{name:"Bob".to_string()};
|
||||
let s5: MyType = box some_fields { field1: 55 };
|
||||
let s = SameDir::SameStruct { name: "Bob".to_string() };
|
||||
let s = SubDir::SubStruct { name: "Bob".to_string() };
|
||||
let s6: SomeEnum = SomeEnum::MyTypes(box s2.clone(), s5);
|
||||
let s7: SomeEnum = SomeEnum::Strings("one", "two", "three");
|
||||
matchSomeEnum(s6);
|
||||
matchSomeEnum(s7);
|
||||
let s8: SomeOtherEnum = SomeOtherEnum::SomeConst2;
|
||||
matchSomeOtherEnum(s8);
|
||||
let s9: SomeStructEnum = SomeStructEnum::EnumStruct2{ f1: box some_fields{ field1:10 },
|
||||
f2: box s2 };
|
||||
let s9: SomeStructEnum =
|
||||
SomeStructEnum::EnumStruct2 { f1: box some_fields { field1: 10 }, f2: box s2 };
|
||||
matchSomeStructEnum(s9);
|
||||
|
||||
for x in &vec![1, 2, 3] {
|
||||
@ -409,8 +416,7 @@ impl<'a> Pattern<'a> for CharEqPattern {
|
||||
|
||||
struct CharSearcher<'a>(<CharEqPattern as Pattern<'a>>::Searcher);
|
||||
|
||||
pub trait Error {
|
||||
}
|
||||
pub trait Error {}
|
||||
|
||||
impl Error + 'static {
|
||||
pub fn is<T: Error + 'static>(&self) -> bool {
|
||||
@ -437,13 +443,13 @@ fn test_format_args() {
|
||||
print!("x is {}, y is {1}, name is {n}", x, y, n = name);
|
||||
}
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
static EXTERN_FOO: u8;
|
||||
fn extern_foo(a: u8, b: i32) -> String;
|
||||
}
|
||||
|
||||
struct Rls699 {
|
||||
f: u32,
|
||||
f: u32,
|
||||
}
|
||||
|
||||
fn new(f: u32) -> Rls699 {
|
||||
|
@ -3,6 +3,6 @@
|
||||
extern crate foo;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn bar() {
|
||||
pub extern "C" fn bar() {
|
||||
foo::foo();
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
#![feature(static_nobundle)]
|
||||
|
||||
#[link(name = "aaa", kind = "static-nobundle")]
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn native_func();
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![crate_type = "staticlib"]
|
||||
|
||||
#[link(name = "foo", kind = "static")]
|
||||
extern {}
|
||||
extern "C" {}
|
||||
|
||||
fn main() {}
|
||||
|
@ -6,6 +6,6 @@ extern crate bar;
|
||||
static A: bar::A = bar::A;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn a(a: u32, b: u32) -> u32 {
|
||||
pub extern "C" fn a(a: u32, b: u32) -> u32 {
|
||||
a / b
|
||||
}
|
||||
|
@ -1,19 +1,21 @@
|
||||
#![feature(lang_items, no_core, auto_traits)]
|
||||
#![no_core]
|
||||
|
||||
#[lang="copy"]
|
||||
trait Copy { }
|
||||
#[lang = "copy"]
|
||||
trait Copy {}
|
||||
|
||||
#[lang="sized"]
|
||||
trait Sized { }
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
|
||||
#[lang = "freeze"]
|
||||
auto trait Freeze {}
|
||||
|
||||
#[lang="start"]
|
||||
fn start(_main: *const u8, _argc: isize, _argv: *const *const u8) -> isize { 0 }
|
||||
#[lang = "start"]
|
||||
fn start(_main: *const u8, _argc: isize, _argv: *const *const u8) -> isize {
|
||||
0
|
||||
}
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
fn _foo() -> [u8; 16];
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,9 @@
|
||||
// For linking libstdc++ on MinGW
|
||||
#![cfg_attr(all(windows, target_env = "gnu"), feature(static_nobundle))]
|
||||
|
||||
extern { fn get() -> u32; }
|
||||
extern "C" {
|
||||
fn get() -> u32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let i = unsafe { get() };
|
||||
|
@ -4,13 +4,13 @@
|
||||
extern crate foo;
|
||||
|
||||
#[link(wasm_import_module = "./me")]
|
||||
extern {
|
||||
extern "C" {
|
||||
#[link_name = "me_in_dep"]
|
||||
fn dep();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn foo() {
|
||||
pub extern "C" fn foo() {
|
||||
unsafe {
|
||||
foo::dep();
|
||||
dep();
|
||||
|
@ -2,6 +2,6 @@
|
||||
#![deny(warnings)]
|
||||
|
||||
#[link(wasm_import_module = "./dep")]
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn dep();
|
||||
}
|
||||
|
@ -6,13 +6,15 @@ extern crate libc;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[link(name = "CoreFoundation", kind = "framework")]
|
||||
extern {
|
||||
extern "C" {
|
||||
fn CFRunLoopGetTypeID() -> libc::c_ulong;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn main() {
|
||||
unsafe { CFRunLoopGetTypeID(); }
|
||||
unsafe {
|
||||
CFRunLoopGetTypeID();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
|
@ -5,7 +5,7 @@ pub trait Foo {
|
||||
}
|
||||
|
||||
#[doc(alias = "foo")] //~ ERROR
|
||||
extern {}
|
||||
extern "C" {}
|
||||
|
||||
#[doc(alias = "bar")] //~ ERROR
|
||||
impl Bar {
|
||||
@ -17,5 +17,7 @@ impl Bar {
|
||||
impl Foo for Bar {
|
||||
#[doc(alias = "assoc")] //~ ERROR
|
||||
type X = i32;
|
||||
fn foo() -> Self::X { 0 }
|
||||
fn foo() -> Self::X {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,6 @@ macro_rules! some_macro {
|
||||
() => {};
|
||||
}
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
pub type ExternType;
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
extern {
|
||||
extern "C" {
|
||||
pub fn extern_c_fn();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![feature(extern_types)]
|
||||
|
||||
mod sub {
|
||||
extern {
|
||||
extern "C" {
|
||||
/// Another extern type.
|
||||
pub type C2;
|
||||
pub fn f2();
|
||||
@ -10,7 +10,7 @@ mod sub {
|
||||
}
|
||||
|
||||
pub mod sub2 {
|
||||
extern {
|
||||
extern "C" {
|
||||
// @has foreigntype_reexport/sub2/foreigntype.C.html
|
||||
pub type C;
|
||||
// @has foreigntype_reexport/sub2/fn.f.html
|
||||
@ -21,7 +21,7 @@ pub mod sub2 {
|
||||
}
|
||||
|
||||
mod sub3 {
|
||||
extern {
|
||||
extern "C" {
|
||||
pub type C4;
|
||||
pub fn f4();
|
||||
pub static K4: usize;
|
||||
@ -35,7 +35,7 @@ mod sub3 {
|
||||
// @has foreigntype_reexport/index.html '//a[@class="foreigntype"]' 'C2'
|
||||
// @has foreigntype_reexport/index.html '//a[@class="fn"]' 'f2'
|
||||
// @has foreigntype_reexport/index.html '//a[@class="static"]' 'K2'
|
||||
pub use self::sub::{C2, f2, K as K2};
|
||||
pub use self::sub::{f2, C2, K as K2};
|
||||
|
||||
// @has foreigntype_reexport/index.html '//a[@class="foreigntype"]' 'C'
|
||||
// @has foreigntype_reexport/index.html '//a[@class="fn"]' 'f'
|
||||
@ -43,7 +43,7 @@ pub use self::sub::{C2, f2, K as K2};
|
||||
// @has foreigntype_reexport/index.html '//code' 'pub use self::sub2::C as C3;'
|
||||
// @has foreigntype_reexport/index.html '//code' 'pub use self::sub2::f as f3;'
|
||||
// @has foreigntype_reexport/index.html '//code' 'pub use self::sub2::K3;'
|
||||
pub use self::sub2::{C as C3, f as f3, K3};
|
||||
pub use self::sub2::{f as f3, C as C3, K3};
|
||||
|
||||
// @has foreigntype_reexport/foreigntype.C4.html
|
||||
// @has foreigntype_reexport/fn.f4.html
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user