Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,22 @@ impl<S: Stage> CombineAttributeParser<S> for LinkParser {
cx: &'c mut AcceptContext<'_, '_, S>,
args: &'c ArgParser<'_>,
) -> impl IntoIterator<Item = Self::Item> + 'c {
let mut result = None;
let Some(items) = args.list() else {
cx.expected_list(cx.attr_span);
return result;
let items = match args {
ArgParser::List(list) => list,
// This is an edgecase added because making this a hard error would break too many crates
// Specifically `#[link = "dl"]` is accepted with a FCW
// For more information, see https://github.com/rust-lang/rust/pull/143193
ArgParser::NameValue(nv) if nv.value_as_str().is_some_and(|v| v == sym::dl) => {
let suggestions = <Self as CombineAttributeParser<S>>::TEMPLATE
.suggestions(cx.attr_style, "link");
let span = cx.attr_span;
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
return None;
}
_ => {
cx.expected_list(cx.attr_span);
return None;
}
};

let sess = cx.sess();
Expand Down Expand Up @@ -113,7 +125,7 @@ impl<S: Stage> CombineAttributeParser<S> for LinkParser {
}
};
if !cont {
return result;
return None;
}
}

Expand Down Expand Up @@ -202,7 +214,7 @@ impl<S: Stage> CombineAttributeParser<S> for LinkParser {
}
let Some((name, name_span)) = name else {
cx.emit_err(LinkRequiresName { span: cx.attr_span });
return result;
return None;
};

// Do this outside of the loop so that `import_name_type` can be specified before `kind`.
Expand All @@ -218,15 +230,14 @@ impl<S: Stage> CombineAttributeParser<S> for LinkParser {
cx.emit_err(RawDylibNoNul { span: name_span });
}

result = Some(LinkEntry {
Some(LinkEntry {
span: cx.attr_span,
kind: kind.unwrap_or(NativeLibKind::Unspecified),
name,
cfg,
verbatim,
import_name_type,
});
result
})
}
}

Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,14 +741,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
errors.retain(|(_import, err)| match err.module {
// Skip `use` errors for `use foo::Bar;` if `foo.rs` has unrecovered parse errors.
Some(def_id) if self.mods_with_parse_errors.contains(&def_id) => false,
_ => true,
});
errors.retain(|(_import, err)| {
// If we've encountered something like `use _;`, we've already emitted an error stating
// that `_` is not a valid identifier, so we ignore that resolve error.
err.segment != Some(kw::Underscore)
_ => err.segment != Some(kw::Underscore),
});

