Auto merge of #64438 - cuviper:beta-rollup, r=Mark-Simulacrum
[beta] Rollup backports Cherry-picked: - Permit unwinding through FFI by default #62603 - pprust: Do not print spaces before some tokens #63897 - Account for doc comments coming from proc macros without spans #63930 - Support "soft" feature-gating using a lint #64066 - Update xLTO compatibility table in rustc book. #64092 - Include compiler-rt in the source tarball #64240 - Update LLVM submodule #64317 r? @Mark-Simulacrum
This commit is contained in:
commit
fdd48565d0
32 changed files with 151 additions and 60 deletions
|
|
@ -808,6 +808,7 @@ fn copy_src_dirs(builder: &Builder<'_>, src_dirs: &[&str], exclude_dirs: &[&str]
|
|||
"llvm-project/lld", "llvm-project\\lld",
|
||||
"llvm-project/lldb", "llvm-project\\lldb",
|
||||
"llvm-project/llvm", "llvm-project\\llvm",
|
||||
"llvm-project/compiler-rt", "llvm-project\\compiler-rt",
|
||||
];
|
||||
if spath.contains("llvm-project") && !spath.ends_with("llvm-project")
|
||||
&& !LLVM_PROJECTS.iter().any(|path| spath.contains(path))
|
||||
|
|
|
|||
|
|
@ -105,5 +105,6 @@ The following table shows known good combinations of toolchain versions.
|
|||
| Rust 1.34 | ✗ | ✓ |
|
||||
| Rust 1.35 | ✗ | ✓ |
|
||||
| Rust 1.36 | ✗ | ✓ |
|
||||
| Rust 1.37 | ✗ | ✓ |
|
||||
|
||||
Note that the compatibility policy for this feature might change in the future.
|
||||
|
|
|
|||
|
|
@ -1281,8 +1281,10 @@ pub(crate) mod builtin {
|
|||
pub macro test($item:item) { /* compiler built-in */ }
|
||||
|
||||
/// Attribute macro applied to a function to turn it into a benchmark test.
|
||||
#[unstable(feature = "test", issue = "50297",
|
||||
reason = "`bench` is a part of custom test frameworks which are unstable")]
|
||||
#[cfg_attr(not(boostrap_stdarch_ignore_this), unstable(soft, feature = "test", issue = "50297",
|
||||
reason = "`bench` is a part of custom test frameworks which are unstable"))]
|
||||
#[cfg_attr(boostrap_stdarch_ignore_this, unstable(feature = "test", issue = "50297",
|
||||
reason = "`bench` is a part of custom test frameworks which are unstable"))]
|
||||
#[allow_internal_unstable(test, rustc_attrs)]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
|
|
|
|||
|
|
@ -136,9 +136,10 @@ for ::syntax::attr::StabilityLevel {
|
|||
hasher: &mut StableHasher<W>) {
|
||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
match *self {
|
||||
::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue } => {
|
||||
::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue, ref is_soft } => {
|
||||
reason.hash_stable(hcx, hasher);
|
||||
issue.hash_stable(hcx, hasher);
|
||||
is_soft.hash_stable(hcx, hasher);
|
||||
}
|
||||
::syntax::attr::StabilityLevel::Stable { ref since } => {
|
||||
since.hash_stable(hcx, hasher);
|
||||
|
|
|
|||
|
|
@ -395,6 +395,12 @@ declare_lint! {
|
|||
"reservation of a two-phased borrow conflicts with other shared borrows"
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub SOFT_UNSTABLE,
|
||||
Deny,
|
||||
"a feature gate that doesn't break dependent crates"
|
||||
}
|
||||
|
||||
declare_lint_pass! {
|
||||
/// Does nothing as a lint pass, but registers some `Lint`s
|
||||
/// that are used by other parts of the compiler.
|
||||
|
|
@ -460,6 +466,7 @@ declare_lint_pass! {
|
|||
NESTED_IMPL_TRAIT,
|
||||
MUTABLE_BORROW_RESERVATION_CONFLICT,
|
||||
INDIRECT_STRUCTURAL_MATCH,
|
||||
SOFT_UNSTABLE,
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -438,6 +438,7 @@ impl<'tcx> Index<'tcx> {
|
|||
level: attr::StabilityLevel::Unstable {
|
||||
reason: Some(Symbol::intern(reason)),
|
||||
issue: 27812,
|
||||
is_soft: false,
|
||||
},
|
||||
feature: sym::rustc_private,
|
||||
rustc_depr: None,
|
||||
|
|
@ -480,7 +481,7 @@ pub fn provide(providers: &mut Providers<'_>) {
|
|||
}
|
||||
|
||||
pub fn report_unstable(
|
||||
sess: &Session, feature: Symbol, reason: Option<Symbol>, issue: u32, span: Span
|
||||
sess: &Session, feature: Symbol, reason: Option<Symbol>, issue: u32, is_soft: bool, span: Span
|
||||
) {
|
||||
let msg = match reason {
|
||||
Some(r) => format!("use of unstable library feature '{}': {}", feature, r),
|
||||
|
|
@ -505,7 +506,13 @@ pub fn report_unstable(
|
|||
let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
|
||||
let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id);
|
||||
if fresh {
|
||||
emit_feature_err(&sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg);
|
||||
if is_soft {
|
||||
sess.buffer_lint(lint::builtin::SOFT_UNSTABLE, CRATE_NODE_ID, span, &msg);
|
||||
} else {
|
||||
emit_feature_err(
|
||||
&sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -621,6 +628,7 @@ pub enum EvalResult {
|
|||
feature: Symbol,
|
||||
reason: Option<Symbol>,
|
||||
issue: u32,
|
||||
is_soft: bool,
|
||||
},
|
||||
/// The item does not have the `#[stable]` or `#[unstable]` marker assigned.
|
||||
Unmarked,
|
||||
|
|
@ -720,7 +728,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
match stability {
|
||||
Some(&Stability { level: attr::Unstable { reason, issue }, feature, .. }) => {
|
||||
Some(&Stability {
|
||||
level: attr::Unstable { reason, issue, is_soft }, feature, ..
|
||||
}) => {
|
||||
if span.allows_unstable(feature) {
|
||||
debug!("stability: skipping span={:?} since it is internal", span);
|
||||
return EvalResult::Allow;
|
||||
|
|
@ -744,7 +754,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
EvalResult::Deny { feature, reason, issue }
|
||||
EvalResult::Deny { feature, reason, issue, is_soft }
|
||||
}
|
||||
Some(_) => {
|
||||
// Stable APIs are always ok to call and deprecated APIs are
|
||||
|
|
@ -767,8 +777,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) {
|
||||
match self.eval_stability(def_id, id, span) {
|
||||
EvalResult::Allow => {}
|
||||
EvalResult::Deny { feature, reason, issue } =>
|
||||
report_unstable(self.sess, feature, reason, issue, span),
|
||||
EvalResult::Deny { feature, reason, issue, is_soft } =>
|
||||
report_unstable(self.sess, feature, reason, issue, is_soft, span),
|
||||
EvalResult::Unmarked => {
|
||||
// The API could be uncallable for other reasons, for example when a private module
|
||||
// was referenced.
|
||||
|
|
|
|||
|
|
@ -433,7 +433,12 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||
id: LintId::of(INDIRECT_STRUCTURAL_MATCH),
|
||||
reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>",
|
||||
edition: None,
|
||||
}
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(SOFT_UNSTABLE),
|
||||
reference: "issue #64266 <https://github.com/rust-lang/rust/issues/64266>",
|
||||
edition: None,
|
||||
},
|
||||
]);
|
||||
|
||||
// Register renamed and removed lints.
|
||||
|
|
|
|||
|
|
@ -502,7 +502,7 @@ fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, abi: Abi) -> bool {
|
|||
// This is a special case: some functions have a C abi but are meant to
|
||||
// unwind anyway. Don't stop them.
|
||||
match unwind_attr {
|
||||
None => true,
|
||||
None => false, // FIXME(#58794)
|
||||
Some(UnwindAttr::Allowed) => false,
|
||||
Some(UnwindAttr::Aborts) => true,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -797,10 +797,10 @@ impl<'a> Resolver<'a> {
|
|||
fn check_stability_and_deprecation(&self, ext: &SyntaxExtension, path: &ast::Path) {
|
||||
let span = path.span;
|
||||
if let Some(stability) = &ext.stability {
|
||||
if let StabilityLevel::Unstable { reason, issue } = stability.level {
|
||||
if let StabilityLevel::Unstable { reason, issue, is_soft } = stability.level {
|
||||
let feature = stability.feature;
|
||||
if !self.active_features.contains(&feature) && !span.allows_unstable(feature) {
|
||||
stability::report_unstable(self.session, feature, reason, issue, span);
|
||||
stability::report_unstable(self.session, feature, reason, issue, is_soft, span);
|
||||
}
|
||||
}
|
||||
if let Some(depr) = &stability.rustc_depr {
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
|
|||
// We couldn't calculate the span of the markdown block that had the error, so our
|
||||
// diagnostics are going to be a bit lacking.
|
||||
let mut diag = self.cx.sess().struct_span_warn(
|
||||
super::span_of_attrs(&item.attrs),
|
||||
super::span_of_attrs(&item.attrs).unwrap_or(item.source.span()),
|
||||
"doc comment contains an invalid Rust code block",
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -464,7 +464,7 @@ fn resolution_failure(
|
|||
}
|
||||
};
|
||||
let attrs = &item.attrs;
|
||||
let sp = span_of_attrs(attrs);
|
||||
let sp = span_of_attrs(attrs).unwrap_or(item.source.span());
|
||||
|
||||
let mut diag = cx.tcx.struct_span_lint_hir(
|
||||
lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
|
||||
|
|
@ -516,7 +516,7 @@ fn ambiguity_error(
|
|||
}
|
||||
};
|
||||
let attrs = &item.attrs;
|
||||
let sp = span_of_attrs(attrs);
|
||||
let sp = span_of_attrs(attrs).unwrap_or(item.source.span());
|
||||
|
||||
let mut msg = format!("`{}` is ", path_str);
|
||||
|
||||
|
|
|
|||
|
|
@ -339,7 +339,7 @@ pub fn look_for_tests<'tcx>(
|
|||
find_testable_code(&dox, &mut tests, ErrorCodes::No);
|
||||
|
||||
if check_missing_code == true && tests.found_tests == 0 {
|
||||
let sp = span_of_attrs(&item.attrs).substitute_dummy(item.source.span());
|
||||
let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span());
|
||||
let mut diag = cx.tcx.struct_span_lint_hir(
|
||||
lint::builtin::MISSING_DOC_CODE_EXAMPLES,
|
||||
hir_id,
|
||||
|
|
@ -352,20 +352,23 @@ pub fn look_for_tests<'tcx>(
|
|||
let mut diag = cx.tcx.struct_span_lint_hir(
|
||||
lint::builtin::PRIVATE_DOC_TESTS,
|
||||
hir_id,
|
||||
span_of_attrs(&item.attrs),
|
||||
span_of_attrs(&item.attrs).unwrap_or(item.source.span()),
|
||||
"Documentation test in private item");
|
||||
diag.emit();
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a span encompassing all the given attributes.
|
||||
crate fn span_of_attrs(attrs: &clean::Attributes) -> Span {
|
||||
crate fn span_of_attrs(attrs: &clean::Attributes) -> Option<Span> {
|
||||
if attrs.doc_strings.is_empty() {
|
||||
return DUMMY_SP;
|
||||
return None;
|
||||
}
|
||||
let start = attrs.doc_strings[0].span();
|
||||
if start == DUMMY_SP {
|
||||
return None;
|
||||
}
|
||||
let end = attrs.doc_strings.last().expect("No doc strings provided").span();
|
||||
start.to(end)
|
||||
Some(start.to(end))
|
||||
}
|
||||
|
||||
/// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code.
|
||||
|
|
@ -391,7 +394,7 @@ crate fn source_span_for_markdown_range(
|
|||
let snippet = cx
|
||||
.sess()
|
||||
.source_map()
|
||||
.span_to_snippet(span_of_attrs(attrs))
|
||||
.span_to_snippet(span_of_attrs(attrs)?)
|
||||
.ok()?;
|
||||
|
||||
let starting_line = markdown[..md_range.start].matches('\n').count();
|
||||
|
|
@ -441,10 +444,8 @@ crate fn source_span_for_markdown_range(
|
|||
}
|
||||
}
|
||||
|
||||
let sp = span_of_attrs(attrs).from_inner(InnerSpan::new(
|
||||
Some(span_of_attrs(attrs)?.from_inner(InnerSpan::new(
|
||||
md_range.start + start_bytes,
|
||||
md_range.end + start_bytes + end_bytes,
|
||||
));
|
||||
|
||||
Some(sp)
|
||||
)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,23 +154,10 @@ pub struct Stability {
|
|||
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)]
|
||||
pub enum StabilityLevel {
|
||||
// Reason for the current stability level and the relevant rust-lang issue
|
||||
Unstable { reason: Option<Symbol>, issue: u32 },
|
||||
Unstable { reason: Option<Symbol>, issue: u32, is_soft: bool },
|
||||
Stable { since: Symbol },
|
||||
}
|
||||
|
||||
impl Stability {
|
||||
pub fn unstable(feature: Symbol, reason: Option<Symbol>, issue: u32) -> Stability {
|
||||
Stability {
|
||||
level: StabilityLevel::Unstable { reason, issue },
|
||||
feature,
|
||||
rustc_depr: None,
|
||||
const_stability: None,
|
||||
promotable: false,
|
||||
allow_const_fn_ptr: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StabilityLevel {
|
||||
pub fn is_unstable(&self) -> bool {
|
||||
if let StabilityLevel::Unstable {..} = *self {
|
||||
|
|
@ -356,19 +343,27 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
|
|||
let mut feature = None;
|
||||
let mut reason = None;
|
||||
let mut issue = None;
|
||||
let mut is_soft = false;
|
||||
for meta in metas {
|
||||
if let Some(mi) = meta.meta_item() {
|
||||
match mi.name_or_empty() {
|
||||
sym::feature => if !get(mi, &mut feature) { continue 'outer },
|
||||
sym::reason => if !get(mi, &mut reason) { continue 'outer },
|
||||
sym::issue => if !get(mi, &mut issue) { continue 'outer },
|
||||
sym::soft => {
|
||||
if !mi.is_word() {
|
||||
let msg = "`soft` should not have any arguments";
|
||||
sess.span_diagnostic.span_err(mi.span, msg);
|
||||
}
|
||||
is_soft = true;
|
||||
}
|
||||
_ => {
|
||||
handle_errors(
|
||||
sess,
|
||||
meta.span(),
|
||||
AttrError::UnknownMetaItem(
|
||||
mi.path.to_string(),
|
||||
&["feature", "reason", "issue"]
|
||||
&["feature", "reason", "issue", "soft"]
|
||||
),
|
||||
);
|
||||
continue 'outer
|
||||
|
|
@ -400,7 +395,8 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
|
|||
"incorrect 'issue'");
|
||||
continue
|
||||
}
|
||||
}
|
||||
},
|
||||
is_soft,
|
||||
},
|
||||
feature,
|
||||
rustc_depr: None,
|
||||
|
|
|
|||
|
|
@ -152,6 +152,18 @@ pub fn to_string<F>(f: F) -> String where
|
|||
printer.s.eof()
|
||||
}
|
||||
|
||||
// This makes comma-separated lists look slightly nicer,
|
||||
// and also addresses a specific regression described in issue #63896.
|
||||
fn tt_prepend_space(tt: &TokenTree) -> bool {
|
||||
match tt {
|
||||
TokenTree::Token(token) => match token.kind {
|
||||
token::Comma => false,
|
||||
_ => true,
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
fn binop_to_string(op: BinOpToken) -> &'static str {
|
||||
match op {
|
||||
token::Plus => "+",
|
||||
|
|
@ -684,7 +696,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target=pp::Printer> + std::ops::DerefM
|
|||
|
||||
fn print_tts(&mut self, tts: tokenstream::TokenStream, convert_dollar_crate: bool) {
|
||||
for (i, tt) in tts.into_trees().enumerate() {
|
||||
if i != 0 {
|
||||
if i != 0 && tt_prepend_space(&tt) {
|
||||
self.space();
|
||||
}
|
||||
self.print_tt(tt, convert_dollar_crate);
|
||||
|
|
|
|||
|
|
@ -623,6 +623,7 @@ symbols! {
|
|||
size,
|
||||
slice_patterns,
|
||||
slicing_syntax,
|
||||
soft,
|
||||
Some,
|
||||
specialization,
|
||||
speed,
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 48818e9f5d0f2d5978a9b43ad1a2e8d0b83f6aa0
|
||||
Subproject commit 71fe7ec06b85f612fc0e4eb4134c7a7d0f23fac5
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(c_variadic)]
|
||||
#![feature(unwind_attributes)]
|
||||
#![no_std]
|
||||
use core::ffi::VaList;
|
||||
|
||||
|
|
@ -10,6 +11,7 @@ extern "C" {
|
|||
fn foreign_c_variadic_1(_: VaList, ...);
|
||||
}
|
||||
|
||||
#[unwind(aborts)] // FIXME(#58794)
|
||||
pub unsafe extern "C" fn use_foreign_c_variadic_0() {
|
||||
// Ensure that we correctly call foreign C-variadic functions.
|
||||
// CHECK: invoke void (i32, ...) @foreign_c_variadic_0(i32 0)
|
||||
|
|
@ -24,20 +26,24 @@ pub unsafe extern "C" fn use_foreign_c_variadic_0() {
|
|||
|
||||
// Ensure that we do not remove the `va_list` passed to the foreign function when
|
||||
// removing the "spoofed" `VaListImpl` that is used by Rust defined C-variadics.
|
||||
#[unwind(aborts)] // FIXME(#58794)
|
||||
pub unsafe extern "C" fn use_foreign_c_variadic_1_0(ap: VaList) {
|
||||
// CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap)
|
||||
foreign_c_variadic_1(ap);
|
||||
}
|
||||
|
||||
#[unwind(aborts)] // FIXME(#58794)
|
||||
pub unsafe extern "C" fn use_foreign_c_variadic_1_1(ap: VaList) {
|
||||
// CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, i32 42)
|
||||
foreign_c_variadic_1(ap, 42i32);
|
||||
}
|
||||
#[unwind(aborts)] // FIXME(#58794)
|
||||
pub unsafe extern "C" fn use_foreign_c_variadic_1_2(ap: VaList) {
|
||||
// CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, i32 2, i32 42)
|
||||
foreign_c_variadic_1(ap, 2i32, 42i32);
|
||||
}
|
||||
|
||||
#[unwind(aborts)] // FIXME(#58794)
|
||||
pub unsafe extern "C" fn use_foreign_c_variadic_1_3(ap: VaList) {
|
||||
// CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, i32 2, i32 42, i32 0)
|
||||
foreign_c_variadic_1(ap, 2i32, 42i32, 0i32);
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ pub unsafe fn make_unsafe() {}
|
|||
pub fn make_extern() {}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, mir_built, typeck_tables_of, fn_sig")]
|
||||
#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, typeck_tables_of, fn_sig")]
|
||||
#[rustc_clean(cfg = "cfail3")]
|
||||
pub extern "C" fn make_extern() {}
|
||||
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ impl Foo {
|
|||
#[rustc_clean(cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
impl Foo {
|
||||
#[rustc_clean(cfg="cfail2", except="Hir,HirBody,mir_built,fn_sig,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="Hir,HirBody,fn_sig,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub extern fn make_method_extern(&self) { }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@
|
|||
#![feature(rustc_attrs)]
|
||||
|
||||
fn main() {
|
||||
#![rustc_dummy("hi" , 1 , 2 , 1.012 , pi = 3.14 , bye , name ("John"))]
|
||||
#![rustc_dummy("hi", 1, 2, 1.012, pi = 3.14, bye, name ("John"))]
|
||||
#[rustc_dummy = 8]
|
||||
fn f() { }
|
||||
|
||||
#[rustc_dummy(1 , 2 , 3)]
|
||||
#[rustc_dummy(1, 2, 3)]
|
||||
fn g() { }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,8 +99,5 @@ fn main() {
|
|||
'\u{2004}', '\u{2005}', '\u{2006}', '\u{2007}', '\u{2008}',
|
||||
'\u{2009}', '\u{200A}', '\u{2028}', '\u{2029}', '\u{202F}',
|
||||
'\u{205F}', '\u{3000}'];
|
||||
for c in &chars {
|
||||
let ws = c.is_whitespace();
|
||||
println!("{} {}" , c , ws);
|
||||
}
|
||||
for c in &chars { let ws = c.is_whitespace(); println!("{} {}", c, ws); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
macro_rules! mac { ($ ($ tt : tt) *) => () }
|
||||
|
||||
mac! {
|
||||
struct S { field1 : u8 , field2 : u16 , } impl Clone for S
|
||||
struct S { field1 : u8, field2 : u16, } impl Clone for S
|
||||
{
|
||||
fn clone () -> S
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
fn f<F>(f: F) where F: Fn(isize) { f(10) }
|
||||
|
||||
fn main() { f(|i| { assert_eq!(i , 10) }) }
|
||||
fn main() { f(|i| { assert_eq!(i, 10) }) }
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
fn main() {
|
||||
let x = match { 5 } { 1 => 5, 2 => 6, _ => 7, };
|
||||
assert_eq!(x , 7);
|
||||
assert_eq!(x, 7);
|
||||
}
|
||||
|
|
|
|||
20
src/test/rustdoc/auxiliary/through-proc-macro-aux.rs
Normal file
20
src/test/rustdoc/auxiliary/through-proc-macro-aux.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// force-host
|
||||
// no-prefer-dynamic
|
||||
#![crate_type = "proc-macro"]
|
||||
#![crate_name="some_macros"]
|
||||
|
||||
extern crate proc_macro;
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn first(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
item // This doesn't erase the spans.
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn second(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
// Make a new `TokenStream` to erase the spans:
|
||||
let mut out: TokenStream = TokenStream::new();
|
||||
out.extend(item);
|
||||
out
|
||||
}
|
||||
12
src/test/rustdoc/through-proc-macro.rs
Normal file
12
src/test/rustdoc/through-proc-macro.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// aux-build:through-proc-macro-aux.rs
|
||||
// build-aux-docs
|
||||
#![warn(intra_doc_link_resolution_failure)]
|
||||
extern crate some_macros;
|
||||
|
||||
#[some_macros::second]
|
||||
pub enum Boom {
|
||||
/// [Oooops]
|
||||
Bam,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
// run-pass
|
||||
|
||||
#![allow(unused_must_use)]
|
||||
#![feature(unwind_attributes)]
|
||||
// Since we mark some ABIs as "nounwind" to LLVM, we must make sure that
|
||||
// we never unwind through them.
|
||||
|
||||
|
|
@ -13,6 +14,7 @@ use std::io::prelude::*;
|
|||
use std::io;
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
#[unwind(aborts)] // FIXME(#58794)
|
||||
extern "C" fn panic_in_ffi() {
|
||||
panic!("Test");
|
||||
}
|
||||
|
|
|
|||
5
src/test/ui/feature-gates/bench.rs
Normal file
5
src/test/ui/feature-gates/bench.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#[bench] //~ ERROR use of unstable library feature 'test'
|
||||
//~| WARN this was previously accepted
|
||||
fn bench() {}
|
||||
|
||||
fn main() {}
|
||||
12
src/test/ui/feature-gates/bench.stderr
Normal file
12
src/test/ui/feature-gates/bench.stderr
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
error: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable
|
||||
--> $DIR/bench.rs:1:3
|
||||
|
|
||||
LL | #[bench]
|
||||
| ^^^^^
|
||||
|
|
||||
= note: `#[deny(soft_unstable)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ macro_rules! foo_26444 {
|
|||
}
|
||||
|
||||
fn test_26444() {
|
||||
assert_eq!("a , b , c , d , e", foo_26444!(a, b; c; d, e));
|
||||
assert_eq!("a, b, c, d, e", foo_26444!(a, b; c; d, e));
|
||||
assert_eq!("f", foo_26444!(; f ;));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||
#[proc_macro_attribute]
|
||||
pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert_eq!(item.to_string(), "println!(\"{}\" , string);");
|
||||
assert_eq!(item.to_string(), "println!(\"{}\", string);");
|
||||
item
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||
#[proc_macro_attribute]
|
||||
pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert_eq!(item.to_string(), "println!(\"{}\" , string)");
|
||||
assert_eq!(item.to_string(), "println!(\"{}\", string)");
|
||||
item
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||
#[proc_macro_attribute]
|
||||
pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert_eq!(item.to_string(), "println!(\"{}\" , string);");
|
||||
assert_eq!(item.to_string(), "println!(\"{}\", string);");
|
||||
item
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||
#[proc_macro_attribute]
|
||||
pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert_eq!(item.to_string(), "println!(\"{}\" , string)");
|
||||
assert_eq!(item.to_string(), "println!(\"{}\", string)");
|
||||
item
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue