diff --git a/compiler/rustc_error_codes/src/error_codes/E0373.md b/compiler/rustc_error_codes/src/error_codes/E0373.md index effa597aad9..d4d26007aa5 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0373.md +++ b/compiler/rustc_error_codes/src/error_codes/E0373.md @@ -70,4 +70,4 @@ fn spawn<F: Future + Send + 'static>(future: F) { Similarly to closures, `async` blocks are not executed immediately and may capture closed-over data by reference. For more information, see -https://rust-lang.github.io/async-book/03_async_await/01_chapter.html. +<https://rust-lang.github.io/async-book/03_async_await/01_chapter.html>. diff --git a/compiler/rustc_error_codes/src/error_codes/E0378.md b/compiler/rustc_error_codes/src/error_codes/E0378.md index c6fe997f3dc..7d939b99b04 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0378.md +++ b/compiler/rustc_error_codes/src/error_codes/E0378.md @@ -20,7 +20,7 @@ where The `DispatchFromDyn` trait currently can only be implemented for builtin pointer types and structs that are newtype wrappers around them -— that is, the struct must have only one field (except for`PhantomData`), +— that is, the struct must have only one field (except for `PhantomData`), and that field must itself implement `DispatchFromDyn`. ``` diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 2086d4030f9..2a850d9303c 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -15,6 +15,7 @@ #![feature(box_patterns)] #![feature(error_reporter)] #![feature(extract_if)] +#![feature(if_let_guard)] #![feature(let_chains)] #![feature(negative_impls)] #![feature(never_type)] diff --git a/compiler/rustc_errors/src/markdown/parse.rs b/compiler/rustc_errors/src/markdown/parse.rs index 67e4963fddf..69e7120e714 100644 --- a/compiler/rustc_errors/src/markdown/parse.rs +++ b/compiler/rustc_errors/src/markdown/parse.rs @@ -10,15 +10,15 @@ const CBK: &[u8] = b"```"; const CIL: &[u8] = b"`"; const CMT_E: &[u8] = b"-->"; const CMT_S: &[u8] = b"<!--"; -const EMP: &[u8] = b"_"; +const EMP_U: &[u8] = b"_"; +const EMP_A: &[u8] = b"*"; const HDG: &[u8] = b"#"; const LNK_CHARS: &str = "$-_.+!*'()/&?=:%"; const LNK_E: &[u8] = b"]"; const LNK_S: &[u8] = b"["; -const STG: &[u8] = b"**"; +const STG_U: &[u8] = b"__"; +const STG_A: &[u8] = b"**"; const STK: &[u8] = b"~~"; -const UL1: &[u8] = b"* "; -const UL2: &[u8] = b"- "; /// Pattern replacements const REPLACEMENTS: &[(&str, &str)] = &[ @@ -100,22 +100,29 @@ fn parse_recursive<'a>(buf: &'a [u8], ctx: Context) -> MdStream<'_> { }; let res: ParseResult<'_> = match (top_blk, prev) { - (_, Newline | Whitespace) if loop_buf.starts_with(CMT_S) => { + _ if loop_buf.starts_with(CMT_S) => { parse_simple_pat(loop_buf, CMT_S, CMT_E, Po::TrimNoEsc, MdTree::Comment) } (true, Newline) if loop_buf.starts_with(CBK) => Some(parse_codeblock(loop_buf)), - (_, Newline | Whitespace) if loop_buf.starts_with(CIL) => parse_codeinline(loop_buf), + _ if loop_buf.starts_with(CIL) => parse_codeinline(loop_buf), (true, Newline | Whitespace) if loop_buf.starts_with(HDG) => parse_heading(loop_buf), (true, Newline) if loop_buf.starts_with(BRK) => { Some((MdTree::HorizontalRule, parse_to_newline(loop_buf).1)) } - (_, Newline | Whitespace) if loop_buf.starts_with(EMP) => { - parse_simple_pat(loop_buf, EMP, EMP, Po::None, MdTree::Emphasis) + (_, Newline) if unordered_list_start(loop_buf) => Some(parse_unordered_li(loop_buf)), + (_, Newline | Whitespace) if loop_buf.starts_with(STG_U) => { + parse_simple_pat(loop_buf, STG_U, STG_U, Po::None, MdTree::Strong) } - (_, Newline | Whitespace) if loop_buf.starts_with(STG) => { - parse_simple_pat(loop_buf, STG, STG, Po::None, MdTree::Strong) + _ if loop_buf.starts_with(STG_A) => { + parse_simple_pat(loop_buf, STG_A, STG_A, Po::None, MdTree::Strong) } - (_, Newline | Whitespace) if loop_buf.starts_with(STK) => { + (_, Newline | Whitespace) if loop_buf.starts_with(EMP_U) => { + parse_simple_pat(loop_buf, EMP_U, EMP_U, Po::None, MdTree::Emphasis) + } + _ if loop_buf.starts_with(EMP_A) => { + parse_simple_pat(loop_buf, EMP_A, EMP_A, Po::None, MdTree::Emphasis) + } + _ if loop_buf.starts_with(STK) => { parse_simple_pat(loop_buf, STK, STK, Po::None, MdTree::Strikethrough) } (_, Newline | Whitespace) if loop_buf.starts_with(ANC_S) => { @@ -130,11 +137,8 @@ fn parse_recursive<'a>(buf: &'a [u8], ctx: Context) -> MdStream<'_> { _ => None, } } - (_, Newline) if (loop_buf.starts_with(UL1) || loop_buf.starts_with(UL2)) => { - Some(parse_unordered_li(loop_buf)) - } (_, Newline) if ord_list_start(loop_buf).is_some() => Some(parse_ordered_li(loop_buf)), - (_, Newline | Whitespace) if loop_buf.starts_with(LNK_S) => { + _ if loop_buf.starts_with(LNK_S) => { parse_any_link(loop_buf, top_blk && prev == Prev::Newline) } (_, Escape | _) => None, @@ -251,7 +255,6 @@ fn parse_heading(buf: &[u8]) -> ParseResult<'_> { /// Bulleted list fn parse_unordered_li(buf: &[u8]) -> Parsed<'_> { - debug_assert!(buf.starts_with(b"* ") || buf.starts_with(b"- ")); let (txt, rest) = get_indented_section(&buf[2..]); let ctx = Context { top_block: false, prev: Prev::Whitespace }; let stream = parse_recursive(trim_ascii_start(txt), ctx); @@ -267,25 +270,28 @@ fn parse_ordered_li(buf: &[u8]) -> Parsed<'_> { (MdTree::OrderedListItem(num, stream), rest) } -/// Find first line that isn't empty or doesn't start with whitespace, that will -/// be our contents fn get_indented_section(buf: &[u8]) -> (&[u8], &[u8]) { - let mut end = buf.len(); - for (idx, window) in buf.windows(2).enumerate() { - let &[ch, next_ch] = window else { unreachable!("always 2 elements") }; - if idx >= buf.len().saturating_sub(2) && next_ch == b'\n' { - // End of stream - end = buf.len().saturating_sub(1); - break; - } else if ch == b'\n' && (!next_ch.is_ascii_whitespace() || next_ch == b'\n') { - end = idx; - break; + let mut lines = buf.split(|&byte| byte == b'\n'); + let mut end = lines.next().map_or(0, |line| line.len()); + for line in lines { + if let Some(first) = line.first() { + if unordered_list_start(line) || !first.is_ascii_whitespace() { + break; + } } + end += line.len() + 1; } (&buf[..end], &buf[end..]) } +fn unordered_list_start(mut buf: &[u8]) -> bool { + while let [b' ', rest @ ..] = buf { + buf = rest; + } + matches!(buf, [b'*' | b'-', b' ', ..]) +} + /// Verify a valid ordered list start (e.g. `1.`) and parse it. Returns the /// parsed number and offset of character after the dot. fn ord_list_start(buf: &[u8]) -> Option<(u16, usize)> { diff --git a/compiler/rustc_errors/src/markdown/tests/parse.rs b/compiler/rustc_errors/src/markdown/tests/parse.rs index e39e8c89b35..e2e3f354ff6 100644 --- a/compiler/rustc_errors/src/markdown/tests/parse.rs +++ b/compiler/rustc_errors/src/markdown/tests/parse.rs @@ -4,13 +4,13 @@ use ParseOpt as PO; #[test] fn test_parse_simple() { let buf = "**abcd** rest"; - let (t, r) = parse_simple_pat(buf.as_bytes(), STG, STG, PO::None, MdTree::Strong).unwrap(); + let (t, r) = parse_simple_pat(buf.as_bytes(), b"**", b"**", PO::None, MdTree::Strong).unwrap(); assert_eq!(t, MdTree::Strong("abcd")); assert_eq!(r, b" rest"); // Escaping should fail let buf = r"**abcd\** rest"; - let res = parse_simple_pat(buf.as_bytes(), STG, STG, PO::None, MdTree::Strong); + let res = parse_simple_pat(buf.as_bytes(), b"**", b"**", PO::None, MdTree::Strong); assert!(res.is_none()); } @@ -141,12 +141,12 @@ fn test_indented_section() { assert_eq!(str::from_utf8(r).unwrap(), "\nnot ind"); let (txt, rest) = get_indented_section(IND2.as_bytes()); - assert_eq!(str::from_utf8(txt).unwrap(), "test end of stream\n 1\n 2"); - assert_eq!(str::from_utf8(rest).unwrap(), "\n"); + assert_eq!(str::from_utf8(txt).unwrap(), "test end of stream\n 1\n 2\n"); + assert_eq!(str::from_utf8(rest).unwrap(), ""); let (txt, rest) = get_indented_section(IND3.as_bytes()); - assert_eq!(str::from_utf8(txt).unwrap(), "test empty lines\n 1\n 2"); - assert_eq!(str::from_utf8(rest).unwrap(), "\n\nnot ind"); + assert_eq!(str::from_utf8(txt).unwrap(), "test empty lines\n 1\n 2\n"); + assert_eq!(str::from_utf8(rest).unwrap(), "\nnot ind"); } const HBT: &str = r"# Heading @@ -310,3 +310,56 @@ fn test_code_at_start() { let res = entrypoint(CODE_STARTLINE); assert_eq!(res, expected); } + +#[test] +fn test_code_in_parens() { + let expected = + vec![MdTree::PlainText("("), MdTree::CodeInline("Foo"), MdTree::PlainText(")")].into(); + let res = entrypoint("(`Foo`)"); + assert_eq!(res, expected); +} + +const LIST_WITH_SPACE: &str = " +para + * l1 + * l2 +"; + +#[test] +fn test_list_with_space() { + let expected = vec![ + MdTree::PlainText("para"), + MdTree::ParagraphBreak, + MdTree::UnorderedListItem(vec![MdTree::PlainText("l1")].into()), + MdTree::LineBreak, + MdTree::UnorderedListItem(vec![MdTree::PlainText("l2")].into()), + ] + .into(); + let res = entrypoint(LIST_WITH_SPACE); + assert_eq!(res, expected); +} + +const SNAKE_CASE: &str = " +foo*bar* +foo**bar** +foo_bar_ +foo__bar__ +"; + +#[test] +fn test_snake_case() { + let expected = vec![ + MdTree::PlainText("foo"), + MdTree::Emphasis("bar"), + MdTree::PlainText(" "), + MdTree::PlainText("foo"), + MdTree::Strong("bar"), + MdTree::PlainText(" "), + MdTree::PlainText("foo_bar_"), + MdTree::PlainText(" "), + MdTree::PlainText("foo__bar__"), + ] + .into(); + let res = entrypoint(SNAKE_CASE); + assert_eq!(res, expected); +} diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 341d533492d..65229722771 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -495,6 +495,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { err.span_label(self.span, "invalid cast"); } + fcx.suggest_no_capture_closure(&mut err, self.cast_ty, self.expr_ty); self.try_suggest_collection_to_bool(fcx, &mut err); err.emit(); diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 7d67cc3b36e..649bcdd8733 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -472,6 +472,11 @@ impl Step for Rustc { ); } } + if builder.build_wasm_component_ld() { + let src_dir = builder.sysroot_libdir(compiler, host).parent().unwrap().join("bin"); + let ld = exe("wasm-component-ld", compiler.host); + builder.copy_link(&src_dir.join(&ld), &dst_dir.join(&ld)); + } // Man pages t!(fs::create_dir_all(image.join("share/man/man1"))); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 9d5aa795c6c..e32288e2caf 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1570,11 +1570,22 @@ impl Config { let mut is_user_configured_rust_channel = false; if let Some(rust) = toml.rust { - config.download_rustc_commit = - config.download_ci_rustc_commit(rust.download_rustc.clone()); + if let Some(commit) = config.download_ci_rustc_commit(rust.download_rustc.clone()) { + // Primarily used by CI runners to avoid handling download-rustc incompatible + // options one by one on shell scripts. + let disable_ci_rustc_if_incompatible = + env::var_os("DISABLE_CI_RUSTC_IF_INCOMPATIBLE") + .is_some_and(|s| s == "1" || s == "true"); - if config.download_rustc_commit.is_some() { - check_incompatible_options_for_ci_rustc(&rust); + if let Err(e) = check_incompatible_options_for_ci_rustc(&rust) { + if disable_ci_rustc_if_incompatible { + config.download_rustc_commit = None; + } else { + panic!("{}", e); + } + } else { + config.download_rustc_commit = Some(commit); + } } let Rust { @@ -2612,14 +2623,15 @@ impl Config { /// Checks the CI rustc incompatible options by destructuring the `Rust` instance /// and makes sure that no rust options from config.toml are missed. -fn check_incompatible_options_for_ci_rustc(rust: &Rust) { +fn check_incompatible_options_for_ci_rustc(rust: &Rust) -> Result<(), String> { macro_rules! err { ($name:expr) => { - assert!( - $name.is_none(), - "ERROR: Setting `rust.{}` is incompatible with `rust.download-rustc`.", - stringify!($name).replace("_", "-") - ); + if $name.is_some() { + return Err(format!( + "ERROR: Setting `rust.{}` is incompatible with `rust.download-rustc`.", + stringify!($name).replace("_", "-") + )); + } }; } @@ -2715,6 +2727,8 @@ fn check_incompatible_options_for_ci_rustc(rust: &Rust) { warn!(channel); warn!(description); warn!(incremental); + + Ok(()) } fn set<T>(field: &mut T, val: Option<T>) { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 16c08f709df..78c06551ff2 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -3378,6 +3378,7 @@ impl<'test> TestCx<'test> { cmd.env("IS_MSVC", "1") .env("IS_WINDOWS", "1") .env("MSVC_LIB", format!("'{}' -nologo", lib.display())) + .env("MSVC_LIB_PATH", format!("{}", lib.display())) .env("CC", format!("'{}' {}", self.config.cc, cflags)) .env("CXX", format!("'{}' {}", &self.config.cxx, cxxflags)); } else { @@ -3748,6 +3749,7 @@ impl<'test> TestCx<'test> { cmd.env("IS_MSVC", "1") .env("IS_WINDOWS", "1") .env("MSVC_LIB", format!("'{}' -nologo", lib.display())) + .env("MSVC_LIB_PATH", format!("{}", lib.display())) // Note: we diverge from legacy run_make and don't lump `CC` the compiler and // default flags together. .env("CC_DEFAULT_FLAGS", &cflags) diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 158d5cc8ade..4042bac8dac 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -27,7 +27,6 @@ run-make/foreign-rust-exceptions/Makefile run-make/incr-add-rust-src-component/Makefile run-make/incr-foreign-head-span/Makefile run-make/interdependent-c-libraries/Makefile -run-make/issue-15460/Makefile run-make/issue-35164/Makefile run-make/issue-36710/Makefile run-make/issue-47551/Makefile @@ -40,21 +39,17 @@ run-make/libtest-json/Makefile run-make/libtest-junit/Makefile run-make/libtest-thread-limit/Makefile run-make/link-cfg/Makefile -run-make/link-framework/Makefile run-make/long-linker-command-lines-cmd-exe/Makefile run-make/long-linker-command-lines/Makefile -run-make/lto-linkage-used-attr/Makefile run-make/macos-deployment-target/Makefile run-make/min-global-align/Makefile run-make/native-link-modifier-bundle/Makefile run-make/native-link-modifier-whole-archive/Makefile run-make/no-alloc-shim/Makefile run-make/no-builtins-attribute/Makefile -run-make/no-duplicate-libs/Makefile run-make/panic-abort-eh_frame/Makefile run-make/pdb-buildinfo-cl-cmd/Makefile run-make/pgo-gen-lto/Makefile -run-make/pgo-gen-no-imp-symbols/Makefile run-make/pgo-indirect-call-promotion/Makefile run-make/pointer-auth-link-with-c/Makefile run-make/print-calling-conventions/Makefile diff --git a/tests/run-make/issue-15460/Makefile b/tests/run-make/issue-15460/Makefile deleted file mode 100644 index a36a085fa6f..00000000000 --- a/tests/run-make/issue-15460/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: $(call NATIVE_STATICLIB,foo) - $(RUSTC) foo.rs -C extra-filename=-383hf8 -C prefer-dynamic - $(RUSTC) bar.rs - $(call RUN,bar) diff --git a/tests/run-make/link-framework/Makefile b/tests/run-make/link-framework/Makefile deleted file mode 100644 index 96d832ad4a8..00000000000 --- a/tests/run-make/link-framework/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# only-apple -# -# Check that linking to a framework actually makes it to the linker. - -include ../tools.mk - -all: - $(RUSTC) dep-link-framework.rs - $(RUSTC) dep-link-weak-framework.rs - - $(RUSTC) empty.rs - otool -L $(TMPDIR)/no-link | $(CGREP) -v CoreFoundation - - $(RUSTC) link-framework.rs - otool -L $(TMPDIR)/link-framework | $(CGREP) CoreFoundation | $(CGREP) -v weak - - $(RUSTC) link-weak-framework.rs - otool -L $(TMPDIR)/link-weak-framework | $(CGREP) CoreFoundation | $(CGREP) weak - -# When linking the framework both normally, and weakly, the weak linking takes preference - - $(RUSTC) link-both.rs - otool -L $(TMPDIR)/link-both | $(CGREP) CoreFoundation | $(CGREP) weak diff --git a/tests/run-make/link-framework/rmake.rs b/tests/run-make/link-framework/rmake.rs new file mode 100644 index 00000000000..e5df93b181a --- /dev/null +++ b/tests/run-make/link-framework/rmake.rs @@ -0,0 +1,38 @@ +// Check that linking to a framework actually makes it to the linker. + +//@ only-apple + +use run_make_support::{cmd, rustc}; + +fn main() { + rustc().input("dep-link-framework.rs").run(); + rustc().input("dep-link-weak-framework.rs").run(); + + rustc().input("empty.rs").run(); + cmd("otool").arg("-L").arg("no-link").run_fail().assert_stdout_not_contains("CoreFoundation"); + + rustc().input("link-framework.rs").run(); + cmd("otool") + .arg("-L") + .arg("link-framework") + .run() + .assert_stdout_contains("CoreFoundation") + .assert_stdout_not_contains("weak"); + + rustc().input("link-weak-framework.rs").run(); + cmd("otool") + .arg("-L") + .arg("link-weak-framework") + .run() + .assert_stdout_contains("CoreFoundation") + .assert_stdout_contains("weak"); + + // When linking the framework both normally, and weakly, the weak linking takes preference. + rustc().input("link-both.rs").run(); + cmd("otool") + .arg("-L") + .arg("link-both") + .run() + .assert_stdout_contains("CoreFoundation") + .assert_stdout_contains("weak"); +} diff --git a/tests/run-make/issue-15460/bar.rs b/tests/run-make/link-native-static-lib-to-dylib/bar.rs similarity index 100% rename from tests/run-make/issue-15460/bar.rs rename to tests/run-make/link-native-static-lib-to-dylib/bar.rs diff --git a/tests/run-make/issue-15460/foo.c b/tests/run-make/link-native-static-lib-to-dylib/foo.c similarity index 100% rename from tests/run-make/issue-15460/foo.c rename to tests/run-make/link-native-static-lib-to-dylib/foo.c diff --git a/tests/run-make/issue-15460/foo.rs b/tests/run-make/link-native-static-lib-to-dylib/foo.rs similarity index 100% rename from tests/run-make/issue-15460/foo.rs rename to tests/run-make/link-native-static-lib-to-dylib/foo.rs diff --git a/tests/run-make/link-native-static-lib-to-dylib/rmake.rs b/tests/run-make/link-native-static-lib-to-dylib/rmake.rs new file mode 100644 index 00000000000..0746c396314 --- /dev/null +++ b/tests/run-make/link-native-static-lib-to-dylib/rmake.rs @@ -0,0 +1,14 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/15460>. + +//@ ignore-cross-compile + +use run_make_support::{build_native_static_lib, run, rustc}; + +fn main() { + build_native_static_lib("foo"); + + rustc().input("foo.rs").extra_filename("-383hf8").arg("-Cprefer-dynamic").run(); + rustc().input("bar.rs").run(); + + run("bar"); +} diff --git a/tests/run-make/lto-linkage-used-attr/Makefile b/tests/run-make/lto-linkage-used-attr/Makefile deleted file mode 100644 index fed41a00f84..00000000000 --- a/tests/run-make/lto-linkage-used-attr/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -include ../tools.mk - -# Verify that the impl_* symbols are preserved. #108030 -# only-x86_64-unknown-linux-gnu - -all: - $(RUSTC) -Cdebuginfo=0 -Copt-level=3 lib.rs - $(RUSTC) -Clto=fat -Cdebuginfo=0 -Copt-level=3 main.rs diff --git a/tests/run-make/lto-linkage-used-attr/rmake.rs b/tests/run-make/lto-linkage-used-attr/rmake.rs new file mode 100644 index 00000000000..12463b79a75 --- /dev/null +++ b/tests/run-make/lto-linkage-used-attr/rmake.rs @@ -0,0 +1,15 @@ +// Link time optimizations (LTO) used to snip away some important symbols +// when setting optimization level to 3 or higher. +// This is an LLVM, not a rustc bug, fixed here: https://reviews.llvm.org/D145293 +// This test checks that the impl_* symbols are preserved as they should. +// See https://github.com/rust-lang/rust/issues/108030 + +//@ only-x86_64-unknown-linux-gnu +// Reason: some of the inline assembly directives are architecture-specific. + +use run_make_support::rustc; + +fn main() { + rustc().arg("-Cdebuginfo=0").opt_level("3").input("lib.rs").run(); + rustc().arg("-Clto=fat").arg("-Cdebuginfo=0").opt_level("3").input("main.rs").run(); +} diff --git a/tests/run-make/no-duplicate-libs/Makefile b/tests/run-make/no-duplicate-libs/Makefile deleted file mode 100644 index 4be8c026294..00000000000 --- a/tests/run-make/no-duplicate-libs/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -ifdef IS_MSVC -# FIXME(#27979) -all: -else -all: $(call STATICLIB,foo) $(call STATICLIB,bar) - $(RUSTC) main.rs - $(call RUN,main) -endif diff --git a/tests/run-make/no-duplicate-libs/rmake.rs b/tests/run-make/no-duplicate-libs/rmake.rs new file mode 100644 index 00000000000..469348e266c --- /dev/null +++ b/tests/run-make/no-duplicate-libs/rmake.rs @@ -0,0 +1,22 @@ +// The rust compiler used to try to detect duplicated libraries in +// the linking order and remove the duplicates... but certain edge cases, +// such as the one presented in `foo` and `bar` in this test, demand precise +// control over the link order, including duplicates. As the anti-duplication +// filter was removed, this test should now successfully see main be compiled +// and executed. +// See https://github.com/rust-lang/rust/pull/12688 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +//@ ignore-msvc +// Reason: native compilation results in an unresolved external symbol + +use run_make_support::{build_native_static_lib, run, rustc}; + +fn main() { + build_native_static_lib("foo"); + build_native_static_lib("bar"); + rustc().input("main.rs").run(); + run("main"); +} diff --git a/tests/run-make/pgo-gen-no-imp-symbols/Makefile b/tests/run-make/pgo-gen-no-imp-symbols/Makefile deleted file mode 100644 index d2baa145ba5..00000000000 --- a/tests/run-make/pgo-gen-no-imp-symbols/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include ../tools.mk - -COMPILE_FLAGS=-O -Ccodegen-units=1 -Cprofile-generate="$(TMPDIR)" -Zno-profiler-runtime - -all: - $(RUSTC) $(COMPILE_FLAGS) --emit=llvm-ir test.rs - # We expect symbols starting with "__llvm_profile_". - $(CGREP) "__llvm_profile_" < $(TMPDIR)/test.ll - # We do NOT expect the "__imp_" version of these symbols. - $(CGREP) -v "__imp___llvm_profile_" < $(TMPDIR)/test.ll # 64 bit - $(CGREP) -v "__imp____llvm_profile_" < $(TMPDIR)/test.ll # 32 bit diff --git a/tests/run-make/pgo-gen-no-imp-symbols/rmake.rs b/tests/run-make/pgo-gen-no-imp-symbols/rmake.rs new file mode 100644 index 00000000000..85ade7885ce --- /dev/null +++ b/tests/run-make/pgo-gen-no-imp-symbols/rmake.rs @@ -0,0 +1,27 @@ +// LLVM's profiling instrumentation adds a few symbols that are used by the profiler runtime. +// Since these show up as globals in the LLVM IR, the compiler generates dllimport-related +// __imp_ stubs for them. This can lead to linker errors because the instrumentation +// symbols have weak linkage or are in a comdat section, but the __imp_ stubs aren't. +// Since profiler-related symbols were excluded from stub-generation in #59812, this has +// been fixed, and this test checks that the llvm profile symbol appear, but without the +// anomalous __imp_ stubs. +// See https://github.com/rust-lang/rust/pull/59812 + +use run_make_support::{cwd, rfs, rustc}; + +fn main() { + rustc() + .input("test.rs") + .emit("llvm-ir") + .opt() + .codegen_units(1) + .profile_generate(cwd()) + .arg("-Zno-profiler-runtime") + .run(); + let out = rfs::read_to_string("test.ll"); + // We expect symbols starting with "__llvm_profile_". + assert!(out.contains("__llvm_profile_")); + // We do NOT expect the "__imp_" version of these symbols. + assert!(!out.contains("__imp___llvm_profile_")); // 64 bit + assert!(!out.contains("__imp____llvm_profile_")); // 32 bit +} diff --git a/tests/ui/closures/closure-no-fn-3.stderr b/tests/ui/closures/closure-no-fn-3.stderr index bbf3677fb72..7711347c568 100644 --- a/tests/ui/closures/closure-no-fn-3.stderr +++ b/tests/ui/closures/closure-no-fn-3.stderr @@ -3,6 +3,12 @@ error[E0605]: non-primitive cast: `{closure@$DIR/closure-no-fn-3.rs:6:28: 6:30}` | LL | let baz: fn() -> u8 = (|| { b }) as fn() -> u8; | ^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast + | +note: closures can only be coerced to `fn` types if they do not capture any variables + --> $DIR/closure-no-fn-3.rs:6:33 + | +LL | let baz: fn() -> u8 = (|| { b }) as fn() -> u8; + | ^ `b` captured here error: aborting due to 1 previous error