diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 9a28428cb62c3..2f5a864d70eaf 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -97,7 +97,9 @@ impl<'a> ArchiveBuilder for LlvmArchiveBuilder<'a> { fn build(mut self: Box, output: &Path) -> bool { match self.build_with_llvm(output) { Ok(any_members) => any_members, - Err(e) => self.sess.dcx().emit_fatal(ArchiveBuildFailure { error: e }), + Err(error) => { + self.sess.dcx().emit_fatal(ArchiveBuildFailure { path: output.to_owned(), error }) + } } } } diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 000fe2e3ce0f5..57d789aef80ca 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -4,8 +4,7 @@ codegen_ssa_add_native_library = failed to add native library {$library_path}: { codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {$error} -codegen_ssa_archive_build_failure = - failed to build archive: {$error} +codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error} codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing failure memory ordering @@ -198,7 +197,7 @@ codegen_ssa_read_file = failed to read file: {$message} codegen_ssa_repair_vs_build_tools = the Visual Studio build tools may need to be repaired using the Visual Studio installer -codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib: {$error} +codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib at `{$path}`: {$error} codegen_ssa_rlib_incompatible_dependency_formats = `{$ty1}` and `{$ty2}` do not have equivalent dependency formats (`{$list1}` vs `{$list2}`) diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index fd39ef2649bf5..dd9507036158f 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -207,7 +207,9 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> { let sess = self.sess; match self.build_inner(output) { Ok(any_members) => any_members, - Err(e) => sess.dcx().emit_fatal(ArchiveBuildFailure { error: e }), + Err(error) => { + sess.dcx().emit_fatal(ArchiveBuildFailure { path: output.to_owned(), error }) + } } } } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 55662bfc2cf37..7d457526380d9 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2911,7 +2911,8 @@ fn add_static_crate( false }), ) { - sess.dcx().emit_fatal(errors::RlibArchiveBuildFailure { error }); + sess.dcx() + .emit_fatal(errors::RlibArchiveBuildFailure { path: cratepath.clone(), error }); } if archive.build(&dst) { link_upstream(&dst); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 46d7cfe87e6ac..2d1eae630cf16 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -500,6 +500,7 @@ pub struct UnableToWriteDebuggerVisualizer { #[derive(Diagnostic)] #[diag(codegen_ssa_rlib_archive_build_failure)] pub struct RlibArchiveBuildFailure { + pub path: PathBuf, pub error: Error, } @@ -557,6 +558,7 @@ pub struct UnsupportedLinkSelfContained; #[diag(codegen_ssa_archive_build_failure)] // Public for rustc_codegen_llvm::back::archive pub struct ArchiveBuildFailure { + pub path: PathBuf, pub error: std::io::Error, } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index a5e25b917dc5b..8c99b1f444766 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -544,7 +544,13 @@ fn resolver_for_lowering_raw<'tcx>( let arenas = Resolver::arenas(); let _ = tcx.registered_tools(()); // Uses `crate_for_resolver`. let (krate, pre_configured_attrs) = tcx.crate_for_resolver(()).steal(); - let mut resolver = Resolver::new(tcx, &pre_configured_attrs, krate.spans.inner_span, &arenas); + let mut resolver = Resolver::new( + tcx, + &pre_configured_attrs, + krate.spans.inner_span, + krate.spans.inject_use_span, + &arenas, + ); let krate = configure_and_expand(krate, &pre_configured_attrs, &mut resolver); // Make sure we don't mutate the cstore from here on. diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a58c57041f830..07c0a116bfeaf 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -207,37 +207,34 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_safe_intrinsic] => { self.check_rustc_safe_intrinsic(hir_id, attr, span, target) } - _ => true, - }; - - // lint-only checks - match attr.name_or_empty() { - sym::cold => self.check_cold(hir_id, attr, span, target), - sym::link => self.check_link(hir_id, attr, span, target), - sym::link_name => self.check_link_name(hir_id, attr, span, target), - sym::link_section => self.check_link_section(hir_id, attr, span, target), - sym::no_mangle => self.check_no_mangle(hir_id, attr, span, target), - sym::deprecated => self.check_deprecated(hir_id, attr, span, target), - sym::macro_use | sym::macro_escape => self.check_macro_use(hir_id, attr, target), - sym::path => self.check_generic_attr(hir_id, attr, target, Target::Mod), - sym::macro_export => self.check_macro_export(hir_id, attr, target), - sym::ignore | sym::should_panic => { + [sym::cold] => self.check_cold(hir_id, attr, span, target), + [sym::link] => self.check_link(hir_id, attr, span, target), + [sym::link_name] => self.check_link_name(hir_id, attr, span, target), + [sym::link_section] => self.check_link_section(hir_id, attr, span, target), + [sym::no_mangle] => self.check_no_mangle(hir_id, attr, span, target), + [sym::deprecated] => self.check_deprecated(hir_id, attr, span, target), + [sym::macro_use] | [sym::macro_escape] => { + self.check_macro_use(hir_id, attr, target) + } + [sym::path] => self.check_generic_attr(hir_id, attr, target, Target::Mod), + [sym::macro_export] => self.check_macro_export(hir_id, attr, target), + [sym::ignore] | [sym::should_panic] => { self.check_generic_attr(hir_id, attr, target, Target::Fn) } - sym::automatically_derived => { + [sym::automatically_derived] => { self.check_generic_attr(hir_id, attr, target, Target::Impl) } - sym::no_implicit_prelude => { + [sym::no_implicit_prelude] => { self.check_generic_attr(hir_id, attr, target, Target::Mod) } - sym::rustc_object_lifetime_default => self.check_object_lifetime_default(hir_id), - sym::proc_macro => { + [sym::rustc_object_lifetime_default] => self.check_object_lifetime_default(hir_id), + [sym::proc_macro] => { self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike) } - sym::proc_macro_attribute => { + [sym::proc_macro_attribute] => { self.check_proc_macro(hir_id, target, ProcMacroKind::Attribute); } - sym::proc_macro_derive => { + [sym::proc_macro_derive] => { self.check_generic_attr(hir_id, attr, target, Target::Fn); self.check_proc_macro(hir_id, target, ProcMacroKind::Derive) } @@ -297,7 +294,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } /// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl. - fn check_do_not_recommend(&self, attr_span: Span, hir_id: HirId, target: Target) -> bool { + fn check_do_not_recommend(&self, attr_span: Span, hir_id: HirId, target: Target) { if !matches!(target, Target::Impl) { self.tcx.emit_node_span_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, @@ -306,16 +303,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { errors::IncorrectDoNotRecommendLocation, ); } - true } /// Checks if `#[diagnostic::on_unimplemented]` is applied to a trait definition - fn check_diagnostic_on_unimplemented( - &self, - attr_span: Span, - hir_id: HirId, - target: Target, - ) -> bool { + fn check_diagnostic_on_unimplemented(&self, attr_span: Span, hir_id: HirId, target: Target) { if !matches!(target, Target::Trait) { self.tcx.emit_node_span_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, @@ -324,68 +315,60 @@ impl<'tcx> CheckAttrVisitor<'tcx> { DiagnosticOnUnimplementedOnlyForTraits, ); } - true } - /// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid. - fn check_inline(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool { + /// Checks if an `#[inline]` is applied to a function or a closure. + fn check_inline(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { match target { Target::Fn | Target::Closure - | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, + | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {} Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { self.tcx.emit_node_span_lint( UNUSED_ATTRIBUTES, hir_id, attr.span, errors::IgnoredInlineAttrFnProto, - ); - true + ) } // FIXME(#65833): We permit associated consts to have an `#[inline]` attribute with // just a lint, because we previously erroneously allowed it and some crates used it // accidentally, to be compatible with crates depending on them, we can't throw an // error here. - Target::AssocConst => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredInlineAttrConstants, - ); - true - } + Target::AssocConst => self.tcx.emit_node_span_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr.span, + errors::IgnoredInlineAttrConstants, + ), // FIXME(#80564): Same for fields, arms, and macro defs Target::Field | Target::Arm | Target::MacroDef => { - self.inline_attr_str_error_with_macro_def(hir_id, attr, "inline"); - true + self.inline_attr_str_error_with_macro_def(hir_id, attr, "inline") } _ => { self.dcx().emit_err(errors::InlineNotFnOrClosure { attr_span: attr.span, defn_span: span, }); - false } } } /// Checks that `#[coverage(..)]` is applied to a function/closure/method, /// or to an impl block or module. - fn check_coverage(&self, attr: &Attribute, span: Span, target: Target) -> bool { + fn check_coverage(&self, attr: &Attribute, span: Span, target: Target) { match target { Target::Fn | Target::Closure | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) | Target::Impl - | Target::Mod => true, + | Target::Mod => {} _ => { self.dcx().emit_err(errors::CoverageNotFnOrClosure { attr_span: attr.span, defn_span: span, }); - false } } } @@ -418,7 +401,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { span: Span, target: Target, attrs: &[Attribute], - ) -> bool { + ) { // many attributes don't make sense in combination with #[naked]. // Notable attributes that are incompatible with `#[naked]` are: // @@ -468,19 +451,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr: other_attr.name_or_empty(), }); - return false; + return; } } - - true } // FIXME(#80564): We permit struct fields, match arms and macro defs to have an // `#[naked]` attribute with just a lint, because we previously // erroneously allowed it and some crates used it accidentally, to be compatible // with crates depending on them, we can't throw an error here. Target::Field | Target::Arm | Target::MacroDef => { - self.inline_attr_str_error_with_macro_def(hir_id, attr, "naked"); - true + self.inline_attr_str_error_with_macro_def(hir_id, attr, "naked") } _ => { self.dcx().emit_err(errors::AttrShouldBeAppliedToFn { @@ -488,7 +468,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { defn_span: span, on_crate: hir_id == CRATE_HIR_ID, }); - false } } } @@ -500,17 +479,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr: &Attribute, span: Span, target: Target, - ) -> bool { + ) { match target { Target::Fn - | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, + | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {} _ => { self.dcx().emit_err(errors::AttrShouldBeAppliedToFn { attr_span: attr.span, defn_span: span, on_crate: hir_id == CRATE_HIR_ID, }); - false } } } @@ -536,19 +514,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } /// Checks if `#[collapse_debuginfo]` is applied to a macro. - fn check_collapse_debuginfo(&self, attr: &Attribute, span: Span, target: Target) -> bool { + fn check_collapse_debuginfo(&self, attr: &Attribute, span: Span, target: Target) { match target { - Target::MacroDef => true, + Target::MacroDef => {} _ => { self.tcx .dcx() .emit_err(errors::CollapseDebuginfo { attr_span: attr.span, defn_span: span }); - false } } } - /// Checks if a `#[track_caller]` is applied to a function. Returns `true` if valid. + /// Checks if a `#[track_caller]` is applied to a function. fn check_track_caller( &self, hir_id: HirId, @@ -556,7 +533,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attrs: &[Attribute], span: Span, target: Target, - ) -> bool { + ) { match target { Target::Fn => { // `#[track_caller]` is not valid on weak lang items because they are called via @@ -572,12 +549,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { name: lang_item, sig_span: sig.span, }); - false - } else { - true } } - Target::Method(..) | Target::ForeignFn | Target::Closure => true, + Target::Method(..) | Target::ForeignFn | Target::Closure => {} // FIXME(#80564): We permit struct fields, match arms and macro defs to have an // `#[track_caller]` attribute with just a lint, because we previously // erroneously allowed it and some crates used it accidentally, to be compatible @@ -586,7 +560,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { for attr in attrs { self.inline_attr_str_error_with_macro_def(hir_id, attr, "track_caller"); } - true } _ => { self.dcx().emit_err(errors::TrackedCallerWrongLocation { @@ -594,62 +567,51 @@ impl<'tcx> CheckAttrVisitor<'tcx> { defn_span: span, on_crate: hir_id == CRATE_HIR_ID, }); - false } } } - /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid. - fn check_non_exhaustive( - &self, - hir_id: HirId, - attr: &Attribute, - span: Span, - target: Target, - ) -> bool { + /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. + fn check_non_exhaustive(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { match target { - Target::Struct | Target::Enum | Target::Variant => true, + Target::Struct | Target::Enum | Target::Variant => {} // FIXME(#80564): We permit struct fields, match arms and macro defs to have an // `#[non_exhaustive]` attribute with just a lint, because we previously // erroneously allowed it and some crates used it accidentally, to be compatible // with crates depending on them, we can't throw an error here. Target::Field | Target::Arm | Target::MacroDef => { self.inline_attr_str_error_with_macro_def(hir_id, attr, "non_exhaustive"); - true } _ => { self.dcx().emit_err(errors::NonExhaustiveWrongLocation { attr_span: attr.span, defn_span: span, }); - false } } } - /// Checks if the `#[marker]` attribute on an `item` is valid. Returns `true` if valid. - fn check_marker(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool { + /// Checks if the `#[marker]` attribute on an `item` is valid. + fn check_marker(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { match target { - Target::Trait => true, + Target::Trait => {} // FIXME(#80564): We permit struct fields, match arms and macro defs to have an // `#[marker]` attribute with just a lint, because we previously // erroneously allowed it and some crates used it accidentally, to be compatible // with crates depending on them, we can't throw an error here. Target::Field | Target::Arm | Target::MacroDef => { self.inline_attr_str_error_with_macro_def(hir_id, attr, "marker"); - true } _ => { self.dcx().emit_err(errors::AttrShouldBeAppliedToTrait { attr_span: attr.span, defn_span: span, }); - false } } } - /// Checks if the `#[target_feature]` attribute on `item` is valid. Returns `true` if valid. + /// Checks if the `#[target_feature]` attribute on `item` is valid. fn check_target_feature( &self, hir_id: HirId, @@ -657,7 +619,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { span: Span, target: Target, attrs: &[Attribute], - ) -> bool { + ) { match target { Target::Fn => { // `#[target_feature]` is not allowed in lang items. @@ -674,12 +636,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { name: lang_item, sig_span: sig.span, }); - false - } else { - true } } - Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, + Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {} // FIXME: #[target_feature] was previously erroneously allowed on statements and some // crates used this, so only emit a warning. Target::Statement => { @@ -689,7 +648,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr.span, errors::TargetFeatureOnStatement, ); - true } // FIXME(#80564): We permit struct fields, match arms and macro defs to have an // `#[target_feature]` attribute with just a lint, because we previously @@ -697,7 +655,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // with crates depending on them, we can't throw an error here. Target::Field | Target::Arm | Target::MacroDef => { self.inline_attr_str_error_with_macro_def(hir_id, attr, "target_feature"); - true } _ => { self.dcx().emit_err(errors::AttrShouldBeAppliedToFn { @@ -705,21 +662,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> { defn_span: span, on_crate: hir_id == CRATE_HIR_ID, }); - false } } } - /// Checks if the `#[thread_local]` attribute on `item` is valid. Returns `true` if valid. - fn check_thread_local(&self, attr: &Attribute, span: Span, target: Target) -> bool { + /// Checks if the `#[thread_local]` attribute on `item` is valid. + fn check_thread_local(&self, attr: &Attribute, span: Span, target: Target) { match target { - Target::ForeignStatic | Target::Static => true, + Target::ForeignStatic | Target::Static => {} _ => { self.dcx().emit_err(errors::AttrShouldBeAppliedToStatic { attr_span: attr.span, defn_span: span, }); - false } } } @@ -736,14 +691,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> { target: Target, is_list: bool, aliases: &mut FxHashMap, - ) -> bool { + ) { let tcx = self.tcx; let span = meta.name_value_literal_span().unwrap_or_else(|| meta.span()); let attr_str = &format!("`#[doc(alias{})]`", if is_list { "(\"...\")" } else { " = \"...\"" }); if doc_alias == kw::Empty { tcx.dcx().emit_err(errors::DocAliasEmpty { span, attr_str }); - return false; + return; } let doc_alias_str = doc_alias.as_str(); @@ -752,11 +707,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { .find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' ')) { tcx.dcx().emit_err(errors::DocAliasBadChar { span, attr_str, char_: c }); - return false; + return; } if doc_alias_str.starts_with(' ') || doc_alias_str.ends_with(' ') { tcx.dcx().emit_err(errors::DocAliasStartEnd { span, attr_str }); - return false; + return; } let span = meta.span(); @@ -781,7 +736,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } // we check the validity of params elsewhere - Target::Param => return false, + Target::Param => return, Target::Expression | Target::Statement | Target::Arm @@ -814,12 +769,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | Target::ExprField => None, } { tcx.dcx().emit_err(errors::DocAliasBadLocation { span, attr_str, location }); - return false; + return; } let item_name = self.tcx.hir().name(hir_id); if item_name == doc_alias { tcx.dcx().emit_err(errors::DocAliasNotAnAlias { span, attr_str }); - return false; + return; } if let Err(entry) = aliases.try_insert(doc_alias_str.to_owned(), span) { self.tcx.emit_node_span_lint( @@ -829,7 +784,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { errors::DocAliasDuplicated { first_defn: *entry.entry.get() }, ); } - true } fn check_doc_alias( @@ -838,46 +792,39 @@ impl<'tcx> CheckAttrVisitor<'tcx> { hir_id: HirId, target: Target, aliases: &mut FxHashMap, - ) -> bool { + ) { if let Some(values) = meta.meta_item_list() { - let mut errors = 0; for v in values { match v.lit() { Some(l) => match l.kind { LitKind::Str(s, _) => { - if !self.check_doc_alias_value(v, s, hir_id, target, true, aliases) { - errors += 1; - } + self.check_doc_alias_value(v, s, hir_id, target, true, aliases); } _ => { self.tcx .dcx() .emit_err(errors::DocAliasNotStringLiteral { span: v.span() }); - errors += 1; } }, None => { self.tcx .dcx() .emit_err(errors::DocAliasNotStringLiteral { span: v.span() }); - errors += 1; } } } - errors == 0 } else if let Some(doc_alias) = meta.value_str() { self.check_doc_alias_value(meta, doc_alias, hir_id, target, false, aliases) } else { self.dcx().emit_err(errors::DocAliasMalformed { span: meta.span() }); - false } } - fn check_doc_keyword(&self, meta: &NestedMetaItem, hir_id: HirId) -> bool { + fn check_doc_keyword(&self, meta: &NestedMetaItem, hir_id: HirId) { let doc_keyword = meta.value_str().unwrap_or(kw::Empty); if doc_keyword == kw::Empty { self.doc_attr_str_error(meta, "keyword"); - return false; + return; } let item_kind = match self.tcx.hir_node(hir_id) { hir::Node::Item(item) => Some(&item.kind), @@ -887,12 +834,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Some(ItemKind::Mod(module)) => { if !module.item_ids.is_empty() { self.dcx().emit_err(errors::DocKeywordEmptyMod { span: meta.span() }); - return false; + return; } } _ => { self.dcx().emit_err(errors::DocKeywordNotMod { span: meta.span() }); - return false; + return; } } if !rustc_lexer::is_ident(doc_keyword.as_str()) { @@ -900,12 +847,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { span: meta.name_value_literal_span().unwrap_or_else(|| meta.span()), doc_keyword, }); - return false; } - true } - fn check_doc_fake_variadic(&self, meta: &NestedMetaItem, hir_id: HirId) -> bool { + fn check_doc_fake_variadic(&self, meta: &NestedMetaItem, hir_id: HirId) { let item_kind = match self.tcx.hir_node(hir_id) { hir::Node::Item(item) => Some(&item.kind), _ => None, @@ -920,18 +865,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }; if !is_valid { self.dcx().emit_err(errors::DocFakeVariadicNotValid { span: meta.span() }); - return false; } } _ => { self.dcx().emit_err(errors::DocKeywordOnlyImpl { span: meta.span() }); - return false; } } - true } - /// Checks `#[doc(inline)]`/`#[doc(no_inline)]` attributes. Returns `true` if valid. + /// Checks `#[doc(inline)]`/`#[doc(no_inline)]` attributes. /// /// A doc inlining attribute is invalid if it is applied to a non-`use` item, or /// if there are conflicting attributes for one item. @@ -947,7 +889,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { hir_id: HirId, target: Target, specified_inline: &mut Option<(bool, Span)>, - ) -> bool { + ) { match target { Target::Use | Target::ExternCrate => { let do_inline = meta.name_or_empty() == sym::inline; @@ -960,12 +902,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fluent::passes_doc_inline_conflict_second, ); self.dcx().emit_err(errors::DocKeywordConflict { spans }); - return false; } - true } else { *specified_inline = Some((do_inline, meta.span())); - true } } _ => { @@ -979,7 +918,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { .then(|| self.tcx.hir().span(hir_id)), }, ); - false } } } @@ -990,7 +928,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { meta: &NestedMetaItem, hir_id: HirId, target: Target, - ) -> bool { + ) { if target != Target::ExternCrate { self.tcx.emit_node_span_lint( INVALID_DOC_ATTRIBUTES, @@ -1002,7 +940,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { .then(|| self.tcx.hir().span(hir_id)), }, ); - return false; + return; } if self.tcx.extern_mod_stmt_cnum(hir_id.owner).is_none() { @@ -1016,10 +954,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { .then(|| self.tcx.hir().span(hir_id)), }, ); - return false; } - - true } /// Checks that an attribute is *not* used at the crate level. Returns `true` if valid. @@ -1064,8 +999,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// Checks that `doc(test(...))` attribute contains only valid attributes. Returns `true` if /// valid. - fn check_test_attr(&self, meta: &NestedMetaItem, hir_id: HirId) -> bool { - let mut is_valid = true; + fn check_test_attr(&self, meta: &NestedMetaItem, hir_id: HirId) { if let Some(metas) = meta.meta_item_list() { for i_meta in metas { match (i_meta.name_or_empty(), i_meta.meta_item()) { @@ -1079,7 +1013,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { path: rustc_ast_pretty::pprust::path_to_string(&m.path), }, ); - is_valid = false; } (_, None) => { self.tcx.emit_node_span_lint( @@ -1088,7 +1021,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { i_meta.span(), errors::DocTestLiteral, ); - is_valid = false; } } } @@ -1099,28 +1031,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> { meta.span(), errors::DocTestTakesList, ); - is_valid = false; } - is_valid } /// Check that the `#![doc(cfg_hide(...))]` attribute only contains a list of attributes. - /// Returns `true` if valid. - fn check_doc_cfg_hide(&self, meta: &NestedMetaItem, hir_id: HirId) -> bool { - if meta.meta_item_list().is_some() { - true - } else { + /// + fn check_doc_cfg_hide(&self, meta: &NestedMetaItem, hir_id: HirId) { + if meta.meta_item_list().is_none() { self.tcx.emit_node_span_lint( INVALID_DOC_ATTRIBUTES, hir_id, meta.span(), errors::DocCfgHideTakesList, ); - false } } - /// Runs various checks on `#[doc]` attributes. Returns `true` if valid. + /// Runs various checks on `#[doc]` attributes. /// /// `specified_inline` should be initialized to `None` and kept for the scope /// of one item. Read the documentation of [`check_doc_inline`] for more information. @@ -1134,34 +1061,35 @@ impl<'tcx> CheckAttrVisitor<'tcx> { target: Target, specified_inline: &mut Option<(bool, Span)>, aliases: &mut FxHashMap, - ) -> bool { - let mut is_valid = true; - + ) { if let Some(mi) = attr.meta() && let Some(list) = mi.meta_item_list() { for meta in list { if let Some(i_meta) = meta.meta_item() { match i_meta.name_or_empty() { - sym::alias - if !self.check_attr_not_crate_level(meta, hir_id, "alias") - || !self.check_doc_alias(meta, hir_id, target, aliases) => - { - is_valid = false + sym::alias => { + if self.check_attr_not_crate_level(meta, hir_id, "alias") { + self.check_doc_alias(meta, hir_id, target, aliases); + } + } + + sym::keyword => { + if self.check_attr_not_crate_level(meta, hir_id, "keyword") { + self.check_doc_keyword(meta, hir_id); + } } - sym::keyword - if !self.check_attr_not_crate_level(meta, hir_id, "keyword") - || !self.check_doc_keyword(meta, hir_id) => - { - is_valid = false + sym::fake_variadic => { + if self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") { + self.check_doc_fake_variadic(meta, hir_id); + } } - sym::fake_variadic - if !self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") - || !self.check_doc_fake_variadic(meta, hir_id) => - { - is_valid = false + sym::test => { + if self.check_attr_crate_level(attr, meta, hir_id) { + self.check_test_attr(meta, hir_id); + } } sym::html_favicon_url @@ -1169,62 +1097,36 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::html_playground_url | sym::issue_tracker_base_url | sym::html_root_url - | sym::html_no_source - | sym::test - | sym::rust_logo - if !self.check_attr_crate_level(attr, meta, hir_id) => - { - is_valid = false; + | sym::html_no_source => { + self.check_attr_crate_level(attr, meta, hir_id); } - sym::cfg_hide - if !self.check_attr_crate_level(attr, meta, hir_id) - || !self.check_doc_cfg_hide(meta, hir_id) => - { - is_valid = false; + sym::cfg_hide => { + if self.check_attr_crate_level(attr, meta, hir_id) { + self.check_doc_cfg_hide(meta, hir_id); + } } - sym::inline | sym::no_inline - if !self.check_doc_inline( - attr, - meta, - hir_id, - target, - specified_inline, - ) => - { - is_valid = false; + sym::inline | sym::no_inline => { + self.check_doc_inline(attr, meta, hir_id, target, specified_inline) } - sym::masked if !self.check_doc_masked(attr, meta, hir_id, target) => { - is_valid = false; - } + sym::masked => self.check_doc_masked(attr, meta, hir_id, target), // no_default_passes: deprecated // passes: deprecated // plugins: removed, but rustdoc warns about it itself - sym::alias - | sym::cfg - | sym::cfg_hide + sym::cfg | sym::hidden - | sym::html_favicon_url - | sym::html_logo_url - | sym::html_no_source - | sym::html_playground_url - | sym::html_root_url - | sym::inline - | sym::issue_tracker_base_url - | sym::keyword - | sym::masked | sym::no_default_passes - | sym::no_inline | sym::notable_trait | sym::passes - | sym::plugins - | sym::fake_variadic => {} + | sym::plugins => {} sym::rust_logo => { - if !self.tcx.features().rustdoc_internals { + if self.check_attr_crate_level(attr, meta, hir_id) + && !self.tcx.features().rustdoc_internals + { feature_err( &self.tcx.sess, sym::rustdoc_internals, @@ -1235,12 +1137,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - sym::test => { - if !self.check_test_attr(meta, hir_id) { - is_valid = false; - } - } - _ => { let path = rustc_ast_pretty::pprust::path_to_string(&i_meta.path); if i_meta.has_name(sym::spotlight) { @@ -1282,7 +1178,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { errors::DocTestUnknownAny { path }, ); } - is_valid = false; } } } else { @@ -1292,79 +1187,60 @@ impl<'tcx> CheckAttrVisitor<'tcx> { meta.span(), errors::DocInvalid, ); - is_valid = false; } } } - - is_valid } /// Warns against some misuses of `#[pass_by_value]` - fn check_pass_by_value(&self, attr: &Attribute, span: Span, target: Target) -> bool { + fn check_pass_by_value(&self, attr: &Attribute, span: Span, target: Target) { match target { - Target::Struct | Target::Enum | Target::TyAlias => true, + Target::Struct | Target::Enum | Target::TyAlias => {} _ => { self.dcx().emit_err(errors::PassByValue { attr_span: attr.span, span }); - false } } } - fn check_allow_incoherent_impl(&self, attr: &Attribute, span: Span, target: Target) -> bool { + fn check_allow_incoherent_impl(&self, attr: &Attribute, span: Span, target: Target) { match target { - Target::Method(MethodKind::Inherent) => true, + Target::Method(MethodKind::Inherent) => {} _ => { self.dcx().emit_err(errors::AllowIncoherentImpl { attr_span: attr.span, span }); - false } } } - fn check_has_incoherent_inherent_impls( - &self, - attr: &Attribute, - span: Span, - target: Target, - ) -> bool { + fn check_has_incoherent_inherent_impls(&self, attr: &Attribute, span: Span, target: Target) { match target { - Target::Trait | Target::Struct | Target::Enum | Target::Union | Target::ForeignTy => { - true - } + Target::Trait | Target::Struct | Target::Enum | Target::Union | Target::ForeignTy => {} _ => { self.tcx .dcx() .emit_err(errors::HasIncoherentInherentImpl { attr_span: attr.span, span }); - false } } } - fn check_ffi_pure(&self, attr_span: Span, attrs: &[Attribute], target: Target) -> bool { + fn check_ffi_pure(&self, attr_span: Span, attrs: &[Attribute], target: Target) { if target != Target::ForeignFn { self.dcx().emit_err(errors::FfiPureInvalidTarget { attr_span }); - return false; + return; } if attrs.iter().any(|a| a.has_name(sym::ffi_const)) { // `#[ffi_const]` functions cannot be `#[ffi_pure]` self.dcx().emit_err(errors::BothFfiConstAndPure { attr_span }); - false - } else { - true } } - fn check_ffi_const(&self, attr_span: Span, target: Target) -> bool { - if target == Target::ForeignFn { - true - } else { + fn check_ffi_const(&self, attr_span: Span, target: Target) { + if target != Target::ForeignFn { self.dcx().emit_err(errors::FfiConstInvalidTarget { attr_span }); - false } } /// Warns against some misuses of `#[must_use]` - fn check_must_use(&self, hir_id: HirId, attr: &Attribute, target: Target) -> bool { + fn check_must_use(&self, hir_id: HirId, attr: &Attribute, target: Target) { if !matches!( target, Target::Fn @@ -1397,23 +1273,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> { errors::MustUseNoEffect { article, target }, ); } - - // For now, its always valid - true } - /// Checks if `#[must_not_suspend]` is applied to a function. Returns `true` if valid. - fn check_must_not_suspend(&self, attr: &Attribute, span: Span, target: Target) -> bool { + /// Checks if `#[must_not_suspend]` is applied to a function. + fn check_must_not_suspend(&self, attr: &Attribute, span: Span, target: Target) { match target { - Target::Struct | Target::Enum | Target::Union | Target::Trait => true, + Target::Struct | Target::Enum | Target::Union | Target::Trait => {} _ => { self.dcx().emit_err(errors::MustNotSuspend { attr_span: attr.span, span }); - false } } } - /// Checks if `#[cold]` is applied to a non-function. Returns `true` if valid. + /// Checks if `#[cold]` is applied to a non-function. fn check_cold(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { match target { Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => {} @@ -1489,21 +1361,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks if `#[no_link]` is applied to an `extern crate`. Returns `true` if valid. - fn check_no_link(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool { + /// Checks if `#[no_link]` is applied to an `extern crate`. + fn check_no_link(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { match target { - Target::ExternCrate => true, + Target::ExternCrate => {} // FIXME(#80564): We permit struct fields, match arms and macro defs to have an // `#[no_link]` attribute with just a lint, because we previously // erroneously allowed it and some crates used it accidentally, to be compatible // with crates depending on them, we can't throw an error here. Target::Field | Target::Arm | Target::MacroDef => { self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_link"); - true } _ => { self.dcx().emit_err(errors::NoLink { attr_span: attr.span, span }); - false } } } @@ -1512,57 +1382,42 @@ impl<'tcx> CheckAttrVisitor<'tcx> { matches!(self.tcx.hir_node(hir_id), hir::Node::ImplItem(..)) } - /// Checks if `#[export_name]` is applied to a function or static. Returns `true` if valid. - fn check_export_name( - &self, - hir_id: HirId, - attr: &Attribute, - span: Span, - target: Target, - ) -> bool { + /// Checks if `#[export_name]` is applied to a function or static. + fn check_export_name(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { match target { - Target::Static | Target::Fn => true, - Target::Method(..) if self.is_impl_item(hir_id) => true, + Target::Static | Target::Fn => {} + Target::Method(..) if self.is_impl_item(hir_id) => {} // FIXME(#80564): We permit struct fields, match arms and macro defs to have an // `#[export_name]` attribute with just a lint, because we previously // erroneously allowed it and some crates used it accidentally, to be compatible // with crates depending on them, we can't throw an error here. Target::Field | Target::Arm | Target::MacroDef => { self.inline_attr_str_error_with_macro_def(hir_id, attr, "export_name"); - true } _ => { self.dcx().emit_err(errors::ExportName { attr_span: attr.span, span }); - false } } } - fn check_rustc_layout_scalar_valid_range( - &self, - attr: &Attribute, - span: Span, - target: Target, - ) -> bool { + fn check_rustc_layout_scalar_valid_range(&self, attr: &Attribute, span: Span, target: Target) { if target != Target::Struct { self.dcx().emit_err(errors::RustcLayoutScalarValidRangeNotStruct { attr_span: attr.span, span, }); - return false; + return; } let Some(list) = attr.meta_item_list() else { - return false; + return; }; - if matches!(&list[..], &[NestedMetaItem::Lit(MetaItemLit { kind: LitKind::Int(..), .. })]) { - true - } else { + if !matches!(&list[..], &[NestedMetaItem::Lit(MetaItemLit { kind: LitKind::Int(..), .. })]) + { self.tcx .dcx() .emit_err(errors::RustcLayoutScalarValidRangeArg { attr_span: attr.span }); - false } } @@ -1574,7 +1429,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { span: Span, target: Target, item: Option>, - ) -> bool { + ) { let is_function = matches!(target, Target::Fn); if !is_function { self.dcx().emit_err(errors::AttrShouldBeAppliedToFn { @@ -1582,12 +1437,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> { defn_span: span, on_crate: hir_id == CRATE_HIR_ID, }); - return false; + return; } let Some(list) = attr.meta_item_list() else { // The attribute form is validated on AST. - return false; + return; }; let Some(ItemLike::Item(Item { @@ -1605,7 +1460,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr_span: attr.span, param_span: param.span, }); - return false; + return; } } } @@ -1615,7 +1470,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr_span: attr.span, generics_span: generics.span, }); - return false; + return; } let arg_count = decl.inputs.len() as u128 + generics.params.len() as u128; @@ -1628,7 +1483,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { span, arg_count: arg_count as usize, }); - return false; + return; } } else { invalid_args.push(meta.span()); @@ -1637,9 +1492,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if !invalid_args.is_empty() { self.dcx().emit_err(errors::RustcLegacyConstGenericsIndexNegative { invalid_args }); - false - } else { - true } } @@ -1651,7 +1503,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr: &Attribute, span: Span, target: Target, - ) -> bool { + ) { let is_function = matches!(target, Target::Fn | Target::Method(..)); if !is_function { self.dcx().emit_err(errors::AttrShouldBeAppliedToFn { @@ -1659,9 +1511,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { defn_span: span, on_crate: hir_id == CRATE_HIR_ID, }); - false - } else { - true } } @@ -1673,7 +1522,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr: &Attribute, span: Span, target: Target, - ) -> bool { + ) { self.check_applied_to_fn_or_method(hir_id, attr, span, target) } @@ -1685,60 +1534,49 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr: &Attribute, span: Span, target: Target, - ) -> bool { + ) { self.check_applied_to_fn_or_method(hir_id, attr, span, target) } /// Checks that the `#[rustc_lint_opt_ty]` attribute is only applied to a struct. - fn check_rustc_lint_opt_ty(&self, attr: &Attribute, span: Span, target: Target) -> bool { + fn check_rustc_lint_opt_ty(&self, attr: &Attribute, span: Span, target: Target) { match target { - Target::Struct => true, + Target::Struct => {} _ => { self.dcx().emit_err(errors::RustcLintOptTy { attr_span: attr.span, span }); - false } } } /// Checks that the `#[rustc_lint_opt_deny_field_access]` attribute is only applied to a field. - fn check_rustc_lint_opt_deny_field_access( - &self, - attr: &Attribute, - span: Span, - target: Target, - ) -> bool { + fn check_rustc_lint_opt_deny_field_access(&self, attr: &Attribute, span: Span, target: Target) { match target { - Target::Field => true, + Target::Field => {} _ => { self.tcx .dcx() .emit_err(errors::RustcLintOptDenyFieldAccess { attr_span: attr.span, span }); - false } } } /// Checks that the dep-graph debugging attributes are only present when the query-dep-graph /// option is passed to the compiler. - fn check_rustc_dirty_clean(&self, attr: &Attribute) -> bool { - if self.tcx.sess.opts.unstable_opts.query_dep_graph { - true - } else { + fn check_rustc_dirty_clean(&self, attr: &Attribute) { + if !self.tcx.sess.opts.unstable_opts.query_dep_graph { self.dcx().emit_err(errors::RustcDirtyClean { span: attr.span }); - false } } /// Checks if the attribute is applied to a trait. - fn check_must_be_applied_to_trait(&self, attr: &Attribute, span: Span, target: Target) -> bool { + fn check_must_be_applied_to_trait(&self, attr: &Attribute, span: Span, target: Target) { match target { - Target::Trait => true, + Target::Trait => {} _ => { self.dcx().emit_err(errors::AttrShouldBeAppliedToTrait { attr_span: attr.span, defn_span: span, }); - false } } } @@ -2036,43 +1874,38 @@ impl<'tcx> CheckAttrVisitor<'tcx> { span: Span, target: Target, attrs: &[Attribute], - ) -> bool { + ) { debug!("Checking target: {:?}", target); match target { Target::Fn => { for attr in attrs { if attr.is_proc_macro_attr() { debug!("Is proc macro attr"); - return true; + return; } } debug!("Is not proc macro attr"); - false } - Target::MacroDef => true, + Target::MacroDef => {} // FIXME(#80564): We permit struct fields and match arms to have an // `#[allow_internal_unstable]` attribute with just a lint, because we previously // erroneously allowed it and some crates used it accidentally, to be compatible // with crates depending on them, we can't throw an error here. - Target::Field | Target::Arm => { - self.inline_attr_str_error_without_macro_def( - hir_id, - attr, - "allow_internal_unstable", - ); - true - } + Target::Field | Target::Arm => self.inline_attr_str_error_without_macro_def( + hir_id, + attr, + "allow_internal_unstable", + ), _ => { self.tcx .dcx() .emit_err(errors::AllowInternalUnstable { attr_span: attr.span, span }); - false } } } /// Checks if the items on the `#[debugger_visualizer]` attribute are valid. - fn check_debugger_visualizer(&self, attr: &Attribute, target: Target) -> bool { + fn check_debugger_visualizer(&self, attr: &Attribute, target: Target) { // Here we only check that the #[debugger_visualizer] attribute is attached // to nothing other than a module. All other checks are done in the // `debugger_visualizer` query where they need to be done for decoding @@ -2081,11 +1914,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Target::Mod => {} _ => { self.dcx().emit_err(errors::DebugVisualizerPlacement { span: attr.span }); - return false; } } - - true } /// Outputs an error for `#[allow_internal_unstable]` which can only be applied to macros. @@ -2096,26 +1926,21 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr: &Attribute, span: Span, target: Target, - ) -> bool { + ) { match target { Target::Fn | Target::Method(_) - if self.tcx.is_const_fn_raw(hir_id.expect_owner().to_def_id()) => - { - true - } + if self.tcx.is_const_fn_raw(hir_id.expect_owner().to_def_id()) => {} // FIXME(#80564): We permit struct fields and match arms to have an // `#[allow_internal_unstable]` attribute with just a lint, because we previously // erroneously allowed it and some crates used it accidentally, to be compatible // with crates depending on them, we can't throw an error here. Target::Field | Target::Arm | Target::MacroDef => { - self.inline_attr_str_error_with_macro_def(hir_id, attr, "allow_internal_unstable"); - true + self.inline_attr_str_error_with_macro_def(hir_id, attr, "allow_internal_unstable") } _ => { self.tcx .dcx() .emit_err(errors::RustcAllowConstFnUnstable { attr_span: attr.span, span }); - false } } } @@ -2126,65 +1951,56 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr: &Attribute, span: Span, target: Target, - ) -> bool { + ) { if let Target::ForeignFn = target && let hir::Node::Item(Item { kind: ItemKind::ForeignMod { abi: Abi::RustIntrinsic, .. }, .. }) = self.tcx.parent_hir_node(hir_id) { - return true; + return; } self.dcx().emit_err(errors::RustcSafeIntrinsic { attr_span: attr.span, span }); - false } - fn check_rustc_std_internal_symbol( - &self, - attr: &Attribute, - span: Span, - target: Target, - ) -> bool { + fn check_rustc_std_internal_symbol(&self, attr: &Attribute, span: Span, target: Target) { match target { - Target::Fn | Target::Static => true, + Target::Fn | Target::Static => {} _ => { self.tcx .dcx() .emit_err(errors::RustcStdInternalSymbol { attr_span: attr.span, span }); - false } } } - fn check_stability_promotable(&self, attr: &Attribute, target: Target) -> bool { + fn check_stability_promotable(&self, attr: &Attribute, target: Target) { match target { Target::Expression => { self.dcx().emit_err(errors::StabilityPromotable { attr_span: attr.span }); - false } - _ => true, + _ => {} } } - fn check_link_ordinal(&self, attr: &Attribute, _span: Span, target: Target) -> bool { + fn check_link_ordinal(&self, attr: &Attribute, _span: Span, target: Target) { match target { - Target::ForeignFn | Target::ForeignStatic => true, + Target::ForeignFn | Target::ForeignStatic => {} _ => { self.dcx().emit_err(errors::LinkOrdinal { attr_span: attr.span }); - false } } } - fn check_confusables(&self, attr: &Attribute, target: Target) -> bool { + fn check_confusables(&self, attr: &Attribute, target: Target) { match target { Target::Method(MethodKind::Inherent) => { let Some(meta) = attr.meta() else { - return false; + return; }; let ast::MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else { - return false; + return; }; let mut candidates = Vec::new(); @@ -2198,21 +2014,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> { hi: meta.span().shrink_to_hi(), }, }); - return false; + return; }; candidates.push(meta_lit.symbol); } if candidates.is_empty() { self.dcx().emit_err(errors::EmptyConfusables { span: attr.span }); - return false; } - - true } _ => { self.dcx().emit_err(errors::Confusables { attr_span: attr.span }); - false } } } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index ccb7223b62128..8080bb60e415e 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2026,14 +2026,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Applicability::MaybeIncorrect, )), ) + } else if ident.name == kw::Underscore { + (format!("`_` is not a valid crate or module name"), None) } else if self.tcx.sess.is_rust_2015() { ( format!("you might be missing crate `{ident}`"), Some(( - vec![], - format!( - "consider adding `extern crate {ident}` to use the `{ident}` crate" - ), + vec![( + self.current_crate_outer_attr_insert_span, + format!("extern crate {ident};\n"), + )], + format!("consider importing the `{ident}` crate"), Applicability::MaybeIncorrect, )), ) diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 6aca0545e64de..6405cb82493b5 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1180,6 +1180,10 @@ pub struct Resolver<'a, 'tcx> { /// Simplified analogue of module `resolutions` but in trait impls, excluding glob delegations. /// Needed because glob delegations exclude explicitly defined names. impl_binding_keys: FxHashMap>, + + /// This is the `Span` where an `extern crate foo;` suggestion would be inserted, if `foo` + /// could be a crate that wasn't imported. For diagnostics use only. + current_crate_outer_attr_insert_span: Span, } /// Nothing really interesting here; it just provides memory for the rest of the crate. @@ -1342,6 +1346,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { tcx: TyCtxt<'tcx>, attrs: &[ast::Attribute], crate_span: Span, + current_crate_outer_attr_insert_span: Span, arenas: &'a ResolverArenas<'a>, ) -> Resolver<'a, 'tcx> { let root_def_id = CRATE_DEF_ID.to_def_id(); @@ -1525,6 +1530,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { glob_delegation_invoc_ids: Default::default(), impl_unexpanded_invocations: Default::default(), impl_binding_keys: Default::default(), + current_crate_outer_attr_insert_span, }; let root_parent_scope = ParentScope::module(graph_root, &resolver); diff --git a/compiler/rustc_target/src/abi/call/x86_win64.rs b/compiler/rustc_target/src/abi/call/x86_win64.rs index 90de1a42bc06b..4e19460bd28c2 100644 --- a/compiler/rustc_target/src/abi/call/x86_win64.rs +++ b/compiler/rustc_target/src/abi/call/x86_win64.rs @@ -1,5 +1,5 @@ use crate::abi::call::{ArgAbi, FnAbi, Reg}; -use crate::abi::Abi; +use crate::abi::{Abi, Float, Primitive}; // Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing @@ -18,8 +18,12 @@ pub fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { // FIXME(eddyb) there should be a size cap here // (probably what clang calls "illegal vectors"). } - Abi::Scalar(_) => { - if a.layout.size.bytes() > 8 { + Abi::Scalar(scalar) => { + // Match what LLVM does for `f128` so that `compiler-builtins` builtins match up + // with what LLVM expects. + if a.layout.size.bytes() > 8 + && !matches!(scalar.primitive(), Primitive::Float(Float::F128)) + { a.make_indirect(); } else { a.extend_integer_width_to(32); diff --git a/library/std/build.rs b/library/std/build.rs index c542ba81eedc1..9b58dd53ba20a 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -94,7 +94,7 @@ fn main() { // Unsupported ("arm64ec", _) => false, // MinGW ABI bugs - ("x86", "windows") => false, + ("x86_64", "windows") => false, // x86 has ABI bugs that show up with optimizations. This should be partially fixed with // the compiler-builtins update. ("x86" | "x86_64", _) => false, @@ -122,6 +122,8 @@ fn main() { ("nvptx64", _) => false, // ABI unsupported ("sparc", _) => false, + // MinGW ABI bugs + ("x86_64", "windows") => false, // 64-bit Linux is about the only platform to have f128 symbols by default (_, "linux") if target_pointer_width == 64 => true, // Same as for f16, except MacOS is also missing f128 symbols. diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs index 9d969af8c6d84..5e0694e8de2db 100644 --- a/library/std/src/sync/once.rs +++ b/library/std/src/sync/once.rs @@ -70,7 +70,7 @@ pub(crate) enum ExclusiveState { #[stable(feature = "rust1", since = "1.0.0")] #[deprecated( since = "1.38.0", - note = "the `new` function is now preferred", + note = "the `Once::new()` function is now preferred", suggestion = "Once::new()" )] pub const ONCE_INIT: Once = Once::new(); diff --git a/src/tools/compiletest/src/command-list.rs b/src/tools/compiletest/src/command-list.rs index c356f4266f016..68443c300fc5c 100644 --- a/src/tools/compiletest/src/command-list.rs +++ b/src/tools/compiletest/src/command-list.rs @@ -18,6 +18,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "check-test-line-numbers-match", "compare-output-lines-by-subset", "compile-flags", + "doc-flags", "dont-check-compiler-stderr", "dont-check-compiler-stdout", "dont-check-failure-status", @@ -225,6 +226,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "should-ice", "stderr-per-bitwidth", "test-mir-pass", + "unique-doc-out-dir", "unset-exec-env", "unset-rustc-env", // Used by the tidy check `unknown_revision`. diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index cde3e3295c631..1fc24301c85e6 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -95,6 +95,8 @@ pub struct TestProps { pub compile_flags: Vec, // Extra flags to pass when the compiled code is run (such as --bench) pub run_flags: Vec, + /// Extra flags to pass to rustdoc but not the compiler. + pub doc_flags: Vec, // If present, the name of a file that this test should match when // pretty-printed pub pp_exact: Option, @@ -122,6 +124,9 @@ pub struct TestProps { pub unset_exec_env: Vec, // Build documentation for all specified aux-builds as well pub build_aux_docs: bool, + /// Build the documentation for each crate in a unique output directory. + /// Uses /docs//doc + pub unique_doc_out_dir: bool, // Flag to force a crate to be built with the host architecture pub force_host: bool, // Check stdout for error-pattern output as well as stderr @@ -220,8 +225,10 @@ mod directives { pub const REGEX_ERROR_PATTERN: &'static str = "regex-error-pattern"; pub const COMPILE_FLAGS: &'static str = "compile-flags"; pub const RUN_FLAGS: &'static str = "run-flags"; + pub const DOC_FLAGS: &'static str = "doc-flags"; pub const SHOULD_ICE: &'static str = "should-ice"; pub const BUILD_AUX_DOCS: &'static str = "build-aux-docs"; + pub const UNIQUE_DOC_OUT_DIR: &'static str = "unique-doc-out-dir"; pub const FORCE_HOST: &'static str = "force-host"; pub const CHECK_STDOUT: &'static str = "check-stdout"; pub const CHECK_RUN_RESULTS: &'static str = "check-run-results"; @@ -267,6 +274,7 @@ impl TestProps { regex_error_patterns: vec![], compile_flags: vec![], run_flags: vec![], + doc_flags: vec![], pp_exact: None, aux_builds: vec![], aux_bins: vec![], @@ -281,6 +289,7 @@ impl TestProps { exec_env: vec![], unset_exec_env: vec![], build_aux_docs: false, + unique_doc_out_dir: false, force_host: false, check_stdout: false, check_run_results: false, @@ -378,6 +387,8 @@ impl TestProps { |r| r, ); + config.push_name_value_directive(ln, DOC_FLAGS, &mut self.doc_flags, |r| r); + fn split_flags(flags: &str) -> Vec { // Individual flags can be single-quoted to preserve spaces; see // . @@ -415,6 +426,8 @@ impl TestProps { config.set_name_directive(ln, SHOULD_ICE, &mut self.should_ice); config.set_name_directive(ln, BUILD_AUX_DOCS, &mut self.build_aux_docs); + config.set_name_directive(ln, UNIQUE_DOC_OUT_DIR, &mut self.unique_doc_out_dir); + config.set_name_directive(ln, FORCE_HOST, &mut self.force_host); config.set_name_directive(ln, CHECK_STDOUT, &mut self.check_stdout); config.set_name_directive(ln, CHECK_RUN_RESULTS, &mut self.check_run_results); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 1f15605d8beed..e51bf0ef6dfeb 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1,5 +1,6 @@ // ignore-tidy-filelength +use std::borrow::Cow; use std::collections::{HashMap, HashSet}; use std::ffi::{OsStr, OsString}; use std::fs::{self, create_dir_all, File, OpenOptions}; @@ -723,7 +724,7 @@ impl<'test> TestCx<'test> { self.maybe_add_external_args(&mut rustc, &self.config.target_rustcflags); rustc.args(&self.props.compile_flags); - self.compose_and_run_compiler(rustc, Some(src)) + self.compose_and_run_compiler(rustc, Some(src), self.testpaths) } fn run_debuginfo_test(&self) { @@ -1579,13 +1580,15 @@ impl<'test> TestCx<'test> { passes, ); - self.compose_and_run_compiler(rustc, None) + self.compose_and_run_compiler(rustc, None, self.testpaths) } - fn document(&self, out_dir: &Path) -> ProcRes { + /// `root_out_dir` and `root_testpaths` refer to the parameters of the actual test being run. + /// Auxiliaries, no matter how deep, have the same root_out_dir and root_testpaths. + fn document(&self, root_out_dir: &Path, root_testpaths: &TestPaths) -> ProcRes { if self.props.build_aux_docs { for rel_ab in &self.props.aux_builds { - let aux_testpaths = self.compute_aux_test_paths(&self.testpaths, rel_ab); + let aux_testpaths = self.compute_aux_test_paths(root_testpaths, rel_ab); let aux_props = self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config); let aux_cx = TestCx { @@ -1596,7 +1599,9 @@ impl<'test> TestCx<'test> { }; // Create the directory for the stdout/stderr files. create_dir_all(aux_cx.output_base_dir()).unwrap(); - let auxres = aux_cx.document(out_dir); + // use root_testpaths here, because aux-builds should have the + // same --out-dir and auxiliary directory. + let auxres = aux_cx.document(&root_out_dir, root_testpaths); if !auxres.status.success() { return auxres; } @@ -1606,21 +1611,40 @@ impl<'test> TestCx<'test> { let aux_dir = self.aux_output_dir_name(); let rustdoc_path = self.config.rustdoc_path.as_ref().expect("--rustdoc-path not passed"); - let mut rustdoc = Command::new(rustdoc_path); + // actual --out-dir given to the auxiliary or test, as opposed to the root out dir for the entire + // test + let out_dir: Cow<'_, Path> = if self.props.unique_doc_out_dir { + let file_name = self.testpaths.file.file_stem().expect("file name should not be empty"); + let out_dir = PathBuf::from_iter([ + root_out_dir, + Path::new("docs"), + Path::new(file_name), + Path::new("doc"), + ]); + create_dir_all(&out_dir).unwrap(); + Cow::Owned(out_dir) + } else { + Cow::Borrowed(root_out_dir) + }; + + let mut rustdoc = Command::new(rustdoc_path); + let current_dir = output_base_dir(self.config, root_testpaths, self.safe_revision()); + rustdoc.current_dir(current_dir); rustdoc .arg("-L") .arg(self.config.run_lib_path.to_str().unwrap()) .arg("-L") .arg(aux_dir) .arg("-o") - .arg(out_dir) + .arg(out_dir.as_ref()) .arg("--deny") .arg("warnings") .arg(&self.testpaths.file) .arg("-A") .arg("internal_features") - .args(&self.props.compile_flags); + .args(&self.props.compile_flags) + .args(&self.props.doc_flags); if self.config.mode == RustdocJson { rustdoc.arg("--output-format").arg("json").arg("-Zunstable-options"); @@ -1630,7 +1654,7 @@ impl<'test> TestCx<'test> { rustdoc.arg(format!("-Clinker={}", linker)); } - self.compose_and_run_compiler(rustdoc, None) + self.compose_and_run_compiler(rustdoc, None, root_testpaths) } fn exec_compiled_test(&self) -> ProcRes { @@ -1828,9 +1852,16 @@ impl<'test> TestCx<'test> { } } - fn compose_and_run_compiler(&self, mut rustc: Command, input: Option) -> ProcRes { + /// `root_testpaths` refers to the path of the original test. + /// the auxiliary and the test with an aux-build have the same `root_testpaths`. + fn compose_and_run_compiler( + &self, + mut rustc: Command, + input: Option, + root_testpaths: &TestPaths, + ) -> ProcRes { let aux_dir = self.aux_output_dir(); - self.build_all_auxiliary(&self.testpaths, &aux_dir, &mut rustc); + self.build_all_auxiliary(root_testpaths, &aux_dir, &mut rustc); rustc.envs(self.props.rustc_env.clone()); self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove); @@ -2545,7 +2576,7 @@ impl<'test> TestCx<'test> { Vec::new(), ); - let proc_res = self.compose_and_run_compiler(rustc, None); + let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths); let output_path = self.get_filecheck_file("ll"); (proc_res, output_path) } @@ -2581,7 +2612,7 @@ impl<'test> TestCx<'test> { Vec::new(), ); - let proc_res = self.compose_and_run_compiler(rustc, None); + let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths); let output_path = self.get_filecheck_file("s"); (proc_res, output_path) } @@ -2664,7 +2695,7 @@ impl<'test> TestCx<'test> { let out_dir = self.output_base_dir(); remove_and_create_dir_all(&out_dir); - let proc_res = self.document(&out_dir); + let proc_res = self.document(&out_dir, &self.testpaths); if !proc_res.status.success() { self.fatal_proc_rec("rustdoc failed!", &proc_res); } @@ -2723,7 +2754,7 @@ impl<'test> TestCx<'test> { let aux_dir = new_rustdoc.aux_output_dir(); new_rustdoc.build_all_auxiliary(&new_rustdoc.testpaths, &aux_dir, &mut rustc); - let proc_res = new_rustdoc.document(&compare_dir); + let proc_res = new_rustdoc.document(&compare_dir, &new_rustdoc.testpaths); if !proc_res.status.success() { eprintln!("failed to run nightly rustdoc"); return; @@ -2847,7 +2878,7 @@ impl<'test> TestCx<'test> { let out_dir = self.output_base_dir(); remove_and_create_dir_all(&out_dir); - let proc_res = self.document(&out_dir); + let proc_res = self.document(&out_dir, &self.testpaths); if !proc_res.status.success() { self.fatal_proc_rec("rustdoc failed!", &proc_res); } @@ -2923,24 +2954,15 @@ impl<'test> TestCx<'test> { fn check_rustdoc_test_option(&self, res: ProcRes) { let mut other_files = Vec::new(); let mut files: HashMap> = HashMap::new(); - let cwd = env::current_dir().unwrap(); - files.insert( - self.testpaths - .file - .strip_prefix(&cwd) - .unwrap_or(&self.testpaths.file) - .to_str() - .unwrap() - .replace('\\', "/"), - self.get_lines(&self.testpaths.file, Some(&mut other_files)), - ); + let normalized = fs::canonicalize(&self.testpaths.file).expect("failed to canonicalize"); + let normalized = normalized.to_str().unwrap().replace('\\', "/"); + files.insert(normalized, self.get_lines(&self.testpaths.file, Some(&mut other_files))); for other_file in other_files { let mut path = self.testpaths.file.clone(); path.set_file_name(&format!("{}.rs", other_file)); - files.insert( - path.strip_prefix(&cwd).unwrap_or(&path).to_str().unwrap().replace('\\', "/"), - self.get_lines(&path, None), - ); + let path = fs::canonicalize(path).expect("failed to canonicalize"); + let normalized = path.to_str().unwrap().replace('\\', "/"); + files.insert(normalized, self.get_lines(&path, None)); } let mut tested = 0; @@ -3779,7 +3801,7 @@ impl<'test> TestCx<'test> { if let Some(nodejs) = &self.config.nodejs { let out_dir = self.output_base_dir(); - self.document(&out_dir); + self.document(&out_dir, &self.testpaths); let root = self.config.find_rust_src_root().unwrap(); let file_stem = @@ -4095,7 +4117,7 @@ impl<'test> TestCx<'test> { rustc.arg(crate_name); } - let res = self.compose_and_run_compiler(rustc, None); + let res = self.compose_and_run_compiler(rustc, None, self.testpaths); if !res.status.success() { self.fatal_proc_rec("failed to compile fixed code", &res); } diff --git a/src/tools/compiletest/src/runtest/coverage.rs b/src/tools/compiletest/src/runtest/coverage.rs index 6ee147da5a965..05191a159801c 100644 --- a/src/tools/compiletest/src/runtest/coverage.rs +++ b/src/tools/compiletest/src/runtest/coverage.rs @@ -191,7 +191,7 @@ impl<'test> TestCx<'test> { rustdoc_cmd.arg(&self.testpaths.file); - let proc_res = self.compose_and_run_compiler(rustdoc_cmd, None); + let proc_res = self.compose_and_run_compiler(rustdoc_cmd, None, self.testpaths); if !proc_res.status.success() { self.fatal_proc_rec("rustdoc --test failed!", &proc_res) } diff --git a/tests/assembly/x86_64-windows-float-abi.rs b/tests/assembly/x86_64-windows-float-abi.rs new file mode 100644 index 0000000000000..1381d492fa593 --- /dev/null +++ b/tests/assembly/x86_64-windows-float-abi.rs @@ -0,0 +1,39 @@ +//@ assembly-output: emit-asm +//@ compile-flags: -O +//@ only-windows +//@ only-x86_64 + +#![feature(f16, f128)] +#![crate_type = "lib"] + +// CHECK-LABEL: second_f16 +// CHECK: movaps %xmm1, %xmm0 +// CHECK-NEXT: retq +#[no_mangle] +pub extern "C" fn second_f16(_: f16, x: f16) -> f16 { + x +} + +// CHECK-LABEL: second_f32 +// CHECK: movaps %xmm1, %xmm0 +// CHECK-NEXT: retq +#[no_mangle] +pub extern "C" fn second_f32(_: f32, x: f32) -> f32 { + x +} + +// CHECK-LABEL: second_f64 +// CHECK: movaps %xmm1, %xmm0 +// CHECK-NEXT: retq +#[no_mangle] +pub extern "C" fn second_f64(_: f64, x: f64) -> f64 { + x +} + +// CHECK-LABEL: second_f128 +// CHECK: movaps %xmm1, %xmm0 +// CHECK-NEXT: retq +#[no_mangle] +pub extern "C" fn second_f128(_: f128, x: f128) -> f128 { + x +} diff --git a/tests/rustdoc-ui/ice-unresolved-import-100241.stderr b/tests/rustdoc-ui/ice-unresolved-import-100241.stderr index e23e0f01fabe3..2eebedba9a5ee 100644 --- a/tests/rustdoc-ui/ice-unresolved-import-100241.stderr +++ b/tests/rustdoc-ui/ice-unresolved-import-100241.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `inner` LL | pub use inner::S; | ^^^^^ you might be missing crate `inner` | - = help: consider adding `extern crate inner` to use the `inner` crate +help: consider importing the `inner` crate + | +LL + extern crate inner; + | error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr index a74e6b7393891..e68943192130d 100644 --- a/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr +++ b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr @@ -4,7 +4,10 @@ error[E0433]: failed to resolve: you might be missing crate `unresolved_crate` LL | use unresolved_crate::module::Name; | ^^^^^^^^^^^^^^^^ you might be missing crate `unresolved_crate` | - = help: consider adding `extern crate unresolved_crate` to use the `unresolved_crate` crate +help: consider importing the `unresolved_crate` crate + | +LL + extern crate unresolved_crate; + | error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/issues/issue-61732.stderr b/tests/rustdoc-ui/issues/issue-61732.stderr index f49d53b0d9ad0..0aa7d558c307d 100644 --- a/tests/rustdoc-ui/issues/issue-61732.stderr +++ b/tests/rustdoc-ui/issues/issue-61732.stderr @@ -4,7 +4,10 @@ error[E0433]: failed to resolve: you might be missing crate `r#mod` LL | pub(in crate::r#mod) fn main() {} | ^^^^^ you might be missing crate `r#mod` | - = help: consider adding `extern crate r#mod` to use the `r#mod` crate +help: consider importing the `r#mod` crate + | +LL + extern crate r#mod; + | error: aborting due to 1 previous error diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/q.rs b/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/q.rs new file mode 100644 index 0000000000000..5d0881029cb2f --- /dev/null +++ b/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/q.rs @@ -0,0 +1,2 @@ +//@ build-aux-docs +pub struct Quebec; diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/t.rs b/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/t.rs new file mode 100644 index 0000000000000..fab9ec4a92b96 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/t.rs @@ -0,0 +1,4 @@ +//@ aux-build:q.rs +//@ build-aux-docs +extern crate q; +pub trait Tango {} diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/s.rs b/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/s.rs new file mode 100644 index 0000000000000..85c460ace642f --- /dev/null +++ b/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/s.rs @@ -0,0 +1,16 @@ +//@ aux-build:t.rs +//@ build-aux-docs +//@ has q/struct.Quebec.html +//@ has s/struct.Sierra.html +//@ has t/trait.Tango.html +//@ hasraw s/struct.Sierra.html 'Tango' +//@ hasraw trait.impl/t/trait.Tango.js 'struct.Sierra.html' +//@ hasraw search-index.js 'Tango' +//@ hasraw search-index.js 'Sierra' +//@ hasraw search-index.js 'Quebec' + +// We document multiple crates into the same output directory, which +// merges the cross-crate information. Everything is available. +extern crate t; +pub struct Sierra; +impl t::Tango for Sierra {} diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/q.rs b/tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/q.rs new file mode 100644 index 0000000000000..932a0b17206d6 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/q.rs @@ -0,0 +1,5 @@ +//@ build-aux-docs +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub struct Quebec; diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/t.rs b/tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/t.rs new file mode 100644 index 0000000000000..c21a59c65188f --- /dev/null +++ b/tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/t.rs @@ -0,0 +1,7 @@ +//@ aux-build:q.rs +//@ build-aux-docs +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate q; +pub trait Tango {} diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive/s.rs b/tests/rustdoc/cross-crate-info/cargo-transitive/s.rs new file mode 100644 index 0000000000000..68bfc34883bd8 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/cargo-transitive/s.rs @@ -0,0 +1,24 @@ +//@ aux-build:t.rs +//@ build-aux-docs +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html +//@ has index.html '//h1' 'List of all crates' +//@ has index.html '//ul[@class="all-items"]//a[@href="q/index.html"]' 'q' +//@ has index.html '//ul[@class="all-items"]//a[@href="s/index.html"]' 's' +//@ has index.html '//ul[@class="all-items"]//a[@href="t/index.html"]' 't' +//@ has q/struct.Quebec.html +//@ has s/struct.Sierra.html +//@ has t/trait.Tango.html +//@ hasraw s/struct.Sierra.html 'Tango' +//@ hasraw trait.impl/t/trait.Tango.js 'struct.Sierra.html' +//@ hasraw search-index.js 'Tango' +//@ hasraw search-index.js 'Sierra' +//@ hasraw search-index.js 'Quebec' + +// We document multiple crates into the same output directory, which +// merges the cross-crate information. Everything is available. +extern crate t; +pub struct Sierra; +impl t::Tango for Sierra {} diff --git a/tests/rustdoc/cross-crate-info/cargo-two-no-index/auxiliary/f.rs b/tests/rustdoc/cross-crate-info/cargo-two-no-index/auxiliary/f.rs new file mode 100644 index 0000000000000..abc580a388cd2 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/cargo-two-no-index/auxiliary/f.rs @@ -0,0 +1,2 @@ +//@ build-aux-docs +pub trait Foxtrot {} diff --git a/tests/rustdoc/cross-crate-info/cargo-two-no-index/e.rs b/tests/rustdoc/cross-crate-info/cargo-two-no-index/e.rs new file mode 100644 index 0000000000000..c93298f969eab --- /dev/null +++ b/tests/rustdoc/cross-crate-info/cargo-two-no-index/e.rs @@ -0,0 +1,14 @@ +//@ aux-build:f.rs +//@ build-aux-docs +//@ has e/enum.Echo.html +//@ has f/trait.Foxtrot.html +//@ hasraw e/enum.Echo.html 'Foxtrot' +//@ hasraw trait.impl/f/trait.Foxtrot.js 'enum.Echo.html' +//@ hasraw search-index.js 'Foxtrot' +//@ hasraw search-index.js 'Echo' + +// document two crates in the same way that cargo does. do not provide +// --enable-index-page +extern crate f; +pub enum Echo {} +impl f::Foxtrot for Echo {} diff --git a/tests/rustdoc/cross-crate-info/cargo-two/auxiliary/f.rs b/tests/rustdoc/cross-crate-info/cargo-two/auxiliary/f.rs new file mode 100644 index 0000000000000..a2a7033b13112 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/cargo-two/auxiliary/f.rs @@ -0,0 +1,5 @@ +//@ build-aux-docs +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub trait Foxtrot {} diff --git a/tests/rustdoc/cross-crate-info/cargo-two/e.rs b/tests/rustdoc/cross-crate-info/cargo-two/e.rs new file mode 100644 index 0000000000000..00f86cbc34889 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/cargo-two/e.rs @@ -0,0 +1,21 @@ +//@ aux-build:f.rs +//@ build-aux-docs +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html +//@ has index.html '//h1' 'List of all crates' +//@ has index.html '//ul[@class="all-items"]//a[@href="f/index.html"]' 'f' +//@ has index.html '//ul[@class="all-items"]//a[@href="e/index.html"]' 'e' +//@ has e/enum.Echo.html +//@ has f/trait.Foxtrot.html +//@ hasraw e/enum.Echo.html 'Foxtrot' +//@ hasraw trait.impl/f/trait.Foxtrot.js 'enum.Echo.html' +//@ hasraw search-index.js 'Foxtrot' +//@ hasraw search-index.js 'Echo' + +// document two crates in the same way that cargo does, writing them both +// into the same output directory +extern crate f; +pub enum Echo {} +impl f::Foxtrot for Echo {} diff --git a/tests/rustdoc/cross-crate-info/index-on-last/auxiliary/f.rs b/tests/rustdoc/cross-crate-info/index-on-last/auxiliary/f.rs new file mode 100644 index 0000000000000..abc580a388cd2 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/index-on-last/auxiliary/f.rs @@ -0,0 +1,2 @@ +//@ build-aux-docs +pub trait Foxtrot {} diff --git a/tests/rustdoc/cross-crate-info/index-on-last/e.rs b/tests/rustdoc/cross-crate-info/index-on-last/e.rs new file mode 100644 index 0000000000000..ffee898cd966d --- /dev/null +++ b/tests/rustdoc/cross-crate-info/index-on-last/e.rs @@ -0,0 +1,20 @@ +//@ aux-build:f.rs +//@ build-aux-docs +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html +//@ has index.html '//h1' 'List of all crates' +//@ has index.html '//ul[@class="all-items"]//a[@href="f/index.html"]' 'f' +//@ has index.html '//ul[@class="all-items"]//a[@href="e/index.html"]' 'e' +//@ has e/enum.Echo.html +//@ has f/trait.Foxtrot.html +//@ hasraw e/enum.Echo.html 'Foxtrot' +//@ hasraw trait.impl/f/trait.Foxtrot.js 'enum.Echo.html' +//@ hasraw search-index.js 'Foxtrot' +//@ hasraw search-index.js 'Echo' + +// only declare --enable-index-page to the last rustdoc invocation +extern crate f; +pub enum Echo {} +impl f::Foxtrot for Echo {} diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/q.rs b/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/q.rs new file mode 100644 index 0000000000000..932a0b17206d6 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/q.rs @@ -0,0 +1,5 @@ +//@ build-aux-docs +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +pub struct Quebec; diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/r.rs b/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/r.rs new file mode 100644 index 0000000000000..2c0db2abc53d9 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/r.rs @@ -0,0 +1,7 @@ +//@ aux-build:s.rs +//@ build-aux-docs +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate s; +pub type Romeo = s::Sierra; diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/s.rs b/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/s.rs new file mode 100644 index 0000000000000..355d3f1aaa883 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/s.rs @@ -0,0 +1,8 @@ +//@ aux-build:t.rs +//@ build-aux-docs +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate t; +pub struct Sierra; +impl t::Tango for Sierra {} diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/t.rs b/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/t.rs new file mode 100644 index 0000000000000..c21a59c65188f --- /dev/null +++ b/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/t.rs @@ -0,0 +1,7 @@ +//@ aux-build:q.rs +//@ build-aux-docs +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +extern crate q; +pub trait Tango {} diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/i.rs b/tests/rustdoc/cross-crate-info/kitchen-sink/i.rs new file mode 100644 index 0000000000000..bcb9464795af2 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/kitchen-sink/i.rs @@ -0,0 +1,30 @@ +//@ aux-build:r.rs +//@ aux-build:q.rs +//@ aux-build:t.rs +//@ aux-build:s.rs +//@ build-aux-docs +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html '//h1' 'List of all crates' +//@ has index.html +//@ has index.html '//ul[@class="all-items"]//a[@href="i/index.html"]' 'i' +//@ has index.html '//ul[@class="all-items"]//a[@href="q/index.html"]' 'q' +//@ has index.html '//ul[@class="all-items"]//a[@href="r/index.html"]' 'r' +//@ has index.html '//ul[@class="all-items"]//a[@href="s/index.html"]' 's' +//@ has index.html '//ul[@class="all-items"]//a[@href="t/index.html"]' 't' +//@ has q/struct.Quebec.html +//@ has r/type.Romeo.html +//@ has s/struct.Sierra.html +//@ has t/trait.Tango.html +//@ hasraw s/struct.Sierra.html 'Tango' +//@ hasraw trait.impl/t/trait.Tango.js 'struct.Sierra.html' +//@ hasraw search-index.js 'Quebec' +//@ hasraw search-index.js 'Romeo' +//@ hasraw search-index.js 'Sierra' +//@ hasraw search-index.js 'Tango' +//@ has type.impl/s/struct.Sierra.js +//@ hasraw type.impl/s/struct.Sierra.js 'Tango' +//@ hasraw type.impl/s/struct.Sierra.js 'Romeo' + +// document everything in the default mode diff --git a/tests/rustdoc/cross-crate-info/single-crate-baseline/q.rs b/tests/rustdoc/cross-crate-info/single-crate-baseline/q.rs new file mode 100644 index 0000000000000..c5e3dc0a0f4e5 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/single-crate-baseline/q.rs @@ -0,0 +1,12 @@ +//@ build-aux-docs +//@ doc-flags:--enable-index-page +//@ doc-flags:-Zunstable-options + +//@ has index.html +//@ has index.html '//h1' 'List of all crates' +//@ has index.html '//ul[@class="all-items"]//a[@href="q/index.html"]' 'q' +//@ has q/struct.Quebec.html +//@ hasraw search-index.js 'Quebec' + +// there's nothing cross-crate going on here +pub struct Quebec; diff --git a/tests/rustdoc/cross-crate-info/single-crate-no-index/q.rs b/tests/rustdoc/cross-crate-info/single-crate-no-index/q.rs new file mode 100644 index 0000000000000..d3e71fa0ce35f --- /dev/null +++ b/tests/rustdoc/cross-crate-info/single-crate-no-index/q.rs @@ -0,0 +1,6 @@ +//@ build-aux-docs +//@ has q/struct.Quebec.html +//@ hasraw search-index.js 'Quebec' + +// there's nothing cross-crate going on here +pub struct Quebec; diff --git a/tests/rustdoc/cross-crate-info/transitive/auxiliary/q.rs b/tests/rustdoc/cross-crate-info/transitive/auxiliary/q.rs new file mode 100644 index 0000000000000..5d0881029cb2f --- /dev/null +++ b/tests/rustdoc/cross-crate-info/transitive/auxiliary/q.rs @@ -0,0 +1,2 @@ +//@ build-aux-docs +pub struct Quebec; diff --git a/tests/rustdoc/cross-crate-info/transitive/auxiliary/t.rs b/tests/rustdoc/cross-crate-info/transitive/auxiliary/t.rs new file mode 100644 index 0000000000000..fab9ec4a92b96 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/transitive/auxiliary/t.rs @@ -0,0 +1,4 @@ +//@ aux-build:q.rs +//@ build-aux-docs +extern crate q; +pub trait Tango {} diff --git a/tests/rustdoc/cross-crate-info/transitive/s.rs b/tests/rustdoc/cross-crate-info/transitive/s.rs new file mode 100644 index 0000000000000..0a4e5f646ddaa --- /dev/null +++ b/tests/rustdoc/cross-crate-info/transitive/s.rs @@ -0,0 +1,6 @@ +//@ aux-build:t.rs +//@ build-aux-docs +// simple test to see if we support building transitive crates +extern crate t; +pub struct Sierra; +impl t::Tango for Sierra {} diff --git a/tests/rustdoc/cross-crate-info/two/auxiliary/f.rs b/tests/rustdoc/cross-crate-info/two/auxiliary/f.rs new file mode 100644 index 0000000000000..abc580a388cd2 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/two/auxiliary/f.rs @@ -0,0 +1,2 @@ +//@ build-aux-docs +pub trait Foxtrot {} diff --git a/tests/rustdoc/cross-crate-info/two/e.rs b/tests/rustdoc/cross-crate-info/two/e.rs new file mode 100644 index 0000000000000..9665af62706d1 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/two/e.rs @@ -0,0 +1,6 @@ +//@ aux-build:f.rs +//@ build-aux-docs +// simple test to assert that we can do a two-level aux-build +extern crate f; +pub enum Echo {} +impl f::Foxtrot for Echo {} diff --git a/tests/rustdoc/cross-crate-info/working-dir-examples/q.rs b/tests/rustdoc/cross-crate-info/working-dir-examples/q.rs new file mode 100644 index 0000000000000..a7ab062fd9e28 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/working-dir-examples/q.rs @@ -0,0 +1,10 @@ +//@ build-aux-docs +//@ doc-flags:--scrape-examples-output-path=examples +//@ doc-flags:--scrape-examples-target-crate=q +//@ doc-flags:-Zunstable-options + +//@ has examples + +// where will --scrape-examples-output-path resolve the path to be? +// should be the root output directory +pub struct Quebec; diff --git a/tests/rustdoc/cross-crate-info/write-docs-somewhere-else/auxiliary/f.rs b/tests/rustdoc/cross-crate-info/write-docs-somewhere-else/auxiliary/f.rs new file mode 100644 index 0000000000000..f8c9adcaf9cad --- /dev/null +++ b/tests/rustdoc/cross-crate-info/write-docs-somewhere-else/auxiliary/f.rs @@ -0,0 +1,3 @@ +//@ build-aux-docs +//@ unique-doc-out-dir +pub trait Foxtrot {} diff --git a/tests/rustdoc/cross-crate-info/write-docs-somewhere-else/e.rs b/tests/rustdoc/cross-crate-info/write-docs-somewhere-else/e.rs new file mode 100644 index 0000000000000..9dcec211e1787 --- /dev/null +++ b/tests/rustdoc/cross-crate-info/write-docs-somewhere-else/e.rs @@ -0,0 +1,14 @@ +//@ aux-build:f.rs +//@ build-aux-docs +//@ has e/enum.Echo.html +//@ !has f/trait.Foxtrot.html +//@ hasraw e/enum.Echo.html 'Foxtrot' +//@ hasraw trait.impl/f/trait.Foxtrot.js 'enum.Echo.html' +//@ !hasraw search-index.js 'Foxtrot' +//@ hasraw search-index.js 'Echo' + +// test the fact that our test runner will document this crate somewhere +// else +extern crate f; +pub enum Echo {} +impl f::Foxtrot for Echo {} diff --git a/tests/ui/attributes/field-attributes-vis-unresolved.stderr b/tests/ui/attributes/field-attributes-vis-unresolved.stderr index 819cd859ae909..f8610c08b0220 100644 --- a/tests/ui/attributes/field-attributes-vis-unresolved.stderr +++ b/tests/ui/attributes/field-attributes-vis-unresolved.stderr @@ -4,7 +4,10 @@ error[E0433]: failed to resolve: you might be missing crate `nonexistent` LL | pub(in nonexistent) field: u8 | ^^^^^^^^^^^ you might be missing crate `nonexistent` | - = help: consider adding `extern crate nonexistent` to use the `nonexistent` crate +help: consider importing the `nonexistent` crate + | +LL + extern crate nonexistent; + | error[E0433]: failed to resolve: you might be missing crate `nonexistent` --> $DIR/field-attributes-vis-unresolved.rs:22:12 @@ -12,7 +15,10 @@ error[E0433]: failed to resolve: you might be missing crate `nonexistent` LL | pub(in nonexistent) u8 | ^^^^^^^^^^^ you might be missing crate `nonexistent` | - = help: consider adding `extern crate nonexistent` to use the `nonexistent` crate +help: consider importing the `nonexistent` crate + | +LL + extern crate nonexistent; + | error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0432.stderr b/tests/ui/error-codes/E0432.stderr index a0b17e35c94a8..36fefc95897d6 100644 --- a/tests/ui/error-codes/E0432.stderr +++ b/tests/ui/error-codes/E0432.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `something` LL | use something::Foo; | ^^^^^^^^^ you might be missing crate `something` | - = help: consider adding `extern crate something` to use the `something` crate +help: consider importing the `something` crate + | +LL + extern crate something; + | error: aborting due to 1 previous error diff --git a/tests/ui/imports/import-from-missing-star-2.stderr b/tests/ui/imports/import-from-missing-star-2.stderr index 59b000a43822b..dd35627c68465 100644 --- a/tests/ui/imports/import-from-missing-star-2.stderr +++ b/tests/ui/imports/import-from-missing-star-2.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `spam` LL | use spam::*; | ^^^^ you might be missing crate `spam` | - = help: consider adding `extern crate spam` to use the `spam` crate +help: consider importing the `spam` crate + | +LL + extern crate spam; + | error: aborting due to 1 previous error diff --git a/tests/ui/imports/import-from-missing-star-3.stderr b/tests/ui/imports/import-from-missing-star-3.stderr index 23df6b354450b..1e2412b095975 100644 --- a/tests/ui/imports/import-from-missing-star-3.stderr +++ b/tests/ui/imports/import-from-missing-star-3.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `spam` LL | use spam::*; | ^^^^ you might be missing crate `spam` | - = help: consider adding `extern crate spam` to use the `spam` crate +help: consider importing the `spam` crate + | +LL + extern crate spam; + | error[E0432]: unresolved import `spam` --> $DIR/import-from-missing-star-3.rs:27:13 @@ -12,7 +15,10 @@ error[E0432]: unresolved import `spam` LL | use spam::*; | ^^^^ you might be missing crate `spam` | - = help: consider adding `extern crate spam` to use the `spam` crate +help: consider importing the `spam` crate + | +LL + extern crate spam; + | error: aborting due to 2 previous errors diff --git a/tests/ui/imports/import-from-missing-star.stderr b/tests/ui/imports/import-from-missing-star.stderr index b311527bc28e4..c9bb9baeb4dde 100644 --- a/tests/ui/imports/import-from-missing-star.stderr +++ b/tests/ui/imports/import-from-missing-star.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `spam` LL | use spam::*; | ^^^^ you might be missing crate `spam` | - = help: consider adding `extern crate spam` to use the `spam` crate +help: consider importing the `spam` crate + | +LL + extern crate spam; + | error: aborting due to 1 previous error diff --git a/tests/ui/imports/import3.stderr b/tests/ui/imports/import3.stderr index 06260ef9ebc75..157b5b6356687 100644 --- a/tests/ui/imports/import3.stderr +++ b/tests/ui/imports/import3.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `main` LL | use main::bar; | ^^^^ you might be missing crate `main` | - = help: consider adding `extern crate main` to use the `main` crate +help: consider importing the `main` crate + | +LL + extern crate main; + | error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-109343.stderr b/tests/ui/imports/issue-109343.stderr index fe06eddeada69..e66528e8df528 100644 --- a/tests/ui/imports/issue-109343.stderr +++ b/tests/ui/imports/issue-109343.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `unresolved` LL | pub use unresolved::f; | ^^^^^^^^^^ you might be missing crate `unresolved` | - = help: consider adding `extern crate unresolved` to use the `unresolved` crate +help: consider importing the `unresolved` crate + | +LL + extern crate unresolved; + | error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-1697.rs b/tests/ui/imports/issue-1697.rs index 8ec48d4d28628..019237611df0d 100644 --- a/tests/ui/imports/issue-1697.rs +++ b/tests/ui/imports/issue-1697.rs @@ -3,6 +3,6 @@ use unresolved::*; //~^ ERROR unresolved import `unresolved` [E0432] //~| NOTE you might be missing crate `unresolved` -//~| HELP consider adding `extern crate unresolved` to use the `unresolved` crate +//~| HELP consider importing the `unresolved` crate fn main() {} diff --git a/tests/ui/imports/issue-1697.stderr b/tests/ui/imports/issue-1697.stderr index df2957b8f2b13..ec0d94bd672f9 100644 --- a/tests/ui/imports/issue-1697.stderr +++ b/tests/ui/imports/issue-1697.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `unresolved` LL | use unresolved::*; | ^^^^^^^^^^ you might be missing crate `unresolved` | - = help: consider adding `extern crate unresolved` to use the `unresolved` crate +help: consider importing the `unresolved` crate + | +LL + extern crate unresolved; + | error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-33464.stderr b/tests/ui/imports/issue-33464.stderr index 17cc0e4469e43..28fbcee401f91 100644 --- a/tests/ui/imports/issue-33464.stderr +++ b/tests/ui/imports/issue-33464.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `abc` LL | use abc::one_el; | ^^^ you might be missing crate `abc` | - = help: consider adding `extern crate abc` to use the `abc` crate +help: consider importing the `abc` crate + | +LL + extern crate abc; + | error[E0432]: unresolved import `abc` --> $DIR/issue-33464.rs:5:5 @@ -12,7 +15,10 @@ error[E0432]: unresolved import `abc` LL | use abc::{a, bbb, cccccc}; | ^^^ you might be missing crate `abc` | - = help: consider adding `extern crate abc` to use the `abc` crate +help: consider importing the `abc` crate + | +LL + extern crate abc; + | error[E0432]: unresolved import `a_very_long_name` --> $DIR/issue-33464.rs:7:5 @@ -20,7 +26,10 @@ error[E0432]: unresolved import `a_very_long_name` LL | use a_very_long_name::{el, el2}; | ^^^^^^^^^^^^^^^^ you might be missing crate `a_very_long_name` | - = help: consider adding `extern crate a_very_long_name` to use the `a_very_long_name` crate +help: consider importing the `a_very_long_name` crate + | +LL + extern crate a_very_long_name; + | error: aborting due to 3 previous errors diff --git a/tests/ui/imports/issue-36881.stderr b/tests/ui/imports/issue-36881.stderr index 3c136df83fe4c..004836e072c5e 100644 --- a/tests/ui/imports/issue-36881.stderr +++ b/tests/ui/imports/issue-36881.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `issue_36881_aux` LL | use issue_36881_aux::Foo; | ^^^^^^^^^^^^^^^ you might be missing crate `issue_36881_aux` | - = help: consider adding `extern crate issue_36881_aux` to use the `issue_36881_aux` crate +help: consider importing the `issue_36881_aux` crate + | +LL + extern crate issue_36881_aux; + | error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-37887.stderr b/tests/ui/imports/issue-37887.stderr index 36020707405f1..02c2c80326217 100644 --- a/tests/ui/imports/issue-37887.stderr +++ b/tests/ui/imports/issue-37887.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `test` LL | use test::*; | ^^^^ you might be missing crate `test` | - = help: consider adding `extern crate test` to use the `test` crate +help: consider importing the `test` crate + | +LL + extern crate test; + | error[E0658]: use of unstable library feature 'test' --> $DIR/issue-37887.rs:2:5 diff --git a/tests/ui/imports/issue-53269.stderr b/tests/ui/imports/issue-53269.stderr index 317b3c633a65f..d25d85bf46f02 100644 --- a/tests/ui/imports/issue-53269.stderr +++ b/tests/ui/imports/issue-53269.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `nonexistent_module` LL | use nonexistent_module::mac; | ^^^^^^^^^^^^^^^^^^ you might be missing crate `nonexistent_module` | - = help: consider adding `extern crate nonexistent_module` to use the `nonexistent_module` crate +help: consider importing the `nonexistent_module` crate + | +LL + extern crate nonexistent_module; + | error[E0659]: `mac` is ambiguous --> $DIR/issue-53269.rs:8:5 diff --git a/tests/ui/imports/issue-55457.stderr b/tests/ui/imports/issue-55457.stderr index e9126e6575c0d..9c99b6a20de7c 100644 --- a/tests/ui/imports/issue-55457.stderr +++ b/tests/ui/imports/issue-55457.stderr @@ -13,7 +13,10 @@ error[E0432]: unresolved import `non_existent` LL | use non_existent::non_existent; | ^^^^^^^^^^^^ you might be missing crate `non_existent` | - = help: consider adding `extern crate non_existent` to use the `non_existent` crate +help: consider importing the `non_existent` crate + | +LL + extern crate non_existent; + | error: aborting due to 2 previous errors diff --git a/tests/ui/imports/issue-81413.stderr b/tests/ui/imports/issue-81413.stderr index 321b3695d2cc0..aa1246c1d2f50 100644 --- a/tests/ui/imports/issue-81413.stderr +++ b/tests/ui/imports/issue-81413.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `doesnt_exist` LL | pub use doesnt_exist::*; | ^^^^^^^^^^^^ you might be missing crate `doesnt_exist` | - = help: consider adding `extern crate doesnt_exist` to use the `doesnt_exist` crate +help: consider importing the `doesnt_exist` crate + | +LL + extern crate doesnt_exist; + | error: aborting due to 1 previous error diff --git a/tests/ui/imports/tool-mod-child.stderr b/tests/ui/imports/tool-mod-child.stderr index 764256e76f045..ec110ccd75dbc 100644 --- a/tests/ui/imports/tool-mod-child.stderr +++ b/tests/ui/imports/tool-mod-child.stderr @@ -4,7 +4,10 @@ error[E0433]: failed to resolve: you might be missing crate `clippy` LL | use clippy::a::b; | ^^^^^^ you might be missing crate `clippy` | - = help: consider adding `extern crate clippy` to use the `clippy` crate +help: consider importing the `clippy` crate + | +LL + extern crate clippy; + | error[E0432]: unresolved import `clippy` --> $DIR/tool-mod-child.rs:1:5 @@ -12,7 +15,10 @@ error[E0432]: unresolved import `clippy` LL | use clippy::a; | ^^^^^^ you might be missing crate `clippy` | - = help: consider adding `extern crate clippy` to use the `clippy` crate +help: consider importing the `clippy` crate + | +LL + extern crate clippy; + | error[E0433]: failed to resolve: you might be missing crate `rustdoc` --> $DIR/tool-mod-child.rs:5:5 @@ -20,7 +26,10 @@ error[E0433]: failed to resolve: you might be missing crate `rustdoc` LL | use rustdoc::a::b; | ^^^^^^^ you might be missing crate `rustdoc` | - = help: consider adding `extern crate rustdoc` to use the `rustdoc` crate +help: consider importing the `rustdoc` crate + | +LL + extern crate rustdoc; + | error[E0432]: unresolved import `rustdoc` --> $DIR/tool-mod-child.rs:4:5 @@ -28,7 +37,10 @@ error[E0432]: unresolved import `rustdoc` LL | use rustdoc::a; | ^^^^^^^ you might be missing crate `rustdoc` | - = help: consider adding `extern crate rustdoc` to use the `rustdoc` crate +help: consider importing the `rustdoc` crate + | +LL + extern crate rustdoc; + | error: aborting due to 4 previous errors diff --git a/tests/ui/imports/unresolved-imports-used.stderr b/tests/ui/imports/unresolved-imports-used.stderr index 1cbc2356320f7..4bf02ff6e3a9f 100644 --- a/tests/ui/imports/unresolved-imports-used.stderr +++ b/tests/ui/imports/unresolved-imports-used.stderr @@ -16,7 +16,10 @@ error[E0432]: unresolved import `foo` LL | use foo::bar; | ^^^ you might be missing crate `foo` | - = help: consider adding `extern crate foo` to use the `foo` crate +help: consider importing the `foo` crate + | +LL + extern crate foo; + | error[E0432]: unresolved import `baz` --> $DIR/unresolved-imports-used.rs:12:5 @@ -24,7 +27,10 @@ error[E0432]: unresolved import `baz` LL | use baz::*; | ^^^ you might be missing crate `baz` | - = help: consider adding `extern crate baz` to use the `baz` crate +help: consider importing the `baz` crate + | +LL + extern crate baz; + | error[E0432]: unresolved import `foo2` --> $DIR/unresolved-imports-used.rs:14:5 @@ -32,7 +38,10 @@ error[E0432]: unresolved import `foo2` LL | use foo2::bar2; | ^^^^ you might be missing crate `foo2` | - = help: consider adding `extern crate foo2` to use the `foo2` crate +help: consider importing the `foo2` crate + | +LL + extern crate foo2; + | error[E0432]: unresolved import `baz2` --> $DIR/unresolved-imports-used.rs:15:5 @@ -40,7 +49,10 @@ error[E0432]: unresolved import `baz2` LL | use baz2::*; | ^^^^ you might be missing crate `baz2` | - = help: consider adding `extern crate baz2` to use the `baz2` crate +help: consider importing the `baz2` crate + | +LL + extern crate baz2; + | error[E0603]: function `quz` is private --> $DIR/unresolved-imports-used.rs:9:10 diff --git a/tests/ui/keyword/extern/keyword-extern-as-identifier-use.stderr b/tests/ui/keyword/extern/keyword-extern-as-identifier-use.stderr index a647ca27f1c26..f23f855c9e8e8 100644 --- a/tests/ui/keyword/extern/keyword-extern-as-identifier-use.stderr +++ b/tests/ui/keyword/extern/keyword-extern-as-identifier-use.stderr @@ -15,7 +15,10 @@ error[E0432]: unresolved import `r#extern` LL | use extern::foo; | ^^^^^^ you might be missing crate `r#extern` | - = help: consider adding `extern crate r#extern` to use the `r#extern` crate +help: consider importing the `r#extern` crate + | +LL + extern crate r#extern; + | error: aborting due to 2 previous errors diff --git a/tests/ui/privacy/restricted/test.stderr b/tests/ui/privacy/restricted/test.stderr index a48bb671d9f88..5deaffbdbf3f8 100644 --- a/tests/ui/privacy/restricted/test.stderr +++ b/tests/ui/privacy/restricted/test.stderr @@ -4,7 +4,10 @@ error[E0433]: failed to resolve: you might be missing crate `bad` LL | pub(in bad::path) mod m1 {} | ^^^ you might be missing crate `bad` | - = help: consider adding `extern crate bad` to use the `bad` crate +help: consider importing the `bad` crate + | +LL + extern crate bad; + | error[E0742]: visibilities can only be restricted to ancestor modules --> $DIR/test.rs:51:12 diff --git a/tests/ui/resolve/editions-crate-root-2015.stderr b/tests/ui/resolve/editions-crate-root-2015.stderr index 74fb7e6019ff5..7a842aca0fd27 100644 --- a/tests/ui/resolve/editions-crate-root-2015.stderr +++ b/tests/ui/resolve/editions-crate-root-2015.stderr @@ -4,7 +4,10 @@ error[E0433]: failed to resolve: you might be missing crate `nonexistant` LL | fn global_inner(_: ::nonexistant::Foo) { | ^^^^^^^^^^^ you might be missing crate `nonexistant` | - = help: consider adding `extern crate nonexistant` to use the `nonexistant` crate +help: consider importing the `nonexistant` crate + | +LL + extern crate nonexistant; + | error[E0433]: failed to resolve: you might be missing crate `nonexistant` --> $DIR/editions-crate-root-2015.rs:7:30 @@ -12,7 +15,10 @@ error[E0433]: failed to resolve: you might be missing crate `nonexistant` LL | fn crate_inner(_: crate::nonexistant::Foo) { | ^^^^^^^^^^^ you might be missing crate `nonexistant` | - = help: consider adding `extern crate nonexistant` to use the `nonexistant` crate +help: consider importing the `nonexistant` crate + | +LL + extern crate nonexistant; + | error[E0412]: cannot find type `nonexistant` in the crate root --> $DIR/editions-crate-root-2015.rs:11:25 diff --git a/tests/ui/resolve/extern-prelude-fail.stderr b/tests/ui/resolve/extern-prelude-fail.stderr index 4c2d5abb78247..77c10f5f995bc 100644 --- a/tests/ui/resolve/extern-prelude-fail.stderr +++ b/tests/ui/resolve/extern-prelude-fail.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `extern_prelude` LL | use extern_prelude::S; | ^^^^^^^^^^^^^^ you might be missing crate `extern_prelude` | - = help: consider adding `extern crate extern_prelude` to use the `extern_prelude` crate +help: consider importing the `extern_prelude` crate + | +LL + extern crate extern_prelude; + | error[E0433]: failed to resolve: you might be missing crate `extern_prelude` --> $DIR/extern-prelude-fail.rs:8:15 @@ -12,7 +15,10 @@ error[E0433]: failed to resolve: you might be missing crate `extern_prelude` LL | let s = ::extern_prelude::S; | ^^^^^^^^^^^^^^ you might be missing crate `extern_prelude` | - = help: consider adding `extern crate extern_prelude` to use the `extern_prelude` crate +help: consider importing the `extern_prelude` crate + | +LL + extern crate extern_prelude; + | error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-82865.stderr b/tests/ui/resolve/issue-82865.stderr index ce0061a2b665e..bc7e0f0798177 100644 --- a/tests/ui/resolve/issue-82865.stderr +++ b/tests/ui/resolve/issue-82865.stderr @@ -4,7 +4,10 @@ error[E0433]: failed to resolve: you might be missing crate `x` LL | use x::y::z; | ^ you might be missing crate `x` | - = help: consider adding `extern crate x` to use the `x` crate +help: consider importing the `x` crate + | +LL + extern crate x; + | error[E0599]: no function or associated item named `z` found for struct `Box<_, _>` in the current scope --> $DIR/issue-82865.rs:8:10 diff --git a/tests/ui/resolve/resolve-bad-visibility.stderr b/tests/ui/resolve/resolve-bad-visibility.stderr index 8e4757354030e..281e5afb22302 100644 --- a/tests/ui/resolve/resolve-bad-visibility.stderr +++ b/tests/ui/resolve/resolve-bad-visibility.stderr @@ -22,7 +22,10 @@ error[E0433]: failed to resolve: you might be missing crate `nonexistent` LL | pub(in nonexistent) struct G; | ^^^^^^^^^^^ you might be missing crate `nonexistent` | - = help: consider adding `extern crate nonexistent` to use the `nonexistent` crate +help: consider importing the `nonexistent` crate + | +LL + extern crate nonexistent; + | error[E0433]: failed to resolve: you might be missing crate `too_soon` --> $DIR/resolve-bad-visibility.rs:8:8 @@ -30,7 +33,10 @@ error[E0433]: failed to resolve: you might be missing crate `too_soon` LL | pub(in too_soon) struct H; | ^^^^^^^^ you might be missing crate `too_soon` | - = help: consider adding `extern crate too_soon` to use the `too_soon` crate +help: consider importing the `too_soon` crate + | +LL + extern crate too_soon; + | error: aborting due to 5 previous errors diff --git a/tests/ui/underscore-imports/issue-110164.stderr b/tests/ui/underscore-imports/issue-110164.stderr index 240742996e12a..d8a4b6bbb7549 100644 --- a/tests/ui/underscore-imports/issue-110164.stderr +++ b/tests/ui/underscore-imports/issue-110164.stderr @@ -38,33 +38,25 @@ error[E0432]: unresolved import `_` --> $DIR/issue-110164.rs:8:5 | LL | use _::*; - | ^ you might be missing crate `_` - | - = help: consider adding `extern crate _` to use the `_` crate + | ^ `_` is not a valid crate or module name error[E0432]: unresolved import `_` --> $DIR/issue-110164.rs:5:5 | LL | use _::a; - | ^ you might be missing crate `_` - | - = help: consider adding `extern crate _` to use the `_` crate + | ^ `_` is not a valid crate or module name error[E0432]: unresolved import `_` --> $DIR/issue-110164.rs:13:9 | LL | use _::a; - | ^ you might be missing crate `_` - | - = help: consider adding `extern crate _` to use the `_` crate + | ^ `_` is not a valid crate or module name error[E0432]: unresolved import `_` --> $DIR/issue-110164.rs:16:9 | LL | use _::*; - | ^ you might be missing crate `_` - | - = help: consider adding `extern crate _` to use the `_` crate + | ^ `_` is not a valid crate or module name error: aborting due to 10 previous errors diff --git a/tests/ui/unresolved/unresolved-asterisk-imports.stderr b/tests/ui/unresolved/unresolved-asterisk-imports.stderr index 299ec699775e9..ed01f3fdbea41 100644 --- a/tests/ui/unresolved/unresolved-asterisk-imports.stderr +++ b/tests/ui/unresolved/unresolved-asterisk-imports.stderr @@ -4,7 +4,10 @@ error[E0432]: unresolved import `not_existing_crate` LL | use not_existing_crate::*; | ^^^^^^^^^^^^^^^^^^ you might be missing crate `not_existing_crate` | - = help: consider adding `extern crate not_existing_crate` to use the `not_existing_crate` crate +help: consider importing the `not_existing_crate` crate + | +LL + extern crate not_existing_crate; + | error: aborting due to 1 previous error diff --git a/tests/ui/unresolved/unresolved-import.rs b/tests/ui/unresolved/unresolved-import.rs index e8f3b323e3375..ee520d65e6f4a 100644 --- a/tests/ui/unresolved/unresolved-import.rs +++ b/tests/ui/unresolved/unresolved-import.rs @@ -1,7 +1,8 @@ use foo::bar; //~^ ERROR unresolved import `foo` [E0432] //~| NOTE you might be missing crate `foo` -//~| HELP consider adding `extern crate foo` to use the `foo` crate +//~| HELP consider importing the `foo` crate +//~| SUGGESTION extern crate foo; use bar::Baz as x; //~^ ERROR unresolved import `bar::Baz` [E0432] diff --git a/tests/ui/unresolved/unresolved-import.stderr b/tests/ui/unresolved/unresolved-import.stderr index 7b03717c827ce..a1ff2f19eb640 100644 --- a/tests/ui/unresolved/unresolved-import.stderr +++ b/tests/ui/unresolved/unresolved-import.stderr @@ -4,10 +4,13 @@ error[E0432]: unresolved import `foo` LL | use foo::bar; | ^^^ you might be missing crate `foo` | - = help: consider adding `extern crate foo` to use the `foo` crate +help: consider importing the `foo` crate + | +LL + extern crate foo; + | error[E0432]: unresolved import `bar::Baz` - --> $DIR/unresolved-import.rs:6:5 + --> $DIR/unresolved-import.rs:7:5 | LL | use bar::Baz as x; | ^^^^^---^^^^^ @@ -16,7 +19,7 @@ LL | use bar::Baz as x; | no `Baz` in `bar` error[E0432]: unresolved import `food::baz` - --> $DIR/unresolved-import.rs:12:5 + --> $DIR/unresolved-import.rs:13:5 | LL | use food::baz; | ^^^^^^--- @@ -25,7 +28,7 @@ LL | use food::baz; | no `baz` in `food` error[E0432]: unresolved import `food::beens` - --> $DIR/unresolved-import.rs:18:12 + --> $DIR/unresolved-import.rs:19:12 | LL | use food::{beens as Foo}; | -----^^^^^^^ @@ -34,13 +37,13 @@ LL | use food::{beens as Foo}; | help: a similar name exists in the module: `beans` error[E0432]: unresolved import `MyEnum` - --> $DIR/unresolved-import.rs:43:9 + --> $DIR/unresolved-import.rs:44:9 | LL | use MyEnum::*; | ^^^^^^ help: a similar path exists: `self::MyEnum` error[E0432]: unresolved import `Enum` - --> $DIR/unresolved-import.rs:54:9 + --> $DIR/unresolved-import.rs:55:9 | LL | use Enum::*; | ^^^^ help: a similar path exists: `self::Enum`