diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 188ca8048055c..924bacb7aae21 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2017,9 +2017,7 @@ pub enum ProjectionElem { from_end: bool, }, - /// "Downcast" to a variant of an ADT. Currently, we only introduce - /// this for ADTs with more than one variant. It may be better to - /// just introduce it always, or always for enums. + /// "Downcast" to a variant of an enum or a generator. /// /// The included Symbol is the name of the variant, used for printing MIR. Downcast(Option, VariantIdx), diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 597ade4223684..f1d5201454d69 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -12,7 +12,7 @@ use rustc_target::abi::VariantIdx; #[derive(Copy, Clone, Debug, TypeFoldable)] pub struct PlaceTy<'tcx> { pub ty: Ty<'tcx>, - /// Downcast to a particular variant of an enum, if included. + /// Downcast to a particular variant of an enum or a generator, if included. pub variant_index: Option, } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index aef9fb57a6a7c..5d80f49626a04 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -117,7 +117,7 @@ impl<'a> Resolver<'a> { } fn report_with_use_injections(&mut self, krate: &Crate) { - for UseError { mut err, candidates, def_id, instead, suggestion } in + for UseError { mut err, candidates, def_id, instead, suggestion, path } in self.use_injections.drain(..) { let (span, found_use) = if let Some(def_id) = def_id.as_local() { @@ -135,6 +135,7 @@ impl<'a> Resolver<'a> { if instead { Instead::Yes } else { Instead::No }, found_use, IsPattern::No, + path, ); } else if let Some((span, msg, sugg, appl)) = suggestion { err.span_suggestion(span, msg, sugg, appl); @@ -702,6 +703,7 @@ impl<'a> Resolver<'a> { Instead::No, FoundUse::Yes, IsPattern::Yes, + vec![], ); } err @@ -1482,6 +1484,7 @@ impl<'a> Resolver<'a> { Instead::No, FoundUse::Yes, IsPattern::No, + vec![], ); if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) { @@ -2448,6 +2451,7 @@ fn show_candidates( instead: Instead, found_use: FoundUse, is_pattern: IsPattern, + path: Vec, ) { if candidates.is_empty() { return; @@ -2515,6 +2519,14 @@ fn show_candidates( accessible_path_strings.into_iter().map(|a| a.0), Applicability::MaybeIncorrect, ); + if let [first, .., last] = &path[..] { + err.span_suggestion_verbose( + first.ident.span.until(last.ident.span), + &format!("if you import `{}`, refer to it directly", last.ident), + String::new(), + Applicability::Unspecified, + ); + } } else { msg.push(':'); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ab353128cbcce..994a37b473764 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2696,6 +2696,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { def_id, instead, suggestion, + path: path.into(), }); } @@ -2759,6 +2760,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { def_id, instead: false, suggestion: None, + path: path.into(), }); } else { err.cancel(); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index f6109b1dc1a1a..ff11aba49d836 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -696,6 +696,9 @@ struct UseError<'a> { instead: bool, /// Extra free-form suggestion. suggestion: Option<(Span, &'static str, String, Applicability)>, + /// Path `Segment`s at the place of use that failed. Used for accurate suggestion after telling + /// the user to import the item directly. + path: Vec, } #[derive(Clone, Copy, PartialEq, Debug)] diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index a3d3c7c0cf3aa..bfb8ce6f1051c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -866,7 +866,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { return false; } - let orig_ty = old_pred.self_ty().skip_binder(); + // This is a quick fix to resolve an ICE (#96223). + // This change should probably be deeper. + // As suggested by @jackh726, `mk_trait_obligation_with_new_self_ty` could take a `Binder<(TraitRef, Ty)> + // instead of `Binder` leading to some changes to its call places. + let Some(orig_ty) = old_pred.self_ty().no_bound_vars() else { + return false; + }; let mk_result = |new_ty| { let obligation = self.mk_trait_obligation_with_new_self_ty(param_env, old_pred, new_ty); diff --git a/library/core/src/internal_macros.rs b/library/core/src/internal_macros.rs index 7ef78e0b48af1..5d4c9ba73951a 100644 --- a/library/core/src/internal_macros.rs +++ b/library/core/src/internal_macros.rs @@ -190,7 +190,7 @@ macro_rules! impl_fn_for_zst { /// /// # Example /// -/// ``` +/// ```ignore(cannot-test-this-because-non-exported-macro) /// cfg_if! { /// if #[cfg(unix)] { /// fn foo() { /* unix specific functionality */ } diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index edfe31319e8d0..2224bf5f66e90 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1405,7 +1405,8 @@ impl<'a> Builder<'a> { // FIXME(davidtwco): #[cfg(not(bootstrap))] - #95612 needs to be in the bootstrap compiler // for this conditional to be removed. if !target.contains("windows") || compiler.stage >= 1 { - if target.contains("linux") || target.contains("windows") { + if target.contains("linux") || target.contains("windows") || target.contains("openbsd") + { rustflags.arg("-Zunstable-options"); } match self.config.rust_split_debuginfo { diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md index 7bd46fafadf83..fbec3cd9baf50 100644 --- a/src/doc/rustc/src/lints/levels.md +++ b/src/doc/rustc/src/lints/levels.md @@ -100,9 +100,8 @@ This lint level gives you that. 'force-warn' does for 'warn'. It's the same as 'deny' in that a lint at this level will produce an error, but unlike the 'deny' level, the 'forbid' level can not be overridden to be anything lower than an error. However, lint -levels may still be capped with `--cap-lints` (see below) so `rustc --cap- -lints warn` will make lints set to 'forbid' just -warn. +levels may still be capped with `--cap-lints` (see below) so `rustc --cap-lints warn` +will make lints set to 'forbid' just warn. ## Configuring warning levels diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 82e367427ef6f..93ccf60a1de45 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1225,16 +1225,6 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx> fn visit_item(&mut self, item: &'hir hir::Item<'_>) { let name = match &item.kind { - hir::ItemKind::Macro(ref macro_def, _) => { - // FIXME(#88038): Non exported macros have historically not been tested, - // but we really ought to start testing them. - let def_id = item.def_id.to_def_id(); - if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) { - intravisit::walk_item(self, item); - return; - } - item.ident.to_string() - } hir::ItemKind::Impl(impl_) => { rustc_hir_pretty::id_to_string(&self.map, impl_.self_ty.hir_id) } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index cd196a0184799..ef8c766180b8a 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -96,7 +96,7 @@ use crate::passes::collect_intra_doc_links; /// /// Example: /// -/// ``` +/// ```ignore(cannot-test-this-because-non-exported-macro) /// let letters = map!{"a" => "b", "c" => "d"}; /// ``` /// diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs index 1d2ef832db77b..07d05cab1d1d7 100644 --- a/src/librustdoc/passes/collect_intra_doc_links/early.rs +++ b/src/librustdoc/passes/collect_intra_doc_links/early.rs @@ -293,10 +293,22 @@ impl<'ra> EarlyDocLinkResolver<'_, 'ra> { if let Res::Def(DefKind::Mod, ..) = child.res { self.resolve_doc_links_extern_inner(def_id); // Inner attribute scope } - // Traits are processed in `add_extern_traits_in_scope`. + // `DefKind::Trait`s are processed in `process_extern_impls`. if let Res::Def(DefKind::Mod | DefKind::Enum, ..) = child.res { self.process_module_children_or_reexports(def_id); } + if let Res::Def(DefKind::Struct | DefKind::Union | DefKind::Variant, _) = + child.res + { + let field_def_ids = Vec::from_iter( + self.resolver + .cstore() + .associated_item_def_ids_untracked(def_id, self.sess), + ); + for field_def_id in field_def_ids { + self.resolve_doc_links_extern_outer(field_def_id, scope_id); + } + } } } } diff --git a/src/test/rustdoc-ui/block-doc-comment.rs b/src/test/rustdoc-ui/block-doc-comment.rs index c60dfa3f9518e..ce529916e5ede 100644 --- a/src/test/rustdoc-ui/block-doc-comment.rs +++ b/src/test/rustdoc-ui/block-doc-comment.rs @@ -1,5 +1,6 @@ // check-pass // compile-flags:--test +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" // This test ensures that no code block is detected in the doc comments. diff --git a/src/test/rustdoc-ui/block-doc-comment.stdout b/src/test/rustdoc-ui/block-doc-comment.stdout index e5c27bebbdb23..7326c0a25a069 100644 --- a/src/test/rustdoc-ui/block-doc-comment.stdout +++ b/src/test/rustdoc-ui/block-doc-comment.stdout @@ -1,5 +1,5 @@ running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/src/test/rustdoc-ui/intra-doc/assoc-field.rs b/src/test/rustdoc-ui/intra-doc/assoc-field.rs new file mode 100644 index 0000000000000..e18404e44306e --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/assoc-field.rs @@ -0,0 +1,26 @@ +// Traits in scope are collected for doc links in field attributes. + +// check-pass +// aux-build: assoc-field-dep.rs + +extern crate assoc_field_dep; +pub use assoc_field_dep::*; + +#[derive(Clone)] +pub struct Struct; + +pub mod mod1 { + pub struct Fields { + /// [crate::Struct::clone] + pub field: u8, + } +} + +pub mod mod2 { + pub enum Fields { + V { + /// [crate::Struct::clone] + field: u8, + }, + } +} diff --git a/src/test/rustdoc-ui/intra-doc/auxiliary/assoc-field-dep.rs b/src/test/rustdoc-ui/intra-doc/auxiliary/assoc-field-dep.rs new file mode 100644 index 0000000000000..cfb24fc2c665c --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/auxiliary/assoc-field-dep.rs @@ -0,0 +1,18 @@ +#[derive(Clone)] +pub struct Struct; + +pub mod dep_mod1 { + pub struct Fields { + /// [crate::Struct::clone] + pub field: u8, + } +} + +pub mod dep_mod2 { + pub enum Fields { + V { + /// [crate::Struct::clone] + field: u8, + }, + } +} diff --git a/src/test/ui/macros/macro-outer-attributes.stderr b/src/test/ui/macros/macro-outer-attributes.stderr index 8e064d980afab..91073d3698d91 100644 --- a/src/test/ui/macros/macro-outer-attributes.stderr +++ b/src/test/ui/macros/macro-outer-attributes.stderr @@ -8,6 +8,11 @@ help: consider importing this function | LL | use b::bar; | +help: if you import `bar`, refer to it directly + | +LL - a::bar(); +LL + bar(); + | error: aborting due to previous error diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr index b610857229201..037a858d7e101 100644 --- a/src/test/ui/namespace/namespace-mix.stderr +++ b/src/test/ui/namespace/namespace-mix.stderr @@ -18,6 +18,11 @@ LL | use m2::S; | LL | use xm2::S; | +help: if you import `S`, refer to it directly + | +LL - check(m1::S); +LL + check(S); + | error[E0423]: expected value, found type alias `xm1::S` --> $DIR/namespace-mix.rs:40:11 @@ -41,6 +46,11 @@ LL | use m2::S; | LL | use xm2::S; | +help: if you import `S`, refer to it directly + | +LL - check(xm1::S); +LL + check(S); + | error[E0423]: expected value, found struct variant `m7::V` --> $DIR/namespace-mix.rs:100:11 @@ -67,6 +77,11 @@ LL | use m8::V; | LL | use xm8::V; | +help: if you import `V`, refer to it directly + | +LL - check(m7::V); +LL + check(V); + | error[E0423]: expected value, found struct variant `xm7::V` --> $DIR/namespace-mix.rs:106:11 @@ -95,6 +110,11 @@ LL | use m8::V; | LL | use xm8::V; | +help: if you import `V`, refer to it directly + | +LL - check(xm7::V); +LL + check(V); + | error[E0277]: the trait bound `c::Item: Impossible` is not satisfied --> $DIR/namespace-mix.rs:33:11 diff --git a/src/test/ui/parser/circular_modules_main.stderr b/src/test/ui/parser/circular_modules_main.stderr index ee45f65a3bd5a..c5434c72b382b 100644 --- a/src/test/ui/parser/circular_modules_main.stderr +++ b/src/test/ui/parser/circular_modules_main.stderr @@ -14,6 +14,11 @@ help: consider importing this function | LL | use hi_str; | +help: if you import `hi_str`, refer to it directly + | +LL - println!("{}", circular_modules_main::hi_str()); +LL + println!("{}", hi_str()); + | error: aborting due to 2 previous errors diff --git a/src/test/ui/resolve/enums-are-namespaced-xc.stderr b/src/test/ui/resolve/enums-are-namespaced-xc.stderr index 621686dd292d6..1d26a2c005872 100644 --- a/src/test/ui/resolve/enums-are-namespaced-xc.stderr +++ b/src/test/ui/resolve/enums-are-namespaced-xc.stderr @@ -8,6 +8,11 @@ help: consider importing this unit variant | LL | use namespaced_enums::Foo::A; | +help: if you import `A`, refer to it directly + | +LL - let _ = namespaced_enums::A; +LL + let _ = A; + | error[E0425]: cannot find function, tuple struct or tuple variant `B` in crate `namespaced_enums` --> $DIR/enums-are-namespaced-xc.rs:7:31 @@ -19,6 +24,11 @@ help: consider importing this tuple variant | LL | use namespaced_enums::Foo::B; | +help: if you import `B`, refer to it directly + | +LL - let _ = namespaced_enums::B(10); +LL + let _ = B(10); + | error[E0422]: cannot find struct, variant or union type `C` in crate `namespaced_enums` --> $DIR/enums-are-namespaced-xc.rs:9:31 @@ -30,6 +40,11 @@ help: consider importing this variant | LL | use namespaced_enums::Foo::C; | +help: if you import `C`, refer to it directly + | +LL - let _ = namespaced_enums::C { a: 10 }; +LL + let _ = C { a: 10 }; + | error: aborting due to 3 previous errors diff --git a/src/test/ui/resolve/issue-50599.stderr b/src/test/ui/resolve/issue-50599.stderr index 7ec567a06f09d..4cc035cb11e20 100644 --- a/src/test/ui/resolve/issue-50599.stderr +++ b/src/test/ui/resolve/issue-50599.stderr @@ -10,6 +10,11 @@ LL | use std::f32::consts::LOG10_2; | LL | use std::f64::consts::LOG10_2; | +help: if you import `LOG10_2`, refer to it directly + | +LL - const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; +LL + const M: usize = (f64::from(N) * LOG10_2) as usize; + | error: aborting due to previous error diff --git a/src/test/ui/resolve/missing-in-namespace.stderr b/src/test/ui/resolve/missing-in-namespace.stderr index 8b292aeda5074..338a5423aa472 100644 --- a/src/test/ui/resolve/missing-in-namespace.stderr +++ b/src/test/ui/resolve/missing-in-namespace.stderr @@ -8,6 +8,11 @@ help: consider importing this struct | LL | use std::collections::HashMap; | +help: if you import `HashMap`, refer to it directly + | +LL - let _map = std::hahmap::HashMap::new(); +LL + let _map = HashMap::new(); + | error: aborting due to previous error diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr index c93ba915efb2f..ed89170fd8a75 100644 --- a/src/test/ui/resolve/privacy-enum-ctor.stderr +++ b/src/test/ui/resolve/privacy-enum-ctor.stderr @@ -105,6 +105,11 @@ LL | use std::f32::consts::E; | LL | use std::f64::consts::E; | +help: if you import `E`, refer to it directly + | +LL - let _: E = m::E; +LL + let _: E = E; + | error[E0423]: expected value, found struct variant `m::E::Struct` --> $DIR/privacy-enum-ctor.rs:45:16 diff --git a/src/test/ui/resolve/resolve-primitive-fallback.stderr b/src/test/ui/resolve/resolve-primitive-fallback.stderr index 44631f954df33..fcbc28475f998 100644 --- a/src/test/ui/resolve/resolve-primitive-fallback.stderr +++ b/src/test/ui/resolve/resolve-primitive-fallback.stderr @@ -14,6 +14,11 @@ help: consider importing this builtin type | LL | use std::primitive::u8; | +help: if you import `u8`, refer to it directly + | +LL - let _: ::u8; +LL + let _: u8; + | error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/resolve-primitive-fallback.rs:3:5 diff --git a/src/test/ui/suggestions/issue-96223.rs b/src/test/ui/suggestions/issue-96223.rs new file mode 100644 index 0000000000000..85667bb849bd4 --- /dev/null +++ b/src/test/ui/suggestions/issue-96223.rs @@ -0,0 +1,52 @@ +// Previously ICEd because we didn't properly track binders in suggestions +// check-fail + +pub trait Foo<'de>: Sized {} + +pub trait Bar<'a>: 'static { + type Inner: 'a; +} + +pub trait Fubar { + type Bar: for<'a> Bar<'a>; +} + +pub struct Baz(pub T); + +impl<'de, T> Foo<'de> for Baz where T: Foo<'de> {} + +struct Empty; + +impl Dummy for Empty +where + M: Fubar, + for<'de> Baz<>::Inner>: Foo<'de>, +{ +} + +pub trait Dummy +where + M: Fubar, +{ +} + +pub struct EmptyBis<'a>(&'a [u8]); + +impl<'a> Bar<'a> for EmptyBis<'static> { + type Inner = EmptyBis<'a>; +} + +pub struct EmptyMarker; + +impl Fubar for EmptyMarker { + type Bar = EmptyBis<'static>; +} + +fn icey_bounds>(p: &D) {} + +fn trigger_ice() { + let p = Empty; + icey_bounds(&p); //~ERROR the trait bound +} + +fn main() {} diff --git a/src/test/ui/suggestions/issue-96223.stderr b/src/test/ui/suggestions/issue-96223.stderr new file mode 100644 index 0000000000000..513725d99628c --- /dev/null +++ b/src/test/ui/suggestions/issue-96223.stderr @@ -0,0 +1,28 @@ +error[E0277]: the trait bound `for<'de> EmptyBis<'de>: Foo<'_>` is not satisfied + --> $DIR/issue-96223.rs:49:17 + | +LL | icey_bounds(&p); + | ----------- ^^ the trait `for<'de> Foo<'_>` is not implemented for `EmptyBis<'de>` + | | + | required by a bound introduced by this call + | + = help: the trait `Foo<'de>` is implemented for `Baz` +note: required because of the requirements on the impl of `for<'de> Foo<'de>` for `Baz>` + --> $DIR/issue-96223.rs:16:14 + | +LL | impl<'de, T> Foo<'de> for Baz where T: Foo<'de> {} + | ^^^^^^^^ ^^^^^^ +note: required because of the requirements on the impl of `Dummy` for `Empty` + --> $DIR/issue-96223.rs:20:9 + | +LL | impl Dummy for Empty + | ^^^^^^^^ ^^^^^ +note: required by a bound in `icey_bounds` + --> $DIR/issue-96223.rs:45:19 + | +LL | fn icey_bounds>(p: &D) {} + | ^^^^^^^^^^^^^^^^^^ required by this bound in `icey_bounds` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.fixed b/src/test/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.fixed new file mode 100644 index 0000000000000..39e90d7a3f786 --- /dev/null +++ b/src/test/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.fixed @@ -0,0 +1,16 @@ +// run-rustfix +#![allow(non_snake_case)] +mod A { + pub trait Trait {} + impl Trait for i32 {} +} + +mod B { + use A::Trait; + +pub struct A(pub H); //~ ERROR cannot find trait +} + +fn main() { + let _ = B::A(42); +} diff --git a/src/test/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.rs b/src/test/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.rs new file mode 100644 index 0000000000000..ee6ed0cae671c --- /dev/null +++ b/src/test/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.rs @@ -0,0 +1,14 @@ +// run-rustfix +#![allow(non_snake_case)] +mod A { + pub trait Trait {} + impl Trait for i32 {} +} + +mod B { + pub struct A(pub H); //~ ERROR cannot find trait +} + +fn main() { + let _ = B::A(42); +} diff --git a/src/test/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr b/src/test/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr new file mode 100644 index 0000000000000..a8b275f98034a --- /dev/null +++ b/src/test/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr @@ -0,0 +1,19 @@ +error[E0405]: cannot find trait `Trait` in `A` + --> $DIR/shadowed-path-in-trait-bound-suggestion.rs:9:24 + | +LL | pub struct A(pub H); + | ^^^^^ not found in `A` + | +help: consider importing this trait + | +LL | use A::Trait; + | +help: if you import `Trait`, refer to it directly + | +LL - pub struct A(pub H); +LL + pub struct A(pub H); + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0405`.