Auto merge of #125744 - fmease:rollup-ky7d098, r=fmease

Rollup of 7 pull requests

Successful merges:

 - #125653 (Migrate `run-make/const-prop-lint` to `rmake.rs`)
 - #125662 (Rewrite `fpic`, `simple-dylib` and `issue-37893` `run-make` tests in `rmake.rs` or ui test format)
 - #125699 (Streamline `x fmt` and improve its output)
 - #125701 ([ACP 362] genericize `ptr::from_raw_parts`)
 - #125723 (Migrate `run-make/crate-data-smoke` to `rmake.rs`)
 - #125733 (Add lang items for `AsyncFn*`, `Future`, `AsyncFnKindHelper`'s associated types)
 - #125734 (ast: Revert a breaking attribute visiting order change)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-05-30 00:49:44 +00:00
commit caa187f3bc
56 changed files with 522 additions and 300 deletions

View File

@ -852,10 +852,10 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(
ctxt: AssocCtxt,
) -> V::Result {
let &Item { id: _, span: _, ident, ref vis, ref attrs, ref kind, tokens: _ } = item;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_vis(vis));
try_visit!(visitor.visit_ident(ident));
try_visit!(kind.walk(item, ctxt, visitor));
walk_list!(visitor, visit_attribute, attrs);
V::Result::output()
}

View File

@ -228,13 +228,18 @@ language_item_table! {
AsyncFn, sym::async_fn, async_fn_trait, Target::Trait, GenericRequirement::Exact(1);
AsyncFnMut, sym::async_fn_mut, async_fn_mut_trait, Target::Trait, GenericRequirement::Exact(1);
AsyncFnOnce, sym::async_fn_once, async_fn_once_trait, Target::Trait, GenericRequirement::Exact(1);
AsyncFnKindHelper, sym::async_fn_kind_helper,async_fn_kind_helper, Target::Trait, GenericRequirement::Exact(1);
AsyncFnOnceOutput, sym::async_fn_once_output, async_fn_once_output, Target::AssocTy, GenericRequirement::Exact(1);
CallOnceFuture, sym::call_once_future, call_once_future, Target::AssocTy, GenericRequirement::Exact(1);
CallRefFuture, sym::call_ref_future, call_ref_future, Target::AssocTy, GenericRequirement::Exact(2);
AsyncFnKindHelper, sym::async_fn_kind_helper, async_fn_kind_helper, Target::Trait, GenericRequirement::Exact(1);
AsyncFnKindUpvars, sym::async_fn_kind_upvars, async_fn_kind_upvars, Target::AssocTy, GenericRequirement::Exact(5);
FnOnceOutput, sym::fn_once_output, fn_once_output, Target::AssocTy, GenericRequirement::None;
Iterator, sym::iterator, iterator_trait, Target::Trait, GenericRequirement::Exact(0);
FusedIterator, sym::fused_iterator, fused_iterator_trait, Target::Trait, GenericRequirement::Exact(0);
Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0);
FutureOutput, sym::future_output, future_output, Target::AssocTy, GenericRequirement::Exact(0);
AsyncIterator, sym::async_iterator, async_iterator_trait, Target::Trait, GenericRequirement::Exact(0);
CoroutineState, sym::coroutine_state, coroutine_state, Target::Enum, GenericRequirement::None;

View File

