diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index b6d7484bccefd..2e3adc0866931 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -24,7 +24,7 @@ codegen_llvm_error_writing_def_file = Error writing .DEF file: {$error} codegen_llvm_error_calling_dlltool = - Error calling dlltool: {$error} + Error calling dlltool '{$dlltool_path}': {$error} codegen_llvm_dlltool_fail_import_library = Dlltool could not create import library: {$stdout} diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 12da21dc47772..a6416e9540cc0 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -198,7 +198,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { "arm" => ("arm", "--32"), _ => panic!("unsupported arch {}", sess.target.arch), }; - let result = std::process::Command::new(dlltool) + let result = std::process::Command::new(&dlltool) .args([ "-d", def_file_path.to_str().unwrap(), @@ -218,9 +218,13 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { match result { Err(e) => { - sess.emit_fatal(ErrorCallingDllTool { error: e }); + sess.emit_fatal(ErrorCallingDllTool { + dlltool_path: dlltool.to_string_lossy(), + error: e, + }); } - Ok(output) if !output.status.success() => { + // dlltool returns '0' on failure, so check for error output instead. + Ok(output) if !output.stderr.is_empty() => { sess.emit_fatal(DlltoolFailImportLibrary { stdout: String::from_utf8_lossy(&output.stdout), stderr: String::from_utf8_lossy(&output.stderr), @@ -431,7 +435,7 @@ fn string_to_io_error(s: String) -> io::Error { fn find_binutils_dlltool(sess: &Session) -> OsString { assert!(sess.target.options.is_like_windows && !sess.target.options.is_like_msvc); - if let Some(dlltool_path) = &sess.opts.unstable_opts.dlltool { + if let Some(dlltool_path) = &sess.opts.cg.dlltool { return dlltool_path.clone().into_os_string(); } diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index bae88d942934c..672087de31555 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -67,7 +67,8 @@ pub(crate) struct ErrorWritingDEFFile { #[derive(Diagnostic)] #[diag(codegen_llvm_error_calling_dlltool)] -pub(crate) struct ErrorCallingDllTool { +pub(crate) struct ErrorCallingDllTool<'a> { + pub dlltool_path: Cow<'a, str>, pub error: std::io::Error, } diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 5bd42622f2c33..cd5429e228d71 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -592,15 +592,6 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool { fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option { use rustc_ast::{LitIntType, LitKind, MetaItemLit}; - if !tcx.features().raw_dylib && tcx.sess.target.arch == "x86" { - feature_err( - &tcx.sess.parse_sess, - sym::raw_dylib, - attr.span, - "`#[link_ordinal]` is unstable on x86", - ) - .emit(); - } let meta_item_list = attr.meta_item_list(); let meta_item_list = meta_item_list.as_deref(); let sole_meta_list = match meta_item_list { diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 70d608a5ea428..5b2e4d15dfebe 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -280,6 +280,8 @@ declare_features! ( (accepted, pub_restricted, "1.18.0", Some(32409), None), /// Allows use of the postfix `?` operator in expressions. (accepted, question_mark, "1.13.0", Some(31436), None), + /// Allows the use of raw-dylibs (RFC 2627). + (accepted, raw_dylib, "CURRENT_RUSTC_VERSION", Some(58713), None), /// Allows keywords to be escaped for use as identifiers. (accepted, raw_identifiers, "1.30.0", Some(48589), None), /// Allows relaxing the coherence rules such that diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 6201e5b619b87..80bf67ab5f682 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -483,8 +483,6 @@ declare_features! ( (active, precise_pointer_size_matching, "1.32.0", Some(56354), None), /// Allows macro attributes on expressions, statements and non-inline modules. (active, proc_macro_hygiene, "1.30.0", Some(54727), None), - /// Allows the use of raw-dylibs (RFC 2627). - (active, raw_dylib, "1.65.0", Some(58713), None), /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions. (active, raw_ref_op, "1.41.0", Some(64490), None), /// Allows using the `#[register_tool]` attribute. diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 7b0b5102c2db6..89eecba378b9a 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -547,6 +547,7 @@ fn test_codegen_options_tracking_hash() { untracked!(ar, String::from("abc")); untracked!(codegen_units, Some(42)); untracked!(default_linker_libraries, true); + untracked!(dlltool, Some(PathBuf::from("custom_dlltool.exe"))); untracked!(extra_filename, String::from("extra-filename")); untracked!(incremental, Some(String::from("abc"))); // `link_arg` is omitted because it just forwards to `link_args`. @@ -651,7 +652,6 @@ fn test_unstable_options_tracking_hash() { untracked!(assert_incr_state, Some(String::from("loaded"))); untracked!(deduplicate_diagnostics, false); untracked!(dep_tasks, true); - untracked!(dlltool, Some(PathBuf::from("custom_dlltool.exe"))); untracked!(dont_buffer_diagnostics, true); untracked!(dump_dep_graph, true); untracked!(dump_drop_tracking_cfg, Some("cfg.dot".to_string())); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index a6ba742201a3b..4d0a35368b35d 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1250,17 +1250,45 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } } - fn check_foreign_fn(&mut self, def_id: LocalDefId, decl: &hir::FnDecl<'_>) { + /// Check if a function's argument types and result type are "ffi-safe". + /// + /// Argument types and the result type are checked for functions with external ABIs. + /// For functions with internal ABIs, argument types and the result type are walked to find + /// fn-ptr types that have external ABIs, as these still need checked. + fn check_maybe_foreign_fn( + &mut self, + abi: SpecAbi, + def_id: LocalDefId, + decl: &'tcx hir::FnDecl<'_>, + ) { let sig = self.cx.tcx.fn_sig(def_id).subst_identity(); let sig = self.cx.tcx.erase_late_bound_regions(sig); + let is_internal_abi = self.is_internal_abi(abi); + let check_ty = |this: &mut ImproperCTypesVisitor<'a, 'tcx>, + hir_ty: &'tcx hir::Ty<'_>, + ty: Ty<'tcx>, + is_return_type: bool| { + // If this function has an external ABI, then its arguments and return type should be + // checked.. + if !is_internal_abi { + this.check_type_for_ffi_and_report_errors(hir_ty.span, ty, false, is_return_type); + return; + } + + // ..but if this function has an internal ABI, then search the argument or return type + // for any fn-ptr types with external ABI, which should be checked.. + for (fn_ptr_ty, span) in this.find_fn_ptr_ty_with_external_abi(hir_ty, ty) { + this.check_type_for_ffi_and_report_errors(span, fn_ptr_ty, false, is_return_type); + } + }; + for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { - self.check_type_for_ffi_and_report_errors(input_hir.span, *input_ty, false, false); + check_ty(self, input_hir, *input_ty, false); } if let hir::FnRetTy::Return(ref ret_hir) = decl.output { - let ret_ty = sig.output(); - self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, false, true); + check_ty(self, ret_hir, sig.output(), true); } } @@ -1275,28 +1303,134 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { SpecAbi::Rust | SpecAbi::RustCall | SpecAbi::RustIntrinsic | SpecAbi::PlatformIntrinsic ) } + + /// Find any fn-ptr types with external ABIs in `ty`. + /// + /// For example, `Option` returns `extern "C" fn()` + fn find_fn_ptr_ty_with_external_abi( + &self, + hir_ty: &hir::Ty<'tcx>, + ty: Ty<'tcx>, + ) -> Vec<(Ty<'tcx>, Span)> { + struct FnPtrFinder<'parent, 'a, 'tcx> { + visitor: &'parent ImproperCTypesVisitor<'a, 'tcx>, + spans: Vec, + tys: Vec>, + } + + impl<'parent, 'a, 'tcx> hir::intravisit::Visitor<'_> for FnPtrFinder<'parent, 'a, 'tcx> { + fn visit_ty(&mut self, ty: &'_ hir::Ty<'_>) { + debug!(?ty); + if let hir::TyKind::BareFn(hir::BareFnTy { abi, .. }) = ty.kind + && !self.visitor.is_internal_abi(*abi) + { + self.spans.push(ty.span); + } + + hir::intravisit::walk_ty(self, ty) + } + } + + impl<'vis, 'a, 'tcx> ty::visit::TypeVisitor> for FnPtrFinder<'vis, 'a, 'tcx> { + type BreakTy = Ty<'tcx>; + + fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { + if let ty::FnPtr(sig) = ty.kind() && !self.visitor.is_internal_abi(sig.abi()) { + self.tys.push(ty); + } + + ty.super_visit_with(self) + } + } + + let mut visitor = FnPtrFinder { visitor: &*self, spans: Vec::new(), tys: Vec::new() }; + self.cx + .tcx + .try_normalize_erasing_regions(self.cx.param_env, ty) + .unwrap_or(ty) + .visit_with(&mut visitor); + hir::intravisit::Visitor::visit_ty(&mut visitor, hir_ty); + + iter::zip(visitor.tys.drain(..), visitor.spans.drain(..)).collect() + } } impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations { - fn check_foreign_item(&mut self, cx: &LateContext<'_>, it: &hir::ForeignItem<'_>) { + fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, it: &hir::ForeignItem<'tcx>) { let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Declaration }; let abi = cx.tcx.hir().get_foreign_abi(it.hir_id()); - if !vis.is_internal_abi(abi) { - match it.kind { - hir::ForeignItemKind::Fn(ref decl, _, _) => { - vis.check_foreign_fn(it.owner_id.def_id, decl); - } - hir::ForeignItemKind::Static(ref ty, _) => { - vis.check_foreign_static(it.owner_id, ty.span); - } - hir::ForeignItemKind::Type => (), + match it.kind { + hir::ForeignItemKind::Fn(ref decl, _, _) => { + vis.check_maybe_foreign_fn(abi, it.owner_id.def_id, decl); } + hir::ForeignItemKind::Static(ref ty, _) if !vis.is_internal_abi(abi) => { + vis.check_foreign_static(it.owner_id, ty.span); + } + hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => (), } } } +impl ImproperCTypesDefinitions { + fn check_ty_maybe_containing_foreign_fnptr<'tcx>( + &mut self, + cx: &LateContext<'tcx>, + hir_ty: &'tcx hir::Ty<'_>, + ty: Ty<'tcx>, + ) { + let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Definition }; + for (fn_ptr_ty, span) in vis.find_fn_ptr_ty_with_external_abi(hir_ty, ty) { + vis.check_type_for_ffi_and_report_errors(span, fn_ptr_ty, true, false); + } + } +} + +/// `ImproperCTypesDefinitions` checks items outside of foreign items (e.g. stuff that isn't in +/// `extern "C" { }` blocks): +/// +/// - `extern "" fn` definitions are checked in the same way as the +/// `ImproperCtypesDeclarations` visitor checks functions if `` is external (e.g. "C"). +/// - All other items which contain types (e.g. other functions, struct definitions, etc) are +/// checked for extern fn-ptrs with external ABIs. impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { + match item.kind { + hir::ItemKind::Static(ty, ..) + | hir::ItemKind::Const(ty, ..) + | hir::ItemKind::TyAlias(ty, ..) => { + self.check_ty_maybe_containing_foreign_fnptr( + cx, + ty, + cx.tcx.type_of(item.owner_id).subst_identity(), + ); + } + // See `check_fn`.. + hir::ItemKind::Fn(..) => {} + // See `check_field_def`.. + hir::ItemKind::Union(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) => {} + // Doesn't define something that can contain a external type to be checked. + hir::ItemKind::Impl(..) + | hir::ItemKind::TraitAlias(..) + | hir::ItemKind::Trait(..) + | hir::ItemKind::OpaqueTy(..) + | hir::ItemKind::GlobalAsm(..) + | hir::ItemKind::ForeignMod { .. } + | hir::ItemKind::Mod(..) + | hir::ItemKind::Macro(..) + | hir::ItemKind::Use(..) + | hir::ItemKind::ExternCrate(..) => {} + } + } + + fn check_field_def(&mut self, cx: &LateContext<'tcx>, field: &'tcx hir::FieldDef<'tcx>) { + self.check_ty_maybe_containing_foreign_fnptr( + cx, + field.ty, + cx.tcx.type_of(field.def_id).subst_identity(), + ); + } + fn check_fn( &mut self, cx: &LateContext<'tcx>, @@ -1315,9 +1449,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions { }; let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Definition }; - if !vis.is_internal_abi(abi) { - vis.check_foreign_fn(id, decl); - } + vis.check_maybe_foreign_fn(abi, id, decl); } } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index b855c8e433266..d3ad32752c62f 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -161,14 +161,6 @@ impl<'tcx> Collector<'tcx> { "raw-dylib" => { if !sess.target.is_like_windows { sess.emit_err(errors::FrameworkOnlyWindows { span }); - } else if !features.raw_dylib && sess.target.arch == "x86" { - feature_err( - &sess.parse_sess, - sym::raw_dylib, - span, - "link kind `raw-dylib` is unstable on x86", - ) - .emit(); } NativeLibKind::RawDylib } @@ -251,16 +243,6 @@ impl<'tcx> Collector<'tcx> { continue; } }; - if !features.raw_dylib { - let span = item.name_value_literal_span().unwrap(); - feature_err( - &sess.parse_sess, - sym::raw_dylib, - span, - "import name type is unstable", - ) - .emit(); - } import_name_type = Some((link_import_name_type, item.span())); } _ => { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index f5ffdd27cae3f..479bac9b2aaeb 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -837,11 +837,12 @@ fn should_encode_span(def_kind: DefKind) -> bool { | DefKind::AnonConst | DefKind::InlineConst | DefKind::OpaqueTy + | DefKind::ImplTraitPlaceholder | DefKind::Field | DefKind::Impl { .. } | DefKind::Closure | DefKind::Generator => true, - DefKind::ForeignMod | DefKind::ImplTraitPlaceholder | DefKind::GlobalAsm => false, + DefKind::ForeignMod | DefKind::GlobalAsm => false, } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 775fad1a365c2..2a04292e789ff 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1235,6 +1235,8 @@ options! { line-tables-only, limited, or full; default: 0)"), default_linker_libraries: bool = (false, parse_bool, [UNTRACKED], "allow the linker to link its default libraries (default: no)"), + dlltool: Option = (None, parse_opt_pathbuf, [UNTRACKED], + "import library generation tool (ignored except when targeting windows-gnu)"), embed_bitcode: bool = (true, parse_bool, [TRACKED], "emit bitcode in rlibs (default: yes)"), extra_filename: String = (String::new(), parse_string, [UNTRACKED], @@ -1391,8 +1393,6 @@ options! { (default: no)"), diagnostic_width: Option = (None, parse_opt_number, [UNTRACKED], "set the current output width for diagnostic truncation"), - dlltool: Option = (None, parse_opt_pathbuf, [UNTRACKED], - "import library generation tool (windows-gnu only)"), dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED], "emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) \ (default: no)"), diff --git a/compiler/rustc_target/src/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs index 9427f27d1b7bb..2470cdfebe225 100644 --- a/compiler/rustc_target/src/abi/call/x86_64.rs +++ b/compiler/rustc_target/src/abi/call/x86_64.rs @@ -153,9 +153,9 @@ fn reg_component(cls: &[Option], i: &mut usize, size: Size) -> Option], size: Size) -> CastTarget { +fn cast_target(cls: &[Option], size: Size) -> Option { let mut i = 0; - let lo = reg_component(cls, &mut i, size).unwrap(); + let lo = reg_component(cls, &mut i, size)?; let offset = Size::from_bytes(8) * (i as u64); let mut target = CastTarget::from(lo); if size > offset { @@ -164,7 +164,7 @@ fn cast_target(cls: &[Option], size: Size) -> CastTarget { } } assert_eq!(reg_component(cls, &mut i, Size::ZERO), None); - target + Some(target) } const MAX_INT_REGS: usize = 6; // RDI, RSI, RDX, RCX, R8, R9 @@ -227,7 +227,9 @@ where // split into sized chunks passed individually if arg.layout.is_aggregate() { let size = arg.layout.size; - arg.cast_to(cast_target(cls, size)) + if let Some(cast_target) = cast_target(cls, size) { + arg.cast_to(cast_target); + } } else { arg.extend_integer_width_to(32); } diff --git a/library/std/src/sys/common/thread_local/mod.rs b/library/std/src/sys/common/thread_local/mod.rs index 951d509ec9533..77f645883102c 100644 --- a/library/std/src/sys/common/thread_local/mod.rs +++ b/library/std/src/sys/common/thread_local/mod.rs @@ -1,5 +1,10 @@ #![unstable(feature = "thread_local_internals", reason = "should not be necessary", issue = "none")] +// There are three thread-local implementations: "static", "fast", "OS". +// The "OS" thread local key type is accessed via platform-specific API calls and is slow, while the +// "fast" key type is accessed via code generated via LLVM, where TLS keys are set up by the linker. +// "static" is for single-threaded platforms where a global static is sufficient. + cfg_if::cfg_if! { if #[cfg(all(target_family = "wasm", not(target_feature = "atomics")))] { #[doc(hidden)] diff --git a/library/std/src/sys/common/thread_local/os_local.rs b/library/std/src/sys/common/thread_local/os_local.rs index d004897df281a..5d48ce1e03bc3 100644 --- a/library/std/src/sys/common/thread_local/os_local.rs +++ b/library/std/src/sys/common/thread_local/os_local.rs @@ -18,7 +18,7 @@ pub macro thread_local_inner { ) -> $crate::option::Option<&'static $t> { const INIT_EXPR: $t = $init; - // On platforms without `#[thread_local]` we fall back to the + // On platforms without `#[thread_local]` we fall back to the // same implementation as below for os thread locals. #[inline] const fn __init() -> $t { INIT_EXPR } diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 9cdc17a287c96..f712c872708ac 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -193,22 +193,22 @@ pub use scoped::{scope, Scope, ScopedJoinHandle}; #[macro_use] mod local; -#[stable(feature = "rust1", since = "1.0.0")] -pub use self::local::{AccessError, LocalKey}; - -// Provide the type used by the thread_local! macro to access TLS keys. This -// needs to be kept in sync with the macro itself (in `local.rs`). -// There are three types: "static", "fast", "OS". The "OS" thread local key -// type is accessed via platform-specific API calls and is slow, while the "fast" -// key type is accessed via code generated via LLVM, where TLS keys are set up -// by the elf linker. "static" is for single-threaded platforms where a global -// static is sufficient. - -// Implementation details used by the thread_local!{} macro. -#[doc(hidden)] -#[unstable(feature = "thread_local_internals", issue = "none")] -pub mod local_impl { - pub use crate::sys::common::thread_local::{thread_local_inner, Key}; +cfg_if::cfg_if! { + if #[cfg(test)] { + // Avoid duplicating the global state assoicated with thread-locals between this crate and + // realstd. Miri relies on this. + pub use realstd::thread::{local_impl, AccessError, LocalKey}; + } else { + #[stable(feature = "rust1", since = "1.0.0")] + pub use self::local::{AccessError, LocalKey}; + + // Implementation details used by the thread_local!{} macro. + #[doc(hidden)] + #[unstable(feature = "thread_local_internals", issue = "none")] + pub mod local_impl { + pub use crate::sys::common::thread_local::{thread_local_inner, Key}; + } + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index c1cf9b93fb356..3e82a381a1b2d 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -427,7 +427,6 @@ impl Config { fn download_toolchain( &self, - // FIXME(ozkanonur) use CompilerMetadata instead of `version: &str` version: &str, sysroot: &str, stamp_key: &str, diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index d7c6a884fc8fb..b7fa7243cc1c0 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -90,6 +90,14 @@ It takes one of the following values: For example, for gcc flavor linkers, this issues the `-nodefaultlibs` flag to the linker. +## dlltool + +On `windows-gnu` targets, this flag controls which dlltool `rustc` invokes to +generate import libraries when using the [`raw-dylib` link kind](../../reference/items/external-blocks.md#the-link-attribute). +It takes a path to [the dlltool executable](https://sourceware.org/binutils/docs/binutils/dlltool.html). +If this flag is not specified, a dlltool executable will be inferred based on +the host environment and target. + ## embed-bitcode This flag controls whether or not the compiler embeds LLVM bitcode into object diff --git a/src/doc/unstable-book/src/language-features/raw-dylib.md b/src/doc/unstable-book/src/language-features/raw-dylib.md deleted file mode 100644 index 5fd208ae7571c..0000000000000 --- a/src/doc/unstable-book/src/language-features/raw-dylib.md +++ /dev/null @@ -1,34 +0,0 @@ -# `raw_dylib` - -The tracking issue for this feature is: [#58713] - -[#58713]: https://github.com/rust-lang/rust/issues/58713 - ------------------------- - -The `raw_dylib` feature allows you to link against the implementations of functions in an `extern` -block without, on Windows, linking against an import library. - -```rust,ignore (partial-example) -#![feature(raw_dylib)] - -#[link(name="library", kind="raw-dylib")] -extern { - fn extern_function(x: i32); -} - -fn main() { - unsafe { - extern_function(14); - } -} -``` - -## Limitations - -This feature is unstable for the `x86` architecture, and stable for all other architectures. - -This feature is only supported on Windows. - -On the `x86` architecture, this feature supports only the `cdecl`, `stdcall`, `system`, `fastcall`, and -`vectorcall` calling conventions. diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 6fbb4508662c7..a7d5f497756b5 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1259,6 +1259,10 @@ a.tooltip:hover::after { background-color: var(--search-error-code-background-color); } +.search-corrections { + font-weight: normal; +} + #src-sidebar-toggle { position: sticky; top: 0; diff --git a/src/librustdoc/html/static/js/externs.js b/src/librustdoc/html/static/js/externs.js index 4c81a0979c1a7..8b931f74e600a 100644 --- a/src/librustdoc/html/static/js/externs.js +++ b/src/librustdoc/html/static/js/externs.js @@ -9,6 +9,7 @@ function initSearch(searchIndex){} /** * @typedef {{ * name: string, + * id: integer, * fullPath: Array, * pathWithoutLast: Array, * pathLast: string, @@ -36,6 +37,8 @@ let ParserState; * args: Array, * returned: Array, * foundElems: number, + * literalSearch: boolean, + * corrections: Array<{from: string, to: integer}>, * }} */ let ParsedQuery; @@ -139,7 +142,7 @@ let FunctionSearchType; /** * @typedef {{ - * name: (null|string), + * id: (null|number), * ty: (null|number), * generics: Array, * }} diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 3dc4f2149b8b9..62afe40bb3155 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -58,6 +58,7 @@ function printTab(nb) { } iter += 1; }); + const isTypeSearch = (nb > 0 || iter === 1); iter = 0; onEachLazy(document.getElementById("results").childNodes, elem => { if (nb === iter) { @@ -70,6 +71,13 @@ function printTab(nb) { }); if (foundCurrentTab && foundCurrentResultSet) { searchState.currentTab = nb; + // Corrections only kick in on type-based searches. + const correctionsElem = document.getElementsByClassName("search-corrections"); + if (isTypeSearch) { + removeClass(correctionsElem[0], "hidden"); + } else { + addClass(correctionsElem[0], "hidden"); + } } else if (nb !== 0) { printTab(0); } @@ -191,6 +199,13 @@ function initSearch(rawSearchIndex) { */ let searchIndex; let currentResults; + /** + * Map from normalized type names to integers. Used to make type search + * more efficient. + * + * @type {Map} + */ + let typeNameIdMap; const ALIASES = new Map(); function isWhitespace(c) { @@ -358,6 +373,7 @@ function initSearch(rawSearchIndex) { parserState.typeFilter = null; return { name: name, + id: -1, fullPath: pathSegments, pathWithoutLast: pathSegments.slice(0, pathSegments.length - 1), pathLast: pathSegments[pathSegments.length - 1], @@ -718,6 +734,7 @@ function initSearch(rawSearchIndex) { foundElems: 0, literalSearch: false, error: null, + correction: null, }; } @@ -873,7 +890,7 @@ function initSearch(rawSearchIndex) { * * @param {Array} results_in_args * @param {Array} results_returned - * @param {Array} results_in_args + * @param {Array} results_others * @param {ParsedQuery} parsedQuery * * @return {ResultsTable} @@ -1091,48 +1108,50 @@ function initSearch(rawSearchIndex) { * * @param {Row} row - The object to check. * @param {QueryElement} elem - The element from the parsed query. - * @param {integer} defaultDistance - This is the value to return in case there are no - * generics. * - * @return {integer} - Returns the best match (if any) or `maxEditDistance + 1`. + * @return {boolean} - Returns true if a match, false otherwise. */ - function checkGenerics(row, elem, defaultDistance, maxEditDistance) { - if (row.generics.length === 0) { - return elem.generics.length === 0 ? defaultDistance : maxEditDistance + 1; - } else if (row.generics.length > 0 && row.generics[0].name === null) { - return checkGenerics(row.generics[0], elem, defaultDistance, maxEditDistance); - } - // The names match, but we need to be sure that all generics kinda - // match as well. + function checkGenerics(row, elem) { + if (row.generics.length === 0 || elem.generics.length === 0) { + return false; + } + // This function is called if the names match, but we need to make + // sure that all generics match as well. + // + // This search engine implements order-agnostic unification. There + // should be no missing duplicates (generics have "bag semantics"), + // and the row is allowed to have extras. if (elem.generics.length > 0 && row.generics.length >= elem.generics.length) { const elems = new Map(); - for (const entry of row.generics) { - if (entry.name === "") { + const addEntryToElems = function addEntryToElems(entry) { + if (entry.id === -1) { // Pure generic, needs to check into it. - if (checkGenerics(entry, elem, maxEditDistance + 1, maxEditDistance) - !== 0) { - return maxEditDistance + 1; + for (const inner_entry of entry.generics) { + addEntryToElems(inner_entry); } - continue; + return; } let currentEntryElems; - if (elems.has(entry.name)) { - currentEntryElems = elems.get(entry.name); + if (elems.has(entry.id)) { + currentEntryElems = elems.get(entry.id); } else { currentEntryElems = []; - elems.set(entry.name, currentEntryElems); + elems.set(entry.id, currentEntryElems); } currentEntryElems.push(entry); + }; + for (const entry of row.generics) { + addEntryToElems(entry); } // We need to find the type that matches the most to remove it in order // to move forward. const handleGeneric = generic => { - if (!elems.has(generic.name)) { + if (!elems.has(generic.id)) { return false; } - const matchElems = elems.get(generic.name); + const matchElems = elems.get(generic.id); const matchIdx = matchElems.findIndex(tmp_elem => { - if (checkGenerics(tmp_elem, generic, 0, maxEditDistance) !== 0) { + if (generic.generics.length > 0 && !checkGenerics(tmp_elem, generic)) { return false; } return typePassesFilter(generic.typeFilter, tmp_elem.ty); @@ -1142,7 +1161,7 @@ function initSearch(rawSearchIndex) { } matchElems.splice(matchIdx, 1); if (matchElems.length === 0) { - elems.delete(generic.name); + elems.delete(generic.id); } return true; }; @@ -1152,17 +1171,17 @@ function initSearch(rawSearchIndex) { // own type. for (const generic of elem.generics) { if (generic.typeFilter !== -1 && !handleGeneric(generic)) { - return maxEditDistance + 1; + return false; } } for (const generic of elem.generics) { if (generic.typeFilter === -1 && !handleGeneric(generic)) { - return maxEditDistance + 1; + return false; } } - return 0; + return true; } - return maxEditDistance + 1; + return false; } /** @@ -1172,17 +1191,15 @@ function initSearch(rawSearchIndex) { * @param {Row} row * @param {QueryElement} elem - The element from the parsed query. * - * @return {integer} - Returns an edit distance to the best match. + * @return {boolean} - Returns true if found, false otherwise. */ - function checkIfInGenerics(row, elem, maxEditDistance) { - let dist = maxEditDistance + 1; + function checkIfInGenerics(row, elem) { for (const entry of row.generics) { - dist = Math.min(checkType(entry, elem, true, maxEditDistance), dist); - if (dist === 0) { - break; + if (checkType(entry, elem)) { + return true; } } - return dist; + return false; } /** @@ -1191,75 +1208,26 @@ function initSearch(rawSearchIndex) { * * @param {Row} row * @param {QueryElement} elem - The element from the parsed query. - * @param {boolean} literalSearch * - * @return {integer} - Returns an edit distance to the best match. If there is - * no match, returns `maxEditDistance + 1`. + * @return {boolean} - Returns true if the type matches, false otherwise. */ - function checkType(row, elem, literalSearch, maxEditDistance) { - if (row.name === null) { + function checkType(row, elem) { + if (row.id === -1) { // This is a pure "generic" search, no need to run other checks. - if (row.generics.length > 0) { - return checkIfInGenerics(row, elem, maxEditDistance); - } - return maxEditDistance + 1; + return row.generics.length > 0 ? checkIfInGenerics(row, elem) : false; } - let dist; - if (typePassesFilter(elem.typeFilter, row.ty)) { - dist = editDistance(row.name, elem.name, maxEditDistance); - } else { - dist = maxEditDistance + 1; - } - if (literalSearch) { - if (dist !== 0) { - // The name didn't match, let's try to check if the generics do. - if (elem.generics.length === 0) { - const checkGeneric = row.generics.length > 0; - if (checkGeneric && row.generics - .findIndex(tmp_elem => tmp_elem.name === elem.name && - typePassesFilter(elem.typeFilter, tmp_elem.ty)) !== -1) { - return 0; - } - } - return maxEditDistance + 1; - } else if (elem.generics.length > 0) { - return checkGenerics(row, elem, maxEditDistance + 1, maxEditDistance); - } - return 0; - } else if (row.generics.length > 0) { - if (elem.generics.length === 0) { - if (dist === 0) { - return 0; - } - // The name didn't match so we now check if the type we're looking for is inside - // the generics! - dist = Math.min(dist, checkIfInGenerics(row, elem, maxEditDistance)); - return dist; - } else if (dist > maxEditDistance) { - // So our item's name doesn't match at all and has generics. - // - // Maybe it's present in a sub generic? For example "f>>()", if we're - // looking for "B", we'll need to go down. - return checkIfInGenerics(row, elem, maxEditDistance); - } else { - // At this point, the name kinda match and we have generics to check, so - // let's go! - const tmp_dist = checkGenerics(row, elem, dist, maxEditDistance); - if (tmp_dist > maxEditDistance) { - return maxEditDistance + 1; - } - // We compute the median value of both checks and return it. - return (tmp_dist + dist) / 2; + if (row.id === elem.id && typePassesFilter(elem.typeFilter, row.ty)) { + if (elem.generics.length > 0) { + return checkGenerics(row, elem); } - } else if (elem.generics.length > 0) { - // In this case, we were expecting generics but there isn't so we simply reject this - // one. - return maxEditDistance + 1; + return true; } - // No generics on our query or on the target type so we can return without doing - // anything else. - return dist; + + // If the current item does not match, try [unboxing] the generic. + // [unboxing]: + // https://ndmitchell.com/downloads/slides-hoogle_fast_type_searching-09_aug_2008.pdf + return checkIfInGenerics(row, elem); } /** @@ -1267,17 +1235,11 @@ function initSearch(rawSearchIndex) { * * @param {Row} row * @param {QueryElement} elem - The element from the parsed query. - * @param {integer} maxEditDistance * @param {Array} skipPositions - Do not return one of these positions. * - * @return {dist: integer, position: integer} - Returns an edit distance to the best match. - * If there is no match, returns - * `maxEditDistance + 1` and position: -1. + * @return {integer} - Returns the position of the match, or -1 if none. */ - function findArg(row, elem, maxEditDistance, skipPositions) { - let dist = maxEditDistance + 1; - let position = -1; - + function findArg(row, elem, skipPositions) { if (row && row.type && row.type.inputs && row.type.inputs.length > 0) { let i = 0; for (const input of row.type.inputs) { @@ -1285,24 +1247,13 @@ function initSearch(rawSearchIndex) { i += 1; continue; } - const typeDist = checkType( - input, - elem, - parsedQuery.literalSearch, - maxEditDistance - ); - if (typeDist === 0) { - return {dist: 0, position: i}; - } - if (typeDist < dist) { - dist = typeDist; - position = i; + if (checkType(input, elem)) { + return i; } i += 1; } } - dist = parsedQuery.literalSearch ? maxEditDistance + 1 : dist; - return {dist, position}; + return -1; } /** @@ -1310,43 +1261,25 @@ function initSearch(rawSearchIndex) { * * @param {Row} row * @param {QueryElement} elem - The element from the parsed query. - * @param {integer} maxEditDistance * @param {Array} skipPositions - Do not return one of these positions. * - * @return {dist: integer, position: integer} - Returns an edit distance to the best match. - * If there is no match, returns - * `maxEditDistance + 1` and position: -1. + * @return {integer} - Returns the position of the matching item, or -1 if none. */ - function checkReturned(row, elem, maxEditDistance, skipPositions) { - let dist = maxEditDistance + 1; - let position = -1; - + function checkReturned(row, elem, skipPositions) { if (row && row.type && row.type.output.length > 0) { - const ret = row.type.output; let i = 0; - for (const ret_ty of ret) { + for (const ret_ty of row.type.output) { if (skipPositions.indexOf(i) !== -1) { i += 1; continue; } - const typeDist = checkType( - ret_ty, - elem, - parsedQuery.literalSearch, - maxEditDistance - ); - if (typeDist === 0) { - return {dist: 0, position: i}; - } - if (typeDist < dist) { - dist = typeDist; - position = i; + if (checkType(ret_ty, elem)) { + return i; } i += 1; } } - dist = parsedQuery.literalSearch ? maxEditDistance + 1 : dist; - return {dist, position}; + return -1; } function checkPath(contains, ty, maxEditDistance) { @@ -1543,17 +1476,20 @@ function initSearch(rawSearchIndex) { if (!row || (filterCrates !== null && row.crate !== filterCrates)) { return; } - let dist, index = -1, path_dist = 0; + let index = -1, path_dist = 0; const fullId = row.id; const searchWord = searchWords[pos]; - const in_args = findArg(row, elem, maxEditDistance, []); - const returned = checkReturned(row, elem, maxEditDistance, []); - - // path_dist is 0 because no parent path information is currently stored - // in the search index - addIntoResults(results_in_args, fullId, pos, -1, in_args.dist, 0, maxEditDistance); - addIntoResults(results_returned, fullId, pos, -1, returned.dist, 0, maxEditDistance); + const in_args = findArg(row, elem, []); + if (in_args !== -1) { + // path_dist is 0 because no parent path information is currently stored + // in the search index + addIntoResults(results_in_args, fullId, pos, -1, 0, 0, maxEditDistance); + } + const returned = checkReturned(row, elem, []); + if (returned !== -1) { + addIntoResults(results_returned, fullId, pos, -1, 0, 0, maxEditDistance); + } if (!typePassesFilter(elem.typeFilter, row.ty)) { return; @@ -1574,16 +1510,6 @@ function initSearch(rawSearchIndex) { index = row_index; } - // No need to check anything else if it's a "pure" generics search. - if (elem.name.length === 0) { - if (row.type !== null) { - dist = checkGenerics(row.type, elem, maxEditDistance + 1, maxEditDistance); - // path_dist is 0 because we know it's empty - addIntoResults(results_others, fullId, pos, index, dist, 0, maxEditDistance); - } - return; - } - if (elem.fullPath.length > 1) { path_dist = checkPath(elem.pathWithoutLast, row, maxEditDistance); if (path_dist > maxEditDistance) { @@ -1598,7 +1524,7 @@ function initSearch(rawSearchIndex) { return; } - dist = editDistance(searchWord, elem.pathLast, maxEditDistance); + const dist = editDistance(searchWord, elem.pathLast, maxEditDistance); if (index === -1 && dist + path_dist > maxEditDistance) { return; @@ -1616,28 +1542,22 @@ function initSearch(rawSearchIndex) { * @param {integer} pos - Position in the `searchIndex`. * @param {Object} results */ - function handleArgs(row, pos, results, maxEditDistance) { + function handleArgs(row, pos, results) { if (!row || (filterCrates !== null && row.crate !== filterCrates)) { return; } - let totalDist = 0; - let nbDist = 0; - // If the result is too "bad", we return false and it ends this search. function checkArgs(elems, callback) { const skipPositions = []; for (const elem of elems) { // There is more than one parameter to the query so all checks should be "exact" - const { dist, position } = callback( + const position = callback( row, elem, - maxEditDistance, skipPositions ); - if (dist <= 1) { - nbDist += 1; - totalDist += dist; + if (position !== -1) { skipPositions.push(position); } else { return false; @@ -1652,11 +1572,7 @@ function initSearch(rawSearchIndex) { return; } - if (nbDist === 0) { - return; - } - const dist = Math.round(totalDist / nbDist); - addIntoResults(results, row.id, pos, 0, dist, 0, maxEditDistance); + addIntoResults(results, row.id, pos, 0, 0, 0, Number.MAX_VALUE); } function innerRunQuery() { @@ -1671,6 +1587,53 @@ function initSearch(rawSearchIndex) { } const maxEditDistance = Math.floor(queryLen / 3); + /** + * Convert names to ids in parsed query elements. + * This is not used for the "In Names" tab, but is used for the + * "In Params", "In Returns", and "In Function Signature" tabs. + * + * If there is no matching item, but a close-enough match, this + * function also that correction. + * + * See `buildTypeMapIndex` for more information. + * + * @param {QueryElement} elem + */ + function convertNameToId(elem) { + if (typeNameIdMap.has(elem.name)) { + elem.id = typeNameIdMap.get(elem.name); + } else if (!parsedQuery.literalSearch) { + let match = -1; + let matchDist = maxEditDistance + 1; + let matchName = ""; + for (const [name, id] of typeNameIdMap) { + const dist = editDistance(name, elem.name, maxEditDistance); + if (dist <= matchDist && dist <= maxEditDistance) { + if (dist === matchDist && matchName > name) { + continue; + } + match = id; + matchDist = dist; + matchName = name; + } + } + if (match !== -1) { + parsedQuery.correction = matchName; + } + elem.id = match; + } + for (const elem2 of elem.generics) { + convertNameToId(elem2); + } + } + + for (const elem of parsedQuery.elems) { + convertNameToId(elem); + } + for (const elem of parsedQuery.returned) { + convertNameToId(elem); + } + if (parsedQuery.foundElems === 1) { if (parsedQuery.elems.length === 1) { elem = parsedQuery.elems[0]; @@ -1695,22 +1658,23 @@ function initSearch(rawSearchIndex) { in_returned = checkReturned( row, elem, - maxEditDistance, [] ); - addIntoResults( - results_others, - row.id, - i, - -1, - in_returned.dist, - maxEditDistance - ); + if (in_returned !== -1) { + addIntoResults( + results_others, + row.id, + i, + -1, + 0, + Number.MAX_VALUE + ); + } } } } else if (parsedQuery.foundElems > 0) { for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { - handleArgs(searchIndex[i], i, results_others, maxEditDistance); + handleArgs(searchIndex[i], i, results_others); } } } @@ -2030,6 +1994,16 @@ function initSearch(rawSearchIndex) { currentTab = 0; } + if (results.query.correction !== null) { + const orig = results.query.returned.length > 0 + ? results.query.returned[0].name + : results.query.elems[0].name; + output += "

" + + `Type "${orig}" not found. ` + + "Showing results for closest type name " + + `"${results.query.correction}" instead.

`; + } + const resultsElem = document.createElement("div"); resultsElem.id = "results"; resultsElem.appendChild(ret_others[0]); @@ -2108,6 +2082,34 @@ function initSearch(rawSearchIndex) { filterCrates); } + /** + * Add an item to the type Name->ID map, or, if one already exists, use it. + * Returns the number. If name is "" or null, return -1 (pure generic). + * + * This is effectively string interning, so that function matching can be + * done more quickly. Two types with the same name but different item kinds + * get the same ID. + * + * @param {Map} typeNameIdMap + * @param {string} name + * + * @returns {integer} + */ + function buildTypeMapIndex(typeNameIdMap, name) { + + if (name === "" || name === null) { + return -1; + } + + if (typeNameIdMap.has(name)) { + return typeNameIdMap.get(name); + } else { + const id = typeNameIdMap.size; + typeNameIdMap.set(name, id); + return id; + } + } + /** * Convert a list of RawFunctionType / ID to object-based FunctionType. * @@ -2126,7 +2128,7 @@ function initSearch(rawSearchIndex) { * * @return {Array} */ - function buildItemSearchTypeAll(types, lowercasePaths) { + function buildItemSearchTypeAll(types, lowercasePaths, typeNameIdMap) { const PATH_INDEX_DATA = 0; const GENERICS_DATA = 1; return types.map(type => { @@ -2136,11 +2138,17 @@ function initSearch(rawSearchIndex) { generics = []; } else { pathIndex = type[PATH_INDEX_DATA]; - generics = buildItemSearchTypeAll(type[GENERICS_DATA], lowercasePaths); + generics = buildItemSearchTypeAll( + type[GENERICS_DATA], + lowercasePaths, + typeNameIdMap + ); } return { // `0` is used as a sentinel because it's fewer bytes than `null` - name: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].name, + id: pathIndex === 0 + ? -1 + : buildTypeMapIndex(typeNameIdMap, lowercasePaths[pathIndex - 1].name), ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, generics: generics, }; @@ -2159,10 +2167,11 @@ function initSearch(rawSearchIndex) { * * @param {RawFunctionSearchType} functionSearchType * @param {Array<{name: string, ty: number}>} lowercasePaths + * @param {Map} * * @return {null|FunctionSearchType} */ - function buildFunctionSearchType(functionSearchType, lowercasePaths) { + function buildFunctionSearchType(functionSearchType, lowercasePaths, typeNameIdMap) { const INPUTS_DATA = 0; const OUTPUT_DATA = 1; // `0` is used as a sentinel because it's fewer bytes than `null` @@ -2173,23 +2182,35 @@ function initSearch(rawSearchIndex) { if (typeof functionSearchType[INPUTS_DATA] === "number") { const pathIndex = functionSearchType[INPUTS_DATA]; inputs = [{ - name: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].name, + id: pathIndex === 0 + ? -1 + : buildTypeMapIndex(typeNameIdMap, lowercasePaths[pathIndex - 1].name), ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, generics: [], }]; } else { - inputs = buildItemSearchTypeAll(functionSearchType[INPUTS_DATA], lowercasePaths); + inputs = buildItemSearchTypeAll( + functionSearchType[INPUTS_DATA], + lowercasePaths, + typeNameIdMap + ); } if (functionSearchType.length > 1) { if (typeof functionSearchType[OUTPUT_DATA] === "number") { const pathIndex = functionSearchType[OUTPUT_DATA]; output = [{ - name: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].name, + id: pathIndex === 0 + ? -1 + : buildTypeMapIndex(typeNameIdMap, lowercasePaths[pathIndex - 1].name), ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty, generics: [], }]; } else { - output = buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA], lowercasePaths); + output = buildItemSearchTypeAll( + functionSearchType[OUTPUT_DATA], + lowercasePaths, + typeNameIdMap + ); } } else { output = []; @@ -2202,9 +2223,12 @@ function initSearch(rawSearchIndex) { function buildIndex(rawSearchIndex) { searchIndex = []; /** + * List of normalized search words (ASCII lowercased, and undescores removed). + * * @type {Array} */ const searchWords = []; + typeNameIdMap = new Map(); const charA = "A".charCodeAt(0); let currentIndex = 0; let id = 0; @@ -2337,7 +2361,11 @@ function initSearch(rawSearchIndex) { path: itemPaths.has(i) ? itemPaths.get(i) : lastPath, desc: itemDescs[i], parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined, - type: buildFunctionSearchType(itemFunctionSearchTypes[i], lowercasePaths), + type: buildFunctionSearchType( + itemFunctionSearchTypes[i], + lowercasePaths, + typeNameIdMap + ), id: id, normalizedName: word.indexOf("_") === -1 ? word : word.replace(/_/g, ""), deprecated: deprecatedItems.has(i), diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index 81179480ed810..4a57c61406ce4 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -115,6 +115,11 @@ pub(super) fn handle_needs( condition: cache.x86_64_dlltool, ignore_reason: "ignored when dlltool for x86_64 is not present", }, + Need { + name: "needs-dlltool", + condition: cache.dlltool, + ignore_reason: "ignored when dlltool for the current architecture is not present", + }, Need { name: "needs-git-hash", condition: config.git_hash, @@ -183,6 +188,7 @@ pub(super) struct CachedNeedsConditions { rust_lld: bool, i686_dlltool: bool, x86_64_dlltool: bool, + dlltool: bool, } impl CachedNeedsConditions { @@ -190,6 +196,17 @@ impl CachedNeedsConditions { let path = std::env::var_os("PATH").expect("missing PATH environment variable"); let path = std::env::split_paths(&path).collect::>(); + // On Windows, dlltool.exe is used for all architectures. + #[cfg(windows)] + let dlltool = path.iter().any(|dir| dir.join("dlltool.exe").is_file()); + + // For non-Windows, there are architecture specific dlltool binaries. + #[cfg(not(windows))] + let i686_dlltool = path.iter().any(|dir| dir.join("i686-w64-mingw32-dlltool").is_file()); + #[cfg(not(windows))] + let x86_64_dlltool = + path.iter().any(|dir| dir.join("x86_64-w64-mingw32-dlltool").is_file()); + let target = &&*config.target; Self { sanitizer_support: std::env::var_os("RUSTC_SANITIZER_SUPPORT").is_some(), @@ -225,17 +242,26 @@ impl CachedNeedsConditions { .join(if config.host.contains("windows") { "rust-lld.exe" } else { "rust-lld" }) .exists(), - // On Windows, dlltool.exe is used for all architectures. #[cfg(windows)] - i686_dlltool: path.iter().any(|dir| dir.join("dlltool.exe").is_file()), + i686_dlltool: dlltool, #[cfg(windows)] - x86_64_dlltool: path.iter().any(|dir| dir.join("dlltool.exe").is_file()), + x86_64_dlltool: dlltool, + #[cfg(windows)] + dlltool, // For non-Windows, there are architecture specific dlltool binaries. #[cfg(not(windows))] - i686_dlltool: path.iter().any(|dir| dir.join("i686-w64-mingw32-dlltool").is_file()), + i686_dlltool, + #[cfg(not(windows))] + x86_64_dlltool, #[cfg(not(windows))] - x86_64_dlltool: path.iter().any(|dir| dir.join("x86_64-w64-mingw32-dlltool").is_file()), + dlltool: if config.matches_arch("x86") { + i686_dlltool + } else if config.matches_arch("x86_64") { + x86_64_dlltool + } else { + false + }, } } } diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 6b9a9b66a7d9e..270704ebffde6 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -226,6 +226,24 @@ function runSearch(query, expected, doSearch, loadedFile, queryName) { return error_text; } +function runCorrections(query, corrections, getCorrections, loadedFile) { + const qc = getCorrections(query, loadedFile.FILTER_CRATE); + const error_text = []; + + if (corrections === null) { + if (qc !== null) { + error_text.push(`==> expected = null, found = ${qc}`); + } + return error_text; + } + + if (qc !== corrections.toLowerCase()) { + error_text.push(`==> expected = ${corrections}, found = ${qc}`); + } + + return error_text; +} + function checkResult(error_text, loadedFile, displaySuccess) { if (error_text.length === 0 && loadedFile.should_fail === true) { console.log("FAILED"); @@ -272,9 +290,10 @@ function runCheck(loadedFile, key, callback) { return 0; } -function runChecks(testFile, doSearch, parseQuery) { +function runChecks(testFile, doSearch, parseQuery, getCorrections) { let checkExpected = false; let checkParsed = false; + let checkCorrections = false; let testFileContent = readFile(testFile) + "exports.QUERY = QUERY;"; if (testFileContent.indexOf("FILTER_CRATE") !== -1) { @@ -291,9 +310,13 @@ function runChecks(testFile, doSearch, parseQuery) { testFileContent += "exports.PARSED = PARSED;"; checkParsed = true; } - if (!checkParsed && !checkExpected) { + if (testFileContent.indexOf("\nconst CORRECTIONS") !== -1) { + testFileContent += "exports.CORRECTIONS = CORRECTIONS;"; + checkCorrections = true; + } + if (!checkParsed && !checkExpected && !checkCorrections) { console.log("FAILED"); - console.log("==> At least `PARSED` or `EXPECTED` is needed!"); + console.log("==> At least `PARSED`, `EXPECTED`, or `CORRECTIONS` is needed!"); return 1; } @@ -310,6 +333,11 @@ function runChecks(testFile, doSearch, parseQuery) { return runParser(query, expected, parseQuery, text); }); } + if (checkCorrections) { + res += runCheck(loadedFile, "CORRECTIONS", (query, expected) => { + return runCorrections(query, expected, getCorrections, loadedFile); + }); + } return res; } @@ -318,9 +346,10 @@ function runChecks(testFile, doSearch, parseQuery) { * * @param {string} doc_folder - Path to a folder generated by running rustdoc * @param {string} resource_suffix - Version number between filename and .js, e.g. "1.59.0" - * @returns {Object} - Object containing two keys: `doSearch`, which runs a search - * with the loaded index and returns a table of results; and `parseQuery`, which is the - * `parseQuery` function exported from the search module. + * @returns {Object} - Object containing keys: `doSearch`, which runs a search + * with the loaded index and returns a table of results; `parseQuery`, which is the + * `parseQuery` function exported from the search module; and `getCorrections`, which runs + * a search but returns type name corrections instead of results. */ function loadSearchJS(doc_folder, resource_suffix) { const searchIndexJs = path.join(doc_folder, "search-index" + resource_suffix + ".js"); @@ -336,6 +365,12 @@ function loadSearchJS(doc_folder, resource_suffix) { return searchModule.execQuery(searchModule.parseQuery(queryStr), searchWords, filterCrate, currentCrate); }, + getCorrections: function(queryStr, filterCrate, currentCrate) { + const parsedQuery = searchModule.parseQuery(queryStr); + searchModule.execQuery(parsedQuery, searchWords, + filterCrate, currentCrate); + return parsedQuery.correction; + }, parseQuery: searchModule.parseQuery, }; } @@ -417,11 +452,14 @@ function main(argv) { const doSearch = function(queryStr, filterCrate) { return parseAndSearch.doSearch(queryStr, filterCrate, opts["crate_name"]); }; + const getCorrections = function(queryStr, filterCrate) { + return parseAndSearch.getCorrections(queryStr, filterCrate, opts["crate_name"]); + }; if (opts["test_file"].length !== 0) { opts["test_file"].forEach(file => { process.stdout.write(`Testing ${file} ... `); - errors += runChecks(file, doSearch, parseAndSearch.parseQuery); + errors += runChecks(file, doSearch, parseAndSearch.parseQuery, getCorrections); }); } else if (opts["test_folder"].length !== 0) { fs.readdirSync(opts["test_folder"]).forEach(file => { @@ -430,7 +468,7 @@ function main(argv) { } process.stdout.write(`Testing ${file} ... `); errors += runChecks(path.join(opts["test_folder"], file), doSearch, - parseAndSearch.parseQuery); + parseAndSearch.parseQuery, getCorrections); }); } return errors > 0 ? 1 : 0; diff --git a/tests/run-make/raw-dylib-alt-calling-convention/lib.rs b/tests/run-make/raw-dylib-alt-calling-convention/lib.rs index 22f222c12c39b..dcb5fee9ecc76 100644 --- a/tests/run-make/raw-dylib-alt-calling-convention/lib.rs +++ b/tests/run-make/raw-dylib-alt-calling-convention/lib.rs @@ -1,5 +1,4 @@ #![feature(abi_vectorcall)] -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] #[repr(C)] #[derive(Clone)] diff --git a/tests/run-make/raw-dylib-c/lib.rs b/tests/run-make/raw-dylib-c/lib.rs index 5fb1204037c93..f17125f308c20 100644 --- a/tests/run-make/raw-dylib-c/lib.rs +++ b/tests/run-make/raw-dylib-c/lib.rs @@ -1,5 +1,3 @@ -#![feature(raw_dylib)] - #[link(name = "extern_1.dll", kind = "raw-dylib", modifiers = "+verbatim")] extern { fn extern_fn_1(); diff --git a/tests/run-make/raw-dylib-cross-compilation/lib.rs b/tests/run-make/raw-dylib-cross-compilation/lib.rs index 51bf2ec6b6e11..3338ac0a0b50f 100644 --- a/tests/run-make/raw-dylib-cross-compilation/lib.rs +++ b/tests/run-make/raw-dylib-cross-compilation/lib.rs @@ -1,4 +1,3 @@ -#![feature(raw_dylib)] #![feature(no_core, lang_items)] #![no_std] #![no_core] diff --git a/tests/run-make/raw-dylib-custom-dlltool/Makefile b/tests/run-make/raw-dylib-custom-dlltool/Makefile new file mode 100644 index 0000000000000..f5d5360a3fbe8 --- /dev/null +++ b/tests/run-make/raw-dylib-custom-dlltool/Makefile @@ -0,0 +1,11 @@ +# Test using -Cdlltool to change where raw-dylib looks for the dlltool binary. + +# only-windows +# only-gnu +# needs-dlltool + +include ../tools.mk + +all: + $(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs -Cdlltool=$(CURDIR)/script.cmd + $(DIFF) output.txt "$(TMPDIR)"/output.txt diff --git a/tests/run-make/raw-dylib-custom-dlltool/lib.rs b/tests/run-make/raw-dylib-custom-dlltool/lib.rs new file mode 100644 index 0000000000000..2f3f497a00de1 --- /dev/null +++ b/tests/run-make/raw-dylib-custom-dlltool/lib.rs @@ -0,0 +1,10 @@ +#[link(name = "extern_1", kind = "raw-dylib")] +extern { + fn extern_fn_1(); +} + +pub fn library_function() { + unsafe { + extern_fn_1(); + } +} diff --git a/tests/run-make/raw-dylib-custom-dlltool/output.txt b/tests/run-make/raw-dylib-custom-dlltool/output.txt new file mode 100644 index 0000000000000..6dd9466d26ddc --- /dev/null +++ b/tests/run-make/raw-dylib-custom-dlltool/output.txt @@ -0,0 +1 @@ +Called dlltool via script.cmd diff --git a/tests/run-make/raw-dylib-custom-dlltool/script.cmd b/tests/run-make/raw-dylib-custom-dlltool/script.cmd new file mode 100644 index 0000000000000..95f85c61c67d2 --- /dev/null +++ b/tests/run-make/raw-dylib-custom-dlltool/script.cmd @@ -0,0 +1,2 @@ +echo Called dlltool via script.cmd> %TMPDIR%\output.txt +dlltool.exe %* diff --git a/tests/run-make/raw-dylib-import-name-type/driver.rs b/tests/run-make/raw-dylib-import-name-type/driver.rs index 9a3cd9ebe1b4b..6c1c212f187b7 100644 --- a/tests/run-make/raw-dylib-import-name-type/driver.rs +++ b/tests/run-make/raw-dylib-import-name-type/driver.rs @@ -1,4 +1,3 @@ -#![feature(raw_dylib)] #![feature(abi_vectorcall)] #[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")] diff --git a/tests/run-make/raw-dylib-inline-cross-dylib/driver.rs b/tests/run-make/raw-dylib-inline-cross-dylib/driver.rs index f72ded7d9f638..0c3125be6f596 100644 --- a/tests/run-make/raw-dylib-inline-cross-dylib/driver.rs +++ b/tests/run-make/raw-dylib-inline-cross-dylib/driver.rs @@ -1,5 +1,3 @@ -#![feature(raw_dylib)] - extern crate raw_dylib_test; extern crate raw_dylib_test_wrapper; diff --git a/tests/run-make/raw-dylib-inline-cross-dylib/lib.rs b/tests/run-make/raw-dylib-inline-cross-dylib/lib.rs index 00c2c1c42d15f..4877cb80aea5e 100644 --- a/tests/run-make/raw-dylib-inline-cross-dylib/lib.rs +++ b/tests/run-make/raw-dylib-inline-cross-dylib/lib.rs @@ -1,5 +1,3 @@ -#![feature(raw_dylib)] - #[link(name = "extern_1", kind = "raw-dylib")] extern { fn extern_fn_1(); diff --git a/tests/run-make/raw-dylib-link-ordinal/lib.rs b/tests/run-make/raw-dylib-link-ordinal/lib.rs index bb25ac64c613b..1bbb45bbc7725 100644 --- a/tests/run-make/raw-dylib-link-ordinal/lib.rs +++ b/tests/run-make/raw-dylib-link-ordinal/lib.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "exporter", kind = "raw-dylib")] extern { #[link_ordinal(13)] diff --git a/tests/run-make/raw-dylib-stdcall-ordinal/lib.rs b/tests/run-make/raw-dylib-stdcall-ordinal/lib.rs index b7921396a0f4d..74c5c7f8250b2 100644 --- a/tests/run-make/raw-dylib-stdcall-ordinal/lib.rs +++ b/tests/run-make/raw-dylib-stdcall-ordinal/lib.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "exporter", kind = "raw-dylib")] extern "stdcall" { #[link_ordinal(15)] diff --git a/tests/rustdoc-gui/search-corrections.goml b/tests/rustdoc-gui/search-corrections.goml new file mode 100644 index 0000000000000..5d1b83b35c5ee --- /dev/null +++ b/tests/rustdoc-gui/search-corrections.goml @@ -0,0 +1,56 @@ +// ignore-tidy-linelength + +// Checks that the search tab result tell the user about corrections +// First, try a search-by-name +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +// Intentionally wrong spelling of "NotableStructWithLongName" +write: (".search-input", "NotableStructWithLongNamr") +// To be SURE that the search will be run. +press-key: 'Enter' +// Waiting for the search results to appear... +wait-for: "#search-tabs" + +// Corrections aren't shown on the "In Names" tab. +assert: "#search-tabs button.selected:first-child" +assert-css: (".search-corrections", { + "display": "none" +}) + +// Corrections do get shown on the "In Parameters" tab. +click: "#search-tabs button:nth-child(2)" +assert: "#search-tabs button.selected:nth-child(2)" +assert-css: (".search-corrections", { + "display": "block" +}) +assert-text: ( + ".search-corrections", + "Type \"notablestructwithlongnamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead." +) + +// Corrections do get shown on the "In Return Type" tab. +click: "#search-tabs button:nth-child(3)" +assert: "#search-tabs button.selected:nth-child(3)" +assert-css: (".search-corrections", { + "display": "block" +}) +assert-text: ( + ".search-corrections", + "Type \"notablestructwithlongnamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead." +) + +// Now, explicit return values +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +// Intentionally wrong spelling of "NotableStructWithLongName" +write: (".search-input", "-> NotableStructWithLongNamr") +// To be SURE that the search will be run. +press-key: 'Enter' +// Waiting for the search results to appear... +wait-for: "#search-tabs" + +assert-css: (".search-corrections", { + "display": "block" +}) +assert-text: ( + ".search-corrections", + "Type \"notablestructwithlongnamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead." +) diff --git a/tests/rustdoc-js/generics-trait.js b/tests/rustdoc-js/generics-trait.js index 7876622435b60..0e84751603ed6 100644 --- a/tests/rustdoc-js/generics-trait.js +++ b/tests/rustdoc-js/generics-trait.js @@ -1,9 +1,21 @@ +// exact-check + const QUERY = [ 'Result', + 'Result', + 'OtherThingxxxxxxxx', + 'OtherThingxxxxxxxy', +]; + +const CORRECTIONS = [ + null, + null, + null, 'OtherThingxxxxxxxx', ]; const EXPECTED = [ + // Result { 'in_args': [ { 'path': 'generics_trait', 'name': 'beta' }, @@ -12,6 +24,21 @@ const EXPECTED = [ { 'path': 'generics_trait', 'name': 'bet' }, ], }, + // Result + { + 'in_args': [], + 'returned': [], + }, + // OtherThingxxxxxxxx + { + 'in_args': [ + { 'path': 'generics_trait', 'name': 'alpha' }, + ], + 'returned': [ + { 'path': 'generics_trait', 'name': 'alef' }, + ], + }, + // OtherThingxxxxxxxy { 'in_args': [ { 'path': 'generics_trait', 'name': 'alpha' }, diff --git a/tests/ui/abi/foreign/foreign-fn-with-byval.rs b/tests/ui/abi/foreign/foreign-fn-with-byval.rs index f366b6ee1bdd5..e20ee0da45d9d 100644 --- a/tests/ui/abi/foreign/foreign-fn-with-byval.rs +++ b/tests/ui/abi/foreign/foreign-fn-with-byval.rs @@ -1,5 +1,5 @@ // run-pass -#![allow(improper_ctypes)] +#![allow(improper_ctypes, improper_ctypes_definitions)] // ignore-wasm32-bare no libc to test ffi with diff --git a/tests/ui/abi/issue-94223.rs b/tests/ui/abi/issue-94223.rs new file mode 100644 index 0000000000000..79d6b94031bc2 --- /dev/null +++ b/tests/ui/abi/issue-94223.rs @@ -0,0 +1,8 @@ +// check-pass +#![allow(improper_ctypes_definitions)] +#![crate_type = "lib"] + +// Check that computing the fn abi for `bad`, with a external ABI fn ptr that is not FFI-safe, does +// not ICE. + +pub fn bad(f: extern "C" fn([u8])) {} diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib-2.rs b/tests/ui/feature-gates/feature-gate-raw-dylib-2.rs deleted file mode 100644 index fc47a9061d3c0..0000000000000 --- a/tests/ui/feature-gates/feature-gate-raw-dylib-2.rs +++ /dev/null @@ -1,12 +0,0 @@ -// only-x86 -#[link(name = "foo")] -extern "C" { - #[link_ordinal(42)] - //~^ ERROR: `#[link_ordinal]` is unstable on x86 - fn foo(); - #[link_ordinal(5)] - //~^ ERROR: `#[link_ordinal]` is unstable on x86 - static mut imported_variable: i32; -} - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib-2.stderr b/tests/ui/feature-gates/feature-gate-raw-dylib-2.stderr deleted file mode 100644 index 0e900760d245e..0000000000000 --- a/tests/ui/feature-gates/feature-gate-raw-dylib-2.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0658]: `#[link_ordinal]` is unstable on x86 - --> $DIR/feature-gate-raw-dylib-2.rs:4:5 - | -LL | #[link_ordinal(42)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #58713 for more information - = help: add `#![feature(raw_dylib)]` to the crate attributes to enable - -error[E0658]: `#[link_ordinal]` is unstable on x86 - --> $DIR/feature-gate-raw-dylib-2.rs:7:5 - | -LL | #[link_ordinal(5)] - | ^^^^^^^^^^^^^^^^^^ - | - = note: see issue #58713 for more information - = help: add `#![feature(raw_dylib)]` to the crate attributes to enable - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs b/tests/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs deleted file mode 100644 index 295f502d6a3e5..0000000000000 --- a/tests/ui/feature-gates/feature-gate-raw-dylib-import-name-type.rs +++ /dev/null @@ -1,8 +0,0 @@ -// only-windows -// only-x86 -#[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")] -//~^ ERROR link kind `raw-dylib` is unstable on x86 -//~| ERROR import name type is unstable -extern "C" {} - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr b/tests/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr deleted file mode 100644 index d6b165b7610a5..0000000000000 --- a/tests/ui/feature-gates/feature-gate-raw-dylib-import-name-type.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0658]: link kind `raw-dylib` is unstable on x86 - --> $DIR/feature-gate-raw-dylib-import-name-type.rs:3:29 - | -LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")] - | ^^^^^^^^^^^ - | - = note: see issue #58713 for more information - = help: add `#![feature(raw_dylib)]` to the crate attributes to enable - -error[E0658]: import name type is unstable - --> $DIR/feature-gate-raw-dylib-import-name-type.rs:3:61 - | -LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")] - | ^^^^^^^^^^^ - | - = note: see issue #58713 for more information - = help: add `#![feature(raw_dylib)]` to the crate attributes to enable - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib.rs b/tests/ui/feature-gates/feature-gate-raw-dylib.rs deleted file mode 100644 index 291cca8fd2573..0000000000000 --- a/tests/ui/feature-gates/feature-gate-raw-dylib.rs +++ /dev/null @@ -1,7 +0,0 @@ -// only-windows -// only-x86 -#[link(name = "foo", kind = "raw-dylib")] -//~^ ERROR: link kind `raw-dylib` is unstable on x86 -extern "C" {} - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib.stderr b/tests/ui/feature-gates/feature-gate-raw-dylib.stderr deleted file mode 100644 index f02241e4908c0..0000000000000 --- a/tests/ui/feature-gates/feature-gate-raw-dylib.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: link kind `raw-dylib` is unstable on x86 - --> $DIR/feature-gate-raw-dylib.rs:3:29 - | -LL | #[link(name = "foo", kind = "raw-dylib")] - | ^^^^^^^^^^^ - | - = note: see issue #58713 for more information - = help: add `#![feature(raw_dylib)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/hashmap/hashmap-memory.rs b/tests/ui/hashmap/hashmap-memory.rs index 87f8b6ad5730b..bd364b349e263 100644 --- a/tests/ui/hashmap/hashmap-memory.rs +++ b/tests/ui/hashmap/hashmap-memory.rs @@ -1,5 +1,6 @@ // run-pass +#![allow(improper_ctypes_definitions)] #![allow(non_camel_case_types)] #![allow(dead_code)] #![allow(unused_mut)] diff --git a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs index ffeabe5c2edab..776006124dccf 100644 --- a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs +++ b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs @@ -5,10 +5,10 @@ use std::ops::Deref; pub trait Foo { - fn bar() -> impl Deref; + fn bar(self) -> impl Deref; } pub struct Foreign; impl Foo for Foreign { - fn bar() -> &'static () { &() } + fn bar(self) -> &'static () { &() } } diff --git a/tests/ui/impl-trait/in-trait/foreign-dyn-error.rs b/tests/ui/impl-trait/in-trait/foreign-dyn-error.rs new file mode 100644 index 0000000000000..ecb5e62c433a0 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/foreign-dyn-error.rs @@ -0,0 +1,8 @@ +// aux-build: rpitit.rs + +extern crate rpitit; + +fn main() { + let _: &dyn rpitit::Foo = todo!(); + //~^ ERROR the trait `Foo` cannot be made into an object +} diff --git a/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr b/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr new file mode 100644 index 0000000000000..6eef392c05f01 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr @@ -0,0 +1,15 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/foreign-dyn-error.rs:6:12 + | +LL | let _: &dyn rpitit::Foo = todo!(); + | ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/auxiliary/rpitit.rs:8:21 + | +LL | fn bar(self) -> impl Deref; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait cannot be made into an object because method `bar` references an `impl Trait` type in its return type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/impl-trait/in-trait/foreign.rs b/tests/ui/impl-trait/in-trait/foreign.rs index f4972d948b246..98417b343a11e 100644 --- a/tests/ui/impl-trait/in-trait/foreign.rs +++ b/tests/ui/impl-trait/in-trait/foreign.rs @@ -5,17 +5,18 @@ extern crate rpitit; +use rpitit::{Foo, Foreign}; use std::sync::Arc; // Implement an RPITIT from another crate. struct Local; -impl rpitit::Foo for Local { - fn bar() -> Arc { Arc::new(String::new()) } +impl Foo for Local { + fn bar(self) -> Arc { Arc::new(String::new()) } } fn main() { // Witness an RPITIT from another crate. - let &() = ::bar(); + let &() = Foreign.bar(); - let x: Arc = ::bar(); + let x: Arc = Local.bar(); } diff --git a/tests/ui/lint/lint-ctypes-94223.rs b/tests/ui/lint/lint-ctypes-94223.rs new file mode 100644 index 0000000000000..70dd2a71f2675 --- /dev/null +++ b/tests/ui/lint/lint-ctypes-94223.rs @@ -0,0 +1,42 @@ +#![crate_type = "lib"] +#![deny(improper_ctypes_definitions)] + +pub fn bad(f: extern "C" fn([u8])) {} +//~^ ERROR `extern` fn uses type `[u8]`, which is not FFI-safe + +pub fn bad_twice(f: Result) {} +//~^ ERROR `extern` fn uses type `[u8]`, which is not FFI-safe +//~^^ ERROR `extern` fn uses type `[u8]`, which is not FFI-safe + +struct BadStruct(extern "C" fn([u8])); +//~^ ERROR `extern` fn uses type `[u8]`, which is not FFI-safe + +enum BadEnum { + A(extern "C" fn([u8])), + //~^ ERROR `extern` fn uses type `[u8]`, which is not FFI-safe +} + +enum BadUnion { + A(extern "C" fn([u8])), + //~^ ERROR `extern` fn uses type `[u8]`, which is not FFI-safe +} + +type Foo = extern "C" fn([u8]); +//~^ ERROR `extern` fn uses type `[u8]`, which is not FFI-safe + +pub struct FfiUnsafe; + +#[allow(improper_ctypes_definitions)] +extern "C" fn f(_: FfiUnsafe) { + unimplemented!() +} + +pub static BAD: extern "C" fn(FfiUnsafe) = f; +//~^ ERROR `extern` fn uses type `FfiUnsafe`, which is not FFI-safe + +pub static BAD_TWICE: Result = Ok(f); +//~^ ERROR `extern` fn uses type `FfiUnsafe`, which is not FFI-safe +//~^^ ERROR `extern` fn uses type `FfiUnsafe`, which is not FFI-safe + +pub const BAD_CONST: extern "C" fn(FfiUnsafe) = f; +//~^ ERROR `extern` fn uses type `FfiUnsafe`, which is not FFI-safe diff --git a/tests/ui/lint/lint-ctypes-94223.stderr b/tests/ui/lint/lint-ctypes-94223.stderr new file mode 100644 index 0000000000000..49e64ed5140c2 --- /dev/null +++ b/tests/ui/lint/lint-ctypes-94223.stderr @@ -0,0 +1,126 @@ +error: `extern` fn uses type `[u8]`, which is not FFI-safe + --> $DIR/lint-ctypes-94223.rs:4:15 + | +LL | pub fn bad(f: extern "C" fn([u8])) {} + | ^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider using a raw pointer instead + = note: slices have no C equivalent +note: the lint level is defined here + --> $DIR/lint-ctypes-94223.rs:2:9 + | +LL | #![deny(improper_ctypes_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `extern` fn uses type `[u8]`, which is not FFI-safe + --> $DIR/lint-ctypes-94223.rs:7:28 + | +LL | pub fn bad_twice(f: Result) {} + | ^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider using a raw pointer instead + = note: slices have no C equivalent + +error: `extern` fn uses type `[u8]`, which is not FFI-safe + --> $DIR/lint-ctypes-94223.rs:7:49 + | +LL | pub fn bad_twice(f: Result) {} + | ^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider using a raw pointer instead + = note: slices have no C equivalent + +error: `extern` fn uses type `[u8]`, which is not FFI-safe + --> $DIR/lint-ctypes-94223.rs:11:18 + | +LL | struct BadStruct(extern "C" fn([u8])); + | ^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider using a raw pointer instead + = note: slices have no C equivalent + +error: `extern` fn uses type `[u8]`, which is not FFI-safe + --> $DIR/lint-ctypes-94223.rs:15:7 + | +LL | A(extern "C" fn([u8])), + | ^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider using a raw pointer instead + = note: slices have no C equivalent + +error: `extern` fn uses type `[u8]`, which is not FFI-safe + --> $DIR/lint-ctypes-94223.rs:20:7 + | +LL | A(extern "C" fn([u8])), + | ^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider using a raw pointer instead + = note: slices have no C equivalent + +error: `extern` fn uses type `[u8]`, which is not FFI-safe + --> $DIR/lint-ctypes-94223.rs:24:12 + | +LL | type Foo = extern "C" fn([u8]); + | ^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider using a raw pointer instead + = note: slices have no C equivalent + +error: `extern` fn uses type `FfiUnsafe`, which is not FFI-safe + --> $DIR/lint-ctypes-94223.rs:34:17 + | +LL | pub static BAD: extern "C" fn(FfiUnsafe) = f; + | ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/lint-ctypes-94223.rs:27:1 + | +LL | pub struct FfiUnsafe; + | ^^^^^^^^^^^^^^^^^^^^ + +error: `extern` fn uses type `FfiUnsafe`, which is not FFI-safe + --> $DIR/lint-ctypes-94223.rs:37:30 + | +LL | pub static BAD_TWICE: Result = Ok(f); + | ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/lint-ctypes-94223.rs:27:1 + | +LL | pub struct FfiUnsafe; + | ^^^^^^^^^^^^^^^^^^^^ + +error: `extern` fn uses type `FfiUnsafe`, which is not FFI-safe + --> $DIR/lint-ctypes-94223.rs:37:56 + | +LL | pub static BAD_TWICE: Result = Ok(f); + | ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/lint-ctypes-94223.rs:27:1 + | +LL | pub struct FfiUnsafe; + | ^^^^^^^^^^^^^^^^^^^^ + +error: `extern` fn uses type `FfiUnsafe`, which is not FFI-safe + --> $DIR/lint-ctypes-94223.rs:41:22 + | +LL | pub const BAD_CONST: extern "C" fn(FfiUnsafe) = f; + | ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/lint-ctypes-94223.rs:27:1 + | +LL | pub struct FfiUnsafe; + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 11 previous errors + diff --git a/tests/ui/rfc-2627-raw-dylib/dlltool-failed.rs b/tests/ui/rfc-2627-raw-dylib/dlltool-failed.rs new file mode 100644 index 0000000000000..d7a418959bf51 --- /dev/null +++ b/tests/ui/rfc-2627-raw-dylib/dlltool-failed.rs @@ -0,0 +1,19 @@ +// Tests that dlltool failing to generate an import library will raise an error. + +// only-gnu +// only-windows +// needs-dlltool +// compile-flags: --crate-type lib --emit link +// normalize-stderr-test: "[^ ']*/dlltool.exe" -> "$$DLLTOOL" +// normalize-stderr-test: "[^ ]*/foo.def" -> "$$DEF_FILE" +#[link(name = "foo", kind = "raw-dylib")] +extern "C" { + // `@1` is an invalid name to export, as it usually indicates that something + // is being exported via ordinal. + #[link_name = "@1"] + fn f(x: i32); +} + +pub fn lib_main() { + unsafe { f(42); } +} diff --git a/tests/ui/rfc-2627-raw-dylib/dlltool-failed.stderr b/tests/ui/rfc-2627-raw-dylib/dlltool-failed.stderr new file mode 100644 index 0000000000000..020ac6a2b670b --- /dev/null +++ b/tests/ui/rfc-2627-raw-dylib/dlltool-failed.stderr @@ -0,0 +1,5 @@ +error: Dlltool could not create import library: + $DLLTOOL: Syntax error in def file $DEF_FILE:1 + +error: aborting due to previous error + diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs b/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs index 22d57f8bedddc..7bc44d65be9e5 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.rs @@ -1,7 +1,5 @@ // only-windows // only-x86 -#![feature(raw_dylib)] - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] //~^ ERROR import name type must be of the form `import_name_type = "string"` extern "C" { } diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr b/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr index 0e95fec29d257..fb70b987fc7d9 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr @@ -1,5 +1,5 @@ error: import name type must be of the form `import_name_type = "string"` - --> $DIR/import-name-type-invalid-format.rs:5:42 + --> $DIR/import-name-type-invalid-format.rs:3:42 | LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs b/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs index 7ccb0082fb976..b96f61a26da8b 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.rs @@ -1,8 +1,6 @@ // ignore-tidy-linelength // only-windows // only-x86 -#![feature(raw_dylib)] - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")] //~^ ERROR multiple `import_name_type` arguments in a single `#[link]` attribute extern "C" { } diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr b/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr index 7c0e0be911f73..9533061892fee 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-multiple.stderr @@ -1,5 +1,5 @@ error: multiple `import_name_type` arguments in a single `#[link]` attribute - --> $DIR/import-name-type-multiple.rs:6:74 + --> $DIR/import-name-type-multiple.rs:4:74 | LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs b/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs index f728a578d3b8a..067e82a17fdc5 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.rs @@ -1,7 +1,5 @@ // only-windows // only-x86 -#![feature(raw_dylib)] - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] //~^ ERROR unknown import name type `unknown`, expected one of: decorated, noprefix, undecorated extern "C" { } diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr b/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr index 2b299f2fea316..2bce9758e997c 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr @@ -1,5 +1,5 @@ error: unknown import name type `unknown`, expected one of: decorated, noprefix, undecorated - --> $DIR/import-name-type-unknown-value.rs:5:42 + --> $DIR/import-name-type-unknown-value.rs:3:42 | LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs b/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs index ae9207864a2ae..34e907bde839a 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs @@ -1,7 +1,5 @@ // only-windows // only-x86 -#![feature(raw_dylib)] - #[link(name = "foo", import_name_type = "decorated")] //~^ ERROR import name type can only be used with link kind `raw-dylib` extern "C" { } diff --git a/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr b/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr index 5898cd875a1c8..75cadc471c437 100644 --- a/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr +++ b/tests/ui/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr @@ -1,11 +1,11 @@ error: import name type can only be used with link kind `raw-dylib` - --> $DIR/import-name-type-unsupported-link-kind.rs:5:22 + --> $DIR/import-name-type-unsupported-link-kind.rs:3:22 | LL | #[link(name = "foo", import_name_type = "decorated")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: import name type can only be used with link kind `raw-dylib` - --> $DIR/import-name-type-unsupported-link-kind.rs:9:39 + --> $DIR/import-name-type-unsupported-link-kind.rs:7:39 | LL | #[link(name = "bar", kind = "static", import_name_type = "decorated")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/invalid-dlltool.rs b/tests/ui/rfc-2627-raw-dylib/invalid-dlltool.rs new file mode 100644 index 0000000000000..a07be9d92b4ed --- /dev/null +++ b/tests/ui/rfc-2627-raw-dylib/invalid-dlltool.rs @@ -0,0 +1,13 @@ +// Tests that failing to run dlltool will raise an error. + +// only-gnu +// only-windows +// compile-flags: --crate-type lib --emit link -Cdlltool=does_not_exit.exe +#[link(name = "foo", kind = "raw-dylib")] +extern "C" { + fn f(x: i32); +} + +pub fn lib_main() { + unsafe { f(42); } +} diff --git a/tests/ui/rfc-2627-raw-dylib/invalid-dlltool.stderr b/tests/ui/rfc-2627-raw-dylib/invalid-dlltool.stderr new file mode 100644 index 0000000000000..3ae901e0dbc94 --- /dev/null +++ b/tests/ui/rfc-2627-raw-dylib/invalid-dlltool.stderr @@ -0,0 +1,4 @@ +error: Error calling dlltool 'does_not_exit.exe': program not found + +error: aborting due to previous error + diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs index 1a128c87a0c30..b04c2facbcdf3 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name="foo")] extern "C" { #[link_name="foo"] diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr index 481a06d2797d5..f1e54d37827c0 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-and-name.stderr @@ -1,11 +1,11 @@ error: cannot use `#[link_name]` with `#[link_ordinal]` - --> $DIR/link-ordinal-and-name.rs:6:5 + --> $DIR/link-ordinal-and-name.rs:4:5 | LL | #[link_ordinal(42)] | ^^^^^^^^^^^^^^^^^^^ error: cannot use `#[link_name]` with `#[link_ordinal]` - --> $DIR/link-ordinal-and-name.rs:10:5 + --> $DIR/link-ordinal-and-name.rs:8:5 | LL | #[link_ordinal(5)] | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs index 7c8da050cf624..9b7e8d70743b7 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "foo")] extern "C" { #[link_ordinal("JustMonika")] diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr index 55cdcad75a4ad..6341e57a0be53 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr @@ -1,5 +1,5 @@ error: illegal ordinal format in `link_ordinal` - --> $DIR/link-ordinal-invalid-format.rs:5:5 + --> $DIR/link-ordinal-invalid-format.rs:3:5 | LL | #[link_ordinal("JustMonika")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[link_ordinal("JustMonika")] = note: an unsuffixed integer value, e.g., `1`, is expected error: illegal ordinal format in `link_ordinal` - --> $DIR/link-ordinal-invalid-format.rs:8:5 + --> $DIR/link-ordinal-invalid-format.rs:6:5 | LL | #[link_ordinal("JustMonika")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs index 9feed39411046..6b8cd49566dfe 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "foo")] extern "C" { #[link_ordinal()] diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr index 853cdad8c1c54..1b04bb228e76a 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr @@ -1,5 +1,5 @@ error: incorrect number of arguments to `#[link_ordinal]` - --> $DIR/link-ordinal-missing-argument.rs:5:5 + --> $DIR/link-ordinal-missing-argument.rs:3:5 | LL | #[link_ordinal()] | ^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[link_ordinal()] = note: the attribute requires exactly one argument error: incorrect number of arguments to `#[link_ordinal]` - --> $DIR/link-ordinal-missing-argument.rs:8:5 + --> $DIR/link-ordinal-missing-argument.rs:6:5 | LL | #[link_ordinal()] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.rs index 631c363d4ba15..8842cb944045f 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.rs @@ -1,6 +1,4 @@ // only-windows -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "foo", kind = "raw-dylib")] extern "C" { #[link_ordinal(1)] //~ ERROR multiple `link_ordinal` attributes diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.stderr index c0453d2bf0118..2e6cf3761c2f0 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-multiple.stderr @@ -1,23 +1,23 @@ error: multiple `link_ordinal` attributes - --> $DIR/link-ordinal-multiple.rs:6:5 + --> $DIR/link-ordinal-multiple.rs:4:5 | LL | #[link_ordinal(1)] | ^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/link-ordinal-multiple.rs:7:5 + --> $DIR/link-ordinal-multiple.rs:5:5 | LL | #[link_ordinal(2)] | ^^^^^^^^^^^^^^^^^^ error: multiple `link_ordinal` attributes - --> $DIR/link-ordinal-multiple.rs:9:5 + --> $DIR/link-ordinal-multiple.rs:7:5 | LL | #[link_ordinal(1)] | ^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/link-ordinal-multiple.rs:10:5 + --> $DIR/link-ordinal-multiple.rs:8:5 | LL | #[link_ordinal(2)] | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs index 54e614164b3a5..f33a3d62e2688 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link_ordinal(123)] //~^ ERROR attribute should be applied to a foreign function or static struct Foo {} diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr index ec4104fbe5000..8f279508720ce 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr @@ -1,17 +1,17 @@ error: attribute should be applied to a foreign function or static - --> $DIR/link-ordinal-not-foreign-fn.rs:3:1 + --> $DIR/link-ordinal-not-foreign-fn.rs:1:1 | LL | #[link_ordinal(123)] | ^^^^^^^^^^^^^^^^^^^^ error: attribute should be applied to a foreign function or static - --> $DIR/link-ordinal-not-foreign-fn.rs:7:1 + --> $DIR/link-ordinal-not-foreign-fn.rs:5:1 | LL | #[link_ordinal(123)] | ^^^^^^^^^^^^^^^^^^^^ error: attribute should be applied to a foreign function or static - --> $DIR/link-ordinal-not-foreign-fn.rs:11:1 + --> $DIR/link-ordinal-not-foreign-fn.rs:9:1 | LL | #[link_ordinal(42)] | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs index 46731581ebcb0..9d741630fc9da 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "foo")] extern "C" { #[link_ordinal(72436)] diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr index fef6de6aedfe4..811145e77ee46 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-large.stderr @@ -1,5 +1,5 @@ error: ordinal value in `link_ordinal` is too large: `72436` - --> $DIR/link-ordinal-too-large.rs:5:5 + --> $DIR/link-ordinal-too-large.rs:3:5 | LL | #[link_ordinal(72436)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[link_ordinal(72436)] = note: the value may not exceed `u16::MAX` error: ordinal value in `link_ordinal` is too large: `72436` - --> $DIR/link-ordinal-too-large.rs:8:5 + --> $DIR/link-ordinal-too-large.rs:6:5 | LL | #[link_ordinal(72436)] | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs index 71e0ac9f3ee4b..9988115fd8b0d 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "foo")] extern "C" { #[link_ordinal(3, 4)] diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr index 7e0fcd845cbde..d5ce8aff34f20 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr @@ -1,5 +1,5 @@ error: incorrect number of arguments to `#[link_ordinal]` - --> $DIR/link-ordinal-too-many-arguments.rs:5:5 + --> $DIR/link-ordinal-too-many-arguments.rs:3:5 | LL | #[link_ordinal(3, 4)] | ^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[link_ordinal(3, 4)] = note: the attribute requires exactly one argument error: incorrect number of arguments to `#[link_ordinal]` - --> $DIR/link-ordinal-too-many-arguments.rs:8:5 + --> $DIR/link-ordinal-too-many-arguments.rs:6:5 | LL | #[link_ordinal(3, 4)] | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs b/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs index 329c93fc19637..14e915d602aaa 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs @@ -1,5 +1,3 @@ -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] - #[link(name = "foo")] extern "C" { #[link_ordinal(3)] diff --git a/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr b/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr index 5fbffbda570af..200b8f6287465 100644 --- a/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr +++ b/tests/ui/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr @@ -1,11 +1,11 @@ error: `#[link_ordinal]` is only supported if link kind is `raw-dylib` - --> $DIR/link-ordinal-unsupported-link-kind.rs:5:5 + --> $DIR/link-ordinal-unsupported-link-kind.rs:3:5 | LL | #[link_ordinal(3)] | ^^^^^^^^^^^^^^^^^^ error: `#[link_ordinal]` is only supported if link kind is `raw-dylib` - --> $DIR/link-ordinal-unsupported-link-kind.rs:12:5 + --> $DIR/link-ordinal-unsupported-link-kind.rs:10:5 | LL | #[link_ordinal(3)] | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/multiple-declarations.rs b/tests/ui/rfc-2627-raw-dylib/multiple-declarations.rs index 6542faad26412..b4173f3b60bce 100644 --- a/tests/ui/rfc-2627-raw-dylib/multiple-declarations.rs +++ b/tests/ui/rfc-2627-raw-dylib/multiple-declarations.rs @@ -2,7 +2,6 @@ // only-windows // compile-flags: --crate-type lib --emit link #![allow(clashing_extern_declarations)] -#![feature(raw_dylib)] #[link(name = "foo", kind = "raw-dylib")] extern "C" { fn f(x: i32); diff --git a/tests/ui/rfc-2627-raw-dylib/multiple-declarations.stderr b/tests/ui/rfc-2627-raw-dylib/multiple-declarations.stderr index c6808bec7b5c5..5101084054882 100644 --- a/tests/ui/rfc-2627-raw-dylib/multiple-declarations.stderr +++ b/tests/ui/rfc-2627-raw-dylib/multiple-declarations.stderr @@ -1,5 +1,5 @@ error: multiple declarations of external function `f` from library `foo.dll` have different calling conventions - --> $DIR/multiple-declarations.rs:14:9 + --> $DIR/multiple-declarations.rs:13:9 | LL | fn f(x: i32); | ^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs b/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs index 4efffbd532e13..d4c6658a33024 100644 --- a/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs +++ b/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs @@ -1,6 +1,5 @@ // ignore-windows // compile-flags: --crate-type lib -#![cfg_attr(target_arch = "x86", feature(raw_dylib))] #[link(name = "foo", kind = "raw-dylib")] //~^ ERROR: link kind `raw-dylib` is only supported on Windows targets extern "C" {} diff --git a/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr b/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr index 14e791f1fb9a1..b635a09afba4e 100644 --- a/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr +++ b/tests/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr @@ -1,5 +1,5 @@ error[E0455]: link kind `raw-dylib` is only supported on Windows targets - --> $DIR/raw-dylib-windows-only.rs:4:29 + --> $DIR/raw-dylib-windows-only.rs:3:29 | LL | #[link(name = "foo", kind = "raw-dylib")] | ^^^^^^^^^^^