From ff4ca95691a3ca0f2b0b50845ec26ce201df2389 Mon Sep 17 00:00:00 2001 From: Andrew Pollack Date: Mon, 19 Dec 2022 11:24:59 -0800 Subject: [PATCH 1/6] Revert "Replace usage of `ResumeTy` in async lowering with `Context`" --- compiler/rustc_ast_lowering/src/expr.rs | 57 +++++++------------ compiler/rustc_hir/src/lang_items.rs | 3 +- compiler/rustc_span/src/symbol.rs | 3 +- library/core/src/future/mod.rs | 10 +--- library/core/src/task/wake.rs | 1 - .../async-await-let-else.drop-tracking.stderr | 2 +- .../issue-68112.drop_tracking.stderr | 2 +- .../issue-68112.no_drop_tracking.stderr | 2 +- .../issue-69446-fnmut-capture.stderr | 3 - ...e-70935-complex-spans.drop_tracking.stderr | 2 +- ...l-drop-partial-reinit.drop_tracking.stderr | 2 +- ...rop-partial-reinit.no_drop_tracking.stderr | 2 +- .../closure-in-projection-issue-97405.rs | 4 +- .../closure-in-projection-issue-97405.stderr | 20 +++---- 14 files changed, 43 insertions(+), 70 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 24e2985cf567a..77b7ee38bde04 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -16,7 +16,7 @@ use rustc_hir::def::Res; use rustc_hir::definitions::DefPathData; use rustc_session::errors::report_lit_error; use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned}; -use rustc_span::symbol::{kw, sym, Ident}; +use rustc_span::symbol::{sym, Ident}; use rustc_span::DUMMY_SP; use thin_vec::thin_vec; @@ -585,38 +585,14 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> hir::ExprKind<'hir> { let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span))); - // Resume argument type, which should be `&mut Context<'_>`. - // NOTE: Using the `'static` lifetime here is technically cheating. - // The `Future::poll` argument really is `&'a mut Context<'b>`, but we cannot - // express the fact that we are not storing it across yield-points yet, - // and we would thus run into lifetime errors. - // See . - // Our lowering makes sure we are not mis-using the `_task_context` input type - // in the sense that we are indeed not using it across yield points. We - // get a fresh `&mut Context` for each resume / call of `Future::poll`. - // This "cheating" was previously done with a `ResumeTy` that contained a raw - // pointer, and a `get_context` accessor that pulled the `Context` lifetimes - // out of thin air. - let context_lifetime_ident = Ident::with_dummy_span(kw::StaticLifetime); - let context_lifetime = self.arena.alloc(hir::Lifetime { - hir_id: self.next_id(), - ident: context_lifetime_ident, - res: hir::LifetimeName::Static, - }); - let context_path = - hir::QPath::LangItem(hir::LangItem::Context, self.lower_span(span), None); - let context_ty = hir::MutTy { - ty: self.arena.alloc(hir::Ty { - hir_id: self.next_id(), - kind: hir::TyKind::Path(context_path), - span: self.lower_span(span), - }), - mutbl: hir::Mutability::Mut, - }; + // Resume argument type: `ResumeTy` + let unstable_span = + self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone()); + let resume_ty = hir::QPath::LangItem(hir::LangItem::ResumeTy, unstable_span, None); let input_ty = hir::Ty { hir_id: self.next_id(), - kind: hir::TyKind::Rptr(context_lifetime, context_ty), - span: self.lower_span(span), + kind: hir::TyKind::Path(resume_ty), + span: unstable_span, }; // The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`. @@ -674,9 +650,12 @@ impl<'hir> LoweringContext<'_, 'hir> { .map_or(false, |attrs| attrs.into_iter().any(|attr| attr.has_name(sym::track_caller))); let hir_id = self.lower_node_id(closure_node_id); - let unstable_span = - self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone()); if track_caller { + let unstable_span = self.mark_span_with_reason( + DesugaringKind::Async, + span, + self.allow_gen_future.clone(), + ); self.lower_attrs( hir_id, &[Attribute { @@ -719,7 +698,7 @@ impl<'hir> LoweringContext<'_, 'hir> { /// mut __awaitee => loop { /// match unsafe { ::std::future::Future::poll( /// <::std::pin::Pin>::new_unchecked(&mut __awaitee), - /// task_context, + /// ::std::future::get_context(task_context), /// ) } { /// ::std::task::Poll::Ready(result) => break result, /// ::std::task::Poll::Pending => {} @@ -760,7 +739,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // unsafe { // ::std::future::Future::poll( // ::std::pin::Pin::new_unchecked(&mut __awaitee), - // task_context, + // ::std::future::get_context(task_context), // ) // } let poll_expr = { @@ -778,10 +757,16 @@ impl<'hir> LoweringContext<'_, 'hir> { arena_vec![self; ref_mut_awaitee], Some(expr_hir_id), ); + let get_context = self.expr_call_lang_item_fn_mut( + gen_future_span, + hir::LangItem::GetContext, + arena_vec![self; task_context], + Some(expr_hir_id), + ); let call = self.expr_call_lang_item_fn( span, hir::LangItem::FuturePoll, - arena_vec![self; new_unchecked, task_context], + arena_vec![self; new_unchecked, get_context], Some(expr_hir_id), ); self.arena.alloc(self.expr_unsafe(call)) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index b51257df713ea..038509031b180 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -286,9 +286,10 @@ language_item_table! { // FIXME(swatinem): the following lang items are used for async lowering and // should become obsolete eventually. + ResumeTy, sym::ResumeTy, resume_ty, Target::Struct, GenericRequirement::None; IdentityFuture, sym::identity_future, identity_future_fn, Target::Fn, GenericRequirement::None; + GetContext, sym::get_context, get_context_fn, Target::Fn, GenericRequirement::None; - Context, sym::Context, context, Target::Struct, GenericRequirement::None; FuturePoll, sym::poll, future_poll_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; FromFrom, sym::from, from_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6125384549723..9e446c96db319 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -165,7 +165,6 @@ symbols! { Capture, Center, Clone, - Context, Continue, Copy, Count, @@ -265,6 +264,7 @@ symbols! { Relaxed, Release, Result, + ResumeTy, Return, Right, Rust, @@ -754,6 +754,7 @@ symbols! { generic_associated_types_extended, generic_const_exprs, generic_param_attrs, + get_context, global_allocator, global_asm, globs, diff --git a/library/core/src/future/mod.rs b/library/core/src/future/mod.rs index 2a8e12fd4cf60..f2b961d62e00c 100644 --- a/library/core/src/future/mod.rs +++ b/library/core/src/future/mod.rs @@ -44,7 +44,7 @@ pub use poll_fn::{poll_fn, PollFn}; /// non-Send/Sync as well, and we don't want that. /// /// It also simplifies the HIR lowering of `.await`. -// FIXME(swatinem): This type can be removed when bumping the bootstrap compiler +#[cfg_attr(not(bootstrap), lang = "ResumeTy")] #[doc(hidden)] #[unstable(feature = "gen_future", issue = "50547")] #[derive(Debug, Copy, Clone)] @@ -61,7 +61,6 @@ unsafe impl Sync for ResumeTy {} /// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give /// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`). // This is `const` to avoid extra errors after we recover from `const async fn` -// FIXME(swatinem): This fn can be removed when bumping the bootstrap compiler #[cfg_attr(bootstrap, lang = "from_generator")] #[doc(hidden)] #[unstable(feature = "gen_future", issue = "50547")] @@ -103,8 +102,7 @@ where GenFuture(gen) } -// FIXME(swatinem): This fn can be removed when bumping the bootstrap compiler -#[cfg_attr(bootstrap, lang = "get_context")] +#[lang = "get_context"] #[doc(hidden)] #[unstable(feature = "gen_future", issue = "50547")] #[must_use] @@ -115,10 +113,6 @@ pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> { unsafe { &mut *cx.0.as_ptr().cast() } } -// FIXME(swatinem): This fn is currently needed to work around shortcomings -// in type and lifetime inference. -// See the comment at the bottom of `LoweringContext::make_async_expr` and -// . #[cfg_attr(not(bootstrap), lang = "identity_future")] #[doc(hidden)] #[unstable(feature = "gen_future", issue = "50547")] diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 9ab9b0ba1c797..0cff972df3a5a 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -174,7 +174,6 @@ impl RawWakerVTable { /// Currently, `Context` only serves to provide access to a [`&Waker`](Waker) /// which can be used to wake the current task. #[stable(feature = "futures_api", since = "1.36.0")] -#[cfg_attr(not(bootstrap), lang = "Context")] pub struct Context<'a> { waker: &'a Waker, // Ensure we future-proof against variance changes by forcing diff --git a/src/test/ui/async-await/async-await-let-else.drop-tracking.stderr b/src/test/ui/async-await/async-await-let-else.drop-tracking.stderr index 616623ee07759..3be7f370da3f5 100644 --- a/src/test/ui/async-await/async-await-let-else.drop-tracking.stderr +++ b/src/test/ui/async-await/async-await-let-else.drop-tracking.stderr @@ -40,7 +40,7 @@ LL | async fn bar2(_: T) -> ! { LL | | panic!() LL | | } | |_^ - = note: required because it captures the following types: `&mut Context<'_>`, `Option`, `impl Future`, `()` + = note: required because it captures the following types: `ResumeTy`, `Option`, `impl Future`, `()` note: required because it's used within this `async fn` body --> $DIR/async-await-let-else.rs:21:32 | diff --git a/src/test/ui/async-await/issue-68112.drop_tracking.stderr b/src/test/ui/async-await/issue-68112.drop_tracking.stderr index 1c90bedae790c..f2802698fd5b6 100644 --- a/src/test/ui/async-await/issue-68112.drop_tracking.stderr +++ b/src/test/ui/async-await/issue-68112.drop_tracking.stderr @@ -57,7 +57,7 @@ note: required because it appears within the type `impl Future impl Future>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: required because it captures the following types: `&mut Context<'_>`, `impl Future>>`, `()`, `Ready` + = note: required because it captures the following types: `ResumeTy`, `impl Future>>`, `()`, `Ready` note: required because it's used within this `async` block --> $DIR/issue-68112.rs:60:20 | diff --git a/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr b/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr index e09ae7fedd805..38eb85b302fd5 100644 --- a/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr +++ b/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr @@ -57,7 +57,7 @@ note: required because it appears within the type `impl Future impl Future>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: required because it captures the following types: `&mut Context<'_>`, `impl Future>>`, `()`, `i32`, `Ready` + = note: required because it captures the following types: `ResumeTy`, `impl Future>>`, `()`, `i32`, `Ready` note: required because it's used within this `async` block --> $DIR/issue-68112.rs:60:20 | diff --git a/src/test/ui/async-await/issue-69446-fnmut-capture.stderr b/src/test/ui/async-await/issue-69446-fnmut-capture.stderr index e6ad2f0d444bb..3d2b0402bc52c 100644 --- a/src/test/ui/async-await/issue-69446-fnmut-capture.stderr +++ b/src/test/ui/async-await/issue-69446-fnmut-capture.stderr @@ -14,9 +14,6 @@ LL | | }); | = note: `FnMut` closures only have access to their captured variables while they are executing... = note: ...therefore, they cannot allow references to captured variables to escape - = note: requirement occurs because of a mutable reference to `Context<'_>` - = note: mutable references are invariant over their type parameter - = help: see for more information about variance error: aborting due to previous error diff --git a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr index a8fd97cde8f7a..721234aa4a782 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr +++ b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr @@ -18,7 +18,7 @@ LL | async fn baz(_c: impl FnMut() -> T) where T: Future { | ___________________________________________________________________^ LL | | } | |_^ - = note: required because it captures the following types: `&mut Context<'_>`, `impl Future`, `()` + = note: required because it captures the following types: `ResumeTy`, `impl Future`, `()` note: required because it's used within this `async` block --> $DIR/issue-70935-complex-spans.rs:16:5 | diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr b/src/test/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr index 25876d5084015..17b4ef7bdc671 100644 --- a/src/test/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr +++ b/src/test/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr @@ -11,7 +11,7 @@ LL | async fn foo() { | = help: within `impl Future`, the trait `Send` is not implemented for `NotSend` = note: required because it appears within the type `(NotSend,)` - = note: required because it captures the following types: `&mut Context<'_>`, `(NotSend,)`, `()`, `impl Future` + = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `()`, `impl Future` note: required because it's used within this `async fn` body --> $DIR/partial-drop-partial-reinit.rs:31:16 | diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr b/src/test/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr index dba2a620779f0..34d8a159f1064 100644 --- a/src/test/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr +++ b/src/test/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr @@ -11,7 +11,7 @@ LL | async fn foo() { | = help: within `impl Future`, the trait `Send` is not implemented for `NotSend` = note: required because it appears within the type `(NotSend,)` - = note: required because it captures the following types: `&mut Context<'_>`, `(NotSend,)`, `impl Future`, `()` + = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `impl Future`, `()` note: required because it's used within this `async fn` body --> $DIR/partial-drop-partial-reinit.rs:31:16 | diff --git a/src/test/ui/regions/closure-in-projection-issue-97405.rs b/src/test/ui/regions/closure-in-projection-issue-97405.rs index 88b1c1396516d..e567d5c2723f2 100644 --- a/src/test/ui/regions/closure-in-projection-issue-97405.rs +++ b/src/test/ui/regions/closure-in-projection-issue-97405.rs @@ -22,11 +22,11 @@ fn good_generic_fn() { // This should fail because `T` ends up in the upvars of the closure. fn bad_generic_fn(t: T) { assert_static(opaque(async move { t; }).next()); - //~^ ERROR the parameter type `T` may not live long enough + //~^ ERROR the associated type `::Item` may not live long enough assert_static(opaque(move || { t; }).next()); //~^ ERROR the associated type `::Item` may not live long enough assert_static(opaque(opaque(async move { t; }).next()).next()); - //~^ ERROR the parameter type `T` may not live long enough + //~^ ERROR the associated type `::Item` may not live long enough } fn main() {} diff --git a/src/test/ui/regions/closure-in-projection-issue-97405.stderr b/src/test/ui/regions/closure-in-projection-issue-97405.stderr index 907964aaf379e..c08f1059ebf58 100644 --- a/src/test/ui/regions/closure-in-projection-issue-97405.stderr +++ b/src/test/ui/regions/closure-in-projection-issue-97405.stderr @@ -1,13 +1,11 @@ -error[E0310]: the parameter type `T` may not live long enough +error[E0310]: the associated type `::Item` may not live long enough --> $DIR/closure-in-projection-issue-97405.rs:24:5 | LL | assert_static(opaque(async move { t; }).next()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds - | -help: consider adding an explicit lifetime bound... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -LL | fn bad_generic_fn(t: T) { - | +++++++++ + = help: consider adding an explicit lifetime bound `::Item: 'static`... + = note: ...so that the type `::Item` will meet its required lifetime bounds error[E0310]: the associated type `::Item` may not live long enough --> $DIR/closure-in-projection-issue-97405.rs:26:5 @@ -18,16 +16,14 @@ LL | assert_static(opaque(move || { t; }).next()); = help: consider adding an explicit lifetime bound `::Item: 'static`... = note: ...so that the type `::Item` will meet its required lifetime bounds -error[E0310]: the parameter type `T` may not live long enough +error[E0310]: the associated type `::Item` may not live long enough --> $DIR/closure-in-projection-issue-97405.rs:28:5 | LL | assert_static(opaque(opaque(async move { t; }).next()).next()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds - | -help: consider adding an explicit lifetime bound... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -LL | fn bad_generic_fn(t: T) { - | +++++++++ + = help: consider adding an explicit lifetime bound `::Item: 'static`... + = note: ...so that the type `::Item` will meet its required lifetime bounds error: aborting due to 3 previous errors From 0645c3df578a53bd39f77de71b45c68ec3a89ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 16 Dec 2022 20:37:53 +0000 Subject: [PATCH 2/6] don't copy symbols from dylibs with -Zdylib-lto --- compiler/rustc_codegen_ssa/src/back/link.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 882430694e16d..fe2e4b36cd0f1 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -253,7 +253,7 @@ pub fn each_linked_rlib( }; for &cnum in crates { match fmts.get(cnum.as_usize() - 1) { - Some(&Linkage::NotLinked | &Linkage::IncludedFromDylib) => continue, + Some(&Linkage::NotLinked | &Linkage::Dynamic | &Linkage::IncludedFromDylib) => continue, Some(_) => {} None => return Err(errors::LinkRlibError::MissingFormat), } From 95887f270a4cdf80ee94437395df9eaf907d351e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 16 Dec 2022 20:38:32 +0000 Subject: [PATCH 3/6] add simulated non-regression test for issue 105637 --- src/test/ui/lto/auxiliary/thinlto-dylib.rs | 23 ++++++++++++++++++ src/test/ui/lto/issue-105637.rs | 28 ++++++++++++++++++++++ src/test/ui/lto/issue-105637.run.stderr | 1 + 3 files changed, 52 insertions(+) create mode 100644 src/test/ui/lto/auxiliary/thinlto-dylib.rs create mode 100644 src/test/ui/lto/issue-105637.rs create mode 100644 src/test/ui/lto/issue-105637.run.stderr diff --git a/src/test/ui/lto/auxiliary/thinlto-dylib.rs b/src/test/ui/lto/auxiliary/thinlto-dylib.rs new file mode 100644 index 0000000000000..9d17c35dafc25 --- /dev/null +++ b/src/test/ui/lto/auxiliary/thinlto-dylib.rs @@ -0,0 +1,23 @@ +// Auxiliary crate for test issue-105637: the LTOed dylib which had duplicate symbols from libstd, +// breaking the panic hook feature. +// +// This simulates the `rustc_driver` crate, and the main crate simulates rustc's main binary hooking +// into this driver. + +// compile-flags: -Zdylib-lto -C lto=thin + +use std::panic; + +pub fn main() { + // Install the hook we want to see executed + panic::set_hook(Box::new(|_| { + eprintln!("LTOed auxiliary crate panic hook"); + })); + + // Trigger the panic hook with an ICE + run_compiler(); +} + +fn run_compiler() { + panic!("ICEing"); +} diff --git a/src/test/ui/lto/issue-105637.rs b/src/test/ui/lto/issue-105637.rs new file mode 100644 index 0000000000000..0d9f0bec00fd3 --- /dev/null +++ b/src/test/ui/lto/issue-105637.rs @@ -0,0 +1,28 @@ +// Regression test for issue #105637: `-Zdylib-lto` with LTO duplicated symbols from other dylibs, +// in this case from libstd. +// +// That manifested as both `rustc_driver` and rustc's "main" (`compiler/rustc`) having their own +// `std::panicking::HOOK` static, and the hook in rustc's main (the default stdlib's) being executed +// when rustc ICEs, instead of the overriden hook from `rustc_driver` (which also displays the query +// stack and information on how to open a GH issue for the encountered ICE). +// +// In this test, we reproduce this setup by installing a panic hook in both the main and an LTOed +// dylib: the last hook set should be the one being executed, the dylib's. + +// aux-build: thinlto-dylib.rs +// run-fail +// check-run-results + +extern crate thinlto_dylib; + +use std::panic; + +fn main() { + // We don't want to see this panic hook executed + std::panic::set_hook(Box::new(|_| { + eprintln!("main crate panic hook"); + })); + + // Have the LTOed dylib install its own hook and panic, we want to see its hook executed. + thinlto_dylib::main(); +} diff --git a/src/test/ui/lto/issue-105637.run.stderr b/src/test/ui/lto/issue-105637.run.stderr new file mode 100644 index 0000000000000..43388e7763ee2 --- /dev/null +++ b/src/test/ui/lto/issue-105637.run.stderr @@ -0,0 +1 @@ +LTOed auxiliary crate panic hook From 4b988c9f11742d7b2a8453cd5a130125c727a7a7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 10 Dec 2022 21:01:48 +0100 Subject: [PATCH 4/6] Don't take into account hashtag prepended lines if not in rust code block --- src/librustdoc/html/markdown.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 5ce62224d35e5..1e1c657b0bf22 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -246,8 +246,6 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { _ => {} } } - let lines = origtext.lines().filter_map(|l| map_line(l).for_html()); - let text = lines.intersperse("\n".into()).collect::(); let parse_result = match kind { CodeBlockKind::Fenced(ref lang) => { @@ -260,7 +258,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> {
{}
\ ", lang, - Escape(&text), + Escape(&origtext), ) .into(), )); @@ -270,6 +268,9 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { CodeBlockKind::Indented => Default::default(), }; + let lines = origtext.lines().filter_map(|l| map_line(l).for_html()); + let text = lines.intersperse("\n".into()).collect::(); + compile_fail = parse_result.compile_fail; should_panic = parse_result.should_panic; ignore = parse_result.ignore; From d4bafb6aa554e16a79ec19693ffbe81427d088eb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 10 Dec 2022 21:02:08 +0100 Subject: [PATCH 5/6] Add test for non-rust code block hashtag prepended lines --- src/librustdoc/html/markdown/tests.rs | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index e4f72a057892f..68b31a6ee083d 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -309,3 +309,40 @@ fn test_find_testable_code_line() { t("```rust\n```\n```rust\n```", &[1, 3]); t("```rust\n```\n ```rust\n```", &[1, 3]); } + +#[test] +fn test_ascii_with_prepending_hashtag() { + fn t(input: &str, expect: &str) { + let mut map = IdMap::new(); + let output = Markdown { + content: input, + links: &[], + ids: &mut map, + error_codes: ErrorCodes::Yes, + edition: DEFAULT_EDITION, + playground: &None, + heading_offset: HeadingOffset::H2, + } + .into_string(); + assert_eq!(output, expect, "original: {}", input); + } + + t( + r#"```ascii +#..#.####.#....#.....##.. +#..#.#....#....#....#..#. +####.###..#....#....#..#. +#..#.#....#....#....#..#. +#..#.#....#....#....#..#. +#..#.####.####.####..##.. +```"#, + "
\
+#..#.####.#....#.....##..
+#..#.#....#....#....#..#.
+####.###..#....#....#..#.
+#..#.#....#....#....#..#.
+#..#.#....#....#....#..#.
+#..#.####.####.####..##..
+
", + ); +} From dbc1048dc9b67a67621fa1dd360540952eddfe85 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 8 Dec 2022 10:35:46 -0800 Subject: [PATCH 6/6] Mangle "main" as "__main_void" on wasm32-wasi On wasm, the age-old C trick of having a main function which can either have no arguments or argc+argv doesn't work, because wasm requires caller and callee signatures to match. WASI's current strategy is to have compilers mangle main's name to indicate which signature they're using. Rust uses the no-argument form, which should be mangled as `__main_void`. This is needed on wasm32-wasi as of #105395. --- compiler/rustc_target/src/spec/wasm32_wasi.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs index 6f0bbf0672d44..a0476d542e642 100644 --- a/compiler/rustc_target/src/spec/wasm32_wasi.rs +++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs @@ -104,6 +104,10 @@ pub fn target() -> Target { // `args::args()` makes the WASI API calls itself. options.main_needs_argc_argv = false; + // And, WASI mangles the name of "main" to distinguish between different + // signatures. + options.entry_name = "__main_void".into(); + Target { llvm_target: "wasm32-wasi".into(), pointer_width: 32,