@ -1478,7 +1478,7 @@ pub fn suggest_impl_trait<'tcx>(
),
(
infcx.tcx.lang_items().future_trait(),
infcx.tcx.get_diagnostic_item(sym::FutureOutput),
infcx.tcx.lang_items().future_output(),
format_as_assoc,
),
(

View File

@ -210,7 +210,6 @@ symbols! {
FsPermissions,
FusedIterator,
Future,
FutureOutput,
GlobalAlloc,
Hash,
HashMap,
@ -439,8 +438,10 @@ symbols! {
async_fn,
async_fn_in_trait,
async_fn_kind_helper,
async_fn_kind_upvars,
async_fn_mut,
async_fn_once,
async_fn_once_output,
async_fn_track_caller,
async_fn_traits,
async_for_loop,
@ -498,6 +499,8 @@ symbols! {
call,
call_mut,
call_once,
call_once_future,
call_ref_future,
caller_location,
capture_disjoint_fields,
catch_unwind,
@ -911,6 +914,7 @@ symbols! {
fundamental,
fused_iterator,
future,
future_output,
future_trait,
gdb_script_file,
ge,

View File

@ -9,7 +9,6 @@ use rustc_macros::{TypeFoldable, TypeVisitable};
use rustc_middle::bug;
use rustc_middle::traits::solve::Goal;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, Upcast};
use rustc_span::sym;
use crate::solve::EvalCtxt;
@ -454,12 +453,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc
.rebind(ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()]))
.upcast(tcx),
];
let future_output_def_id = tcx
.associated_items(future_trait_def_id)
.filter_by_name_unhygienic(sym::Output)
.next()
.unwrap()
.def_id;
let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None);
let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]);
Ok((
bound_sig.rebind(AsyncCallableRelevantTypes {
@ -510,12 +504,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc
);
}
let future_output_def_id = tcx
.associated_items(future_trait_def_id)
.filter_by_name_unhygienic(sym::Output)
.next()
.unwrap()
.def_id;
let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None);
let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]);
Ok((
bound_sig.rebind(AsyncCallableRelevantTypes {
@ -592,13 +581,7 @@ fn coroutine_closure_to_ambiguous_coroutine<'tcx>(
args: ty::CoroutineClosureArgs<'tcx>,
sig: ty::CoroutineClosureSignature<'tcx>,
) -> Ty<'tcx> {
let async_fn_kind_trait_def_id = tcx.require_lang_item(LangItem::AsyncFnKindHelper, None);
let upvars_projection_def_id = tcx
.associated_items(async_fn_kind_trait_def_id)
.filter_by_name_unhygienic(sym::Upvars)
.next()
.unwrap()
.def_id;
let upvars_projection_def_id = tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None);
let tupled_upvars_ty = Ty::new_projection(
tcx,
upvars_projection_def_id,

View File

@ -407,16 +407,20 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
output_coroutine_ty,
coroutine_return_ty,
}| {
let (projection_term, term) = match tcx.item_name(goal.predicate.def_id()) {
sym::CallOnceFuture => (
let lang_items = tcx.lang_items();
let (projection_term, term) = if Some(goal.predicate.def_id())
== lang_items.call_once_future()
{
(
ty::AliasTerm::new(
tcx,
goal.predicate.def_id(),
[goal.predicate.self_ty(), tupled_inputs_ty],
),
output_coroutine_ty.into(),
),
sym::CallRefFuture => (
)
} else if Some(goal.predicate.def_id()) == lang_items.call_ref_future() {
(
ty::AliasTerm::new(
tcx,
goal.predicate.def_id(),
@ -427,8 +431,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
],
),
output_coroutine_ty.into(),
),
sym::Output => (
)
} else if Some(goal.predicate.def_id()) == lang_items.async_fn_once_output() {
(
ty::AliasTerm::new(
tcx,
goal.predicate.def_id(),
@ -438,8 +443,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
],
),
coroutine_return_ty.into(),
),
name => bug!("no such associated type: {name}"),
)
} else {
bug!("no such associated type in `AsyncFn*`: {:?}", goal.predicate.def_id())
};
ty::ProjectionPredicate { projection_term, term }
},

View File

@ -1680,14 +1680,8 @@ fn confirm_closure_candidate<'cx, 'tcx>(
args.coroutine_captures_by_ref_ty(),
)
} else {
let async_fn_kind_trait_def_id =
tcx.require_lang_item(LangItem::AsyncFnKindHelper, None);
let upvars_projection_def_id = tcx
.associated_items(async_fn_kind_trait_def_id)
.filter_by_name_unhygienic(sym::Upvars)
.next()
.unwrap()
.def_id;
let upvars_projection_def_id =
tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None);
let tupled_upvars_ty = Ty::new_projection(
tcx,
upvars_projection_def_id,
@ -1816,14 +1810,8 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
args.coroutine_captures_by_ref_ty(),
)
} else {
let async_fn_kind_trait_def_id =
tcx.require_lang_item(LangItem::AsyncFnKindHelper, None);
let upvars_projection_def_id = tcx
.associated_items(async_fn_kind_trait_def_id)
.filter_by_name_unhygienic(sym::Upvars)
.next()
.unwrap()
.def_id;
let upvars_projection_def_id =
tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None);
// When we don't know the closure kind (and therefore also the closure's upvars,
// which are computed at the same time), we must delay the computation of the
// generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait
@ -1880,13 +1868,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
let term = match item_name {
sym::CallOnceFuture | sym::CallRefFuture => sig.output(),
sym::Output => {
let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
let future_output_def_id = tcx
.associated_items(future_trait_def_id)
.filter_by_name_unhygienic(sym::Output)
.next()
.unwrap()
.def_id;
let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None);
Ty::new_projection(tcx, future_output_def_id, [sig.output()])
}
name => bug!("no such associated type: {name}"),
@ -1919,13 +1901,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>(
let term = match item_name {
sym::CallOnceFuture | sym::CallRefFuture => sig.output(),
sym::Output => {
let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
let future_output_def_id = tcx
.associated_items(future_trait_def_id)
.filter_by_name_unhygienic(sym::Output)
.next()
.unwrap()
.def_id;
let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None);
Ty::new_projection(tcx, future_output_def_id, [sig.output()])
}
name => bug!("no such associated type: {name}"),

View File

@ -35,7 +35,7 @@ use crate::task::{Context, Poll};
pub trait Future {
/// The type of value produced on completion.
#[stable(feature = "futures_api", since = "1.36.0")]
#[rustc_diagnostic_item = "FutureOutput"]
#[cfg_attr(not(bootstrap), lang = "future_output")]
type Output;
/// Attempt to resolve the future to a final value, registering

View File

@ -26,6 +26,7 @@ pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
/// Future returned by [`AsyncFnMut::async_call_mut`] and [`AsyncFn::async_call`].
#[unstable(feature = "async_fn_traits", issue = "none")]
#[cfg_attr(not(bootstrap), lang = "call_ref_future")]
type CallRefFuture<'a>: Future<Output = Self::Output>
where
Self: 'a;
@ -46,10 +47,12 @@ pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
pub trait AsyncFnOnce<Args: Tuple> {
/// Future returned by [`AsyncFnOnce::async_call_once`].
#[unstable(feature = "async_fn_traits", issue = "none")]
#[cfg_attr(not(bootstrap), lang = "call_once_future")]
type CallOnceFuture: Future<Output = Self::Output>;
/// Output type of the called closure's future.
#[unstable(feature = "async_fn_traits", issue = "none")]
#[cfg_attr(not(bootstrap), lang = "async_fn_once_output")]
type Output;
/// Call the [`AsyncFnOnce`], returning a future which may move out of the called closure.
@ -143,6 +146,7 @@ mod internal_implementation_detail {
// `for<'env> fn() -> (&'env T, ...)`. This allows us to represent the binder
// of the closure's self-capture, and these upvar types will be instantiated with
// the `'closure_env` region provided to the associated type.
#[cfg_attr(not(bootstrap), lang = "async_fn_kind_upvars")]
type Upvars<'closure_env, Inputs, Upvars, BorrowedUpvarsAsFnPtr>;
}
}

View File

@ -120,7 +120,7 @@ pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
#[inline]
pub const fn from_raw_parts<T: ?Sized>(
data_pointer: *const (),
data_pointer: *const impl Thin,
metadata: <T as Pointee>::Metadata,
) -> *const T {
aggregate_raw_ptr(data_pointer, metadata)
@ -134,7 +134,7 @@ pub const fn from_raw_parts<T: ?Sized>(
#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
#[inline]
pub const fn from_raw_parts_mut<T: ?Sized>(
data_pointer: *mut (),
data_pointer: *mut impl Thin,
metadata: <T as Pointee>::Metadata,
) -> *mut T {
aggregate_raw_ptr(data_pointer, metadata)

View File

@ -565,7 +565,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
#[rustc_allow_const_fn_unstable(ptr_metadata)]
#[rustc_diagnostic_item = "ptr_null"]
pub const fn null<T: ?Sized + Thin>() -> *const T {
from_raw_parts(without_provenance(0), ())
from_raw_parts(without_provenance::<()>(0), ())
}
/// Creates a null mutable raw pointer.
@ -591,7 +591,7 @@ pub const fn null<T: ?Sized + Thin>() -> *const T {
#[rustc_allow_const_fn_unstable(ptr_metadata)]
#[rustc_diagnostic_item = "ptr_null_mut"]
pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
from_raw_parts_mut(without_provenance_mut(0), ())
from_raw_parts_mut(without_provenance_mut::<()>(0), ())
}
/// Creates a pointer with the given address and no provenance.
@ -835,7 +835,7 @@ pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T {
#[rustc_allow_const_fn_unstable(ptr_metadata)]
#[rustc_diagnostic_item = "ptr_slice_from_raw_parts"]
pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
intrinsics::aggregate_raw_ptr(data, len)
from_raw_parts(data, len)
}
/// Forms a raw mutable slice from a pointer and a length.
@ -881,7 +881,7 @@ pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
#[rustc_const_unstable(feature = "const_slice_from_raw_parts_mut", issue = "67456")]
#[rustc_diagnostic_item = "ptr_slice_from_raw_parts_mut"]
pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
intrinsics::aggregate_raw_ptr(data, len)
from_raw_parts_mut(data, len)
}
/// Swaps the values at two mutable locations of the same type, without

View File

@ -222,7 +222,7 @@ pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
#[rustc_const_unstable(feature = "str_from_raw_parts", issue = "119206")]
pub const unsafe fn from_raw_parts<'a>(ptr: *const u8, len: usize) -> &'a str {
// SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
unsafe { &*ptr::from_raw_parts(ptr.cast(), len) }
unsafe { &*ptr::from_raw_parts(ptr, len) }
}
/// Creates an `&mut str` from a pointer and a length.
@ -241,5 +241,5 @@ pub const unsafe fn from_raw_parts<'a>(ptr: *const u8, len: usize) -> &'a str {
#[rustc_const_unstable(feature = "const_str_from_raw_parts_mut", issue = "119206")]
pub const unsafe fn from_raw_parts_mut<'a>(ptr: *mut u8, len: usize) -> &'a mut str {
// SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
unsafe { &mut *ptr::from_raw_parts_mut(ptr.cast(), len) }
unsafe { &mut *ptr::from_raw_parts_mut(ptr, len) }
}

View File

@ -83,12 +83,12 @@ fn align_of_val_raw_packed() {
f: [u32],
}
let storage = [0u8; 4];
let b: *const B = ptr::from_raw_parts(storage.as_ptr().cast(), 1);
let b: *const B = ptr::from_raw_parts(storage.as_ptr(), 1);
assert_eq!(unsafe { align_of_val_raw(b) }, 1);
const ALIGN_OF_VAL_RAW: usize = {
let storage = [0u8; 4];
let b: *const B = ptr::from_raw_parts(storage.as_ptr().cast(), 1);
let b: *const B = ptr::from_raw_parts(storage.as_ptr(), 1);
unsafe { align_of_val_raw(b) }
};
assert_eq!(ALIGN_OF_VAL_RAW, 1);

View File

@ -965,7 +965,7 @@ fn thin_box() {
fn value_ptr(&self) -> *const T {
let (_, offset) = self.layout();
let data_ptr = unsafe { self.ptr.cast::<u8>().as_ptr().add(offset) };
ptr::from_raw_parts(data_ptr.cast(), self.meta())
ptr::from_raw_parts(data_ptr, self.meta())
}
fn value_mut_ptr(&mut self) -> *mut T {
@ -973,7 +973,7 @@ fn thin_box() {
// FIXME: can this line be shared with the same in `value_ptr()`
// without upsetting Stacked Borrows?
let data_ptr = unsafe { self.ptr.cast::<u8>().as_ptr().add(offset) };
from_raw_parts_mut(data_ptr.cast(), self.meta())
from_raw_parts_mut(data_ptr, self.meta())
}
}

View File

@ -9,6 +9,7 @@ use std::collections::VecDeque;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::sync::mpsc::SyncSender;
use std::sync::Mutex;
fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl FnMut(bool) -> bool {
let mut cmd = Command::new(rustfmt);
@ -24,20 +25,23 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F
cmd.args(paths);
let cmd_debug = format!("{cmd:?}");
let mut cmd = cmd.spawn().expect("running rustfmt");
// Poor man's async: return a closure that'll wait for rustfmt's completion.
// Poor man's async: return a closure that might wait for rustfmt's completion (depending on
// the value of the `block` argument).
move |block: bool| -> bool {
if !block {
let status = if !block {
match cmd.try_wait() {
Ok(Some(_)) => {}
_ => return false,
Ok(Some(status)) => Ok(status),
Ok(None) => return false,
Err(err) => Err(err),
}
}
let status = cmd.wait().unwrap();
if !status.success() {
} else {
cmd.wait()
};
if !status.unwrap().success() {
eprintln!(
"Running `{}` failed.\nIf you're running `tidy`, \
try again with `--bless`. Or, if you just want to format \
code, run `./x.py fmt` instead.",
"fmt error: Running `{}` failed.\nIf you're running `tidy`, \
try again with `--bless`. Or, if you just want to format \
code, run `./x.py fmt` instead.",
cmd_debug,
);
crate::exit!(1);
@ -97,35 +101,61 @@ struct RustfmtConfig {
ignore: Vec<String>,
}
pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
// Prints output describing a collection of paths, with lines such as "formatted modified file
// foo/bar/baz" or "skipped 20 untracked files".
fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
let len = paths.len();
let adjective =
if let Some(adjective) = adjective { format!("{adjective} ") } else { String::new() };
if len <= 10 {
for path in paths {
println!("fmt: {verb} {adjective}file {path}");
}
} else {
println!("fmt: {verb} {len} {adjective}files");
}
}
pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {
if !paths.is_empty() {
eprintln!("fmt error: path arguments are not accepted");
crate::exit!(1);
};
if build.config.dry_run() {
return;
}
// By default, we only check modified files locally to speed up runtime. Exceptions are if
// `--all` is specified or we are in CI. We check all files in CI to avoid bugs in
// `get_modified_rs_files` letting regressions slip through; we also care about CI time less
// since this is still very fast compared to building the compiler.
let all = all || CiEnv::is_ci();
let mut builder = ignore::types::TypesBuilder::new();
builder.add_defaults();
builder.select("rust");
let matcher = builder.build().unwrap();
let rustfmt_config = build.src.join("rustfmt.toml");
if !rustfmt_config.exists() {
eprintln!("Not running formatting checks; rustfmt.toml does not exist.");
eprintln!("This may happen in distributed tarballs.");
eprintln!("fmt error: Not running formatting checks; rustfmt.toml does not exist.");
eprintln!("fmt error: This may happen in distributed tarballs.");
return;
}
let rustfmt_config = t!(std::fs::read_to_string(&rustfmt_config));
let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config));
let mut fmt_override = ignore::overrides::OverrideBuilder::new(&build.src);
let mut override_builder = ignore::overrides::OverrideBuilder::new(&build.src);
for ignore in rustfmt_config.ignore {
if ignore.starts_with('!') {
// A `!`-prefixed entry could be added as a whitelisted entry in `fmt_override`, i.e.
// strip the `!` prefix. But as soon as whitelisted entries are added, an
// A `!`-prefixed entry could be added as a whitelisted entry in `override_builder`,
// i.e. strip the `!` prefix. But as soon as whitelisted entries are added, an
// `OverrideBuilder` will only traverse those whitelisted entries, and won't traverse
// any files that aren't explicitly mentioned. No bueno! Maybe there's a way to combine
// explicit whitelisted entries and traversal of unmentioned files, but for now just
// forbid such entries.
eprintln!("`!`-prefixed entries are not supported in rustfmt.toml, sorry");
eprintln!("fmt error: `!`-prefixed entries are not supported in rustfmt.toml, sorry");
crate::exit!(1);
} else {
fmt_override.add(&format!("!{ignore}")).expect(&ignore);
override_builder.add(&format!("!{ignore}")).expect(&ignore);
}
}
let git_available = match Command::new("git")
@ -138,6 +168,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
Err(_) => false,
};
let mut adjective = None;
if git_available {
let in_working_tree = match build
.config
@ -161,127 +192,56 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
.arg("-z")
.arg("--untracked-files=normal"),
);
let untracked_paths = untracked_paths_output.split_terminator('\0').filter_map(
|entry| entry.strip_prefix("?? "), // returns None if the prefix doesn't match
);
let mut untracked_count = 0;
let untracked_paths: Vec<_> = untracked_paths_output
.split_terminator('\0')
.filter_map(
|entry| entry.strip_prefix("?? "), // returns None if the prefix doesn't match
)
.map(|x| x.to_string())
.collect();
print_paths("skipped", Some("untracked"), &untracked_paths);
for untracked_path in untracked_paths {
println!("skip untracked path {untracked_path} during rustfmt invocations");
// The leading `/` makes it an exact match against the
// repository root, rather than a glob. Without that, if you
// have `foo.rs` in the repository root it will also match
// against anything like `compiler/rustc_foo/src/foo.rs`,
// preventing the latter from being formatted.
untracked_count += 1;
fmt_override.add(&format!("!/{untracked_path}")).expect(untracked_path);
override_builder.add(&format!("!/{untracked_path}")).expect(&untracked_path);
}
// Only check modified files locally to speed up runtime. We still check all files in
// CI to avoid bugs in `get_modified_rs_files` letting regressions slip through; we
// also care about CI time less since this is still very fast compared to building the
// compiler.
if !CiEnv::is_ci() && paths.is_empty() {
if !all {
adjective = Some("modified");
match get_modified_rs_files(build) {
Ok(Some(files)) => {
if files.len() <= 10 {
for file in &files {
println!("formatting modified file {file}");
}
} else {
let pluralized = |count| if count > 1 { "files" } else { "file" };
let untracked_msg = if untracked_count == 0 {
"".to_string()
} else {
format!(
", skipped {} untracked {}",
untracked_count,
pluralized(untracked_count),
)
};
println!(
"formatting {} modified {}{}",
files.len(),
pluralized(files.len()),
untracked_msg
);
}
for file in files {
fmt_override.add(&format!("/{file}")).expect(&file);
override_builder.add(&format!("/{file}")).expect(&file);
}
}
Ok(None) => {}
Err(err) => {
println!(
"WARN: Something went wrong when running git commands:\n{err}\n\
Falling back to formatting all files."
);
eprintln!("fmt warning: Something went wrong running git commands:");
eprintln!("fmt warning: {err}");
eprintln!("fmt warning: Falling back to formatting all files.");
}
}
}
} else {
println!("Not in git tree. Skipping git-aware format checks");
eprintln!("fmt: warning: Not in git tree. Skipping git-aware format checks");
}
} else {
println!("Could not find usable git. Skipping git-aware format checks");
eprintln!("fmt: warning: Could not find usable git. Skipping git-aware format checks");
}
let fmt_override = fmt_override.build().unwrap();
let override_ = override_builder.build().unwrap(); // `override` is a reserved keyword
let rustfmt_path = build.initial_rustfmt().unwrap_or_else(|| {
eprintln!("./x.py fmt is not supported on this channel");
eprintln!("fmt error: `x fmt` is not supported on this channel");
crate::exit!(1);
});
assert!(rustfmt_path.exists(), "{}", rustfmt_path.display());
let src = build.src.clone();
let (tx, rx): (SyncSender<PathBuf>, _) = std::sync::mpsc::sync_channel(128);
let walker = match paths.first() {
Some(first) => {
let find_shortcut_candidates = |p: &PathBuf| {
let mut candidates = Vec::new();
for entry in
WalkBuilder::new(src.clone()).max_depth(Some(3)).build().map_while(Result::ok)
{
if let Some(dir_name) = p.file_name() {
if entry.path().is_dir() && entry.file_name() == dir_name {
candidates.push(entry.into_path());
}
}
}
candidates
};
// Only try to look for shortcut candidates for single component paths like
// `std` and not for e.g. relative paths like `../library/std`.
let should_look_for_shortcut_dir = |p: &PathBuf| p.components().count() == 1;
let mut walker = if should_look_for_shortcut_dir(first) {
if let [single_candidate] = &find_shortcut_candidates(first)[..] {
WalkBuilder::new(single_candidate)
} else {
WalkBuilder::new(first)
}
} else {
WalkBuilder::new(src.join(first))
};
for path in &paths[1..] {
if should_look_for_shortcut_dir(path) {
if let [single_candidate] = &find_shortcut_candidates(path)[..] {
walker.add(single_candidate);
} else {
walker.add(path);
}
} else {
walker.add(src.join(path));
}
}
walker
}
None => WalkBuilder::new(src.clone()),
}
.types(matcher)
.overrides(fmt_override)
.build_parallel();
let walker = WalkBuilder::new(src.clone()).types(matcher).overrides(override_).build_parallel();
// There is a lot of blocking involved in spawning a child process and reading files to format.
// Spawn more processes than available concurrency to keep the CPU busy.
@ -319,16 +279,33 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
}
});
let formatted_paths = Mutex::new(Vec::new());
let formatted_paths_ref = &formatted_paths;
walker.run(|| {
let tx = tx.clone();
Box::new(move |entry| {
let cwd = std::env::current_dir();
let entry = t!(entry);
if entry.file_type().map_or(false, |t| t.is_file()) {
formatted_paths_ref.lock().unwrap().push({
// `into_path` produces an absolute path. Try to strip `cwd` to get a shorter
// relative path.
let mut path = entry.clone().into_path();
if let Ok(cwd) = cwd {
if let Ok(path2) = path.strip_prefix(cwd) {
path = path2.to_path_buf();
}
}
path.display().to_string()
});
t!(tx.send(entry.into_path()));
}
ignore::WalkState::Continue
})
});
let mut paths = formatted_paths.into_inner().unwrap();
paths.sort();
print_paths(if check { "checked" } else { "formatted" }, adjective, &paths);
drop(tx);

View File

@ -1140,7 +1140,13 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to
);
crate::exit!(1);
}
crate::core::build_steps::format::format(builder, !builder.config.cmd.bless(), &[]);
let all = false;
crate::core::build_steps::format::format(
builder,
!builder.config.cmd.bless(),
all,
&[],
);
}
builder.info("tidy check");

