Auto merge of #125257 - jieyouxu:rollup-11evnm9, r=jieyouxu
Rollup of 3 pull requests Successful merges: - #125214 (Only make GAT ambiguous in `match_projection_projections` considering shallow resolvability) - #125236 (Add tests for `-Zunpretty=expanded` ported from stringify's tests) - #125251 (Clarify how String::leak and into_boxed_str differ ) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
b1ec1bd65f
13 changed files with 1844 additions and 57 deletions
compiler/rustc_trait_selection/src/traits/select
library/alloc/src
src/tools/tidy/src
tests/ui
generic-associated-types
macros
unpretty
|
@ -1778,9 +1778,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// If this type is a GAT, and of the GAT args resolve to something new,
|
// If this type is a GAT, and of the GAT args resolve to something new,
|
||||||
// that means that we must have newly inferred something about the GAT.
|
// that means that we must have newly inferred something about the GAT.
|
||||||
// We should give up in that case.
|
// We should give up in that case.
|
||||||
|
// FIXME(generic-associated-types): This only detects one layer of inference,
|
||||||
|
// which is probably not what we actually want, but fixing it causes some ambiguity:
|
||||||
|
// <https://github.com/rust-lang/rust/issues/125196>.
|
||||||
if !generics.own_params.is_empty()
|
if !generics.own_params.is_empty()
|
||||||
&& obligation.predicate.args[generics.parent_count..].iter().any(|&p| {
|
&& obligation.predicate.args[generics.parent_count..].iter().any(|&p| {
|
||||||
p.has_non_region_infer() && self.infcx.resolve_vars_if_possible(p) != p
|
p.has_non_region_infer()
|
||||||
|
&& match p.unpack() {
|
||||||
|
ty::GenericArgKind::Const(ct) => {
|
||||||
|
self.infcx.shallow_resolve_const(ct) != ct
|
||||||
|
}
|
||||||
|
ty::GenericArgKind::Type(ty) => self.infcx.shallow_resolve(ty) != ty,
|
||||||
|
ty::GenericArgKind::Lifetime(_) => false,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
ProjectionMatchesProjection::Ambiguous
|
ProjectionMatchesProjection::Ambiguous
|
||||||
|
|
|
@ -1940,8 +1940,10 @@ impl String {
|
||||||
|
|
||||||
/// Converts this `String` into a <code>[Box]<[str]></code>.
|
/// Converts this `String` into a <code>[Box]<[str]></code>.
|
||||||
///
|
///
|
||||||
/// This will drop any excess capacity.
|
/// Before doing the conversion, this method discards excess capacity like [`shrink_to_fit`].
|
||||||
|
/// Note that this call may reallocate and copy the bytes of the string.
|
||||||
///
|
///
|
||||||
|
/// [`shrink_to_fit`]: String::shrink_to_fit
|
||||||
/// [str]: prim@str "str"
|
/// [str]: prim@str "str"
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
@ -1967,10 +1969,10 @@ impl String {
|
||||||
/// this function is ideally used for data that lives for the remainder of the program's life,
|
/// this function is ideally used for data that lives for the remainder of the program's life,
|
||||||
/// as dropping the returned reference will cause a memory leak.
|
/// as dropping the returned reference will cause a memory leak.
|
||||||
///
|
///
|
||||||
/// It does not reallocate or shrink the `String`,
|
/// It does not reallocate or shrink the `String`, so the leaked allocation may include unused
|
||||||
/// so the leaked allocation may include unused capacity that is not part
|
/// capacity that is not part of the returned slice. If you want to discard excess capacity,
|
||||||
/// of the returned slice. If you don't want that, call [`into_boxed_str`],
|
/// call [`into_boxed_str`], and then [`Box::leak`] instead. However, keep in mind that
|
||||||
/// and then [`Box::leak`].
|
/// trimming the capacity may result in a reallocation and copy.
|
||||||
///
|
///
|
||||||
/// [`into_boxed_str`]: Self::into_boxed_str
|
/// [`into_boxed_str`]: Self::into_boxed_str
|
||||||
///
|
///
|
||||||
|
|
|
@ -2915,7 +2915,6 @@ ui/macros/issue-95267.rs
|
||||||
ui/macros/issue-95533.rs
|
ui/macros/issue-95533.rs
|
||||||
ui/macros/issue-98466-allow.rs
|
ui/macros/issue-98466-allow.rs
|
||||||
ui/macros/issue-98466.rs
|
ui/macros/issue-98466.rs
|
||||||
ui/macros/issue-98790.rs
|
|
||||||
ui/macros/issue-99261.rs
|
ui/macros/issue-99261.rs
|
||||||
ui/macros/issue-99265.rs
|
ui/macros/issue-99265.rs
|
||||||
ui/macros/issue-99907.rs
|
ui/macros/issue-99907.rs
|
||||||
|
|
|
@ -41,6 +41,7 @@ const EXTENSION_EXCEPTION_PATHS: &[&str] = &[
|
||||||
"tests/ui/macros/not-utf8.bin", // testing including data with the include macros
|
"tests/ui/macros/not-utf8.bin", // testing including data with the include macros
|
||||||
"tests/ui/macros/syntax-extension-source-utils-files/includeme.fragment", // more include
|
"tests/ui/macros/syntax-extension-source-utils-files/includeme.fragment", // more include
|
||||||
"tests/ui/proc-macro/auxiliary/included-file.txt", // more include
|
"tests/ui/proc-macro/auxiliary/included-file.txt", // more include
|
||||||
|
"tests/ui/unpretty/auxiliary/data.txt", // more include
|
||||||
"tests/ui/invalid/foo.natvis.xml", // sample debugger visualizer
|
"tests/ui/invalid/foo.natvis.xml", // sample debugger visualizer
|
||||||
"tests/ui/sanitizer/dataflow-abilist.txt", // dataflow sanitizer ABI list file
|
"tests/ui/sanitizer/dataflow-abilist.txt", // dataflow sanitizer ABI list file
|
||||||
"tests/ui/shell-argfiles/shell-argfiles.args", // passing args via a file
|
"tests/ui/shell-argfiles/shell-argfiles.args", // passing args via a file
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
// Fix for <https://github.com/rust-lang/rust/issues/125196>.
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
trait Tr {
|
||||||
|
type Gat<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct W<T>(T);
|
||||||
|
|
||||||
|
fn foo<T: Tr>() where for<'a> &'a T: Tr<Gat<W<i32>> = i32> {
|
||||||
|
let x: <&T as Tr>::Gat<W<_>> = 1i32;
|
||||||
|
// Previously, `match_projection_projections` only checked that
|
||||||
|
// `shallow_resolve(W<?0>) = W<?0>`. This won't prevent *all* inference guidance
|
||||||
|
// from projection predicates in the environment, just ones that guide the
|
||||||
|
// outermost type of each GAT constructor. This is definitely wrong, but there is
|
||||||
|
// code that relies on it in the wild :/
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -1,24 +0,0 @@
|
||||||
//@ run-pass
|
|
||||||
|
|
||||||
macro_rules! stringify_item {
|
|
||||||
($item:item) => {
|
|
||||||
stringify!($item)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! repro {
|
|
||||||
($expr:expr) => {
|
|
||||||
stringify_item! {
|
|
||||||
pub fn repro() -> bool {
|
|
||||||
$expr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
assert_eq!(
|
|
||||||
repro!(match () { () => true } | true),
|
|
||||||
"pub fn repro() -> bool { (match () { () => true, }) | true }"
|
|
||||||
);
|
|
||||||
}
|
|
1
tests/ui/unpretty/auxiliary/data.txt
Normal file
1
tests/ui/unpretty/auxiliary/data.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
data for include_bytes in ../expanded-exhaustive.rs
|
888
tests/ui/unpretty/expanded-exhaustive.rs
Normal file
888
tests/ui/unpretty/expanded-exhaustive.rs
Normal file
|
@ -0,0 +1,888 @@
|
||||||
|
//@ compile-flags: -Zunpretty=expanded -Zunstable-options
|
||||||
|
//@ edition:2024
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
#![feature(auto_traits)]
|
||||||
|
#![feature(box_patterns)]
|
||||||
|
#![feature(builtin_syntax)]
|
||||||
|
#![feature(concat_idents)]
|
||||||
|
#![feature(const_trait_impl)]
|
||||||
|
#![feature(core_pattern_type)]
|
||||||
|
#![feature(decl_macro)]
|
||||||
|
#![feature(deref_patterns)]
|
||||||
|
#![feature(explicit_tail_calls)]
|
||||||
|
#![feature(gen_blocks)]
|
||||||
|
#![feature(let_chains)]
|
||||||
|
#![feature(more_qualified_paths)]
|
||||||
|
#![feature(never_patterns)]
|
||||||
|
#![feature(never_type)]
|
||||||
|
#![feature(pattern_types)]
|
||||||
|
#![feature(prelude_import)]
|
||||||
|
#![feature(raw_ref_op)]
|
||||||
|
#![feature(specialization)]
|
||||||
|
#![feature(trace_macros)]
|
||||||
|
#![feature(trait_alias)]
|
||||||
|
#![feature(try_blocks)]
|
||||||
|
#![feature(unnamed_fields)]
|
||||||
|
#![feature(yeet_expr)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
#[prelude_import]
|
||||||
|
use self::prelude::*;
|
||||||
|
|
||||||
|
mod prelude {
|
||||||
|
pub use std::prelude::rust_2024::*;
|
||||||
|
|
||||||
|
pub type T = _;
|
||||||
|
|
||||||
|
pub trait Trait {
|
||||||
|
const CONST: ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod attributes {
|
||||||
|
//! inner single-line doc comment
|
||||||
|
/*!
|
||||||
|
* inner multi-line doc comment
|
||||||
|
*/
|
||||||
|
#![doc = "inner doc attribute"]
|
||||||
|
#![allow(dead_code, unused_variables)]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
/// outer single-line doc comment
|
||||||
|
/**
|
||||||
|
* outer multi-line doc comment
|
||||||
|
*/
|
||||||
|
#[doc = "outer doc attribute"]
|
||||||
|
#[doc = concat!("mac", "ro")]
|
||||||
|
#[allow()]
|
||||||
|
#[repr(C)]
|
||||||
|
struct Struct;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod expressions {
|
||||||
|
/// ExprKind::Array
|
||||||
|
fn expr_array() {
|
||||||
|
[];
|
||||||
|
[true];
|
||||||
|
[true,];
|
||||||
|
[true, true];
|
||||||
|
["long........................................................................"];
|
||||||
|
["long............................................................", true];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::ConstBlock
|
||||||
|
fn expr_const_block() {
|
||||||
|
const {};
|
||||||
|
const { 1 };
|
||||||
|
const { struct S; };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Call
|
||||||
|
fn expr_call() {
|
||||||
|
let f;
|
||||||
|
f();
|
||||||
|
f::<u8>();
|
||||||
|
f::<1>();
|
||||||
|
f::<'static, u8, 1>();
|
||||||
|
f(true);
|
||||||
|
f(true,);
|
||||||
|
()();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::MethodCall
|
||||||
|
fn expr_method_call() {
|
||||||
|
let x;
|
||||||
|
x.f();
|
||||||
|
x.f::<u8>();
|
||||||
|
x.collect::<Vec<_>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Tup
|
||||||
|
fn expr_tup() {
|
||||||
|
();
|
||||||
|
(true,);
|
||||||
|
(true, false);
|
||||||
|
(true, false,);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Binary
|
||||||
|
fn expr_binary() {
|
||||||
|
let (a, b, c, d, x, y);
|
||||||
|
true || false;
|
||||||
|
true || false && false;
|
||||||
|
a < 1 && 2 < b && c > 3 && 4 > d;
|
||||||
|
a & b & !c;
|
||||||
|
a + b * c - d + -1 * -2 - -3;
|
||||||
|
x = !y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Unary
|
||||||
|
fn expr_unary() {
|
||||||
|
let expr;
|
||||||
|
*expr;
|
||||||
|
!expr;
|
||||||
|
-expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Lit
|
||||||
|
fn expr_lit() {
|
||||||
|
'x';
|
||||||
|
1_000_i8;
|
||||||
|
1.00000000000000000000001;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Cast
|
||||||
|
fn expr_cast() {
|
||||||
|
let expr;
|
||||||
|
expr as T;
|
||||||
|
expr as T<u8>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Type
|
||||||
|
fn expr_type() {
|
||||||
|
let expr;
|
||||||
|
builtin # type_ascribe(expr, T);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Let
|
||||||
|
fn expr_let() {
|
||||||
|
let b;
|
||||||
|
if let Some(a) = b {}
|
||||||
|
if let _ = true && false {}
|
||||||
|
if let _ = (true && false) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::If
|
||||||
|
fn expr_if() {
|
||||||
|
if true {}
|
||||||
|
if !true {}
|
||||||
|
if let true = true {} else {}
|
||||||
|
if true {} else if false {}
|
||||||
|
if true {} else if false {} else {}
|
||||||
|
if true { return; } else if false { 0 } else { 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::While
|
||||||
|
fn expr_while() {
|
||||||
|
while false {}
|
||||||
|
'a: while false {}
|
||||||
|
while let true = true {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::ForLoop
|
||||||
|
fn expr_for_loop() {
|
||||||
|
let x;
|
||||||
|
for _ in x {}
|
||||||
|
'a: for _ in x {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Loop
|
||||||
|
fn expr_loop() {
|
||||||
|
loop {}
|
||||||
|
'a: loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Match
|
||||||
|
fn expr_match() {
|
||||||
|
let value;
|
||||||
|
match value {}
|
||||||
|
match value { ok => 1 }
|
||||||
|
match value {
|
||||||
|
ok => 1,
|
||||||
|
err => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Closure
|
||||||
|
fn expr_closure() {
|
||||||
|
let value;
|
||||||
|
|| {};
|
||||||
|
|x| {};
|
||||||
|
|x: u8| {};
|
||||||
|
|| ();
|
||||||
|
move || value;
|
||||||
|
async || value;
|
||||||
|
async move || value;
|
||||||
|
static || value;
|
||||||
|
static move || value;
|
||||||
|
(static async || value);
|
||||||
|
(static async move || value);
|
||||||
|
|| -> u8 { value };
|
||||||
|
1 + || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Block
|
||||||
|
fn expr_block() {
|
||||||
|
{}
|
||||||
|
unsafe {}
|
||||||
|
'a: {}
|
||||||
|
#[allow()] {}
|
||||||
|
{ #![allow()] }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Gen
|
||||||
|
fn expr_gen() {
|
||||||
|
async {};
|
||||||
|
async move {};
|
||||||
|
gen {};
|
||||||
|
gen move {};
|
||||||
|
async gen {};
|
||||||
|
async gen move {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Await
|
||||||
|
fn expr_await() {
|
||||||
|
let fut;
|
||||||
|
fut.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::TryBlock
|
||||||
|
fn expr_try_block() {
|
||||||
|
try {}
|
||||||
|
try { return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Assign
|
||||||
|
fn expr_assign() {
|
||||||
|
let expr;
|
||||||
|
expr = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::AssignOp
|
||||||
|
fn expr_assign_op() {
|
||||||
|
let expr;
|
||||||
|
expr += true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Field
|
||||||
|
fn expr_field() {
|
||||||
|
let expr;
|
||||||
|
expr.field;
|
||||||
|
expr.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Index
|
||||||
|
fn expr_index() {
|
||||||
|
let expr;
|
||||||
|
expr[true];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Range
|
||||||
|
fn expr_range() {
|
||||||
|
let (lo, hi);
|
||||||
|
..;
|
||||||
|
..hi;
|
||||||
|
lo..;
|
||||||
|
lo..hi;
|
||||||
|
lo .. hi;
|
||||||
|
..=hi;
|
||||||
|
lo..=hi;
|
||||||
|
-2..=-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Underscore
|
||||||
|
fn expr_underscore() {
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Path
|
||||||
|
fn expr_path() {
|
||||||
|
let x;
|
||||||
|
crate::expressions::expr_path;
|
||||||
|
crate::expressions::expr_path::<'static>;
|
||||||
|
<T as Default>::default;
|
||||||
|
<T as ::core::default::Default>::default::<>;
|
||||||
|
x::();
|
||||||
|
x::(T, T) -> T;
|
||||||
|
crate::() -> ()::expressions::() -> ()::expr_path;
|
||||||
|
core::()::marker::()::PhantomData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::AddrOf
|
||||||
|
fn expr_addr_of() {
|
||||||
|
let expr;
|
||||||
|
&expr;
|
||||||
|
&mut expr;
|
||||||
|
&raw const expr;
|
||||||
|
&raw mut expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Break
|
||||||
|
fn expr_break() {
|
||||||
|
'a: {
|
||||||
|
break;
|
||||||
|
break 'a;
|
||||||
|
break true;
|
||||||
|
break 'a true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Continue
|
||||||
|
fn expr_continue() {
|
||||||
|
'a: {
|
||||||
|
continue;
|
||||||
|
continue 'a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Ret
|
||||||
|
fn expr_ret() {
|
||||||
|
return;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::InlineAsm
|
||||||
|
fn expr_inline_asm() {
|
||||||
|
let x;
|
||||||
|
core::arch::asm!(
|
||||||
|
"mov {tmp}, {x}",
|
||||||
|
"shl {tmp}, 1",
|
||||||
|
"shl {x}, 2",
|
||||||
|
"add {x}, {tmp}",
|
||||||
|
x = inout(reg) x,
|
||||||
|
tmp = out(reg) _,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::OffsetOf
|
||||||
|
fn expr_offset_of() {
|
||||||
|
core::mem::offset_of!(T, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::MacCall
|
||||||
|
fn expr_mac_call() {
|
||||||
|
stringify!(...);
|
||||||
|
stringify![...];
|
||||||
|
stringify! { ... };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Struct
|
||||||
|
fn expr_struct() {
|
||||||
|
struct Struct {}
|
||||||
|
let (x, base);
|
||||||
|
Struct {};
|
||||||
|
<Struct as ToOwned>::Owned {};
|
||||||
|
Struct { .. };
|
||||||
|
Struct { .. base };
|
||||||
|
Struct { x };
|
||||||
|
Struct { x, ..base };
|
||||||
|
Struct { x: true };
|
||||||
|
Struct { x: true, .. };
|
||||||
|
Struct { x: true, ..base };
|
||||||
|
Struct { 0: true, ..base };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Repeat
|
||||||
|
fn expr_repeat() {
|
||||||
|
[(); 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Paren
|
||||||
|
fn expr_paren() {
|
||||||
|
let expr;
|
||||||
|
(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Try
|
||||||
|
fn expr_try() {
|
||||||
|
let expr;
|
||||||
|
expr?;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Yield
|
||||||
|
fn expr_yield() {
|
||||||
|
yield;
|
||||||
|
yield true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Yeet
|
||||||
|
fn expr_yeet() {
|
||||||
|
do yeet;
|
||||||
|
do yeet 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Become
|
||||||
|
fn expr_become() {
|
||||||
|
become true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::IncludedBytes
|
||||||
|
fn expr_include_bytes() {
|
||||||
|
include_bytes!("auxiliary/data.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::FormatArgs
|
||||||
|
fn expr_format_args() {
|
||||||
|
let expr;
|
||||||
|
format_args!("");
|
||||||
|
format_args!("{}", expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod items {
|
||||||
|
/// ItemKind::ExternCrate
|
||||||
|
mod item_extern_crate {
|
||||||
|
extern crate core;
|
||||||
|
extern crate self as unpretty;
|
||||||
|
pub extern crate core as _;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::Use
|
||||||
|
mod item_use {
|
||||||
|
use crate::{expressions, items::item_use};
|
||||||
|
pub use core::*;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::Static
|
||||||
|
mod item_static {
|
||||||
|
pub static A: () = {};
|
||||||
|
static mut B: () = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::Const
|
||||||
|
mod item_const {
|
||||||
|
pub const A: () = {};
|
||||||
|
|
||||||
|
trait TraitItems {
|
||||||
|
const B: ();
|
||||||
|
const C: () = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::Fn
|
||||||
|
mod item_fn {
|
||||||
|
pub const unsafe extern "C" fn f() {}
|
||||||
|
pub async unsafe extern fn g() {}
|
||||||
|
fn h<'a, T>() where T: 'a {}
|
||||||
|
|
||||||
|
trait TraitItems {
|
||||||
|
unsafe extern fn f();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TraitItems for _ {
|
||||||
|
default unsafe extern fn f() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::Mod
|
||||||
|
mod item_mod {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::ForeignMod
|
||||||
|
mod item_foreign_mod {
|
||||||
|
extern "C++" {}
|
||||||
|
extern {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::GlobalAsm
|
||||||
|
mod item_global_asm {
|
||||||
|
core::arch::global_asm!(".globl my_asm_func");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::TyAlias
|
||||||
|
mod item_ty_alias {
|
||||||
|
pub type Type<'a> where T: 'a, = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::Enum
|
||||||
|
mod item_enum {
|
||||||
|
pub enum Void {}
|
||||||
|
enum Empty {
|
||||||
|
Unit,
|
||||||
|
Tuple(),
|
||||||
|
Struct {},
|
||||||
|
}
|
||||||
|
enum Generic<'a, T>
|
||||||
|
where
|
||||||
|
T: 'a,
|
||||||
|
{
|
||||||
|
Tuple(T),
|
||||||
|
Struct { t: T },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::Struct
|
||||||
|
mod item_struct {
|
||||||
|
pub struct Unit;
|
||||||
|
struct Tuple();
|
||||||
|
struct Newtype(Unit);
|
||||||
|
struct Struct {}
|
||||||
|
struct Generic<'a, T>
|
||||||
|
where
|
||||||
|
T: 'a,
|
||||||
|
{
|
||||||
|
t: T,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::Union
|
||||||
|
mod item_union {
|
||||||
|
union Generic<'a, T>
|
||||||
|
where
|
||||||
|
T: 'a,
|
||||||
|
{
|
||||||
|
t: T,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::Trait
|
||||||
|
mod item_trait {
|
||||||
|
pub unsafe auto trait Send {}
|
||||||
|
trait Trait<'a>: Sized
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::TraitAlias
|
||||||
|
mod item_trait_alias {
|
||||||
|
pub trait Trait<T> = Sized where for<'a> T: 'a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::Impl
|
||||||
|
mod item_impl {
|
||||||
|
impl () {}
|
||||||
|
impl<T> () {}
|
||||||
|
impl Default for () {}
|
||||||
|
impl<T> const Default for () {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::MacCall
|
||||||
|
mod item_mac_call {
|
||||||
|
trace_macros!(false);
|
||||||
|
trace_macros![false];
|
||||||
|
trace_macros! { false }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::MacroDef
|
||||||
|
mod item_macro_def {
|
||||||
|
macro_rules! mac { () => {...}; }
|
||||||
|
pub macro stringify() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::Delegation
|
||||||
|
mod item_delegation {
|
||||||
|
/*! FIXME: todo */
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ItemKind::DelegationMac
|
||||||
|
mod item_delegation_mac {
|
||||||
|
/*! FIXME: todo */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod patterns {
|
||||||
|
/// PatKind::Wild
|
||||||
|
fn pat_wild() {
|
||||||
|
let _;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Ident
|
||||||
|
fn pat_ident() {
|
||||||
|
let x;
|
||||||
|
let ref x;
|
||||||
|
let mut x;
|
||||||
|
let ref mut x;
|
||||||
|
let ref mut x @ _;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Struct
|
||||||
|
fn pat_struct() {
|
||||||
|
let T {};
|
||||||
|
let T::<T> {};
|
||||||
|
let T::<'static> {};
|
||||||
|
let T { x };
|
||||||
|
let T { x: _x };
|
||||||
|
let T { .. };
|
||||||
|
let T { x, .. };
|
||||||
|
let T { x: _x, .. };
|
||||||
|
let T { 0: _x, .. };
|
||||||
|
let <T as ToOwned>::Owned {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::TupleStruct
|
||||||
|
fn pat_tuple_struct() {
|
||||||
|
struct Tuple();
|
||||||
|
let Tuple();
|
||||||
|
let Tuple::<T>();
|
||||||
|
let Tuple::<'static>();
|
||||||
|
let Tuple(x);
|
||||||
|
let Tuple(..);
|
||||||
|
let Tuple(x, ..);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Or
|
||||||
|
fn pat_or() {
|
||||||
|
let (true | false);
|
||||||
|
let (| true);
|
||||||
|
let (|true| false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Path
|
||||||
|
fn pat_path() {
|
||||||
|
let core::marker::PhantomData;
|
||||||
|
let core::marker::PhantomData::<T>;
|
||||||
|
let core::marker::PhantomData::<'static>;
|
||||||
|
let <T as Trait>::CONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Tuple
|
||||||
|
fn pat_tuple() {
|
||||||
|
let ();
|
||||||
|
let (true,);
|
||||||
|
let (true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Box
|
||||||
|
fn pat_box() {
|
||||||
|
let box pat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Deref
|
||||||
|
fn pat_deref() {
|
||||||
|
let deref!(pat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Ref
|
||||||
|
fn pat_ref() {
|
||||||
|
let &pat;
|
||||||
|
let &mut pat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Lit
|
||||||
|
fn pat_lit() {
|
||||||
|
let 1_000_i8;
|
||||||
|
let -"";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Range
|
||||||
|
fn pat_range() {
|
||||||
|
let ..1;
|
||||||
|
let 0..;
|
||||||
|
let 0..1;
|
||||||
|
let 0..=1;
|
||||||
|
let -2..=-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Slice
|
||||||
|
fn pat_slice() {
|
||||||
|
let [];
|
||||||
|
let [true];
|
||||||
|
let [true,];
|
||||||
|
let [true, false];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Rest
|
||||||
|
fn pat_rest() {
|
||||||
|
let ..;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Never
|
||||||
|
fn pat_never() {
|
||||||
|
let !;
|
||||||
|
let Some(!);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::Paren
|
||||||
|
fn pat_paren() {
|
||||||
|
let (pat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PatKind::MacCall
|
||||||
|
fn pat_mac_call() {
|
||||||
|
let stringify!();
|
||||||
|
let stringify![];
|
||||||
|
let stringify! {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod statements {
|
||||||
|
/// StmtKind::Let
|
||||||
|
fn stmt_let() {
|
||||||
|
let _;
|
||||||
|
let _ = true;
|
||||||
|
let _: T = true;
|
||||||
|
let _ = true else { return; };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// StmtKind::Item
|
||||||
|
fn stmt_item() {
|
||||||
|
struct Struct {}
|
||||||
|
struct Unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// StmtKind::Expr
|
||||||
|
fn stmt_expr() {
|
||||||
|
()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// StmtKind::Semi
|
||||||
|
fn stmt_semi() {
|
||||||
|
1 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// StmtKind::Empty
|
||||||
|
fn stmt_empty() {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// StmtKind::MacCall
|
||||||
|
fn stmt_mac_call() {
|
||||||
|
stringify!(...);
|
||||||
|
stringify![...];
|
||||||
|
stringify! { ... };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod types {
|
||||||
|
/// TyKind::Slice
|
||||||
|
fn ty_slice() {
|
||||||
|
let _: [T];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::Array
|
||||||
|
fn ty_array() {
|
||||||
|
let _: [T; 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::Ptr
|
||||||
|
fn ty_ptr() {
|
||||||
|
let _: *const T;
|
||||||
|
let _: *mut T;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::Ref
|
||||||
|
fn ty_ref() {
|
||||||
|
let _: &T;
|
||||||
|
let _: &mut T;
|
||||||
|
let _: &'static T;
|
||||||
|
let _: &'static mut [T];
|
||||||
|
let _: &T<T<T<T<T>>>>;
|
||||||
|
let _: &T<T<T<T<T> > > >;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::BareFn
|
||||||
|
fn ty_bare_fn() {
|
||||||
|
let _: fn();
|
||||||
|
let _: fn() -> ();
|
||||||
|
let _: fn(T);
|
||||||
|
let _: fn(t: T);
|
||||||
|
let _: for<> fn();
|
||||||
|
let _: for<'a> fn();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::Never
|
||||||
|
fn ty_never() {
|
||||||
|
let _: !;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::Tup
|
||||||
|
fn ty_tup() {
|
||||||
|
let _: ();
|
||||||
|
let _: (T,);
|
||||||
|
let _: (T, T);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::AnonStruct
|
||||||
|
fn ty_anon_struct() {
|
||||||
|
struct Struct {
|
||||||
|
_: struct { t: T },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::AnonUnion
|
||||||
|
fn ty_anon_union() {
|
||||||
|
struct Struct {
|
||||||
|
_: union { t: T },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::Path
|
||||||
|
fn ty_path() {
|
||||||
|
let _: T;
|
||||||
|
let _: T<'static>;
|
||||||
|
let _: T<T>;
|
||||||
|
let _: T::<T>;
|
||||||
|
let _: T() -> !;
|
||||||
|
let _: <T as ToOwned>::Owned;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::TraitObject
|
||||||
|
fn ty_trait_object() {
|
||||||
|
let _: dyn Send;
|
||||||
|
let _: dyn Send + 'static;
|
||||||
|
let _: dyn 'static + Send;
|
||||||
|
let _: dyn for<'a> Send;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::ImplTrait
|
||||||
|
const fn ty_impl_trait() {
|
||||||
|
let _: impl Send;
|
||||||
|
let _: impl Send + 'static;
|
||||||
|
let _: impl 'static + Send;
|
||||||
|
let _: impl ?Sized;
|
||||||
|
let _: impl ~const Clone;
|
||||||
|
let _: impl for<'a> Send;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::Paren
|
||||||
|
fn ty_paren() {
|
||||||
|
let _: (T);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::Typeof
|
||||||
|
fn ty_typeof() {
|
||||||
|
/*! unused for now */
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::Infer
|
||||||
|
fn ty_infer() {
|
||||||
|
let _: _;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::ImplicitSelf
|
||||||
|
fn ty_implicit_self() {
|
||||||
|
/*! there is no syntax for this */
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::MacCall
|
||||||
|
fn ty_mac_call() {
|
||||||
|
let _: concat_idents!(T);
|
||||||
|
let _: concat_idents![T];
|
||||||
|
let _: concat_idents! { T };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::CVarArgs
|
||||||
|
fn ty_c_var_args() {
|
||||||
|
/*! FIXME: todo */
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TyKind::Pat
|
||||||
|
fn ty_pat() {
|
||||||
|
let _: core::pattern_type!(u32 is 1..);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod visibilities {
|
||||||
|
/// VisibilityKind::Public
|
||||||
|
mod visibility_public {
|
||||||
|
pub struct Pub;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// VisibilityKind::Restricted
|
||||||
|
mod visibility_restricted {
|
||||||
|
pub(crate) struct PubCrate;
|
||||||
|
pub(self) struct PubSelf;
|
||||||
|
pub(super) struct PubSuper;
|
||||||
|
pub(in crate) struct PubInCrate;
|
||||||
|
pub(in self) struct PubInSelf;
|
||||||
|
pub(in super) struct PubInSuper;
|
||||||
|
pub(in crate::visibilities) struct PubInCrateVisibilities;
|
||||||
|
pub(in self::super) struct PubInSelfSuper;
|
||||||
|
pub(in super::visibility_restricted) struct PubInSuperMod;
|
||||||
|
}
|
||||||
|
}
|
719
tests/ui/unpretty/expanded-exhaustive.stdout
Normal file
719
tests/ui/unpretty/expanded-exhaustive.stdout
Normal file
|
@ -0,0 +1,719 @@
|
||||||
|
#![feature(prelude_import)]
|
||||||
|
//@ compile-flags: -Zunpretty=expanded -Zunstable-options
|
||||||
|
//@ edition:2024
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(async_closure)]
|
||||||
|
#![feature(auto_traits)]
|
||||||
|
#![feature(box_patterns)]
|
||||||
|
#![feature(builtin_syntax)]
|
||||||
|
#![feature(concat_idents)]
|
||||||
|
#![feature(const_trait_impl)]
|
||||||
|
#![feature(core_pattern_type)]
|
||||||
|
#![feature(decl_macro)]
|
||||||
|
#![feature(deref_patterns)]
|
||||||
|
#![feature(explicit_tail_calls)]
|
||||||
|
#![feature(gen_blocks)]
|
||||||
|
#![feature(let_chains)]
|
||||||
|
#![feature(more_qualified_paths)]
|
||||||
|
#![feature(never_patterns)]
|
||||||
|
#![feature(never_type)]
|
||||||
|
#![feature(pattern_types)]
|
||||||
|
#![feature(prelude_import)]
|
||||||
|
#![feature(raw_ref_op)]
|
||||||
|
#![feature(specialization)]
|
||||||
|
#![feature(trace_macros)]
|
||||||
|
#![feature(trait_alias)]
|
||||||
|
#![feature(try_blocks)]
|
||||||
|
#![feature(unnamed_fields)]
|
||||||
|
#![feature(yeet_expr)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
#[prelude_import]
|
||||||
|
use std::prelude::rust_2024::*;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate std;
|
||||||
|
|
||||||
|
#[prelude_import]
|
||||||
|
use self::prelude::*;
|
||||||
|
|
||||||
|
mod prelude {
|
||||||
|
pub use std::prelude::rust_2024::*;
|
||||||
|
|
||||||
|
pub type T = _;
|
||||||
|
|
||||||
|
pub trait Trait {
|
||||||
|
const CONST: ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod attributes {
|
||||||
|
//! inner single-line doc comment
|
||||||
|
/*!
|
||||||
|
* inner multi-line doc comment
|
||||||
|
*/
|
||||||
|
#![doc = "inner doc attribute"]
|
||||||
|
#![allow(dead_code, unused_variables)]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
/// outer single-line doc comment
|
||||||
|
/**
|
||||||
|
* outer multi-line doc comment
|
||||||
|
*/
|
||||||
|
#[doc = "outer doc attribute"]
|
||||||
|
#[doc = "macro"]
|
||||||
|
#[allow()]
|
||||||
|
#[repr(C)]
|
||||||
|
struct Struct;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod expressions {
|
||||||
|
/// ExprKind::Array
|
||||||
|
fn expr_array() {
|
||||||
|
[];
|
||||||
|
[true];
|
||||||
|
[true];
|
||||||
|
[true, true];
|
||||||
|
["long........................................................................"];
|
||||||
|
["long............................................................",
|
||||||
|
true];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::ConstBlock
|
||||||
|
fn expr_const_block() {
|
||||||
|
const {};
|
||||||
|
const { 1 };
|
||||||
|
const {
|
||||||
|
struct S;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Call
|
||||||
|
fn expr_call() {
|
||||||
|
let f;
|
||||||
|
f();
|
||||||
|
f::<u8>();
|
||||||
|
f::<1>();
|
||||||
|
f::<'static, u8, 1>();
|
||||||
|
f(true);
|
||||||
|
f(true);
|
||||||
|
()();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::MethodCall
|
||||||
|
fn expr_method_call() {
|
||||||
|
let x;
|
||||||
|
x.f();
|
||||||
|
x.f::<u8>();
|
||||||
|
x.collect::<Vec<_>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Tup
|
||||||
|
fn expr_tup() { (); (true,); (true, false); (true, false); }
|
||||||
|
|
||||||
|
/// ExprKind::Binary
|
||||||
|
fn expr_binary() {
|
||||||
|
let (a, b, c, d, x, y);
|
||||||
|
true || false;
|
||||||
|
true || false && false;
|
||||||
|
a < 1 && 2 < b && c > 3 && 4 > d;
|
||||||
|
a & b & !c;
|
||||||
|
a + b * c - d + -1 * -2 - -3;
|
||||||
|
x = !y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Unary
|
||||||
|
fn expr_unary() { let expr; *expr; !expr; -expr; }
|
||||||
|
|
||||||
|
/// ExprKind::Lit
|
||||||
|
fn expr_lit() { 'x'; 1_000_i8; 1.00000000000000000000001; }
|
||||||
|
|
||||||
|
/// ExprKind::Cast
|
||||||
|
fn expr_cast() { let expr; expr as T; expr as T<u8>; }
|
||||||
|
|
||||||
|
/// ExprKind::Type
|
||||||
|
fn expr_type() { let expr; builtin # type_ascribe(expr, T); }
|
||||||
|
|
||||||
|
/// ExprKind::Let
|
||||||
|
fn expr_let() {
|
||||||
|
let b;
|
||||||
|
if let Some(a) = b {}
|
||||||
|
if let _ = true && false {}
|
||||||
|
if let _ = (true && false) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::If
|
||||||
|
fn expr_if() {
|
||||||
|
if true {}
|
||||||
|
if !true {}
|
||||||
|
if let true = true {} else {}
|
||||||
|
if true {} else if false {}
|
||||||
|
if true {} else if false {} else {}
|
||||||
|
if true { return; } else if false { 0 } else { 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::While
|
||||||
|
fn expr_while() {
|
||||||
|
while false {}
|
||||||
|
'a: while false {}
|
||||||
|
while let true = true {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::ForLoop
|
||||||
|
fn expr_for_loop() { let x; for _ in x {} 'a: for _ in x {} }
|
||||||
|
|
||||||
|
/// ExprKind::Loop
|
||||||
|
fn expr_loop() { loop {} 'a: loop {} }
|
||||||
|
|
||||||
|
/// ExprKind::Match
|
||||||
|
fn expr_match() {
|
||||||
|
let value;
|
||||||
|
match value {}
|
||||||
|
match value { ok => 1, }
|
||||||
|
match value { ok => 1, err => 0, }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Closure
|
||||||
|
fn expr_closure() {
|
||||||
|
let value;
|
||||||
|
|| {};
|
||||||
|
|x| {};
|
||||||
|
|x: u8| {};
|
||||||
|
|| ();
|
||||||
|
move || value;
|
||||||
|
async || value;
|
||||||
|
async move || value;
|
||||||
|
static || value;
|
||||||
|
static move || value;
|
||||||
|
(static async || value);
|
||||||
|
(static async move || value);
|
||||||
|
|| -> u8 { value };
|
||||||
|
1 + (|| {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Block
|
||||||
|
fn expr_block() {
|
||||||
|
{}
|
||||||
|
unsafe {}
|
||||||
|
'a: {}
|
||||||
|
|
||||||
|
#[allow()]
|
||||||
|
{}
|
||||||
|
{
|
||||||
|
#![allow()]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Gen
|
||||||
|
fn expr_gen() {
|
||||||
|
async {};
|
||||||
|
async move {};
|
||||||
|
gen {};
|
||||||
|
gen move {};
|
||||||
|
async gen {};
|
||||||
|
async gen move {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Await
|
||||||
|
fn expr_await() { let fut; fut.await; }
|
||||||
|
|
||||||
|
/// ExprKind::TryBlock
|
||||||
|
fn expr_try_block() { try {} try { return; } }
|
||||||
|
|
||||||
|
/// ExprKind::Assign
|
||||||
|
fn expr_assign() { let expr; expr = true; }
|
||||||
|
|
||||||
|
/// ExprKind::AssignOp
|
||||||
|
fn expr_assign_op() { let expr; expr += true; }
|
||||||
|
|
||||||
|
/// ExprKind::Field
|
||||||
|
fn expr_field() { let expr; expr.field; expr.0; }
|
||||||
|
|
||||||
|
/// ExprKind::Index
|
||||||
|
fn expr_index() { let expr; expr[true]; }
|
||||||
|
|
||||||
|
/// ExprKind::Range
|
||||||
|
fn expr_range() {
|
||||||
|
let (lo, hi);
|
||||||
|
..;
|
||||||
|
..hi;
|
||||||
|
lo..;
|
||||||
|
lo..hi;
|
||||||
|
lo..hi;
|
||||||
|
..=hi;
|
||||||
|
lo..=hi;
|
||||||
|
-2..=-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Underscore
|
||||||
|
fn expr_underscore() { _; }
|
||||||
|
|
||||||
|
/// ExprKind::Path
|
||||||
|
fn expr_path() {
|
||||||
|
let x;
|
||||||
|
crate::expressions::expr_path;
|
||||||
|
crate::expressions::expr_path::<'static>;
|
||||||
|
<T as Default>::default;
|
||||||
|
<T as ::core::default::Default>::default::<>;
|
||||||
|
x::();
|
||||||
|
x::(T, T) -> T;
|
||||||
|
crate::() -> ()::expressions::() -> ()::expr_path;
|
||||||
|
core::()::marker::()::PhantomData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::AddrOf
|
||||||
|
fn expr_addr_of() {
|
||||||
|
let expr;
|
||||||
|
&expr;
|
||||||
|
&mut expr;
|
||||||
|
&raw const expr;
|
||||||
|
&raw mut expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::Break
|
||||||
|
fn expr_break() { 'a: { break; break 'a; break true; break 'a true; } }
|
||||||
|
|
||||||
|
/// ExprKind::Continue
|
||||||
|
fn expr_continue() { 'a: { continue; continue 'a; } }
|
||||||
|
|
||||||
|
/// ExprKind::Ret
|
||||||
|
fn expr_ret() { return; return true; }
|
||||||
|
|
||||||
|
/// ExprKind::InlineAsm
|
||||||
|
fn expr_inline_asm() {
|
||||||
|
let x;
|
||||||
|
asm!("mov {1}, {0}\nshl {1}, 1\nshl {0}, 2\nadd {0}, {1}",
|
||||||
|
inout(reg)
|
||||||
|
x,
|
||||||
|
out(reg)
|
||||||
|
_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ExprKind::OffsetOf
|
||||||
|
fn expr_offset_of() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{ builtin # offset_of(T, field) };
|
||||||
|
}
|
||||||
|
/// ExprKind::MacCall
|
||||||
|
fn expr_mac_call() { "..."; "..."; "..."; }
|
||||||
|
/// ExprKind::Struct
|
||||||
|
fn expr_struct() {
|
||||||
|
struct Struct {}
|
||||||
|
let (x, base);
|
||||||
|
Struct {};
|
||||||
|
<Struct as ToOwned>::Owned {};
|
||||||
|
Struct { .. };
|
||||||
|
Struct { ..base };
|
||||||
|
Struct { x };
|
||||||
|
Struct { x, ..base };
|
||||||
|
Struct { x: true };
|
||||||
|
Struct { x: true, .. };
|
||||||
|
Struct { x: true, ..base };
|
||||||
|
Struct { 0: true, ..base };
|
||||||
|
}
|
||||||
|
/// ExprKind::Repeat
|
||||||
|
fn expr_repeat() { [(); 0]; }
|
||||||
|
/// ExprKind::Paren
|
||||||
|
fn expr_paren() { let expr; (expr); }
|
||||||
|
/// ExprKind::Try
|
||||||
|
fn expr_try() { let expr; expr?; }
|
||||||
|
/// ExprKind::Yield
|
||||||
|
fn expr_yield() { yield; yield true; }
|
||||||
|
/// ExprKind::Yeet
|
||||||
|
fn expr_yeet() { do yeet; do yeet 0; }
|
||||||
|
/// ExprKind::Become
|
||||||
|
fn expr_become() { become true; }
|
||||||
|
/// ExprKind::IncludedBytes
|
||||||
|
fn expr_include_bytes() {
|
||||||
|
b"data for include_bytes in ../expanded-exhaustive.rs\n";
|
||||||
|
}
|
||||||
|
/// ExprKind::FormatArgs
|
||||||
|
fn expr_format_args() {
|
||||||
|
let expr;
|
||||||
|
format_args!("");
|
||||||
|
format_args!("{0}", expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mod items {
|
||||||
|
/// ItemKind::ExternCrate
|
||||||
|
mod item_extern_crate {
|
||||||
|
extern crate core;
|
||||||
|
extern crate self as unpretty;
|
||||||
|
pub extern crate core as _;
|
||||||
|
}
|
||||||
|
/// ItemKind::Use
|
||||||
|
mod item_use {
|
||||||
|
use crate::{expressions, items::item_use};
|
||||||
|
pub use core::*;
|
||||||
|
}
|
||||||
|
/// ItemKind::Static
|
||||||
|
mod item_static {
|
||||||
|
pub static A: () = {};
|
||||||
|
static mut B: () = {};
|
||||||
|
}
|
||||||
|
/// ItemKind::Const
|
||||||
|
mod item_const {
|
||||||
|
pub const A: () = {};
|
||||||
|
trait TraitItems {
|
||||||
|
const B: ();
|
||||||
|
const C: () = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// ItemKind::Fn
|
||||||
|
mod item_fn {
|
||||||
|
pub const unsafe extern "C" fn f() {}
|
||||||
|
pub async unsafe extern fn g() {}
|
||||||
|
fn h<'a, T>() where T: 'a {}
|
||||||
|
trait TraitItems {
|
||||||
|
unsafe extern fn f();
|
||||||
|
}
|
||||||
|
impl TraitItems for _ {
|
||||||
|
default unsafe extern fn f() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// ItemKind::Mod
|
||||||
|
mod item_mod { }
|
||||||
|
/// ItemKind::ForeignMod
|
||||||
|
mod item_foreign_mod {
|
||||||
|
extern "C++" {}
|
||||||
|
extern {}
|
||||||
|
}
|
||||||
|
/// ItemKind::GlobalAsm
|
||||||
|
mod item_global_asm {
|
||||||
|
global_asm! (".globl my_asm_func");
|
||||||
|
}
|
||||||
|
/// ItemKind::TyAlias
|
||||||
|
mod item_ty_alias {
|
||||||
|
pub type Type<'a> where T: 'a = T;
|
||||||
|
}
|
||||||
|
/// ItemKind::Enum
|
||||||
|
mod item_enum {
|
||||||
|
pub enum Void {}
|
||||||
|
enum Empty { Unit, Tuple(), Struct {}, }
|
||||||
|
enum Generic<'a, T> where T: 'a {
|
||||||
|
Tuple(T),
|
||||||
|
Struct {
|
||||||
|
t: T,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// ItemKind::Struct
|
||||||
|
mod item_struct {
|
||||||
|
pub struct Unit;
|
||||||
|
struct Tuple();
|
||||||
|
struct Newtype(Unit);
|
||||||
|
struct Struct {}
|
||||||
|
struct Generic<'a, T> where T: 'a {
|
||||||
|
t: T,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// ItemKind::Union
|
||||||
|
mod item_union {
|
||||||
|
union Generic<'a, T> where T: 'a {
|
||||||
|
t: T,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// ItemKind::Trait
|
||||||
|
mod item_trait {
|
||||||
|
pub unsafe auto trait Send {}
|
||||||
|
trait Trait<'a>: Sized where Self: 'a {}
|
||||||
|
}
|
||||||
|
/// ItemKind::TraitAlias
|
||||||
|
mod item_trait_alias {
|
||||||
|
pub trait Trait<T> = Sized where for<'a> T: 'a;
|
||||||
|
}
|
||||||
|
/// ItemKind::Impl
|
||||||
|
mod item_impl {
|
||||||
|
impl () {}
|
||||||
|
impl<T> () {}
|
||||||
|
impl Default for () {}
|
||||||
|
impl<T> const Default for () {}
|
||||||
|
}
|
||||||
|
/// ItemKind::MacCall
|
||||||
|
mod item_mac_call { }
|
||||||
|
/// ItemKind::MacroDef
|
||||||
|
mod item_macro_def {
|
||||||
|
macro_rules! mac { () => { ... }; }
|
||||||
|
pub macro stringify { () => {} }
|
||||||
|
}
|
||||||
|
/// ItemKind::Delegation
|
||||||
|
mod item_delegation {
|
||||||
|
/*! FIXME: todo */
|
||||||
|
}
|
||||||
|
/// ItemKind::DelegationMac
|
||||||
|
mod item_delegation_mac {
|
||||||
|
/*! FIXME: todo */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mod patterns {
|
||||||
|
/// PatKind::Wild
|
||||||
|
fn pat_wild() { let _; }
|
||||||
|
/// PatKind::Ident
|
||||||
|
fn pat_ident() {
|
||||||
|
let x;
|
||||||
|
let ref x;
|
||||||
|
let mut x;
|
||||||
|
let ref mut x;
|
||||||
|
let ref mut x @ _;
|
||||||
|
}
|
||||||
|
/// PatKind::Struct
|
||||||
|
fn pat_struct() {
|
||||||
|
let T {};
|
||||||
|
let T::<T> {};
|
||||||
|
let T::<'static> {};
|
||||||
|
let T { x };
|
||||||
|
let T { x: _x };
|
||||||
|
let T { .. };
|
||||||
|
let T { x, .. };
|
||||||
|
let T { x: _x, .. };
|
||||||
|
let T { 0: _x, .. };
|
||||||
|
let <T as ToOwned>::Owned {};
|
||||||
|
}
|
||||||
|
/// PatKind::TupleStruct
|
||||||
|
fn pat_tuple_struct() {
|
||||||
|
struct Tuple();
|
||||||
|
let Tuple();
|
||||||
|
let Tuple::<T>();
|
||||||
|
let Tuple::<'static>();
|
||||||
|
let Tuple(x);
|
||||||
|
let Tuple(..);
|
||||||
|
let Tuple(x, ..);
|
||||||
|
}
|
||||||
|
/// PatKind::Or
|
||||||
|
fn pat_or() { let (true | false); let (true); let (true | false); }
|
||||||
|
/// PatKind::Path
|
||||||
|
fn pat_path() {
|
||||||
|
let core::marker::PhantomData;
|
||||||
|
let core::marker::PhantomData::<T>;
|
||||||
|
let core::marker::PhantomData::<'static>;
|
||||||
|
let <T as Trait>::CONST;
|
||||||
|
}
|
||||||
|
/// PatKind::Tuple
|
||||||
|
fn pat_tuple() { let (); let (true,); let (true, false); }
|
||||||
|
/// PatKind::Box
|
||||||
|
fn pat_box() { let box pat; }
|
||||||
|
/// PatKind::Deref
|
||||||
|
fn pat_deref() { let deref!(pat); }
|
||||||
|
/// PatKind::Ref
|
||||||
|
fn pat_ref() { let &pat; let &mut pat; }
|
||||||
|
/// PatKind::Lit
|
||||||
|
fn pat_lit() { let 1_000_i8; let -""; }
|
||||||
|
/// PatKind::Range
|
||||||
|
fn pat_range() { let ..1; let 0..; let 0..1; let 0..=1; let -2..=-1; }
|
||||||
|
/// PatKind::Slice
|
||||||
|
fn pat_slice() { let []; let [true]; let [true]; let [true, false]; }
|
||||||
|
/// PatKind::Rest
|
||||||
|
fn pat_rest() { let ..; }
|
||||||
|
/// PatKind::Never
|
||||||
|
fn pat_never() { let !; let Some(!); }
|
||||||
|
/// PatKind::Paren
|
||||||
|
fn pat_paren() { let (pat); }
|
||||||
|
/// PatKind::MacCall
|
||||||
|
fn pat_mac_call() { let ""; let ""; let ""; }
|
||||||
|
}
|
||||||
|
mod statements {
|
||||||
|
/// StmtKind::Let
|
||||||
|
fn stmt_let() {
|
||||||
|
let _;
|
||||||
|
let _ = true;
|
||||||
|
let _: T = true;
|
||||||
|
let _ = true else { return; };
|
||||||
|
}
|
||||||
|
/// StmtKind::Item
|
||||||
|
fn stmt_item() {
|
||||||
|
struct Struct {}
|
||||||
|
struct Unit;
|
||||||
|
}
|
||||||
|
/// StmtKind::Expr
|
||||||
|
fn stmt_expr() { () }
|
||||||
|
/// StmtKind::Semi
|
||||||
|
fn stmt_semi() { 1 + 1; }
|
||||||
|
/// StmtKind::Empty
|
||||||
|
fn stmt_empty() { ; }
|
||||||
|
/// StmtKind::MacCall
|
||||||
|
fn stmt_mac_call() { "..."; "..."; "..."; }
|
||||||
|
}
|
||||||
|
mod types {
|
||||||
|
/// TyKind::Slice
|
||||||
|
fn ty_slice() { let _: [T]; }
|
||||||
|
/// TyKind::Array
|
||||||
|
fn ty_array() { let _: [T; 0]; }
|
||||||
|
/// TyKind::Ptr
|
||||||
|
fn ty_ptr() { let _: *const T; let _: *mut T; }
|
||||||
|
/// TyKind::Ref
|
||||||
|
fn ty_ref() {
|
||||||
|
let _: &T;
|
||||||
|
let _: &mut T;
|
||||||
|
let _: &'static T;
|
||||||
|
let _: &'static mut [T];
|
||||||
|
let _: &T<T<T<T<T>>>>;
|
||||||
|
let _: &T<T<T<T<T>>>>;
|
||||||
|
}
|
||||||
|
/// TyKind::BareFn
|
||||||
|
fn ty_bare_fn() {
|
||||||
|
let _: fn();
|
||||||
|
let _: fn() -> ();
|
||||||
|
let _: fn(T);
|
||||||
|
let _: fn(t: T);
|
||||||
|
let _: fn();
|
||||||
|
let _: for<'a> fn();
|
||||||
|
}
|
||||||
|
/// TyKind::Never
|
||||||
|
fn ty_never() { let _: !; }
|
||||||
|
/// TyKind::Tup
|
||||||
|
fn ty_tup() { let _: (); let _: (T,); let _: (T, T); }
|
||||||
|
/// TyKind::AnonStruct
|
||||||
|
fn ty_anon_struct() {
|
||||||
|
struct Struct {
|
||||||
|
_: struct {
|
||||||
|
t: T,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// TyKind::AnonUnion
|
||||||
|
fn ty_anon_union() {
|
||||||
|
struct Struct {
|
||||||
|
_: union {
|
||||||
|
t: T,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// TyKind::Path
|
||||||
|
fn ty_path() {
|
||||||
|
let _: T;
|
||||||
|
let _: T<'static>;
|
||||||
|
let _: T<T>;
|
||||||
|
let _: T<T>;
|
||||||
|
let _: T() -> !;
|
||||||
|
let _: <T as ToOwned>::Owned;
|
||||||
|
}
|
||||||
|
/// TyKind::TraitObject
|
||||||
|
fn ty_trait_object() {
|
||||||
|
let _: dyn Send;
|
||||||
|
let _: dyn Send + 'static;
|
||||||
|
let _: dyn 'static + Send;
|
||||||
|
let _: dyn for<'a> Send;
|
||||||
|
}
|
||||||
|
/// TyKind::ImplTrait
|
||||||
|
const fn ty_impl_trait() {
|
||||||
|
let _: impl Send;
|
||||||
|
let _: impl Send + 'static;
|
||||||
|
let _: impl 'static + Send;
|
||||||
|
let _: impl ?Sized;
|
||||||
|
let _: impl ~const Clone;
|
||||||
|
let _: impl for<'a> Send;
|
||||||
|
}
|
||||||
|
/// TyKind::Paren
|
||||||
|
fn ty_paren() { let _: (T); }
|
||||||
|
/// TyKind::Typeof
|
||||||
|
fn ty_typeof() {
|
||||||
|
/*! unused for now */
|
||||||
|
}
|
||||||
|
/// TyKind::Infer
|
||||||
|
fn ty_infer() { let _: _; }
|
||||||
|
/// TyKind::ImplicitSelf
|
||||||
|
fn ty_implicit_self() {
|
||||||
|
/*! there is no syntax for this */
|
||||||
|
}
|
||||||
|
/// TyKind::MacCall
|
||||||
|
fn ty_mac_call() { let _: T; let _: T; let _: T; }
|
||||||
|
/// TyKind::CVarArgs
|
||||||
|
fn ty_c_var_args() {
|
||||||
|
/*! FIXME: todo */
|
||||||
|
}
|
||||||
|
/// TyKind::Pat
|
||||||
|
fn ty_pat() { let _: u32 is 1..; }
|
||||||
|
}
|
||||||
|
mod visibilities {
|
||||||
|
/// VisibilityKind::Public
|
||||||
|
mod visibility_public {
|
||||||
|
pub struct Pub;
|
||||||
|
}
|
||||||
|
/// VisibilityKind::Restricted
|
||||||
|
mod visibility_restricted {
|
||||||
|
pub(crate) struct PubCrate;
|
||||||
|
pub(self) struct PubSelf;
|
||||||
|
pub(super) struct PubSuper;
|
||||||
|
pub(in crate) struct PubInCrate;
|
||||||
|
pub(in self) struct PubInSelf;
|
||||||
|
pub(in super) struct PubInSuper;
|
||||||
|
pub(in crate::visibilities) struct PubInCrateVisibilities;
|
||||||
|
pub(in self::super) struct PubInSelfSuper;
|
||||||
|
pub(in super::visibility_restricted) struct PubInSuperMod;
|
||||||
|
}
|
||||||
|
}
|
106
tests/ui/unpretty/expanded-interpolation.rs
Normal file
106
tests/ui/unpretty/expanded-interpolation.rs
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
//@ compile-flags: -Zunpretty=expanded
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// This test covers the AST pretty-printer's insertion of parentheses in some
|
||||||
|
// macro metavariable edge cases. Synthetic parentheses (i.e. not appearing in
|
||||||
|
// the syntax tree) need to be printed in order for the printed code to be valid
|
||||||
|
// Rust syntax. We also test negative cases: the pretty-printer should not be
|
||||||
|
// synthesizing parentheses indiscriminately; only where necessary.
|
||||||
|
|
||||||
|
#![feature(let_chains)]
|
||||||
|
#![feature(if_let_guard)]
|
||||||
|
|
||||||
|
macro_rules! expr {
|
||||||
|
($expr:expr) => { $expr };
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! stmt {
|
||||||
|
($stmt:stmt) => { $stmt };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if_let() {
|
||||||
|
macro_rules! if_let {
|
||||||
|
($pat:pat, $expr:expr) => {
|
||||||
|
if let $pat = $expr {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if let no_paren = true && false {}
|
||||||
|
if_let!(paren_around_binary, true && false);
|
||||||
|
if_let!(no_paren, true);
|
||||||
|
|
||||||
|
struct Struct {}
|
||||||
|
match () {
|
||||||
|
_ if let no_paren = Struct {} => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn let_else() {
|
||||||
|
let no_paren = expr!(1 + 1) else { return; };
|
||||||
|
let paren_around_loop = expr!(loop {}) else { return; };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn local() {
|
||||||
|
macro_rules! let_expr_minus_one {
|
||||||
|
($pat:pat, $expr:expr) => {
|
||||||
|
let $pat = $expr - 1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let void;
|
||||||
|
let_expr_minus_one!(no_paren, match void {});
|
||||||
|
|
||||||
|
macro_rules! let_expr_else_return {
|
||||||
|
($pat:pat, $expr:expr) => {
|
||||||
|
let $pat = $expr else { return; };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let_expr_else_return!(no_paren, void());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_arm() {
|
||||||
|
macro_rules! match_arm {
|
||||||
|
($pat:pat, $expr:expr) => {
|
||||||
|
match () { $pat => $expr }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
match_arm!(no_paren, 1 - 1);
|
||||||
|
match_arm!(paren_around_brace, { 1 } - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://github.com/rust-lang/rust/issues/98790
|
||||||
|
fn stmt_boundary() {
|
||||||
|
macro_rules! expr_as_stmt {
|
||||||
|
($expr:expr) => {
|
||||||
|
stmt!($expr)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let paren_around_match;
|
||||||
|
expr_as_stmt!(match paren_around_match {} | true);
|
||||||
|
|
||||||
|
macro_rules! minus_one {
|
||||||
|
($expr:expr) => {
|
||||||
|
expr_as_stmt!($expr - 1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let (no_paren, paren_around_loop);
|
||||||
|
minus_one!(no_paren);
|
||||||
|
minus_one!(match paren_around_match {});
|
||||||
|
minus_one!(match paren_around_match {}());
|
||||||
|
minus_one!(match paren_around_match {}[0]);
|
||||||
|
minus_one!(loop { break paren_around_loop; });
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vis_inherited() {
|
||||||
|
macro_rules! vis_inherited {
|
||||||
|
($vis:vis struct) => {
|
||||||
|
$vis struct Struct;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
vis_inherited!(struct);
|
||||||
|
}
|
92
tests/ui/unpretty/expanded-interpolation.stdout
Normal file
92
tests/ui/unpretty/expanded-interpolation.stdout
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
#![feature(prelude_import)]
|
||||||
|
#![no_std]
|
||||||
|
//@ compile-flags: -Zunpretty=expanded
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// This test covers the AST pretty-printer's insertion of parentheses in some
|
||||||
|
// macro metavariable edge cases. Synthetic parentheses (i.e. not appearing in
|
||||||
|
// the syntax tree) need to be printed in order for the printed code to be valid
|
||||||
|
// Rust syntax. We also test negative cases: the pretty-printer should not be
|
||||||
|
// synthesizing parentheses indiscriminately; only where necessary.
|
||||||
|
|
||||||
|
#![feature(let_chains)]
|
||||||
|
#![feature(if_let_guard)]
|
||||||
|
#[prelude_import]
|
||||||
|
use ::std::prelude::rust_2015::*;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate std;
|
||||||
|
|
||||||
|
macro_rules! expr { ($expr:expr) => { $expr }; }
|
||||||
|
|
||||||
|
macro_rules! stmt { ($stmt:stmt) => { $stmt }; }
|
||||||
|
|
||||||
|
fn if_let() {
|
||||||
|
macro_rules! if_let {
|
||||||
|
($pat:pat, $expr:expr) => { if let $pat = $expr {} };
|
||||||
|
}
|
||||||
|
|
||||||
|
if let no_paren = true && false {}
|
||||||
|
if let paren_around_binary = (true && false) {};
|
||||||
|
if let no_paren = true {};
|
||||||
|
|
||||||
|
struct Struct {}
|
||||||
|
match () { _ if let no_paren = Struct {} => {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn let_else() {
|
||||||
|
let no_paren = 1 + 1 else { return; };
|
||||||
|
let paren_around_loop = (loop {}) else { return; };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn local() {
|
||||||
|
macro_rules! let_expr_minus_one {
|
||||||
|
($pat:pat, $expr:expr) => { let $pat = $expr - 1; };
|
||||||
|
}
|
||||||
|
|
||||||
|
let void;
|
||||||
|
let no_paren = match void {} - 1;
|
||||||
|
|
||||||
|
macro_rules! let_expr_else_return {
|
||||||
|
($pat:pat, $expr:expr) => { let $pat = $expr else { return; }; };
|
||||||
|
}
|
||||||
|
let
|
||||||
|
|
||||||
|
no_paren = void() else { return; };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_arm() {
|
||||||
|
macro_rules! match_arm {
|
||||||
|
($pat:pat, $expr:expr) => { match () { $pat => $expr } };
|
||||||
|
}
|
||||||
|
match () {
|
||||||
|
|
||||||
|
|
||||||
|
no_paren => 1 - 1,
|
||||||
|
};
|
||||||
|
match () { paren_around_brace => ({ 1 }) - 1, };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://github.com/rust-lang/rust/issues/98790
|
||||||
|
fn stmt_boundary() {
|
||||||
|
macro_rules! expr_as_stmt { ($expr:expr) => { stmt!($expr) }; }
|
||||||
|
|
||||||
|
let paren_around_match;
|
||||||
|
(match paren_around_match {}) | true;
|
||||||
|
|
||||||
|
macro_rules! minus_one { ($expr:expr) => { expr_as_stmt!($expr - 1) }; }
|
||||||
|
|
||||||
|
let (no_paren, paren_around_loop);
|
||||||
|
no_paren - 1;
|
||||||
|
(match paren_around_match {}) - 1;
|
||||||
|
(match paren_around_match {})() - 1;
|
||||||
|
(match paren_around_match {})[0] - 1;
|
||||||
|
(loop { break paren_around_loop; }) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vis_inherited() {
|
||||||
|
macro_rules! vis_inherited {
|
||||||
|
($vis:vis struct) => { $vis struct Struct; };
|
||||||
|
}
|
||||||
|
struct Struct;
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +0,0 @@
|
||||||
//@ compile-flags: -Zunpretty=expanded
|
|
||||||
//@ check-pass
|
|
||||||
|
|
||||||
macro_rules! expr {
|
|
||||||
($e:expr) => { $e };
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let _ = expr!(1 + 1) else { return; };
|
|
||||||
let _ = expr!(loop {}) else { return; };
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
#![feature(prelude_import)]
|
|
||||||
#![no_std]
|
|
||||||
#[prelude_import]
|
|
||||||
use ::std::prelude::rust_2015::*;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate std;
|
|
||||||
//@ compile-flags: -Zunpretty=expanded
|
|
||||||
//@ check-pass
|
|
||||||
|
|
||||||
macro_rules! expr { ($e:expr) => { $e }; }
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let _ = 1 + 1 else { return; };
|
|
||||||
let _ = (loop {}) else { return; };
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue