From 833af65f38c4674e3ae6d886174e65f0fcabab3d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 7 Aug 2024 13:01:34 -0400 Subject: [PATCH 1/3] Use FnSig instead of raw FnDecl for ForeignItemKind::Fn --- compiler/rustc_ast_lowering/src/delegation.rs | 2 +- compiler/rustc_ast_lowering/src/item.rs | 24 +++++--- compiler/rustc_hir/src/hir.rs | 39 +++++++----- compiler/rustc_hir/src/intravisit.rs | 4 +- .../rustc_hir_analysis/src/check/check.rs | 4 +- .../rustc_hir_analysis/src/check/intrinsic.rs | 2 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 4 +- compiler/rustc_hir_analysis/src/collect.rs | 6 +- .../src/collect/resolve_bound_vars.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 11 +--- compiler/rustc_lint/src/types.rs | 9 ++- compiler/rustc_middle/src/hir/map/mod.rs | 10 ++-- compiler/rustc_middle/src/hir/mod.rs | 2 +- .../ui/extern/extern-main-issue-86110.stderr | 2 +- .../safe-intrinsic-mismatch.effects.stderr | 4 +- .../safe-intrinsic-mismatch.stock.stderr | 4 +- tests/ui/issues/issue-16725.stderr | 2 +- tests/ui/lint/clashing-extern-fn.stderr | 60 +++++++++---------- tests/ui/lint/issue-1866.stderr | 4 +- .../ui/lint/lint-attr-everywhere-late.stderr | 8 +-- tests/ui/lint/lint-missing-doc.stderr | 2 +- tests/ui/lint/unreachable_pub.stderr | 2 +- .../ui/privacy/private-in-public-warn.stderr | 4 +- 23 files changed, 113 insertions(+), 98 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 300bfa101c6bd..9c073130827c8 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -189,7 +189,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> hir::FnSig<'hir> { let header = if let Some(local_sig_id) = sig_id.as_local() { match self.resolver.delegation_fn_sigs.get(&local_sig_id) { - Some(sig) => self.lower_fn_header(sig.header), + Some(sig) => self.lower_fn_header(sig.header, hir::Safety::Safe), None => self.generate_header_error(), } } else { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 7af3945d3f99d..f6065259d8d21 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -237,7 +237,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }); let sig = hir::FnSig { decl, - header: this.lower_fn_header(*header), + header: this.lower_fn_header(*header, hir::Safety::Safe), span: this.lower_span(*fn_sig_span), }; hir::ItemKind::Fn(sig, generics, body_id) @@ -668,7 +668,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ForeignItemKind::Fn(box Fn { sig, generics, .. }) => { let fdec = &sig.decl; let itctx = ImplTraitContext::Universal; - let (generics, (fn_dec, fn_args)) = + let (generics, (decl, fn_args)) = self.lower_generics(generics, Const::No, false, i.id, itctx, |this| { ( // Disallow `impl Trait` in foreign items. @@ -682,9 +682,15 @@ impl<'hir> LoweringContext<'_, 'hir> { this.lower_fn_params_to_names(fdec), ) }); - let safety = self.lower_safety(sig.header.safety, hir::Safety::Unsafe); - hir::ForeignItemKind::Fn(fn_dec, fn_args, generics, safety) + // Unmarked safety in unsafe block defaults to unsafe. + let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe); + + hir::ForeignItemKind::Fn( + hir::FnSig { header, decl, span: self.lower_span(sig.span) }, + fn_args, + generics, + ) } ForeignItemKind::Static(box StaticItem { ty, mutability, expr: _, safety }) => { let ty = self @@ -1390,7 +1396,7 @@ impl<'hir> LoweringContext<'_, 'hir> { coroutine_kind: Option, parent_constness: Const, ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) { - let header = self.lower_fn_header(sig.header); + let header = self.lower_fn_header(sig.header, hir::Safety::Safe); // Don't pass along the user-provided constness of trait associated functions; we don't want to // synthesize a host effect param for them. We reject `const` on them during AST validation. let constness = @@ -1403,14 +1409,18 @@ impl<'hir> LoweringContext<'_, 'hir> { (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) }) } - pub(super) fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader { + pub(super) fn lower_fn_header( + &mut self, + h: FnHeader, + default_safety: hir::Safety, + ) -> hir::FnHeader { let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coroutine_kind { hir::IsAsync::Async(span) } else { hir::IsAsync::NotAsync }; hir::FnHeader { - safety: self.lower_safety(h.safety, hir::Safety::Safe), + safety: self.lower_safety(h.safety, default_safety), asyncness: asyncness, constness: self.lower_constness(h.constness), abi: self.lower_extern(h.ext), diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 33e8432596be1..6599e70346117 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3586,7 +3586,7 @@ impl ForeignItem<'_> { #[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ForeignItemKind<'hir> { /// A foreign function. - Fn(&'hir FnDecl<'hir>, &'hir [Ident], &'hir Generics<'hir>, Safety), + Fn(FnSig<'hir>, &'hir [Ident], &'hir Generics<'hir>), /// A foreign static item (`static ext: u8`). Static(&'hir Ty<'hir>, Mutability, Safety), /// A foreign type. @@ -3645,7 +3645,10 @@ impl<'hir> OwnerNode<'hir> { match self { OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. }) | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. }) - | OwnerNode::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig), + | OwnerNode::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) + | OwnerNode::ForeignItem(ForeignItem { + kind: ForeignItemKind::Fn(fn_sig, _, _), .. + }) => Some(fn_sig), _ => None, } } @@ -3654,11 +3657,10 @@ impl<'hir> OwnerNode<'hir> { match self { OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. }) | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. }) - | OwnerNode::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl), - OwnerNode::ForeignItem(ForeignItem { - kind: ForeignItemKind::Fn(fn_decl, _, _, _), - .. - }) => Some(fn_decl), + | OwnerNode::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) + | OwnerNode::ForeignItem(ForeignItem { + kind: ForeignItemKind::Fn(fn_sig, _, _), .. + }) => Some(fn_sig.decl), _ => None, } } @@ -3846,11 +3848,13 @@ impl<'hir> Node<'hir> { match self { Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. }) | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. }) - | Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl), - Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. }) - | Node::ForeignItem(ForeignItem { - kind: ForeignItemKind::Fn(fn_decl, _, _, _), .. - }) => Some(fn_decl), + | Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) + | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => { + Some(fn_sig.decl) + } + Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. }) => { + Some(fn_decl) + } _ => None, } } @@ -3874,7 +3878,10 @@ impl<'hir> Node<'hir> { match self { Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. }) | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. }) - | Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig), + | Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) + | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => { + Some(fn_sig) + } _ => None, } } @@ -3949,7 +3956,7 @@ impl<'hir> Node<'hir> { pub fn generics(self) -> Option<&'hir Generics<'hir>> { match self { Node::ForeignItem(ForeignItem { - kind: ForeignItemKind::Fn(_, _, generics, _), .. + kind: ForeignItemKind::Fn(_, _, generics), .. }) | Node::TraitItem(TraitItem { generics, .. }) | Node::ImplItem(ImplItem { generics, .. }) => Some(generics), @@ -4039,8 +4046,8 @@ mod size_asserts { static_assert_size!(Expr<'_>, 64); static_assert_size!(ExprKind<'_>, 48); static_assert_size!(FnDecl<'_>, 40); - static_assert_size!(ForeignItem<'_>, 72); - static_assert_size!(ForeignItemKind<'_>, 40); + static_assert_size!(ForeignItem<'_>, 88); + static_assert_size!(ForeignItemKind<'_>, 56); static_assert_size!(GenericArg<'_>, 16); static_assert_size!(GenericBound<'_>, 48); static_assert_size!(Generics<'_>, 56); diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index dd501f8417e64..a54596e3088dc 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -611,9 +611,9 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>( try_visit!(visitor.visit_ident(foreign_item.ident)); match foreign_item.kind { - ForeignItemKind::Fn(ref function_declaration, param_names, ref generics, _) => { + ForeignItemKind::Fn(ref sig, param_names, ref generics) => { try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_fn_decl(function_declaration)); + try_visit!(visitor.visit_fn_decl(sig.decl)); walk_list!(visitor, visit_ident, param_names.iter().copied()); } ForeignItemKind::Static(ref typ, _, _) => { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 2e778fd375961..0135cdf1e9002 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -804,8 +804,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { let item = tcx.hir().foreign_item(item.id); match &item.kind { - hir::ForeignItemKind::Fn(fn_decl, _, _, _) => { - require_c_abi_if_c_variadic(tcx, fn_decl, abi, item.span); + hir::ForeignItemKind::Fn(sig, _, _) => { + require_c_abi_if_c_variadic(tcx, sig.decl, abi, item.span); } hir::ForeignItemKind::Static(..) => { check_static_inhabited(tcx, def_id); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 4b45ced30c579..c2b2f08132ed8 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -30,7 +30,7 @@ fn equate_intrinsic_type<'tcx>( let (generics, span) = match tcx.hir_node_by_def_id(def_id) { hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }) | hir::Node::ForeignItem(hir::ForeignItem { - kind: hir::ForeignItemKind::Fn(.., generics, _), + kind: hir::ForeignItemKind::Fn(_, _, generics), .. }) => (tcx.generics_of(def_id), generics.span), _ => { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index d3b928fc17c5b..bdf2914fc50c6 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -350,8 +350,8 @@ fn check_foreign_item<'tcx>( ); match item.kind { - hir::ForeignItemKind::Fn(decl, ..) => { - check_item_fn(tcx, def_id, item.ident, item.span, decl) + hir::ForeignItemKind::Fn(sig, ..) => { + check_item_fn(tcx, def_id, item.ident, item.span, sig.decl) } hir::ForeignItemKind::Static(ty, ..) => { check_item_type(tcx, def_id, ty.span, UnsizedHandling::AllowIfForeignTail) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 91fa066ec6a1d..f75954c9edfb7 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1440,11 +1440,9 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn icx.lowerer().lower_fn_ty(hir_id, header.safety, header.abi, decl, Some(generics), None) } - ForeignItem(&hir::ForeignItem { - kind: ForeignItemKind::Fn(fn_decl, _, _, safety), .. - }) => { + ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(sig, _, _), .. }) => { let abi = tcx.hir().get_foreign_abi(hir_id); - compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi, safety) + compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety) } Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => { diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index e11d3c9c48b4e..ae0c70d232685 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -604,7 +604,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) { match item.kind { - hir::ForeignItemKind::Fn(_, _, generics, _) => { + hir::ForeignItemKind::Fn(_, _, generics) => { self.visit_early_late(item.hir_id(), generics, |this| { intravisit::walk_foreign_item(this, item); }) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 089cee2fa0dec..cff21173f7982 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -352,16 +352,11 @@ impl<'a> State<'a> { self.maybe_print_comment(item.span.lo()); self.print_outer_attributes(self.attrs(item.hir_id())); match item.kind { - hir::ForeignItemKind::Fn(decl, arg_names, generics, safety) => { + hir::ForeignItemKind::Fn(sig, arg_names, generics) => { self.head(""); self.print_fn( - decl, - hir::FnHeader { - safety, - constness: hir::Constness::NotConst, - abi: Abi::Rust, - asyncness: hir::IsAsync::NotAsync, - }, + sig.decl, + sig.header, Some(item.ident.name), generics, arg_names, diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 54bf73a40dd52..cb7a07116ced8 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1734,13 +1734,16 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations { let abi = cx.tcx.hir().get_foreign_abi(it.hir_id()); match it.kind { - hir::ForeignItemKind::Fn(decl, _, _, _) if !vis.is_internal_abi(abi) => { - vis.check_foreign_fn(it.owner_id.def_id, decl); + hir::ForeignItemKind::Fn(sig, _, _) => { + if vis.is_internal_abi(abi) { + vis.check_fn(it.owner_id.def_id, sig.decl) + } else { + vis.check_foreign_fn(it.owner_id.def_id, sig.decl); + } } hir::ForeignItemKind::Static(ty, _, _) if !vis.is_internal_abi(abi) => { vis.check_foreign_static(it.owner_id, ty.span); } - hir::ForeignItemKind::Fn(decl, _, _, _) => vis.check_fn(it.owner_id.def_id, decl), hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => (), } } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index edab6b5ebde84..ce489099ed2ae 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -826,6 +826,11 @@ impl<'hir> Map<'hir> { }) | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, ..), span: outer_span, .. + }) + | Node::ForeignItem(ForeignItem { + kind: ForeignItemKind::Fn(sig, ..), + span: outer_span, + .. }) => { // Ensure that the returned span has the item's SyntaxContext, and not the // SyntaxContext of the visibility. @@ -884,10 +889,7 @@ impl<'hir> Map<'hir> { }, Node::Variant(variant) => named_span(variant.span, variant.ident, None), Node::ImplItem(item) => named_span(item.span, item.ident, Some(item.generics)), - Node::ForeignItem(item) => match item.kind { - ForeignItemKind::Fn(decl, _, _, _) => until_within(item.span, decl.output.span()), - _ => named_span(item.span, item.ident, None), - }, + Node::ForeignItem(item) => named_span(item.span, item.ident, None), Node::Ctor(_) => return self.span(self.tcx.parent_hir_id(hir_id)), Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl_span, .. }), diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index fa521ab9f2fa9..596d9f077372e 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -202,7 +202,7 @@ pub fn provide(providers: &mut Providers) { .. }) | Node::ForeignItem(&ForeignItem { - kind: ForeignItemKind::Fn(_, idents, _, _), + kind: ForeignItemKind::Fn(_, idents, _), .. }) = tcx.hir_node(tcx.local_def_id_to_hir_id(def_id)) { diff --git a/tests/ui/extern/extern-main-issue-86110.stderr b/tests/ui/extern/extern-main-issue-86110.stderr index 8a3262fbcc7be..d69f4e617680a 100644 --- a/tests/ui/extern/extern-main-issue-86110.stderr +++ b/tests/ui/extern/extern-main-issue-86110.stderr @@ -2,7 +2,7 @@ error: the `main` function cannot be declared in an `extern` block --> $DIR/extern-main-issue-86110.rs:4:5 | LL | fn main(); - | ^^^^^^^^^ + | ^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.effects.stderr b/tests/ui/intrinsics/safe-intrinsic-mismatch.effects.stderr index d9a4960feec4d..55983a445a4ca 100644 --- a/tests/ui/intrinsics/safe-intrinsic-mismatch.effects.stderr +++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.effects.stderr @@ -7,13 +7,13 @@ error: intrinsic safety mismatch between list of intrinsics within the compiler --> $DIR/safe-intrinsic-mismatch.rs:11:5 | LL | fn size_of() -> usize; - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of` --> $DIR/safe-intrinsic-mismatch.rs:11:5 | LL | fn size_of() -> usize; - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.stock.stderr b/tests/ui/intrinsics/safe-intrinsic-mismatch.stock.stderr index 6864c0f36ded0..c59e357b27526 100644 --- a/tests/ui/intrinsics/safe-intrinsic-mismatch.stock.stderr +++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.stock.stderr @@ -2,13 +2,13 @@ error: intrinsic safety mismatch between list of intrinsics within the compiler --> $DIR/safe-intrinsic-mismatch.rs:11:5 | LL | fn size_of() -> usize; - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of` --> $DIR/safe-intrinsic-mismatch.rs:11:5 | LL | fn size_of() -> usize; - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/issues/issue-16725.stderr b/tests/ui/issues/issue-16725.stderr index a4a406b3d4ba9..dcb7d58b0f961 100644 --- a/tests/ui/issues/issue-16725.stderr +++ b/tests/ui/issues/issue-16725.stderr @@ -8,7 +8,7 @@ note: the function `bar` is defined here --> $DIR/auxiliary/issue-16725.rs:2:5 | LL | fn bar(); - | ^^^^^^^^ + | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/lint/clashing-extern-fn.stderr b/tests/ui/lint/clashing-extern-fn.stderr index 43c8cdead9f41..f75ff6d05a15c 100644 --- a/tests/ui/lint/clashing-extern-fn.stderr +++ b/tests/ui/lint/clashing-extern-fn.stderr @@ -21,10 +21,10 @@ warning: `clash` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:14:13 | LL | fn clash(x: u8); - | --------------- `clash` previously declared here + | ---------------- `clash` previously declared here ... LL | fn clash(x: u64); - | ^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn(u8)` found `unsafe extern "C" fn(u64)` @@ -41,7 +41,7 @@ LL | #[link_name = "extern_link_name"] | --------------------------------- `extern_link_name` previously declared here ... LL | fn extern_link_name(x: u32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn(i16)` found `unsafe extern "C" fn(u32)` @@ -50,7 +50,7 @@ warning: `some_other_extern_link_name` redeclares `some_other_new_name` with a d --> $DIR/clashing-extern-fn.rs:55:9 | LL | fn some_other_new_name(x: i16); - | ------------------------------ `some_other_new_name` previously declared here + | ------------------------------- `some_other_new_name` previously declared here ... LL | #[link_name = "some_other_new_name"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration @@ -74,10 +74,10 @@ warning: `different_mod` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:72:9 | LL | fn different_mod(x: u8); - | ----------------------- `different_mod` previously declared here + | ------------------------ `different_mod` previously declared here ... LL | fn different_mod(x: u64); - | ^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn(u8)` found `unsafe extern "C" fn(u64)` @@ -86,10 +86,10 @@ warning: `variadic_decl` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:82:9 | LL | fn variadic_decl(x: u8, ...); - | ---------------------------- `variadic_decl` previously declared here + | ----------------------------- `variadic_decl` previously declared here ... LL | fn variadic_decl(x: u8); - | ^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn(u8, ...)` found `unsafe extern "C" fn(u8)` @@ -98,10 +98,10 @@ warning: `weigh_banana` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:142:13 | LL | fn weigh_banana(count: *const Banana) -> u64; - | -------------------------------------------- `weigh_banana` previously declared here + | --------------------------------------------- `weigh_banana` previously declared here ... LL | fn weigh_banana(count: *const Banana) -> u64; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn(*const one::Banana) -> u64` found `unsafe extern "C" fn(*const three::Banana) -> u64` @@ -110,10 +110,10 @@ warning: `draw_point` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:171:13 | LL | fn draw_point(p: Point); - | ----------------------- `draw_point` previously declared here + | ------------------------ `draw_point` previously declared here ... LL | fn draw_point(p: Point); - | ^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn(sameish_members::a::Point)` found `unsafe extern "C" fn(sameish_members::b::Point)` @@ -122,10 +122,10 @@ warning: `origin` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:197:13 | LL | fn origin() -> Point3; - | --------------------- `origin` previously declared here + | ---------------------- `origin` previously declared here ... LL | fn origin() -> Point3; - | ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn() -> same_sized_members_clash::a::Point3` found `unsafe extern "C" fn() -> same_sized_members_clash::b::Point3` @@ -134,10 +134,10 @@ warning: `transparent_incorrect` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:220:13 | LL | fn transparent_incorrect() -> T; - | ------------------------------- `transparent_incorrect` previously declared here + | -------------------------------- `transparent_incorrect` previously declared here ... LL | fn transparent_incorrect() -> isize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn() -> T` found `unsafe extern "C" fn() -> isize` @@ -146,10 +146,10 @@ warning: `missing_return_type` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:259:13 | LL | fn missing_return_type() -> usize; - | --------------------------------- `missing_return_type` previously declared here + | ---------------------------------- `missing_return_type` previously declared here ... LL | fn missing_return_type(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn() -> usize` found `unsafe extern "C" fn()` @@ -158,10 +158,10 @@ warning: `non_zero_usize` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:277:13 | LL | fn non_zero_usize() -> core::num::NonZero; - | ------------------------------------------------ `non_zero_usize` previously declared here + | ------------------------------------------------- `non_zero_usize` previously declared here ... LL | fn non_zero_usize() -> usize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn() -> NonZero` found `unsafe extern "C" fn() -> usize` @@ -170,10 +170,10 @@ warning: `non_null_ptr` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:279:13 | LL | fn non_null_ptr() -> core::ptr::NonNull; - | ---------------------------------------------- `non_null_ptr` previously declared here + | ----------------------------------------------- `non_null_ptr` previously declared here ... LL | fn non_null_ptr() -> *const usize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn() -> NonNull` found `unsafe extern "C" fn() -> *const usize` @@ -182,10 +182,10 @@ warning: `option_non_zero_usize_incorrect` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:373:13 | LL | fn option_non_zero_usize_incorrect() -> usize; - | --------------------------------------------- `option_non_zero_usize_incorrect` previously declared here + | ---------------------------------------------- `option_non_zero_usize_incorrect` previously declared here ... LL | fn option_non_zero_usize_incorrect() -> isize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn() -> usize` found `unsafe extern "C" fn() -> isize` @@ -194,10 +194,10 @@ warning: `option_non_null_ptr_incorrect` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:375:13 | LL | fn option_non_null_ptr_incorrect() -> *const usize; - | -------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here + | --------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here ... LL | fn option_non_null_ptr_incorrect() -> *const isize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn() -> *const usize` found `unsafe extern "C" fn() -> *const isize` @@ -206,10 +206,10 @@ warning: `hidden_niche_transparent_no_niche` redeclared with a different signatu --> $DIR/clashing-extern-fn.rs:429:13 | LL | fn hidden_niche_transparent_no_niche() -> usize; - | ----------------------------------------------- `hidden_niche_transparent_no_niche` previously declared here + | ------------------------------------------------ `hidden_niche_transparent_no_niche` previously declared here ... LL | fn hidden_niche_transparent_no_niche() -> Option; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn() -> usize` found `unsafe extern "C" fn() -> Option` @@ -218,10 +218,10 @@ warning: `hidden_niche_unsafe_cell` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:433:13 | LL | fn hidden_niche_unsafe_cell() -> usize; - | -------------------------------------- `hidden_niche_unsafe_cell` previously declared here + | --------------------------------------- `hidden_niche_unsafe_cell` previously declared here ... LL | fn hidden_niche_unsafe_cell() -> Option>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn() -> usize` found `unsafe extern "C" fn() -> Option>>` diff --git a/tests/ui/lint/issue-1866.stderr b/tests/ui/lint/issue-1866.stderr index 36d323825a4de..d19a134966831 100644 --- a/tests/ui/lint/issue-1866.stderr +++ b/tests/ui/lint/issue-1866.stderr @@ -2,10 +2,10 @@ warning: `rust_task_is_unwinding` redeclared with a different signature --> $DIR/issue-1866.rs:23:13 | LL | pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool; - | ----------------------------------------------------------- `rust_task_is_unwinding` previously declared here + | ------------------------------------------------------------ `rust_task_is_unwinding` previously declared here ... LL | pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn(*const usize) -> bool` found `unsafe extern "C" fn(*const bool) -> bool` diff --git a/tests/ui/lint/lint-attr-everywhere-late.stderr b/tests/ui/lint/lint-attr-everywhere-late.stderr index ddc31905afbcf..1937b618236b0 100644 --- a/tests/ui/lint/lint-attr-everywhere-late.stderr +++ b/tests/ui/lint/lint-attr-everywhere-late.stderr @@ -406,10 +406,10 @@ error: `clashing1` redeclared with a different signature --> $DIR/lint-attr-everywhere-late.rs:123:5 | LL | fn clashing1(); - | -------------- `clashing1` previously declared here + | --------------- `clashing1` previously declared here ... LL | fn clashing1(_: i32); - | ^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn()` found `unsafe extern "C" fn(i32)` @@ -423,10 +423,10 @@ error: `clashing2` redeclared with a different signature --> $DIR/lint-attr-everywhere-late.rs:128:5 | LL | fn clashing2(); - | -------------- `clashing2` previously declared here + | --------------- `clashing2` previously declared here ... LL | fn clashing2(_: i32); - | ^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | = note: expected `unsafe extern "C" fn()` found `unsafe extern "C" fn(i32)` diff --git a/tests/ui/lint/lint-missing-doc.stderr b/tests/ui/lint/lint-missing-doc.stderr index 4e9ee4f276962..5165ccc3fd062 100644 --- a/tests/ui/lint/lint-missing-doc.stderr +++ b/tests/ui/lint/lint-missing-doc.stderr @@ -116,7 +116,7 @@ error: missing documentation for a function --> $DIR/lint-missing-doc.rs:196:5 | LL | pub fn extern_fn_undocumented(f: f32) -> f32; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a static --> $DIR/lint-missing-doc.rs:201:5 diff --git a/tests/ui/lint/unreachable_pub.stderr b/tests/ui/lint/unreachable_pub.stderr index 705a537a3f1c4..65f45fbd81689 100644 --- a/tests/ui/lint/unreachable_pub.stderr +++ b/tests/ui/lint/unreachable_pub.stderr @@ -130,7 +130,7 @@ warning: unreachable `pub` item --> $DIR/unreachable_pub.rs:48:9 | LL | pub fn catalyze() -> bool; - | ---^^^^^^^^^^^^^^^^^^^^^^ + | ---^^^^^^^^^^^^^^^^^^^^^^^ | | | help: consider restricting its visibility: `pub(crate)` | diff --git a/tests/ui/privacy/private-in-public-warn.stderr b/tests/ui/privacy/private-in-public-warn.stderr index 3f7b8c281e706..3743879ffa616 100644 --- a/tests/ui/privacy/private-in-public-warn.stderr +++ b/tests/ui/privacy/private-in-public-warn.stderr @@ -100,7 +100,7 @@ error: type `types::Priv` is more private than the item `types::ef1` --> $DIR/private-in-public-warn.rs:28:9 | LL | pub fn ef1(arg: Priv); - | ^^^^^^^^^^^^^^^^^^^^^ function `types::ef1` is reachable at visibility `pub(crate)` + | ^^^^^^^^^^^^^^^^^^^^^^ function `types::ef1` is reachable at visibility `pub(crate)` | note: but type `types::Priv` is only usable at visibility `pub(self)` --> $DIR/private-in-public-warn.rs:9:5 @@ -112,7 +112,7 @@ error: type `types::Priv` is more private than the item `types::ef2` --> $DIR/private-in-public-warn.rs:29:9 | LL | pub fn ef2() -> Priv; - | ^^^^^^^^^^^^^^^^^^^^ function `types::ef2` is reachable at visibility `pub(crate)` + | ^^^^^^^^^^^^^^^^^^^^^ function `types::ef2` is reachable at visibility `pub(crate)` | note: but type `types::Priv` is only usable at visibility `pub(self)` --> $DIR/private-in-public-warn.rs:9:5 From d850f85055b1d46278e29be39d9b4b938e90f199 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 7 Aug 2024 13:08:24 -0400 Subject: [PATCH 2/3] Don't ICE on Fn trait error for foreign fn --- .../traits/fulfillment_errors.rs | 4 ++ .../foreign/foreign-safe-fn-arg-mismatch.rs | 13 ++++++ .../foreign-safe-fn-arg-mismatch.stderr | 44 +++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 tests/ui/foreign/foreign-safe-fn-arg-mismatch.rs create mode 100644 tests/ui/foreign/foreign-safe-fn-arg-mismatch.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 326a0e4e35ce8..79ba9840130e4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2729,6 +2729,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(ref sig, _), .. }) | Node::TraitItem(&hir::TraitItem { kind: hir::TraitItemKind::Fn(ref sig, _), .. + }) + | Node::ForeignItem(&hir::ForeignItem { + kind: hir::ForeignItemKind::Fn(ref sig, _, _), + .. }) => ( sig.span, None, diff --git a/tests/ui/foreign/foreign-safe-fn-arg-mismatch.rs b/tests/ui/foreign/foreign-safe-fn-arg-mismatch.rs new file mode 100644 index 0000000000000..bb1052b15e9d1 --- /dev/null +++ b/tests/ui/foreign/foreign-safe-fn-arg-mismatch.rs @@ -0,0 +1,13 @@ +// Make sure we don't ICE when a foreign fn doesn't implement `Fn` due to arg mismatch. + +unsafe extern "Rust" { + pub safe fn foo(); + pub safe fn bar(x: u32); +} + +fn test(_: impl Fn(i32)) {} + +fn main() { + test(foo); //~ ERROR function is expected to take 1 argument, but it takes 0 arguments + test(bar); //~ ERROR type mismatch in function arguments +} diff --git a/tests/ui/foreign/foreign-safe-fn-arg-mismatch.stderr b/tests/ui/foreign/foreign-safe-fn-arg-mismatch.stderr new file mode 100644 index 0000000000000..73ccecff5ab8c --- /dev/null +++ b/tests/ui/foreign/foreign-safe-fn-arg-mismatch.stderr @@ -0,0 +1,44 @@ +error[E0593]: function is expected to take 1 argument, but it takes 0 arguments + --> $DIR/foreign-safe-fn-arg-mismatch.rs:11:10 + | +LL | pub safe fn foo(); + | ------------------ takes 0 arguments +... +LL | test(foo); + | ---- ^^^ expected function that takes 1 argument + | | + | required by a bound introduced by this call + | +note: required by a bound in `test` + --> $DIR/foreign-safe-fn-arg-mismatch.rs:8:17 + | +LL | fn test(_: impl Fn(i32)) {} + | ^^^^^^^ required by this bound in `test` + +error[E0631]: type mismatch in function arguments + --> $DIR/foreign-safe-fn-arg-mismatch.rs:12:10 + | +LL | pub safe fn bar(x: u32); + | ------------------------ found signature defined here +... +LL | test(bar); + | ---- ^^^ expected due to this + | | + | required by a bound introduced by this call + | + = note: expected function signature `fn(i32) -> _` + found function signature `fn(u32) -> _` +note: required by a bound in `test` + --> $DIR/foreign-safe-fn-arg-mismatch.rs:8:17 + | +LL | fn test(_: impl Fn(i32)) {} + | ^^^^^^^ required by this bound in `test` +help: consider wrapping the function in a closure + | +LL | test(|arg0: i32| bar(/* u32 */)); + | +++++++++++ +++++++++++ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0593, E0631. +For more information about an error, try `rustc --explain E0593`. From 84633f47f671f6c084d83070c6dc97d812de1758 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 7 Aug 2024 13:35:21 -0400 Subject: [PATCH 3/3] Simplify cleaning foreign fns in rustdoc --- src/librustdoc/clean/mod.rs | 14 ++++---------- .../multiple-declarations.stderr | 2 +- .../rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr | 2 +- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 53757349a9b2c..db81b4c4282a1 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -3094,16 +3094,10 @@ fn clean_maybe_renamed_foreign_item<'tcx>( let def_id = item.owner_id.to_def_id(); cx.with_param_env(def_id, |cx| { let kind = match item.kind { - hir::ForeignItemKind::Fn(decl, names, generics, safety) => { - let (generics, decl) = enter_impl_trait(cx, |cx| { - // NOTE: generics must be cleaned before args - let generics = clean_generics(generics, cx); - let args = clean_args_from_types_and_names(cx, decl.inputs, names); - let decl = clean_fn_decl_with_args(cx, decl, None, args); - (generics, decl) - }); - ForeignFunctionItem(Box::new(Function { decl, generics }), safety) - } + hir::ForeignItemKind::Fn(sig, names, generics) => ForeignFunctionItem( + clean_function(cx, &sig, generics, FunctionArgs::Names(names)), + sig.header.safety, + ), hir::ForeignItemKind::Static(ty, mutability, safety) => ForeignStaticItem( Static { type_: Box::new(clean_ty(ty, cx)), mutability, expr: None }, safety, diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr b/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr index 7866af594449f..b766b5c8dd831 100644 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr +++ b/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr @@ -2,7 +2,7 @@ error: multiple declarations of external function `f` from library `foo.dll` hav --> $DIR/multiple-declarations.rs:13:9 | LL | fn f(x: i32); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr b/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr index d7c7344b596db..ef022404e7f67 100644 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr +++ b/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr @@ -2,7 +2,7 @@ error: ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture --> $DIR/unsupported-abi.rs:6:5 | LL | fn f(x: i32); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: aborting due to 1 previous error