View File

@ -284,8 +284,8 @@ pub enum Subcommand {
name = "fmt",
long_about = "\n
Arguments:
This subcommand optionally accepts a `--check` flag which succeeds if formatting is correct and
fails if it is not. For example:
This subcommand optionally accepts a `--check` flag which succeeds if
formatting is correct and fails if it is not. For example:
./x.py fmt
./x.py fmt --check"
)]
@ -294,6 +294,10 @@ pub enum Subcommand {
/// check formatting instead of applying
#[arg(long)]
check: bool,
/// apply to all appropriate files, not just those that have been modified
#[arg(long)]
all: bool,
},
#[command(aliases = ["d"], long_about = "\n
Arguments:

View File

@ -660,10 +660,11 @@ impl Build {
// hardcoded subcommands
match &self.config.cmd {
Subcommand::Format { check } => {
Subcommand::Format { check, all } => {
return core::build_steps::format::format(
&builder::Builder::new(self),
*check,
*all,
&self.config.paths,
);
}

View File

@ -216,6 +216,7 @@ complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-profile-use -d 'us
complete -c x.py -n "__fish_seen_subcommand_from fmt" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
complete -c x.py -n "__fish_seen_subcommand_from fmt" -l set -d 'override options in config.toml' -r -f
complete -c x.py -n "__fish_seen_subcommand_from fmt" -l check -d 'check formatting instead of applying'
complete -c x.py -n "__fish_seen_subcommand_from fmt" -l all -d 'apply to all appropriate files, not just those that have been modified'
complete -c x.py -n "__fish_seen_subcommand_from fmt" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
complete -c x.py -n "__fish_seen_subcommand_from fmt" -s i -l incremental -d 'use incremental compilation'
complete -c x.py -n "__fish_seen_subcommand_from fmt" -l include-default-paths -d 'include default paths in addition to the provided ones'

View File

@ -275,6 +275,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
[CompletionResult]::new('--reproducible-artifact', 'reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
[CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
[CompletionResult]::new('--check', 'check', [CompletionResultType]::ParameterName, 'check formatting instead of applying')
[CompletionResult]::new('--all', 'all', [CompletionResultType]::ParameterName, 'apply to all appropriate files, not just those that have been modified')
[CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
[CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
[CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')

View File

@ -1077,7 +1077,7 @@ _x.py() {
return 0
;;
x.py__fmt)
opts="-v -i -j -h --check --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
opts="-v -i -j -h --check --all --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0

View File

@ -271,6 +271,7 @@ _arguments "${_arguments_options[@]}" \
'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
'*--set=[override options in config.toml]:section.option=value:( )' \
'--check[check formatting instead of applying]' \
'--all[apply to all appropriate files, not just those that have been modified]' \
'*-v[use verbose output (-vv for very verbose)]' \
'*--verbose[use verbose output (-vv for very verbose)]' \
'-i[use incremental compilation]' \

View File

@ -1,35 +1,11 @@
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:6:5
|
LL | /// - first one
| ^^^^ help: consider using four spaces per tab
|
= note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]`
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:6:13
|
LL | /// - first one
| ^^^^^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:7:5
|
LL | /// - second one
| ^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:7:14
|
LL | /// - second one
| ^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:10:9
|
LL | /// - First String:
| ^^^^ help: consider using four spaces per tab
|
= note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]`
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:11:9
@ -49,5 +25,29 @@ error: using tabs in doc comments is not recommended
LL | /// - needs to be inside here
| ^^^^^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:6:5
|
LL | /// - first one
| ^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:6:13
|
LL | /// - first one
| ^^^^^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:7:5
|
LL | /// - second one
| ^^^^ help: consider using four spaces per tab
error: using tabs in doc comments is not recommended
--> tests/ui/tabs_in_doc_comments.rs:7:14
|
LL | /// - second one
| ^^^^ help: consider using four spaces per tab
error: aborting due to 8 previous errors

View File

@ -135,7 +135,13 @@ pub fn dynamic_lib_name(name: &str) -> String {
/// Construct a path to a rust library (rlib) under `$TMPDIR` given the library name. This will return a
/// path with `$TMPDIR` joined with the library name.
pub fn rust_lib(name: &str) -> PathBuf {
tmp_dir().join(format!("lib{name}.rlib"))
tmp_dir().join(rust_lib_name(name))
}
/// Generate the name a rust library (rlib) would have. If you want the complete path, use
/// [`rust_lib`] instead.
pub fn rust_lib_name(name: &str) -> String {
format!("lib{name}.rlib")
}
/// Construct the binary name based on platform.

View File

@ -211,7 +211,7 @@ impl Rustc {
/// Get the [`Output`] of the finished process.
#[track_caller]
pub fn command_output(&mut self) -> ::std::process::Output {
pub fn command_output(&mut self) -> Output {
// let's make sure we piped all the input and outputs
self.cmd.stdin(Stdio::piped());
self.cmd.stdout(Stdio::piped());

View File

@ -21,9 +21,7 @@ run-make/compiler-lookup-paths-2/Makefile
run-make/compiler-lookup-paths/Makefile
run-make/compiler-rt-works-on-mingw/Makefile
run-make/compressed-debuginfo/Makefile
run-make/const-prop-lint/Makefile
run-make/const_fn_mir/Makefile
run-make/crate-data-smoke/Makefile
run-make/crate-hash-rustc-version/Makefile
run-make/crate-name-priority/Makefile
run-make/cross-lang-lto-clang/Makefile
@ -72,7 +70,6 @@ run-make/forced-unwind-terminate-pof/Makefile
run-make/foreign-double-unwind/Makefile
run-make/foreign-exceptions/Makefile
run-make/foreign-rust-exceptions/Makefile
run-make/fpic/Makefile
run-make/glibc-staticlib-args/Makefile
run-make/inaccessible-temp-dir/Makefile
run-make/include_bytes_deps/Makefile
@ -103,7 +100,6 @@ run-make/issue-33329/Makefile
run-make/issue-35164/Makefile
run-make/issue-36710/Makefile
run-make/issue-37839/Makefile
run-make/issue-37893/Makefile
run-make/issue-40535/Makefile
run-make/issue-47384/Makefile
run-make/issue-47551/Makefile
@ -234,7 +230,6 @@ run-make/share-generics-dylib/Makefile
run-make/short-ice/Makefile
run-make/silly-file-names/Makefile
run-make/simd-ffi/Makefile
run-make/simple-dylib/Makefile
run-make/split-debuginfo/Makefile
run-make/stable-symbol-names/Makefile
run-make/static-dylib-by-default/Makefile

View File

@ -27,10 +27,12 @@
+ }
+ }
+ scope 7 (inlined slice_from_raw_parts_mut::<A>) {
+ scope 8 (inlined std::ptr::from_raw_parts_mut::<[A], A>) {
+ }
+ }
+ }
+ }
+ scope 8 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
+ scope 9 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
+ let mut _14: isize;
+ let mut _15: isize;
+ }

View File

@ -16,7 +16,7 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
let mut _6: usize;
scope 5 (inlined std::ptr::metadata::<[u32]>) {
}
scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
scope 6 (inlined std::ptr::from_raw_parts::<[u32], ()>) {
}
}
}

View File

@ -16,7 +16,7 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
let mut _6: usize;
scope 5 (inlined std::ptr::metadata::<[u32]>) {
}
scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
scope 6 (inlined std::ptr::from_raw_parts::<[u32], ()>) {
}
}
}

View File

@ -14,7 +14,7 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 {
scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<u32>) {
scope 5 (inlined std::ptr::metadata::<u32>) {
}
scope 6 (inlined std::ptr::from_raw_parts::<u32>) {
scope 6 (inlined std::ptr::from_raw_parts::<u32, ()>) {
}
}
}

View File

@ -14,7 +14,7 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 {
scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<u32>) {
scope 5 (inlined std::ptr::metadata::<u32>) {
}
scope 6 (inlined std::ptr::from_raw_parts::<u32>) {
scope 6 (inlined std::ptr::from_raw_parts::<u32, ()>) {
}
}
}

View File

@ -37,6 +37,10 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
scope 11 (inlined slice_from_raw_parts::<u8>) {
debug data => _4;
debug len => _5;
scope 12 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
debug data_pointer => _4;
debug metadata => _5;
}
}
}
}

View File

@ -37,6 +37,10 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
scope 11 (inlined slice_from_raw_parts::<u8>) {
debug data => _4;
debug len => _5;
scope 12 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
debug data_pointer => _4;
debug metadata => _5;
}
}
}
}

View File

@ -1,9 +0,0 @@
include ../tools.mk
# Test that emitting an error because of arithmetic
# overflow lint does not leave .o files around
# because of interrupted codegen.
all:
$(RUSTC) input.rs; test $$? -eq 1
ls *.o; test $$? -ne 0

View File

@ -0,0 +1,18 @@
// Tests that const prop lints interrupting codegen don't leave `.o` files around.
use std::fs;
use run_make_support::{rustc, tmp_dir};
fn main() {
rustc().input("input.rs").run_fail_assert_exit_code(1);
for entry in fs::read_dir(tmp_dir()).unwrap() {
let entry = entry.unwrap();
let path = entry.path();
if path.is_file() && path.extension().is_some_and(|ext| ext == "o") {
panic!("there should not be `.o` files!");
}
}
}

View File

@ -1,10 +0,0 @@
include ../tools.mk
all:
[ `$(RUSTC) --print crate-name crate.rs` = "foo" ]
[ `$(RUSTC) --print file-names crate.rs` = "$(call BIN,foo)" ]
[ `$(RUSTC) --print file-names --crate-type=lib \
--test crate.rs` = "$(call BIN,foo)" ]
[ `$(RUSTC) --print file-names --test lib.rs` = "$(call BIN,mylib)" ]
$(RUSTC) --print file-names lib.rs
$(RUSTC) --print file-names rlib.rs

