From d6e69188578d95d6bb75cd00cec62e375e62ba6b Mon Sep 17 00:00:00 2001 From: blyxyas Date: Thu, 23 May 2024 18:45:03 +0200 Subject: [PATCH 1/6] Make clamp inline --- library/core/src/cmp.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index fc6022ab75357..f3f757ce69df7 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -898,6 +898,7 @@ pub trait Ord: Eq + PartialOrd { /// assert_eq!(2.clamp(-2, 1), 1); /// ``` #[must_use] + #[inline] #[stable(feature = "clamp", since = "1.50.0")] fn clamp(self, min: Self, max: Self) -> Self where From c1ac4a2f2840e312af84d453751861f400fd6798 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 24 May 2024 15:08:18 +1000 Subject: [PATCH 2/6] Run rustfmt on files that need it. Somehow these files aren't properly formatted. By default `x fmt` and `x tidy` only check files that have changed against master, so if an ill-formatted file somehow slips in it can stay that way as long as it doesn't get modified(?) I found these when I ran `x fmt` explicitly on every `.rs` file in the repo, while working on https://github.com/rust-lang/compiler-team/issues/750. --- compiler/rustc_codegen_ssa/src/base.rs | 2 +- .../rustc_const_eval/src/const_eval/error.rs | 7 ++--- .../rustc_incremental/src/persist/load.rs | 3 +- .../src/for_loops_over_fallibles.rs | 4 ++- library/test/src/bench.rs | 2 +- src/bootstrap/src/core/builder/tests.rs | 29 +++++++++++++++---- src/bootstrap/src/core/sanity.rs | 10 +++++-- src/tools/build_helper/src/lib.rs | 2 +- 8 files changed, 41 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index b4556f8fcb8fc..5d7eb0525615f 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -29,8 +29,8 @@ use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, Debugger use rustc_middle::middle::exported_symbols; use rustc_middle::middle::exported_symbols::SymbolExportKind; use rustc_middle::middle::lang_items; -use rustc_middle::mir::BinOp; use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem}; +use rustc_middle::mir::BinOp; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 7a1c2a7b6fa51..650669ac690b3 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -139,10 +139,9 @@ where ErrorHandled::TooGeneric(span) } err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar, span), - err_inval!(Layout(LayoutError::ReferencesError(guar))) => ErrorHandled::Reported( - ReportedErrorInfo::tainted_by_errors(guar), - span, - ), + err_inval!(Layout(LayoutError::ReferencesError(guar))) => { + ErrorHandled::Reported(ReportedErrorInfo::tainted_by_errors(guar), span) + } // Report remaining errors. _ => { let (our_span, frames) = get_span_and_frames(); diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 6c3f73cf46594..af667a57ce123 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -116,8 +116,7 @@ fn load_dep_graph(sess: &Session) -> LoadResult<(Arc, WorkPr if let LoadResult::Ok { data: (work_products_data, start_pos) } = load_result { // Decode the list of work_products - let Ok(mut work_product_decoder) = - MemDecoder::new(&work_products_data[..], start_pos) + let Ok(mut work_product_decoder) = MemDecoder::new(&work_products_data[..], start_pos) else { sess.dcx().emit_warn(errors::CorruptFile { path: &work_products_path }); return LoadResult::DataOutOfDate; diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index b05f5e7638b4e..aa00fb4573d80 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -62,7 +62,9 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles { }; let (article, ty, var) = match adt.did() { - did if cx.tcx.is_diagnostic_item(sym::Option, did) && ref_mutability.is_some() => ("a", "Option", "Some"), + did if cx.tcx.is_diagnostic_item(sym::Option, did) && ref_mutability.is_some() => { + ("a", "Option", "Some") + } did if cx.tcx.is_diagnostic_item(sym::Option, did) => ("an", "Option", "Some"), did if cx.tcx.is_diagnostic_item(sym::Result, did) => ("a", "Result", "Ok"), _ => return, diff --git a/library/test/src/bench.rs b/library/test/src/bench.rs index 9a5dc351f6d07..64ca13c0d4ed3 100644 --- a/library/test/src/bench.rs +++ b/library/test/src/bench.rs @@ -98,7 +98,7 @@ fn fmt_thousands_sep(mut n: f64, sep: char) -> String { (0, true) => write!(output, "{:06.2}", n / base as f64).unwrap(), (0, false) => write!(output, "{:.2}", n / base as f64).unwrap(), (_, true) => write!(output, "{:03}", n as usize / base).unwrap(), - _ => write!(output, "{}", n as usize / base).unwrap() + _ => write!(output, "{}", n as usize / base).unwrap(), } if pow != 0 { output.push(sep); diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 9710365ef114d..276fd0b11d64c 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -60,7 +60,14 @@ fn check_cli(paths: [&str; N]) { macro_rules! std { ($host:ident => $target:ident, stage = $stage:literal) => { compile::Std::new( - Compiler { host: TargetSelection::from_user(concat!(stringify!($host), "-", stringify!($host))), stage: $stage }, + Compiler { + host: TargetSelection::from_user(concat!( + stringify!($host), + "-", + stringify!($host) + )), + stage: $stage, + }, TargetSelection::from_user(concat!(stringify!($target), "-", stringify!($target))), ) }; @@ -83,7 +90,14 @@ macro_rules! doc_std { macro_rules! rustc { ($host:ident => $target:ident, stage = $stage:literal) => { compile::Rustc::new( - Compiler { host: TargetSelection::from_user(concat!(stringify!($host), "-", stringify!($host))), stage: $stage }, + Compiler { + host: TargetSelection::from_user(concat!( + stringify!($host), + "-", + stringify!($host) + )), + stage: $stage, + }, TargetSelection::from_user(concat!(stringify!($target), "-", stringify!($target))), ) }; @@ -141,10 +155,14 @@ fn check_missing_paths_for_x_test_tests() { // Skip if not a test directory. if path.ends_with("tests/auxiliary") || !path.is_dir() { - continue + continue; } - assert!(tests_remap_paths.iter().any(|item| path.ends_with(*item)), "{} is missing in PATH_REMAP tests list.", path.display()); + assert!( + tests_remap_paths.iter().any(|item| path.ends_with(*item)), + "{} is missing in PATH_REMAP tests list.", + path.display() + ); } } @@ -185,7 +203,8 @@ fn alias_and_path_for_library() { &[std!(A => A, stage = 0), std!(A => A, stage = 1)] ); - let mut cache = run_build(&["library".into(), "core".into()], configure("doc", &["A-A"], &["A-A"])); + let mut cache = + run_build(&["library".into(), "core".into()], configure("doc", &["A-A"], &["A-A"])); assert_eq!(first(cache.all::()), &[doc_std!(A => A, stage = 0)]); } diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 9c3df6fa9e39b..8ffa97ab78b55 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -199,11 +199,15 @@ than building it. if !["A-A", "B-B", "C-C"].contains(&target_str.as_str()) { let mut has_target = false; - let missing_targets_hashset: HashSet<_> = STAGE0_MISSING_TARGETS.iter().map(|t| t.to_string()).collect(); - let duplicated_targets: Vec<_> = stage0_supported_target_list.intersection(&missing_targets_hashset).collect(); + let missing_targets_hashset: HashSet<_> = + STAGE0_MISSING_TARGETS.iter().map(|t| t.to_string()).collect(); + let duplicated_targets: Vec<_> = + stage0_supported_target_list.intersection(&missing_targets_hashset).collect(); if !duplicated_targets.is_empty() { - println!("Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list."); + println!( + "Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list." + ); for duplicated_target in duplicated_targets { println!(" {duplicated_target}"); } diff --git a/src/tools/build_helper/src/lib.rs b/src/tools/build_helper/src/lib.rs index 6a4e86eb1dfe5..2abda5d3ebf27 100644 --- a/src/tools/build_helper/src/lib.rs +++ b/src/tools/build_helper/src/lib.rs @@ -1,5 +1,5 @@ pub mod ci; pub mod git; pub mod metrics; -pub mod util; pub mod stage0_parser; +pub mod util; From e78671e61fa14cd541a1f6ae357a0d1f070e2cd1 Mon Sep 17 00:00:00 2001 From: Xinzhao Xu Date: Fri, 24 May 2024 15:43:40 +0800 Subject: [PATCH 3/6] Fix the dead link in the bootstrap README --- src/bootstrap/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md index 077db44ae54ee..fb3c862704306 100644 --- a/src/bootstrap/README.md +++ b/src/bootstrap/README.md @@ -6,7 +6,7 @@ and some of the technical details of the build system. Note that this README only covers internal information, not how to use the tool. Please check [bootstrapping dev guide][bootstrapping-dev-guide] for further information. -[bootstrapping-dev-guide]: https://rustc-dev-guide.rust-lang.org/building/bootstrapping.html +[bootstrapping-dev-guide]: https://rustc-dev-guide.rust-lang.org/building/bootstrapping/intro.html ## Introduction From e2ef4e1b0d94ba481ca4d379bb9f1d883e6c0b07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 24 May 2024 10:36:44 +0200 Subject: [PATCH 4/6] Notify kobzol after changes to `opt-dist` --- triagebot.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 2e45b257f8126..95fa3befe60f2 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -842,6 +842,9 @@ cc = ["@Zalathar"] message = "Some changes occurred in coverage tests." cc = ["@Zalathar"] +[mentions."src/tools/opt-dist"] +cc = ["@kobzol"] + [assign] warn_non_default_branch = true contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" @@ -1059,6 +1062,7 @@ project-exploit-mitigations = [ "/src/tools/cargo" = ["@ehuss"] "/src/tools/compiletest" = ["bootstrap", "@wesleywiser", "@oli-obk", "@compiler-errors", "@jieyouxu"] "/src/tools/linkchecker" = ["@ehuss"] +"/src/tools/opt-dist" = ["@kobzol"] "/src/tools/run-make-support" = ["@jieyouxu"] "/src/tools/rust-installer" = ["bootstrap"] "/src/tools/rustbook" = ["@ehuss"] From 56c135c9253563f92755b0a9cd54ec67f7c17fc7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 24 May 2024 13:21:59 +0000 Subject: [PATCH 5/6] Revert "Rollup merge of #123979 - oli-obk:define_opaque_types7, r=compiler-errors" This reverts commit f939d1ff4820844595d0f50f94038869f1445d08, reversing changes made to 183c706305d8c4e0ccb0967932381baf7e0c3611. --- compiler/rustc_infer/src/infer/mod.rs | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 8d4011421bd33..6f603d9b612eb 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -957,27 +957,14 @@ impl<'tcx> InferCtxt<'tcx> { (&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => { return Err((a_vid, b_vid)); } - // We don't silently want to constrain hidden types here, so we assert that either one side is - // an infer var, so it'll get constrained to whatever the other side is, or there are no opaque - // types involved. - // We don't expect this to actually get hit, but if it does, we now at least know how to write - // a test for it. - (_, ty::Infer(ty::TyVar(_))) => {} - (ty::Infer(ty::TyVar(_)), _) => {} - _ if r_a != r_b && (r_a, r_b).has_opaque_types() => { - span_bug!( - cause.span(), - "opaque types got hidden types registered from within subtype predicate: {r_a:?} vs {r_b:?}" - ) - } _ => {} } self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| { if a_is_expected { - Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::Yes, a, b)) + Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::No, a, b)) } else { - Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::Yes, b, a)) + Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::No, b, a)) } }) } From 526090b901cbedcef7e1eec132e217917606a54d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 23 May 2024 10:03:55 +0000 Subject: [PATCH 6/6] Add regression tests --- tests/crashes/124891.rs | 22 ------- .../impl-trait/lazy_subtyping_of_opaques.rs | 59 +++++++++++++++++++ .../lazy_subtyping_of_opaques.stderr | 21 +++++++ .../lazy_subtyping_of_opaques.rs | 30 ++++++++++ .../lazy_subtyping_of_opaques.stderr | 26 ++++++++ 5 files changed, 136 insertions(+), 22 deletions(-) delete mode 100644 tests/crashes/124891.rs create mode 100644 tests/ui/impl-trait/lazy_subtyping_of_opaques.rs create mode 100644 tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr create mode 100644 tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs create mode 100644 tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr diff --git a/tests/crashes/124891.rs b/tests/crashes/124891.rs deleted file mode 100644 index 9b5892418c897..0000000000000 --- a/tests/crashes/124891.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: rust-lang/rust#124891 - -type Tait = impl FnOnce() -> (); - -fn reify_as_tait() -> Thunk { - Thunk::new(|cont| cont) -} - -struct Thunk(F); - -impl Thunk { - fn new(f: F) - where - F: ContFn, - { - todo!(); - } -} - -trait ContFn {} - -impl ()> ContFn for F {} diff --git a/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs b/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs new file mode 100644 index 0000000000000..65331894725a8 --- /dev/null +++ b/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs @@ -0,0 +1,59 @@ +//! This test checks that we allow subtyping predicates that contain opaque types. +//! No hidden types are being constrained in the subtyping predicate, but type and +//! lifetime variables get subtyped in the generic parameter list of the opaque. + +use std::iter; + +mod either { + pub enum Either { + Left(L), + Right(R), + } + + impl> Iterator for Either { + type Item = L::Item; + fn next(&mut self) -> Option { + todo!() + } + } + pub use self::Either::{Left, Right}; +} + +pub enum BabeConsensusLogRef<'a> { + NextEpochData(BabeNextEpochRef<'a>), + NextConfigData, +} + +impl<'a> BabeConsensusLogRef<'a> { + pub fn scale_encoding( + &self, + ) -> impl Iterator + Clone + 'a> + Clone + 'a { + //~^ ERROR is not satisfied + //~| ERROR is not satisfied + //~| ERROR is not satisfied + match self { + BabeConsensusLogRef::NextEpochData(digest) => either::Left(either::Left( + digest.scale_encoding().map(either::Left).map(either::Left), + )), + BabeConsensusLogRef::NextConfigData => either::Right( + // The Opaque type from ``scale_encoding` gets used opaquely here, while the `R` + // generic parameter of `Either` contains type variables that get subtyped and the + // opaque type contains lifetime variables that get subtyped. + iter::once(either::Right(either::Left([1]))) + .chain(std::iter::once([1]).map(either::Right).map(either::Right)), + ), + } + } +} + +pub struct BabeNextEpochRef<'a>(&'a ()); + +impl<'a> BabeNextEpochRef<'a> { + pub fn scale_encoding( + &self, + ) -> impl Iterator + Clone + 'a> + Clone + 'a { + std::iter::once([1]) + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr b/tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr new file mode 100644 index 0000000000000..2f8c957c2c7dc --- /dev/null +++ b/tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `Either + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either + Clone + '_, _> {Either:: + Clone + '_, _>::Left}>, fn(Either + Clone + '_, _>) -> Either + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either:: + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either:: + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>: Clone` is not satisfied + --> $DIR/lazy_subtyping_of_opaques.rs:30:10 + | +LL | ) -> impl Iterator + Clone + 'a> + Clone + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either + Clone + '_, _> {Either:: + Clone + '_, _>::Left}>, fn(Either + Clone + '_, _>) -> Either + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either:: + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either:: + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>` + +error[E0277]: the trait bound `Either + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: AsRef<[u8]>` is not satisfied + --> $DIR/lazy_subtyping_of_opaques.rs:30:31 + | +LL | ) -> impl Iterator + Clone + 'a> + Clone + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsRef<[u8]>` is not implemented for `Either + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>` + +error[E0277]: the trait bound `Either + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: Clone` is not satisfied + --> $DIR/lazy_subtyping_of_opaques.rs:30:31 + | +LL | ) -> impl Iterator + Clone + 'a> + Clone + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs new file mode 100644 index 0000000000000..72a90287e374f --- /dev/null +++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs @@ -0,0 +1,30 @@ +#![feature(type_alias_impl_trait)] + +//! This test used to ICE rust-lang/rust#124891 +//! because we added an assertion for catching cases where opaque types get +//! registered during the processing of subtyping predicates. + +type Tait = impl FnOnce() -> (); + +fn reify_as_tait() -> Thunk { + Thunk::new(|cont| cont) + //~^ ERROR: mismatched types + //~| ERROR: mismatched types +} + +struct Thunk(F); + +impl Thunk { + fn new(f: F) + where + F: ContFn, + { + todo!(); + } +} + +trait ContFn {} + +impl ()> ContFn for F {} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr new file mode 100644 index 0000000000000..5a35dc27446cb --- /dev/null +++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr @@ -0,0 +1,26 @@ +error[E0308]: mismatched types + --> $DIR/lazy_subtyping_of_opaques.rs:10:23 + | +LL | type Tait = impl FnOnce() -> (); + | ------------------- the found opaque type +... +LL | Thunk::new(|cont| cont) + | ^^^^ expected `()`, found opaque type + | + = note: expected unit type `()` + found opaque type `Tait` + +error[E0308]: mismatched types + --> $DIR/lazy_subtyping_of_opaques.rs:10:5 + | +LL | fn reify_as_tait() -> Thunk { + | ----------- expected `Thunk<_>` because of return type +LL | Thunk::new(|cont| cont) + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `Thunk<_>`, found `()` + | + = note: expected struct `Thunk<_>` + found unit type `()` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`.