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:
commit
caa187f3bc
@ -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()
|
||||
}
|
||||
|
||||
|
@ -228,13 +228,18 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
|
||||
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;
|
||||
|
@ -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,
|
||||
),
|
||||
(
|
||||
|
@ -210,7 +210,6 @@
|
||||
FsPermissions,
|
||||
FusedIterator,
|
||||
Future,
|
||||
FutureOutput,
|
||||
GlobalAlloc,
|
||||
Hash,
|
||||
HashMap,
|
||||
@ -439,8 +438,10 @@
|
||||
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 @@
|
||||
call,
|
||||
call_mut,
|
||||
call_once,
|
||||
call_once_future,
|
||||
call_ref_future,
|
||||
caller_location,
|
||||
capture_disjoint_fields,
|
||||
catch_unwind,
|
||||
@ -911,6 +914,7 @@
|
||||
fundamental,
|
||||
fused_iterator,
|
||||
future,
|
||||
future_output,
|
||||
future_trait,
|
||||
gdb_script_file,
|
||||
ge,
|
||||
|
@ -9,7 +9,6 @@
|
||||
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,
|
||||
|
@ -407,16 +407,20 @@ fn consider_builtin_async_fn_trait_candidates(
|
||||
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 @@ fn consider_builtin_async_fn_trait_candidates(
|
||||
],
|
||||
),
|
||||
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 @@ fn consider_builtin_async_fn_trait_candidates(
|
||||
],
|
||||
),
|
||||
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 }
|
||||
},
|
||||
|
@ -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}"),
|
||||
|
@ -35,7 +35,7 @@
|
||||
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
|
||||
|
@ -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 @@ trait AsyncFnKindHelper<GoalKind> {
|
||||
// `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>;
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -222,7 +222,7 @@ pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
|
||||
#[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 fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
|
||||
#[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) }
|
||||
}
|
||||
|
@ -83,12 +83,12 @@ struct B {
|
||||
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);
|
||||
|
@ -965,7 +965,7 @@ fn layout(&self) -> (Layout, usize) {
|
||||
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 value_mut_ptr(&mut self) -> *mut T {
|
||||
// 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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
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);
|
||||
|
||||
|
@ -1140,7 +1140,13 @@ fn run(self, builder: &Builder<'_>) {
|
||||
);
|
||||
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");
|
||||
|
@ -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:
|
||||
|
@ -660,10 +660,11 @@ pub fn build(&mut self) {
|
||||
|
||||
// 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,
|
||||
);
|
||||
}
|
||||
|
@ -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'
|
||||
|
@ -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')
|
||||
|
@ -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
|
||||
|
@ -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]' \
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -211,7 +211,7 @@ pub fn linker(&mut self, linker: &str) -> &mut Self {
|
||||
|
||||
/// 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());
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
+ }
|
||||
|
@ -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], ()>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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], ()>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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, ()>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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, ()>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
18
tests/run-make/const-prop-lint/rmake.rs
Normal file
18
tests/run-make/const-prop-lint/rmake.rs
Normal 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!");
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
43
tests/run-make/crate-data-smoke/rmake.rs
Normal file
43
tests/run-make/crate-data-smoke/rmake.rs
Normal 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"),
|
||||
);
|
||||
}
|
@ -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
|
@ -1 +0,0 @@
|
||||
fn main() { }
|
@ -1,5 +0,0 @@
|
||||
# ignore-cross-compile
|
||||
include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) a.rs && $(RUSTC) b.rs && $(RUSTC) c.rs
|
15
tests/run-make/proc-macro-init-order/rmake.rs
Normal file
15
tests/run-make/proc-macro-init-order/rmake.rs
Normal 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();
|
||||
}
|
@ -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)
|
@ -1 +0,0 @@
|
||||
pub fn bar() {}
|
@ -1,5 +0,0 @@
|
||||
extern crate bar;
|
||||
|
||||
fn main() {
|
||||
bar::bar();
|
||||
}
|
64
tests/ui/attributes/key-value-expansion-scope.rs
Normal file
64
tests/ui/attributes/key-value-expansion-scope.rs
Normal 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() {}
|
122
tests/ui/attributes/key-value-expansion-scope.stderr
Normal file
122
tests/ui/attributes/key-value-expansion-scope.stderr
Normal 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
|
||||
|
12
tests/ui/errors/pic-linker.rs
Normal file
12
tests/ui/errors/pic-linker.rs
Normal 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() {}
|
@ -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
|
||||
|
|
||||
|
@ -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
|
||||
|
|
||||
|
@ -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
|
||||
|
|
||||
|
4
tests/ui/imports/auxiliary/simple-dylib.rs
Normal file
4
tests/ui/imports/auxiliary/simple-dylib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
//@ compile-flags: -Cprefer-dynamic
|
||||
|
||||
#![crate_type = "dylib"]
|
||||
pub fn bar() {}
|
12
tests/ui/imports/simple-dylib-import.rs
Normal file
12
tests/ui/imports/simple-dylib-import.rs
Normal 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();
|
||||
}
|
@ -87,7 +87,7 @@ struct Qux_ {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user