View File

@ -0,0 +1,43 @@
use std::process::Output;
use run_make_support::{bin_name, rust_lib_name, rustc};
fn compare_stdout<S: AsRef<str>>(output: Output, expected: S) {
assert_eq!(
String::from_utf8(output.stdout).unwrap().trim(),
expected.as_ref()
);
}
fn main() {
compare_stdout(rustc().print("crate-name").input("crate.rs").run(), "foo");
compare_stdout(
rustc().print("file-names").input("crate.rs").run(),
bin_name("foo"),
);
compare_stdout(
rustc()
.print("file-names")
.crate_type("lib")
.arg("--test")
.input("crate.rs")
.run(),
bin_name("foo"),
);
compare_stdout(
rustc()
.print("file-names")
.arg("--test")
.input("lib.rs")
.run(),
bin_name("mylib"),
);
compare_stdout(
rustc().print("file-names").input("lib.rs").run(),
rust_lib_name("mylib"),
);
compare_stdout(
rustc().print("file-names").input("rlib.rs").run(),
rust_lib_name("mylib"),
);
}

View File

@ -1,11 +0,0 @@
# ignore-cross-compile
include ../tools.mk
# ignore-windows
# ignore-apple
# Test for #39529.
# `-z text` causes ld to error if there are any non-PIC sections
all:
$(RUSTC) hello.rs -C link-args=-Wl,-z,text

View File

@ -1 +0,0 @@
fn main() { }

View File

@ -1,5 +0,0 @@
# ignore-cross-compile
include ../tools.mk
all:
$(RUSTC) a.rs && $(RUSTC) b.rs && $(RUSTC) c.rs

View File

@ -0,0 +1,15 @@
// a.rs is a procedural macro crate, on which b.rs and c.rs depend. A now
// patched bug caused a compilation failure if the proc-macro crate was
// initialized with its dependents in this exact order. This test checks
// that compilation succeeds even when initialization is done in this order.
// See https://github.com/rust-lang/rust/issues/37893
//@ ignore-cross-compile
use run_make_support::rustc;
fn main() {
rustc().input("a.rs").run();
rustc().input("b.rs").run();
rustc().input("c.rs").run();
}

View File

@ -1,6 +0,0 @@
# ignore-cross-compile
include ../tools.mk
all:
$(RUSTC) bar.rs --crate-type=dylib -C prefer-dynamic
$(RUSTC) foo.rs
$(call RUN,foo)

View File

@ -1 +0,0 @@
pub fn bar() {}

View File

@ -1,5 +0,0 @@
extern crate bar;
fn main() {
bar::bar();
}

View File

@ -0,0 +1,64 @@
#![doc = in_root!()] // FIXME, this is a bug
#![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope
#![doc = in_mod_escape!()] // FIXME, this is a bug
#![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
#[doc = in_root!()] //~ ERROR cannot find macro `in_root` in this scope
#[doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope
#[doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` in this scope
#[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
fn before() {
#![doc = in_root!()] //~ ERROR cannot find macro `in_root` in this scope
#![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope
#![doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` in this scope
#![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
}
macro_rules! in_root { () => { "" } }
mod macros_stay {
#![doc = in_mod!()] // FIXME, this is a bug
macro_rules! in_mod { () => { "" } }
#[doc = in_mod!()] // OK
fn f() {
#![doc = in_mod!()] // OK
}
}
#[macro_use]
mod macros_escape {
#![doc = in_mod_escape!()] // FIXME, this is a bug
macro_rules! in_mod_escape { () => { "" } }
#[doc = in_mod_escape!()] // OK
fn f() {
#![doc = in_mod_escape!()] // OK
}
}
fn block() {
#![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
macro_rules! in_block { () => { "" } }
#[doc = in_block!()] // OK
fn f() {
#![doc = in_block!()] // OK
}
}
#[doc = in_root!()] // OK
#[doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope
#[doc = in_mod_escape!()] // OK
#[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
fn after() {
#![doc = in_root!()] // OK
#![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope
#![doc = in_mod_escape!()] // OK
#![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
}
fn main() {}

View File

@ -0,0 +1,122 @@
error: cannot find macro `in_mod` in this scope
--> $DIR/key-value-expansion-scope.rs:2:10
|
LL | #![doc = in_mod!()]
| ^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_block` in this scope
--> $DIR/key-value-expansion-scope.rs:4:10
|
LL | #![doc = in_block!()]
| ^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_root` in this scope
--> $DIR/key-value-expansion-scope.rs:6:9
|
LL | #[doc = in_root!()]
| ^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_mod` in this scope
--> $DIR/key-value-expansion-scope.rs:7:9
|
LL | #[doc = in_mod!()]
| ^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_mod_escape` in this scope
--> $DIR/key-value-expansion-scope.rs:8:9
|
LL | #[doc = in_mod_escape!()]
| ^^^^^^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_block` in this scope
--> $DIR/key-value-expansion-scope.rs:9:9
|
LL | #[doc = in_block!()]
| ^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_root` in this scope
--> $DIR/key-value-expansion-scope.rs:11:14
|
LL | #![doc = in_root!()]
| ^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_mod` in this scope
--> $DIR/key-value-expansion-scope.rs:12:14
|
LL | #![doc = in_mod!()]
| ^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_mod_escape` in this scope
--> $DIR/key-value-expansion-scope.rs:13:14
|
LL | #![doc = in_mod_escape!()]
| ^^^^^^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_block` in this scope
--> $DIR/key-value-expansion-scope.rs:14:14
|
LL | #![doc = in_block!()]
| ^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_block` in this scope
--> $DIR/key-value-expansion-scope.rs:43:14
|
LL | #![doc = in_block!()]
| ^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_mod` in this scope
--> $DIR/key-value-expansion-scope.rs:54:9
|
LL | #[doc = in_mod!()]
| ^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_block` in this scope
--> $DIR/key-value-expansion-scope.rs:56:9
|
LL | #[doc = in_block!()]
| ^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_mod` in this scope
--> $DIR/key-value-expansion-scope.rs:59:14
|
LL | #![doc = in_mod!()]
| ^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: cannot find macro `in_block` in this scope
--> $DIR/key-value-expansion-scope.rs:61:14
|
LL | #![doc = in_block!()]
| ^^^^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: aborting due to 15 previous errors

View File

@ -0,0 +1,12 @@
// `-z text` caused the linker to error if there were any non-position-independent
// code (PIC) sections. This test checks that this no longer happens.
// See https://github.com/rust-lang/rust/pull/39803
//@ ignore-windows
//@ ignore-macos
//@ ignore-cross-compile
//@ compile-flags: -Clink-args=-Wl,-z,text
//@ run-pass
fn main() {}

View File

@ -1,13 +1,3 @@
error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:4:1
|
LL | #[optimize(size)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
= help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:7:1
|
@ -38,6 +28,16 @@ LL | #[optimize(banana)]
= help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:4:1
|
LL | #[optimize(size)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
= help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `#[optimize]` attribute is an experimental feature
--> $DIR/feature-gate-optimize_attribute.rs:2:1
|

