From 1b76bb03fe9fd0803efeea9964b61d3c1b7e96ae Mon Sep 17 00:00:00 2001 From: CAD97 Date: Fri, 21 Feb 2020 15:38:29 -0500 Subject: [PATCH 01/10] Stabilize some of alloc_layout_extras --- src/libcore/alloc/layout.rs | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/libcore/alloc/layout.rs b/src/libcore/alloc/layout.rs index fa644cfe99ed6..98f9054588a87 100644 --- a/src/libcore/alloc/layout.rs +++ b/src/libcore/alloc/layout.rs @@ -162,7 +162,7 @@ impl Layout { /// Returns an error if the combination of `self.size()` and the given /// `align` violates the conditions listed in /// [`Layout::from_size_align`](#method.from_size_align). - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[inline] pub fn align_to(&self, align: usize) -> Result { Layout::from_size_align(self.size(), cmp::max(self.align(), align)) @@ -218,7 +218,7 @@ impl Layout { /// /// This is equivalent to adding the result of `padding_needed_for` /// to the layout's current size. - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[inline] pub fn pad_to_align(&self) -> Layout { let pad = self.padding_needed_for(self.align()); @@ -258,19 +258,17 @@ impl Layout { /// Creates a layout describing the record for `self` followed by /// `next`, including any necessary padding to ensure that `next` - /// will be properly aligned. Note that the resulting layout will - /// satisfy the alignment properties of both `self` and `next`. - /// - /// The resulting layout will be the same as that of a C struct containing - /// two fields with the layouts of `self` and `next`, in that order. + /// will be properly aligned, but no trailing padding. Note that + /// the resulting layout will satisfy the alignment properties of + /// both `self` and `next`, in order to ensure field alignment. /// - /// Returns `Some((k, offset))`, where `k` is layout of the concatenated + /// Returns `Ok((k, offset))`, where `k` is layout of the concatenated /// record and `offset` is the relative location, in bytes, of the /// start of the `next` embedded within the concatenated record /// (assuming that the record itself starts at offset 0). /// /// On arithmetic overflow, returns `LayoutErr`. - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[inline] pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> { let new_align = cmp::max(self.align(), next.align()); @@ -318,13 +316,12 @@ impl Layout { /// Creates a layout describing the record for a `[T; n]`. /// /// On arithmetic overflow, returns `LayoutErr`. - #[unstable(feature = "alloc_layout_extra", issue = "55724")] + #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[inline] pub fn array(n: usize) -> Result { - Layout::new::().repeat(n).map(|(k, offs)| { - debug_assert!(offs == mem::size_of::()); - k - }) + let (layout, offset) = Layout::new::().repeat(n)?; + debug_assert_eq!(offset, mem::size_of::()); + Ok(layout.pad_to_align()) } } From c266b8b98c763984c6d1183e3518379c0cf2751f Mon Sep 17 00:00:00 2001 From: Christopher Durham Date: Wed, 15 Apr 2020 15:50:31 -0400 Subject: [PATCH 02/10] emphasize *no trailing padding* --- src/libcore/alloc/layout.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/alloc/layout.rs b/src/libcore/alloc/layout.rs index 98f9054588a87..ec3a42469bc11 100644 --- a/src/libcore/alloc/layout.rs +++ b/src/libcore/alloc/layout.rs @@ -258,7 +258,7 @@ impl Layout { /// Creates a layout describing the record for `self` followed by /// `next`, including any necessary padding to ensure that `next` - /// will be properly aligned, but no trailing padding. Note that + /// will be properly aligned, but *no trailing padding*. Note that /// the resulting layout will satisfy the alignment properties of /// both `self` and `next`, in order to ensure field alignment. /// From 053c2dddda209444e7dd0bc8df2f4b0f8337e9f5 Mon Sep 17 00:00:00 2001 From: CAD97 Date: Wed, 15 Apr 2020 19:54:55 -0400 Subject: [PATCH 03/10] Add note about Layout::pad_to_align to Layout::extend --- src/libcore/alloc/layout.rs | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/libcore/alloc/layout.rs b/src/libcore/alloc/layout.rs index ec3a42469bc11..2ad3662740308 100644 --- a/src/libcore/alloc/layout.rs +++ b/src/libcore/alloc/layout.rs @@ -258,9 +258,12 @@ impl Layout { /// Creates a layout describing the record for `self` followed by /// `next`, including any necessary padding to ensure that `next` - /// will be properly aligned, but *no trailing padding*. Note that - /// the resulting layout will satisfy the alignment properties of - /// both `self` and `next`, in order to ensure field alignment. + /// will be properly aligned, but *no trailing padding*. In order to + /// match C representation layout, you should call `pad_to_align` + /// after extending the layout with all fields. + /// + /// Note that the resulting layout will satisfy the alignment properties + /// of both `self` and `next`, in order to ensure alignment of both parts. /// /// Returns `Ok((k, offset))`, where `k` is layout of the concatenated /// record and `offset` is the relative location, in bytes, of the @@ -268,6 +271,31 @@ impl Layout { /// (assuming that the record itself starts at offset 0). /// /// On arithmetic overflow, returns `LayoutErr`. + /// + /// # Examples + /// + /// To calculate the layout of a `#[repr(C)]` structure from its fields' layouts: + /// + /// ```rust + /// # use std::alloc::{Layout, LayoutErr}; + /// pub fn repr_c(fields: &[Layout]) -> Result<(Layout, Vec), LayoutErr> { + /// let mut offsets = Vec::new(); + /// let mut layout = Layout::from_size_align(0, 1)?; + /// for &field in fields { + /// let (new_layout, offset) = layout.extend(field)?; + /// layout = new_layout; + /// offsets.push(offset); + /// } + /// Ok((layout.pad_to_align(), offsets)) + /// } + /// # // test that it works + /// # #[repr(C)] struct S { a: u64, b: u32, c: u16, d: u32 } + /// # let s = Layout::new::(); + /// # let u16 = Layout::new::(); + /// # let u32 = Layout::new::(); + /// # let u64 = Layout::new::(); + /// # assert_eq!(repr_c(&[u64, u32, u16, u32]), Ok((s, vec![0, 8, 12, 16]))); + /// ``` #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[inline] pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> { From 5f1fd9da5488cc2fe88dc89e5ca3f183526388a9 Mon Sep 17 00:00:00 2001 From: Christopher Durham Date: Thu, 16 Apr 2020 16:44:30 -0400 Subject: [PATCH 04/10] Apply suggestions from code review Co-Authored-By: Ralf Jung --- src/libcore/alloc/layout.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcore/alloc/layout.rs b/src/libcore/alloc/layout.rs index 2ad3662740308..be62671f59f41 100644 --- a/src/libcore/alloc/layout.rs +++ b/src/libcore/alloc/layout.rs @@ -274,7 +274,8 @@ impl Layout { /// /// # Examples /// - /// To calculate the layout of a `#[repr(C)]` structure from its fields' layouts: + /// To calculate the layout of a `#[repr(C)]` structure and the offsets of + /// the fields from its fields' layouts: /// /// ```rust /// # use std::alloc::{Layout, LayoutErr}; @@ -286,6 +287,7 @@ impl Layout { /// layout = new_layout; /// offsets.push(offset); /// } + /// // Remember to finalize with `pad_to_align`! /// Ok((layout.pad_to_align(), offsets)) /// } /// # // test that it works From a01b00faf877deab0ef3896ce655351398fe4a47 Mon Sep 17 00:00:00 2001 From: CAD97 Date: Fri, 17 Apr 2020 18:59:36 -0400 Subject: [PATCH 05/10] Clarify layout information in Layout::extend --- src/libcore/alloc/layout.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libcore/alloc/layout.rs b/src/libcore/alloc/layout.rs index be62671f59f41..b2a109d1cd1db 100644 --- a/src/libcore/alloc/layout.rs +++ b/src/libcore/alloc/layout.rs @@ -258,9 +258,11 @@ impl Layout { /// Creates a layout describing the record for `self` followed by /// `next`, including any necessary padding to ensure that `next` - /// will be properly aligned, but *no trailing padding*. In order to - /// match C representation layout, you should call `pad_to_align` - /// after extending the layout with all fields. + /// will be properly aligned, but *no trailing padding*. In order + /// to match C representation layout `repr(C)`, you should call + /// `pad_to_align` after extending the layout with all fields. + /// (There is no way to match the default Rust representation + /// layout `repr(Rust)`, as it is unspecified.) /// /// Note that the resulting layout will satisfy the alignment properties /// of both `self` and `next`, in order to ensure alignment of both parts. From 3c455fe8e1712af5996232053cd6ea3ea743a487 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Sat, 18 Apr 2020 15:26:45 +0200 Subject: [PATCH 06/10] MIR: use span instead of NodeId to determine if optimized_mir should be run --- src/librustc_mir/transform/inline.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index bfa13abb871c2..173c2a3f1d864 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -94,17 +94,15 @@ impl Inliner<'tcx> { continue; } - let self_node_id = self.tcx.hir().as_local_node_id(self.source.def_id()).unwrap(); - let callee_node_id = self.tcx.hir().as_local_node_id(callsite.callee); + let callee_hir_id = self.tcx.hir().as_local_hir_id(callsite.callee); - let callee_body = if let Some(callee_node_id) = callee_node_id { + let callee_body = if let Some(callee_hir_id) = callee_hir_id { + let self_hir_id = self.tcx.hir().as_local_hir_id(self.source.def_id()).unwrap(); // Avoid a cycle here by only using `optimized_mir` only if we have - // a lower node id than the callee. This ensures that the callee will + // a lower `HirId` than the callee. This ensures that the callee will // not inline us. This trick only works without incremental compilation. // So don't do it if that is enabled. - if !self.tcx.dep_graph.is_fully_enabled() - && self_node_id.as_u32() < callee_node_id.as_u32() - { + if !self.tcx.dep_graph.is_fully_enabled() && self_hir_id < callee_hir_id { self.tcx.optimized_mir(callsite.callee) } else { continue; From 6120acec8799616dbd7e646c1d7957eab894202b Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Wed, 8 Apr 2020 15:39:02 -0400 Subject: [PATCH 07/10] Check that main/start is not async * Add new error code E0752 * Add span to hir::IsAsync::Yes * Emit an error if main or the start function is marked as async * Add two regression tests Fix formatting errors and bless test outputs * move tests to ui/async-await fix test error text remove span from IsAsync --- src/librustc_error_codes/error_codes.rs | 1 + src/librustc_error_codes/error_codes/E0752.md | 11 ++++++++ .../error_reporting/on_unimplemented.rs | 14 ++++------ .../traits/error_reporting/suggestions.rs | 5 +--- src/librustc_typeck/lib.rs | 28 +++++++++++++++++-- src/test/ui/async-await/issue-68523-start.rs | 9 ++++++ .../ui/async-await/issue-68523-start.stderr | 9 ++++++ src/test/ui/async-await/issue-68523.rs | 7 +++++ src/test/ui/async-await/issue-68523.stderr | 18 ++++++++++++ 9 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 src/librustc_error_codes/error_codes/E0752.md create mode 100644 src/test/ui/async-await/issue-68523-start.rs create mode 100644 src/test/ui/async-await/issue-68523-start.stderr create mode 100644 src/test/ui/async-await/issue-68523.rs create mode 100644 src/test/ui/async-await/issue-68523.stderr diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 225ede851b4d9..bc04809eaa1df 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -431,6 +431,7 @@ E0748: include_str!("./error_codes/E0748.md"), E0749: include_str!("./error_codes/E0749.md"), E0750: include_str!("./error_codes/E0750.md"), E0751: include_str!("./error_codes/E0751.md"), +E0752: include_str!("./error_codes/E0752.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/src/librustc_error_codes/error_codes/E0752.md b/src/librustc_error_codes/error_codes/E0752.md new file mode 100644 index 0000000000000..86945f83b5524 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0752.md @@ -0,0 +1,11 @@ +`fn main()` or the specified start function is not allowed to be +async. You might be seeing this error because your async runtime +library is not set up correctly. + +Erroneous code example: + +```compile_fail,E0752 +async fn main() -> Result { + Ok(1) +} +``` diff --git a/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs b/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs index 1ecc7fdafc442..3b6c741b89043 100644 --- a/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs +++ b/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs @@ -82,10 +82,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { match &node { hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) => { self.describe_generator(*body_id).or_else(|| { - Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { - "an async function" - } else { - "a function" + Some(match sig.header { + hir::FnHeader { asyncness: hir::IsAsync::Async, .. } => "an async function", + _ => "a function", }) }) } @@ -97,10 +96,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { kind: hir::ImplItemKind::Fn(sig, body_id), .. }) => self.describe_generator(*body_id).or_else(|| { - Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { - "an async method" - } else { - "a method" + Some(match sig.header { + hir::FnHeader { asyncness: hir::IsAsync::Async, .. } => "an async method", + _ => "a method", }) }), hir::Node::Expr(hir::Expr { diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index 254db6cb869b1..982ceec7dca21 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -1313,10 +1313,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let is_async = inner_generator_body .and_then(|body| body.generator_kind()) - .map(|generator_kind| match generator_kind { - hir::GeneratorKind::Async(..) => true, - _ => false, - }) + .map(|generator_kind| matches!(generator_kind, hir::GeneratorKind::Async(..))) .unwrap_or(false); let (await_or_yield, an_await_or_yield) = if is_async { ("await", "an await") } else { ("yield", "a yield") }; diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index df8290fd018c5..cd76184c9bf2d 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -159,7 +159,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { match main_t.kind { ty::FnDef(..) => { if let Some(Node::Item(it)) = tcx.hir().find(main_id) { - if let hir::ItemKind::Fn(.., ref generics, _) = it.kind { + if let hir::ItemKind::Fn(ref sig, ref generics, _) = it.kind { let mut error = false; if !generics.params.is_empty() { let msg = "`main` function is not allowed to have generic \ @@ -182,6 +182,18 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { .emit(); error = true; } + if let hir::IsAsync::Async = sig.header.asyncness { + let span = tcx.sess.source_map().guess_head_span(it.span); + struct_span_err!( + tcx.sess, + span, + E0752, + "`main` function is not allowed to be `async`" + ) + .span_label(span, "`main` function is not allowed to be `async`") + .emit(); + error = true; + } if error { return; } @@ -226,7 +238,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) { match start_t.kind { ty::FnDef(..) => { if let Some(Node::Item(it)) = tcx.hir().find(start_id) { - if let hir::ItemKind::Fn(.., ref generics, _) = it.kind { + if let hir::ItemKind::Fn(ref sig, ref generics, _) = it.kind { let mut error = false; if !generics.params.is_empty() { struct_span_err!( @@ -250,6 +262,18 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) { .emit(); error = true; } + if let hir::IsAsync::Async = sig.header.asyncness { + let span = tcx.sess.source_map().guess_head_span(it.span); + struct_span_err!( + tcx.sess, + span, + E0752, + "start is not allowed to be `async`" + ) + .span_label(span, "start is not allowed to be `async`") + .emit(); + error = true; + } if error { return; } diff --git a/src/test/ui/async-await/issue-68523-start.rs b/src/test/ui/async-await/issue-68523-start.rs new file mode 100644 index 0000000000000..5988dffd68fa7 --- /dev/null +++ b/src/test/ui/async-await/issue-68523-start.rs @@ -0,0 +1,9 @@ +// edition:2018 + +#![feature(start)] + +#[start] +pub async fn start(_: isize, _: *const *const u8) -> isize { +//~^ ERROR start is not allowed to be `async` + 0 +} diff --git a/src/test/ui/async-await/issue-68523-start.stderr b/src/test/ui/async-await/issue-68523-start.stderr new file mode 100644 index 0000000000000..e471945900e7d --- /dev/null +++ b/src/test/ui/async-await/issue-68523-start.stderr @@ -0,0 +1,9 @@ +error[E0752]: start is not allowed to be `async` + --> $DIR/issue-68523-start.rs:6:1 + | +LL | pub async fn start(_: isize, _: *const *const u8) -> isize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ start is not allowed to be `async` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0752`. diff --git a/src/test/ui/async-await/issue-68523.rs b/src/test/ui/async-await/issue-68523.rs new file mode 100644 index 0000000000000..e6250c40c714c --- /dev/null +++ b/src/test/ui/async-await/issue-68523.rs @@ -0,0 +1,7 @@ +// edition:2018 + +async fn main() -> Result { +//~^ ERROR `main` function is not allowed to be `async` +//~^^ ERROR `main` has invalid return type `impl std::future::Future` + Ok(1) +} diff --git a/src/test/ui/async-await/issue-68523.stderr b/src/test/ui/async-await/issue-68523.stderr new file mode 100644 index 0000000000000..62e37cf2629d7 --- /dev/null +++ b/src/test/ui/async-await/issue-68523.stderr @@ -0,0 +1,18 @@ +error[E0277]: `main` has invalid return type `impl std::future::Future` + --> $DIR/issue-68523.rs:3:20 + | +LL | async fn main() -> Result { + | ^^^^^^^^^^^^^^^ `main` can only return types that implement `std::process::Termination` + | + = help: consider using `()`, or a `Result` + +error[E0752]: `main` function is not allowed to be `async` + --> $DIR/issue-68523.rs:3:1 + | +LL | async fn main() -> Result { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` function is not allowed to be `async` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0752. +For more information about an error, try `rustc --explain E0277`. From 9c3adaf89c48931229aca910c6909e6a1c4ddedf Mon Sep 17 00:00:00 2001 From: Christopher Durham Date: Mon, 20 Apr 2020 12:28:30 -0400 Subject: [PATCH 08/10] Update src/libcore/alloc/layout.rs Co-Authored-By: Amanieu d'Antras --- src/libcore/alloc/layout.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/alloc/layout.rs b/src/libcore/alloc/layout.rs index b2a109d1cd1db..3881f0685d4ca 100644 --- a/src/libcore/alloc/layout.rs +++ b/src/libcore/alloc/layout.rs @@ -264,8 +264,8 @@ impl Layout { /// (There is no way to match the default Rust representation /// layout `repr(Rust)`, as it is unspecified.) /// - /// Note that the resulting layout will satisfy the alignment properties - /// of both `self` and `next`, in order to ensure alignment of both parts. + /// Note that the alignment of the resulting layout will be the maximum of + /// those of `self` and `next`, in order to ensure alignment of both parts. /// /// Returns `Ok((k, offset))`, where `k` is layout of the concatenated /// record and `offset` is the relative location, in bytes, of the From 98f0a8241b621b28ac58c7a5e80de4ead13ab0bb Mon Sep 17 00:00:00 2001 From: CAD97 Date: Mon, 20 Apr 2020 12:30:35 -0400 Subject: [PATCH 09/10] Improve Layout::extend docs --- src/libcore/alloc/layout.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libcore/alloc/layout.rs b/src/libcore/alloc/layout.rs index 3881f0685d4ca..6200cd242667f 100644 --- a/src/libcore/alloc/layout.rs +++ b/src/libcore/alloc/layout.rs @@ -258,9 +258,10 @@ impl Layout { /// Creates a layout describing the record for `self` followed by /// `next`, including any necessary padding to ensure that `next` - /// will be properly aligned, but *no trailing padding*. In order - /// to match C representation layout `repr(C)`, you should call - /// `pad_to_align` after extending the layout with all fields. + /// will be properly aligned, but *no trailing padding*. + /// + /// In order to match C representation layout `repr(C)`, you should + /// call `pad_to_align` after extending the layout with all fields. /// (There is no way to match the default Rust representation /// layout `repr(Rust)`, as it is unspecified.) /// From 9296d3ba8247ac292226ba19fefc6d577f2d5dfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Mon, 20 Apr 2020 12:39:12 +0200 Subject: [PATCH 10/10] Do not build tools if user do not want them --- src/bootstrap/tool.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 52f750f448e20..f756b1235abee 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -607,7 +607,15 @@ macro_rules! tool_extended { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let builder = run.builder; - run.path($path).default_condition(builder.config.extended) + run.path($path).default_condition( + builder.config.extended + && builder.config.tools.as_ref().map_or(true, |tools| { + tools.iter().any(|tool| match tool.as_ref() { + "clippy" => $tool_name == "clippy-driver", + x => $tool_name == x, + }) + }), + ) } fn make_run(run: RunConfig<'_>) {