if errors.is_empty() {
self.tcx.dcx().delayed_bug("expected a parse or \"`_` can't be an identifier\" error");
return;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,7 @@ symbols! {
div,
div_assign,
diverging_block_default,
dl,
do_not_recommend,
doc,
doc_alias,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_target/src/spec/targets/avr_none.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ pub(crate) fn target() -> Target {
arch: "avr".into(),
metadata: crate::spec::TargetMetadata {
description: None,
tier: None,
host_tools: None,
std: None,
tier: Some(3),
host_tools: Some(false),
std: Some(false),
},
data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8:16-a:8".into(),
llvm_target: "avr-unknown-unknown".into(),
Expand Down
30 changes: 13 additions & 17 deletions src/librustdoc/doctest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::process::{self, Command, Stdio};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use std::{fmt, panic, str};
use std::{panic, str};

pub(crate) use make::{BuildDocTestBuilder, DocTestBuilder};
pub(crate) use markdown::test as test_markdown;
Expand Down Expand Up @@ -60,24 +60,15 @@ impl MergedDoctestTimes {
self.added_compilation_times += 1;
}

fn display_times(&self) {
/// Returns `(total_time, compilation_time)`.
fn times_in_secs(&self) -> Option<(f64, f64)> {
// If no merged doctest was compiled, then there is nothing to display since the numbers
// displayed by `libtest` for standalone tests are already accurate (they include both
// compilation and runtime).
if self.added_compilation_times > 0 {
println!("{self}");
if self.added_compilation_times == 0 {
return None;
}
}
}

impl fmt::Display for MergedDoctestTimes {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"all doctests ran in {:.2}s; merged doctests compilation took {:.2}s",
self.total_time.elapsed().as_secs_f64(),
self.compilation_time.as_secs_f64(),
)
Some((self.total_time.elapsed().as_secs_f64(), self.compilation_time.as_secs_f64()))
}
}

Expand Down Expand Up @@ -402,15 +393,20 @@ pub(crate) fn run_tests(
if ran_edition_tests == 0 || !standalone_tests.is_empty() {
standalone_tests.sort_by(|a, b| a.desc.name.as_slice().cmp(b.desc.name.as_slice()));
test::test_main_with_exit_callback(&test_args, standalone_tests, None, || {
let times = times.times_in_secs();
// We ensure temp dir destructor is called.
std::mem::drop(temp_dir.take());
times.display_times();
if let Some((total_time, compilation_time)) = times {
test::print_merged_doctests_times(&test_args, total_time, compilation_time);
}
});
} else {
// If the first condition branch exited successfully, `test_main_with_exit_callback` will
// not exit the process. So to prevent displaying the times twice, we put it behind an
// `else` condition.
times.display_times();
if let Some((total_time, compilation_time)) = times.times_in_secs() {
test::print_merged_doctests_times(&test_args, total_time, compilation_time);
}
}
// We ensure temp dir destructor is called.
std::mem::drop(temp_dir);
Expand Down
31 changes: 13 additions & 18 deletions tests/codegen-llvm/autodiff/autodiffv2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,14 @@
// but each shadow argument is `width` times larger (thus 16 and 20 elements here).
// `d_square3` instead takes `width` (4) shadow arguments, which are all the same size as the
// original function arguments.
//
// FIXME(autodiff): We currently can't test `d_square1` and `d_square3` in the same file, since they
// generate the same dummy functions which get merged by LLVM, breaking pieces of our pipeline which
// try to rewrite the dummy functions later. We should consider to change to pure declarations both
// in our frontend and in the llvm backend to avoid these issues.

#![feature(autodiff)]

use std::autodiff::autodiff_forward;

// CHECK: ;
#[no_mangle]
//#[autodiff(d_square1, Forward, Dual, Dual)]
#[autodiff_forward(d_square1, Dual, Dual)]
#[autodiff_forward(d_square2, 4, Dualv, Dualv)]
#[autodiff_forward(d_square3, 4, Dual, Dual)]
fn square(x: &[f32], y: &mut [f32]) {
Expand Down Expand Up @@ -79,25 +74,25 @@ fn main() {
let mut dy3_4 = std::hint::black_box(vec![0.0; 5]);

// scalar.
//d_square1(&x1, &z1, &mut y1, &mut dy1_1);
//d_square1(&x1, &z2, &mut y2, &mut dy1_2);
//d_square1(&x1, &z3, &mut y3, &mut dy1_3);
//d_square1(&x1, &z4, &mut y4, &mut dy1_4);
d_square1(&x1, &z1, &mut y1, &mut dy1_1);
d_square1(&x1, &z2, &mut y2, &mut dy1_2);
d_square1(&x1, &z3, &mut y3, &mut dy1_3);
d_square1(&x1, &z4, &mut y4, &mut dy1_4);

// assert y1 == y2 == y3 == y4
//for i in 0..5 {
// assert_eq!(y1[i], y2[i]);
// assert_eq!(y1[i], y3[i]);
// assert_eq!(y1[i], y4[i]);
//}
for i in 0..5 {
assert_eq!(y1[i], y2[i]);
assert_eq!(y1[i], y3[i]);
assert_eq!(y1[i], y4[i]);
}

// batch mode A)
d_square2(&x1, &z5, &mut y5, &mut dy2);

// assert y1 == y2 == y3 == y4 == y5
//for i in 0..5 {
// assert_eq!(y1[i], y5[i]);
//}
for i in 0..5 {
assert_eq!(y1[i], y5[i]);
}

// batch mode B)
d_square3(&x1, &z1, &z2, &z3, &z4, &mut y6, &mut dy3_1, &mut dy3_2, &mut dy3_3, &mut dy3_4);
Expand Down
4 changes: 2 additions & 2 deletions tests/codegen-llvm/autodiff/identical_fnc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ fn square2(x: &f64) -> f64 {
// CHECK-NOT:br
// CHECK-NOT:ret
// CHECK:; call identical_fnc::d_square
// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square17hcb5768e95528c35fE(double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1)
// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH:.+]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1)
// CHECK:; call identical_fnc::d_square
// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square17hcb5768e95528c35fE(double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2)
// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2)

fn main() {
let x = std::hint::black_box(3.0);
Expand Down
3 changes: 3 additions & 0 deletions tests/run-make/rustdoc-doctest-output-format/file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//! ```
//! let x = 12;
//! ```
83 changes: 83 additions & 0 deletions tests/run-make/rustdoc-doctest-output-format/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//! Regression test to ensure that the output format is respected for doctests.
//!
//! Regression test for <https://github.com/rust-lang/rust/issues/144798>.
//@ ignore-cross-compile

use run_make_support::{rustdoc, serde_json};

fn run_test(edition: &str, format: Option<&str>) -> String {
let mut r = rustdoc();
r.input("file.rs").edition(edition).arg("--test");
if let Some(format) = format {
r.args(&[
"--test-args",
"-Zunstable-options",
"--test-args",
"--format",
"--test-args",
format,
]);
}
r.run().stdout_utf8()
}

fn check_json_output(edition: &str, expected_reports: usize) {
let out = run_test(edition, Some("json"));
let mut found_report = 0;
for (line_nb, line) in out.lines().enumerate() {
match serde_json::from_str::<serde_json::Value>(&line) {
Ok(value) => {
if value.get("type") == Some(&serde_json::json!("report")) {
found_report += 1;
}
}
Err(error) => panic!(
"failed for {edition} edition (json format) at line {}: non-JSON value: {error}\n\
====== output ======\n{out}",
line_nb + 1,
),
}
}
if found_report != expected_reports {
panic!(
"failed for {edition} edition (json format): expected {expected_reports} doctest \
time `report`, found {found_report}\n====== output ======\n{out}",
);
}
}

fn check_non_json_output(edition: &str, expected_reports: usize) {
let out = run_test(edition, None);
let mut found_report = 0;
for (line_nb, line) in out.lines().enumerate() {
if line.starts_with('{') && serde_json::from_str::<serde_json::Value>(&line).is_ok() {
panic!(
"failed for {edition} edition: unexpected json at line {}: `{line}`\n\
====== output ======\n{out}",
line_nb + 1
);
}
if line.starts_with("all doctests ran in")
&& line.contains("; merged doctests compilation took ")
{
found_report += 1;
}
}
if found_report != expected_reports {
panic!(
"failed for {edition} edition: expected {expected_reports} doctest time `report`, \
found {found_report}\n====== output ======\n{out}",
);
}
}

fn main() {
// Only the merged doctests generate the "times report".
check_json_output("2021", 0);
check_json_output("2024", 1);

// Only the merged doctests generate the "times report".
check_non_json_output("2021", 0);
check_non_json_output("2024", 1);
}
10 changes: 10 additions & 0 deletions tests/ui/attributes/link-dl.allowed.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Future incompatibility report: Future breakage diagnostic:
warning: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", wasm_import_module = "...")]`
--> $DIR/link-dl.rs:14:1
|
LL | #[link="dl"]
| ^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>

23 changes: 23 additions & 0 deletions tests/ui/attributes/link-dl.default_fcw.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", wasm_import_module = "...")]`
--> $DIR/link-dl.rs:14:1
|
LL | #[link="dl"]
| ^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
= note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default

error: aborting due to 1 previous error

Future incompatibility report: Future breakage diagnostic:
error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", wasm_import_module = "...")]`
--> $DIR/link-dl.rs:14:1
|
LL | #[link="dl"]
| ^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
= note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default

19 changes: 19 additions & 0 deletions tests/ui/attributes/link-dl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Regression test for an issue discovered in https://github.com/rust-lang/rust/pull/143193/files and rediscovered in https://github.com/rust-lang/rust/issues/147254#event-20049906781
// Malformed #[link] attribute was supposed to be deny-by-default report-in-deps FCW,
// but accidentally was landed as a hard error.
//
// revision `default_fcw` tests that with `ill_formed_attribute_input` (the default) denied,
// the attribute produces an FCW
// revision `allowed` tests that with `ill_formed_attribute_input` allowed the test passes

//@ revisions: default_fcw allowed
//@[allowed] check-pass

#[cfg_attr(allowed, allow(ill_formed_attribute_input))]

#[link="dl"]
//[default_fcw]~^ ERROR valid forms for the attribute are
//[default_fcw]~| WARN previously accepted
extern "C" { }

fn main() {}
Loading