View File

@ -1,9 +1,3 @@
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-stable.rs:10:1
|
LL | #[stable()]
| ^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-stable.rs:14:9
|
@ -34,6 +28,12 @@ error[E0734]: stability attributes may not be used outside of the standard libra
LL | #[stable()]
| ^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-stable.rs:10:1
|
LL | #[stable()]
| ^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-stable.rs:7:1
|

View File

@ -1,9 +1,3 @@
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-unstable.rs:10:1
|
LL | #[unstable()]
| ^^^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-unstable.rs:14:9
|
@ -34,6 +28,12 @@ error[E0734]: stability attributes may not be used outside of the standard libra
LL | #[unstable()]
| ^^^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-unstable.rs:10:1
|
LL | #[unstable()]
| ^^^^^^^^^^^^^
error[E0734]: stability attributes may not be used outside of the standard library
--> $DIR/issue-43106-gating-of-unstable.rs:7:1
|

View File

@ -0,0 +1,4 @@
//@ compile-flags: -Cprefer-dynamic
#![crate_type = "dylib"]
pub fn bar() {}

View File

@ -0,0 +1,12 @@
// A simple test, where foo.rs has a dependency
// on the dynamic library simple-dylib.rs. If the test passes,
// dylibs can be built and linked into another file successfully..
//@ aux-crate:bar=simple-dylib.rs
//@ run-pass
extern crate bar;
fn main() {
bar::bar();
}

View File

@ -87,7 +87,7 @@ pub fn main() {
let obj: Box<St> = Box::new(St { f: 42 });
let obj: &Tr = &*obj;
let data: Box<_> = Box::new(Qux_ { f: St { f: 234 } });
let x: &Qux = &*ptr::from_raw_parts::<Qux>((&*data as *const _).cast(), ptr::metadata(obj));
let x: &Qux = &*ptr::from_raw_parts::<Qux>(&*data as *const _, ptr::metadata(obj));
assert_eq!(x.f.foo(), 234);
}
}