mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-17 22:46:50 +00:00
Auto merge of #128109 - matthiaskrgr:rollup-gc7kopi, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #125886 (Migrate run make issue 15460) - #126898 (Migrate `run-make/link-framework` to `rmake.rs`) - #126994 (Support lists and stylings in more places for `rustc --explain`) - #127990 (Migrate `lto-linkage-used-attr`, `no-duplicate-libs` and `pgo-gen-no-imp-symbols` `run-make` tests to rmake) - #128060 (Fix inclusion of `wasm-component-ld` in dist artifacts) - #128082 (Note closure captures when reporting cast to fn ptr failed) - #128098 (make it possible to disable download-rustc if it's incompatible) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
8bfcae730a
@ -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>.
|
||||
|
@ -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`.
|
||||
|
||||
```
|
||||
|
@ -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)]
|
||||
|
@ -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)> {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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")));
|
||||
|
@ -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>) {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
@ -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
|
38
tests/run-make/link-framework/rmake.rs
Normal file
38
tests/run-make/link-framework/rmake.rs
Normal file
@ -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");
|
||||
}
|
14
tests/run-make/link-native-static-lib-to-dylib/rmake.rs
Normal file
14
tests/run-make/link-native-static-lib-to-dylib/rmake.rs
Normal file
@ -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");
|
||||
}
|
@ -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
|
15
tests/run-make/lto-linkage-used-attr/rmake.rs
Normal file
15
tests/run-make/lto-linkage-used-attr/rmake.rs
Normal file
@ -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();
|
||||
}
|
@ -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
|
22
tests/run-make/no-duplicate-libs/rmake.rs
Normal file
22
tests/run-make/no-duplicate-libs/rmake.rs
Normal file
@ -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");
|
||||
}
|
@ -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
|
27
tests/run-make/pgo-gen-no-imp-symbols/rmake.rs
Normal file
27
tests/run-make/pgo-gen-no-imp-symbols/rmake.rs
Normal file
@ -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
|
||||
}
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user