Merge from rustc
This commit is contained in:
commit
f356f2f203
83 changed files with 852 additions and 270 deletions
|
|
@ -217,14 +217,12 @@ mod llvm_enzyme {
|
|||
ast::StmtKind::Item(iitem) => extract_item_info(iitem),
|
||||
_ => None,
|
||||
},
|
||||
Annotatable::AssocItem(assoc_item, Impl { of_trait: false }) => {
|
||||
match &assoc_item.kind {
|
||||
ast::AssocItemKind::Fn(box ast::Fn { sig, ident, .. }) => {
|
||||
Some((assoc_item.vis.clone(), sig.clone(), ident.clone()))
|
||||
}
|
||||
_ => None,
|
||||
Annotatable::AssocItem(assoc_item, Impl { .. }) => match &assoc_item.kind {
|
||||
ast::AssocItemKind::Fn(box ast::Fn { sig, ident, .. }) => {
|
||||
Some((assoc_item.vis.clone(), sig.clone(), ident.clone()))
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
}) else {
|
||||
dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() });
|
||||
|
|
@ -365,7 +363,7 @@ mod llvm_enzyme {
|
|||
}
|
||||
Annotatable::Item(iitem.clone())
|
||||
}
|
||||
Annotatable::AssocItem(ref mut assoc_item, i @ Impl { of_trait: false }) => {
|
||||
Annotatable::AssocItem(ref mut assoc_item, i @ Impl { .. }) => {
|
||||
if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) {
|
||||
assoc_item.attrs.push(attr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -872,8 +872,21 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
|
||||
// # Function pointers
|
||||
// (both global from `alloc_map` and local from `extra_fn_ptr_map`)
|
||||
if self.get_fn_alloc(id).is_some() {
|
||||
return AllocInfo::new(Size::ZERO, Align::ONE, AllocKind::Function, Mutability::Not);
|
||||
if let Some(fn_val) = self.get_fn_alloc(id) {
|
||||
let align = match fn_val {
|
||||
FnVal::Instance(instance) => {
|
||||
// Function alignment can be set globally with the `-Zmin-function-alignment=<n>` flag;
|
||||
// the alignment from a `#[repr(align(<n>))]` is used if it specifies a higher alignment.
|
||||
let fn_align = self.tcx.codegen_fn_attrs(instance.def_id()).alignment;
|
||||
let global_align = self.tcx.sess.opts.unstable_opts.min_function_alignment;
|
||||
|
||||
Ord::max(global_align, fn_align).unwrap_or(Align::ONE)
|
||||
}
|
||||
// Machine-specific extra functions currently do not support alignment restrictions.
|
||||
FnVal::Other(_) => Align::ONE,
|
||||
};
|
||||
|
||||
return AllocInfo::new(Size::ZERO, align, AllocKind::Function, Mutability::Not);
|
||||
}
|
||||
|
||||
// # Global allocations
|
||||
|
|
|
|||
|
|
@ -3289,8 +3289,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
err.multipart_suggestion(
|
||||
format!("{val} is a raw pointer; try dereferencing it"),
|
||||
vec![
|
||||
(base.span.shrink_to_lo(), "(*".to_string()),
|
||||
(base.span.shrink_to_hi(), ")".to_string()),
|
||||
(base.span.shrink_to_lo(), "(*".into()),
|
||||
(base.span.between(field.span), format!(").")),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -246,9 +246,9 @@ parse_expected_struct_field = expected one of `,`, `:`, or `{"}"}`, found `{$tok
|
|||
|
||||
parse_expected_trait_in_trait_impl_found_type = expected a trait, found type
|
||||
|
||||
parse_expr_rarrow_call = `->` used for field access or method call
|
||||
parse_expr_rarrow_call = `->` is not valid syntax for field accesses and method calls
|
||||
.suggestion = try using `.` instead
|
||||
.help = the `.` operator will dereference the value if needed
|
||||
.help = the `.` operator will automatically dereference the value, except if the value is a raw pointer
|
||||
|
||||
parse_extern_crate_name_with_dashes = crate name using dashes are not valid in `extern crate` statements
|
||||
.label = dash-separated idents are not valid
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ use rustc_macros::Subdiagnostic;
|
|||
use rustc_session::errors::{ExprParenthesesNeeded, report_lit_error};
|
||||
use rustc_session::lint::BuiltinLintDiag;
|
||||
use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::{self, Spanned};
|
||||
use rustc_span::{BytePos, ErrorGuaranteed, Ident, Pos, Span, Symbol, kw, sym};
|
||||
use thin_vec::{ThinVec, thin_vec};
|
||||
|
|
@ -2145,6 +2146,17 @@ impl<'a> Parser<'a> {
|
|||
/// Keep this in sync with `Token::can_begin_literal_maybe_minus` and
|
||||
/// `Lit::from_token` (excluding unary negation).
|
||||
fn eat_token_lit(&mut self) -> Option<token::Lit> {
|
||||
let check_expr = |expr: P<Expr>| {
|
||||
if let ast::ExprKind::Lit(token_lit) = expr.kind {
|
||||
Some(token_lit)
|
||||
} else if let ast::ExprKind::Unary(UnOp::Neg, inner) = &expr.kind
|
||||
&& let ast::Expr { kind: ast::ExprKind::Lit(_), .. } = **inner
|
||||
{
|
||||
None
|
||||
} else {
|
||||
panic!("unexpected reparsed expr/literal: {:?}", expr.kind);
|
||||
}
|
||||
};
|
||||
match self.token.uninterpolate().kind {
|
||||
token::Ident(name, IdentIsRaw::No) if name.is_bool_lit() => {
|
||||
self.bump();
|
||||
|
|
@ -2158,10 +2170,7 @@ impl<'a> Parser<'a> {
|
|||
let lit = self
|
||||
.eat_metavar_seq(MetaVarKind::Literal, |this| this.parse_literal_maybe_minus())
|
||||
.expect("metavar seq literal");
|
||||
let ast::ExprKind::Lit(token_lit) = lit.kind else {
|
||||
panic!("didn't reparse a literal");
|
||||
};
|
||||
Some(token_lit)
|
||||
check_expr(lit)
|
||||
}
|
||||
token::OpenInvisible(InvisibleOrigin::MetaVar(
|
||||
mv_kind @ MetaVarKind::Expr { can_begin_literal_maybe_minus: true, .. },
|
||||
|
|
@ -2169,15 +2178,7 @@ impl<'a> Parser<'a> {
|
|||
let expr = self
|
||||
.eat_metavar_seq(mv_kind, |this| this.parse_expr())
|
||||
.expect("metavar seq expr");
|
||||
if let ast::ExprKind::Lit(token_lit) = expr.kind {
|
||||
Some(token_lit)
|
||||
} else if let ast::ExprKind::Unary(UnOp::Neg, inner) = &expr.kind
|
||||
&& let ast::Expr { kind: ast::ExprKind::Lit(_), .. } = **inner
|
||||
{
|
||||
None
|
||||
} else {
|
||||
panic!("unexpected reparsed expr: {:?}", expr.kind);
|
||||
}
|
||||
check_expr(expr)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
|
@ -2602,7 +2603,10 @@ impl<'a> Parser<'a> {
|
|||
/// Parses an `if` expression (`if` token already eaten).
|
||||
fn parse_expr_if(&mut self) -> PResult<'a, P<Expr>> {
|
||||
let lo = self.prev_token.span;
|
||||
let cond = self.parse_expr_cond()?;
|
||||
// Scoping code checks the top level edition of the `if`; let's match it here.
|
||||
// The `CondChecker` also checks the edition of the `let` itself, just to make sure.
|
||||
let let_chains_policy = LetChainsPolicy::EditionDependent { current_edition: lo.edition() };
|
||||
let cond = self.parse_expr_cond(let_chains_policy)?;
|
||||
self.parse_if_after_cond(lo, cond)
|
||||
}
|
||||
|
||||
|
|
@ -2711,18 +2715,17 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
/// Parses the condition of a `if` or `while` expression.
|
||||
///
|
||||
/// The specified `edition` in `let_chains_policy` should be that of the whole `if` construct,
|
||||
/// i.e. the same span we use to later decide whether the drop behaviour should be that of
|
||||
/// edition `..=2021` or that of `2024..`.
|
||||
// Public because it is used in rustfmt forks such as https://github.com/tucant/rustfmt/blob/30c83df9e1db10007bdd16dafce8a86b404329b2/src/parse/macros/html.rs#L57 for custom if expressions.
|
||||
pub fn parse_expr_cond(&mut self) -> PResult<'a, P<Expr>> {
|
||||
pub fn parse_expr_cond(&mut self, let_chains_policy: LetChainsPolicy) -> PResult<'a, P<Expr>> {
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
let (mut cond, _) =
|
||||
self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL | Restrictions::ALLOW_LET, attrs)?;
|
||||
|
||||
CondChecker::new(self).visit_expr(&mut cond);
|
||||
|
||||
if let ExprKind::Let(_, _, _, Recovered::No) = cond.kind {
|
||||
// Remove the last feature gating of a `let` expression since it's stable.
|
||||
self.psess.gated_spans.ungate_last(sym::let_chains, cond.span);
|
||||
}
|
||||
CondChecker::new(self, let_chains_policy).visit_expr(&mut cond);
|
||||
|
||||
Ok(cond)
|
||||
}
|
||||
|
|
@ -3017,7 +3020,8 @@ impl<'a> Parser<'a> {
|
|||
|
||||
/// Parses a `while` or `while let` expression (`while` token already eaten).
|
||||
fn parse_expr_while(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
|
||||
let cond = self.parse_expr_cond().map_err(|mut err| {
|
||||
let policy = LetChainsPolicy::EditionDependent { current_edition: lo.edition() };
|
||||
let cond = self.parse_expr_cond(policy).map_err(|mut err| {
|
||||
err.span_label(lo, "while parsing the condition of this `while` expression");
|
||||
err
|
||||
})?;
|
||||
|
|
@ -3401,17 +3405,17 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
fn parse_match_arm_guard(&mut self) -> PResult<'a, Option<P<Expr>>> {
|
||||
// Used to check the `let_chains` and `if_let_guard` features mostly by scanning
|
||||
// Used to check the `if_let_guard` feature mostly by scanning
|
||||
// `&&` tokens.
|
||||
fn check_let_expr(expr: &Expr) -> (bool, bool) {
|
||||
fn has_let_expr(expr: &Expr) -> bool {
|
||||
match &expr.kind {
|
||||
ExprKind::Binary(BinOp { node: BinOpKind::And, .. }, lhs, rhs) => {
|
||||
let lhs_rslt = check_let_expr(lhs);
|
||||
let rhs_rslt = check_let_expr(rhs);
|
||||
(lhs_rslt.0 || rhs_rslt.0, false)
|
||||
let lhs_rslt = has_let_expr(lhs);
|
||||
let rhs_rslt = has_let_expr(rhs);
|
||||
lhs_rslt || rhs_rslt
|
||||
}
|
||||
ExprKind::Let(..) => (true, true),
|
||||
_ => (false, true),
|
||||
ExprKind::Let(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
if !self.eat_keyword(exp!(If)) {
|
||||
|
|
@ -3422,14 +3426,9 @@ impl<'a> Parser<'a> {
|
|||
let if_span = self.prev_token.span;
|
||||
let mut cond = self.parse_match_guard_condition()?;
|
||||
|
||||
CondChecker::new(self).visit_expr(&mut cond);
|
||||
CondChecker::new(self, LetChainsPolicy::AlwaysAllowed).visit_expr(&mut cond);
|
||||
|
||||
let (has_let_expr, does_not_have_bin_op) = check_let_expr(&cond);
|
||||
if has_let_expr {
|
||||
if does_not_have_bin_op {
|
||||
// Remove the last feature gating of a `let` expression since it's stable.
|
||||
self.psess.gated_spans.ungate_last(sym::let_chains, cond.span);
|
||||
}
|
||||
if has_let_expr(&cond) {
|
||||
let span = if_span.to(cond.span);
|
||||
self.psess.gated_spans.gate(sym::if_let_guard, span);
|
||||
}
|
||||
|
|
@ -3456,7 +3455,7 @@ impl<'a> Parser<'a> {
|
|||
unreachable!()
|
||||
};
|
||||
self.psess.gated_spans.ungate_last(sym::guard_patterns, cond.span);
|
||||
CondChecker::new(self).visit_expr(&mut cond);
|
||||
CondChecker::new(self, LetChainsPolicy::AlwaysAllowed).visit_expr(&mut cond);
|
||||
let right = self.prev_token.span;
|
||||
self.dcx().emit_err(errors::ParenthesesInMatchPat {
|
||||
span: vec![left, right],
|
||||
|
|
@ -4027,7 +4026,14 @@ pub(crate) enum ForbiddenLetReason {
|
|||
NotSupportedParentheses(#[primary_span] Span),
|
||||
}
|
||||
|
||||
/// Visitor to check for invalid/unstable use of `ExprKind::Let` that can't
|
||||
/// Whether let chains are allowed on all editions, or it's edition dependent (allowed only on
|
||||
/// 2024 and later). In case of edition dependence, specify the currently present edition.
|
||||
pub enum LetChainsPolicy {
|
||||
AlwaysAllowed,
|
||||
EditionDependent { current_edition: Edition },
|
||||
}
|
||||
|
||||
/// Visitor to check for invalid use of `ExprKind::Let` that can't
|
||||
/// easily be caught in parsing. For example:
|
||||
///
|
||||
/// ```rust,ignore (example)
|
||||
|
|
@ -4038,19 +4044,29 @@ pub(crate) enum ForbiddenLetReason {
|
|||
/// ```
|
||||
struct CondChecker<'a> {
|
||||
parser: &'a Parser<'a>,
|
||||
let_chains_policy: LetChainsPolicy,
|
||||
depth: u32,
|
||||
forbid_let_reason: Option<ForbiddenLetReason>,
|
||||
missing_let: Option<errors::MaybeMissingLet>,
|
||||
comparison: Option<errors::MaybeComparison>,
|
||||
}
|
||||
|
||||
impl<'a> CondChecker<'a> {
|
||||
fn new(parser: &'a Parser<'a>) -> Self {
|
||||
CondChecker { parser, forbid_let_reason: None, missing_let: None, comparison: None }
|
||||
fn new(parser: &'a Parser<'a>, let_chains_policy: LetChainsPolicy) -> Self {
|
||||
CondChecker {
|
||||
parser,
|
||||
forbid_let_reason: None,
|
||||
missing_let: None,
|
||||
comparison: None,
|
||||
let_chains_policy,
|
||||
depth: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MutVisitor for CondChecker<'_> {
|
||||
fn visit_expr(&mut self, e: &mut P<Expr>) {
|
||||
self.depth += 1;
|
||||
use ForbiddenLetReason::*;
|
||||
|
||||
let span = e.span;
|
||||
|
|
@ -4065,8 +4081,16 @@ impl MutVisitor for CondChecker<'_> {
|
|||
comparison: self.comparison,
|
||||
},
|
||||
));
|
||||
} else {
|
||||
self.parser.psess.gated_spans.gate(sym::let_chains, span);
|
||||
} else if self.depth > 1 {
|
||||
// Top level `let` is always allowed; only gate chains
|
||||
match self.let_chains_policy {
|
||||
LetChainsPolicy::AlwaysAllowed => (),
|
||||
LetChainsPolicy::EditionDependent { current_edition } => {
|
||||
if !current_edition.at_least_rust_2024() || !span.at_least_rust_2024() {
|
||||
self.parser.psess.gated_spans.gate(sym::let_chains, span);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ExprKind::Binary(Spanned { node: BinOpKind::And, .. }, _, _) => {
|
||||
|
|
@ -4168,5 +4192,6 @@ impl MutVisitor for CondChecker<'_> {
|
|||
// These would forbid any let expressions they contain already.
|
||||
}
|
||||
}
|
||||
self.depth -= 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,6 +145,9 @@ impl f128 {
|
|||
pub const RADIX: u32 = 2;
|
||||
|
||||
/// Number of significant digits in base 2.
|
||||
///
|
||||
/// Note that the size of the mantissa in the bitwise representation is one
|
||||
/// smaller than this since the leading 1 is not stored explicitly.
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
pub const MANTISSA_DIGITS: u32 = 113;
|
||||
|
||||
|
|
|
|||
|
|
@ -140,6 +140,9 @@ impl f16 {
|
|||
pub const RADIX: u32 = 2;
|
||||
|
||||
/// Number of significant digits in base 2.
|
||||
///
|
||||
/// Note that the size of the mantissa in the bitwise representation is one
|
||||
/// smaller than this since the leading 1 is not stored explicitly.
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
pub const MANTISSA_DIGITS: u32 = 11;
|
||||
|
||||
|
|
|
|||
|
|
@ -390,6 +390,9 @@ impl f32 {
|
|||
pub const RADIX: u32 = 2;
|
||||
|
||||
/// Number of significant digits in base 2.
|
||||
///
|
||||
/// Note that the size of the mantissa in the bitwise representation is one
|
||||
/// smaller than this since the leading 1 is not stored explicitly.
|
||||
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
|
||||
pub const MANTISSA_DIGITS: u32 = 24;
|
||||
|
||||
|
|
|
|||
|
|
@ -390,6 +390,9 @@ impl f64 {
|
|||
pub const RADIX: u32 = 2;
|
||||
|
||||
/// Number of significant digits in base 2.
|
||||
///
|
||||
/// Note that the size of the mantissa in the bitwise representation is one
|
||||
/// smaller than this since the leading 1 is not stored explicitly.
|
||||
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
|
||||
pub const MANTISSA_DIGITS: u32 = 53;
|
||||
/// Approximate number of significant digits in base 10.
|
||||
|
|
|
|||
|
|
@ -415,6 +415,7 @@ impl Command {
|
|||
all(target_os = "linux", target_env = "musl"),
|
||||
target_os = "nto",
|
||||
target_vendor = "apple",
|
||||
target_os = "cygwin",
|
||||
)))]
|
||||
fn posix_spawn(
|
||||
&mut self,
|
||||
|
|
@ -433,6 +434,7 @@ impl Command {
|
|||
all(target_os = "linux", target_env = "musl"),
|
||||
target_os = "nto",
|
||||
target_vendor = "apple",
|
||||
target_os = "cygwin",
|
||||
))]
|
||||
fn posix_spawn(
|
||||
&mut self,
|
||||
|
|
@ -584,7 +586,7 @@ impl Command {
|
|||
/// Some platforms can set a new working directory for a spawned process in the
|
||||
/// `posix_spawn` path. This function looks up the function pointer for adding
|
||||
/// such an action to a `posix_spawn_file_actions_t` struct.
|
||||
#[cfg(not(all(target_os = "linux", target_env = "musl")))]
|
||||
#[cfg(not(any(all(target_os = "linux", target_env = "musl"), target_os = "cygwin")))]
|
||||
fn get_posix_spawn_addchdir() -> Option<PosixSpawnAddChdirFn> {
|
||||
use crate::sys::weak::weak;
|
||||
|
||||
|
|
@ -618,7 +620,9 @@ impl Command {
|
|||
/// Weak symbol lookup doesn't work with statically linked libcs, so in cases
|
||||
/// where static linking is possible we need to either check for the presence
|
||||
/// of the symbol at compile time or know about it upfront.
|
||||
#[cfg(all(target_os = "linux", target_env = "musl"))]
|
||||
///
|
||||
/// Cygwin doesn't support weak symbol, so just link it.
|
||||
#[cfg(any(all(target_os = "linux", target_env = "musl"), target_os = "cygwin"))]
|
||||
fn get_posix_spawn_addchdir() -> Option<PosixSpawnAddChdirFn> {
|
||||
// Our minimum required musl supports this function, so we can just use it.
|
||||
Some(libc::posix_spawn_file_actions_addchdir_np)
|
||||
|
|
|
|||
|
|
@ -112,6 +112,8 @@ fn test_nan() {
|
|||
assert!(!nan.is_sign_negative());
|
||||
assert!(!nan.is_normal());
|
||||
assert_eq!(Fp::Nan, nan.classify());
|
||||
// Ensure the quiet bit is set.
|
||||
assert!(nan.to_bits() & (1 << (f128::MANTISSA_DIGITS - 2)) != 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@ fn test_nan() {
|
|||
assert!(!nan.is_sign_negative());
|
||||
assert!(!nan.is_normal());
|
||||
assert_eq!(Fp::Nan, nan.classify());
|
||||
// Ensure the quiet bit is set.
|
||||
assert!(nan.to_bits() & (1 << (f16::MANTISSA_DIGITS - 2)) != 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ fn test_nan() {
|
|||
assert!(nan.is_sign_positive());
|
||||
assert!(!nan.is_sign_negative());
|
||||
assert_eq!(Fp::Nan, nan.classify());
|
||||
// Ensure the quiet bit is set.
|
||||
assert!(nan.to_bits() & (1 << (f32::MANTISSA_DIGITS - 2)) != 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ fn test_nan() {
|
|||
assert!(nan.is_sign_positive());
|
||||
assert!(!nan.is_sign_negative());
|
||||
assert_eq!(Fp::Nan, nan.classify());
|
||||
// Ensure the quiet bit is set.
|
||||
assert!(nan.to_bits() & (1 << (f64::MANTISSA_DIGITS - 2)) != 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 0c10c30cc54736c5c194ce98c50e2de84eeb6e79
|
||||
Subproject commit c76a20f0d987145dcedf05c5c073ce8d91f2e82a
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 3340922df189bddcbaad17dc3927d51a76bcd5ed
|
||||
Subproject commit 3bf3402aea982b876eb56c87da17b0685c6461d5
|
||||
|
|
@ -57,9 +57,11 @@ pub(crate) fn run_tests(config: &Config, tests: Vec<CollectedTest>) -> bool {
|
|||
}
|
||||
|
||||
let completion = deadline_queue
|
||||
.read_channel_while_checking_deadlines(&completion_rx, |_id, test| {
|
||||
listener.test_timed_out(test);
|
||||
})
|
||||
.read_channel_while_checking_deadlines(
|
||||
&completion_rx,
|
||||
|id| running_tests.contains_key(&id),
|
||||
|_id, test| listener.test_timed_out(test),
|
||||
)
|
||||
.expect("receive channel should never be closed early");
|
||||
|
||||
let RunningTest { test, join_handle } = running_tests.remove(&completion.id).unwrap();
|
||||
|
|
|
|||
|
|
@ -21,16 +21,26 @@ impl<'a> DeadlineQueue<'a> {
|
|||
Self { queue: VecDeque::with_capacity(capacity) }
|
||||
}
|
||||
|
||||
/// All calls to [`Instant::now`] go through this wrapper method.
|
||||
/// This makes it easier to find all places that read the current time.
|
||||
fn now(&self) -> Instant {
|
||||
Instant::now()
|
||||
}
|
||||
|
||||
pub(crate) fn push(&mut self, id: TestId, test: &'a CollectedTest) {
|
||||
let deadline = Instant::now() + Duration::from_secs(TEST_WARN_TIMEOUT_S);
|
||||
let deadline = self.now() + Duration::from_secs(TEST_WARN_TIMEOUT_S);
|
||||
if let Some(back) = self.queue.back() {
|
||||
assert!(back.deadline <= deadline);
|
||||
}
|
||||
self.queue.push_back(DeadlineEntry { id, test, deadline });
|
||||
}
|
||||
|
||||
/// Equivalent to `rx.read()`, except that if any test exceeds its deadline
|
||||
/// Equivalent to `rx.recv()`, except that if a test exceeds its deadline
|
||||
/// during the wait, the given callback will also be called for that test.
|
||||
pub(crate) fn read_channel_while_checking_deadlines<T>(
|
||||
&mut self,
|
||||
rx: &mpsc::Receiver<T>,
|
||||
is_running: impl Fn(TestId) -> bool,
|
||||
mut on_deadline_passed: impl FnMut(TestId, &CollectedTest),
|
||||
) -> Result<T, RecvError> {
|
||||
loop {
|
||||
|
|
@ -39,18 +49,18 @@ impl<'a> DeadlineQueue<'a> {
|
|||
// deadline, so do a normal receive.
|
||||
return rx.recv();
|
||||
};
|
||||
let wait_duration = next_deadline.saturating_duration_since(Instant::now());
|
||||
let next_deadline_timeout = next_deadline.saturating_duration_since(self.now());
|
||||
|
||||
let recv_result = rx.recv_timeout(next_deadline_timeout);
|
||||
// Process deadlines after every receive attempt, regardless of
|
||||
// outcome, so that we don't build up an unbounded backlog of stale
|
||||
// entries due to a constant stream of tests finishing.
|
||||
self.for_each_entry_past_deadline(&is_running, &mut on_deadline_passed);
|
||||
|
||||
let recv_result = rx.recv_timeout(wait_duration);
|
||||
match recv_result {
|
||||
Ok(value) => return Ok(value),
|
||||
Err(RecvTimeoutError::Timeout) => {
|
||||
// Notify the callback of tests that have exceeded their
|
||||
// deadline, then loop and do annother channel read.
|
||||
for DeadlineEntry { id, test, .. } in self.remove_tests_past_deadline() {
|
||||
on_deadline_passed(id, test);
|
||||
}
|
||||
}
|
||||
// Deadlines have already been processed, so loop and do another receive.
|
||||
Err(RecvTimeoutError::Timeout) => {}
|
||||
Err(RecvTimeoutError::Disconnected) => return Err(RecvError),
|
||||
}
|
||||
}
|
||||
|
|
@ -60,14 +70,28 @@ impl<'a> DeadlineQueue<'a> {
|
|||
Some(self.queue.front()?.deadline)
|
||||
}
|
||||
|
||||
fn remove_tests_past_deadline(&mut self) -> Vec<DeadlineEntry<'a>> {
|
||||
let now = Instant::now();
|
||||
let mut timed_out = vec![];
|
||||
while let Some(deadline_entry) = pop_front_if(&mut self.queue, |entry| now < entry.deadline)
|
||||
{
|
||||
timed_out.push(deadline_entry);
|
||||
fn for_each_entry_past_deadline(
|
||||
&mut self,
|
||||
is_running: impl Fn(TestId) -> bool,
|
||||
mut on_deadline_passed: impl FnMut(TestId, &CollectedTest),
|
||||
) {
|
||||
let now = self.now();
|
||||
|
||||
// Clear out entries that are past their deadline, but only invoke the
|
||||
// callback for tests that are still considered running.
|
||||
while let Some(entry) = pop_front_if(&mut self.queue, |entry| entry.deadline <= now) {
|
||||
if is_running(entry.id) {
|
||||
on_deadline_passed(entry.id, entry.test);
|
||||
}
|
||||
}
|
||||
|
||||
// Also clear out any leading entries that are no longer running, even
|
||||
// if their deadline hasn't been reached.
|
||||
while let Some(_) = pop_front_if(&mut self.queue, |entry| !is_running(entry.id)) {}
|
||||
|
||||
if let Some(front) = self.queue.front() {
|
||||
assert!(now < front.deadline);
|
||||
}
|
||||
timed_out
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
21
src/tools/miri/tests/pass/fn_align.rs
Normal file
21
src/tools/miri/tests/pass/fn_align.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
//@compile-flags: -Zmin-function-alignment=8
|
||||
#![feature(fn_align)]
|
||||
|
||||
// When a function uses `repr(align(N))`, the function address should be a multiple of `N`.
|
||||
|
||||
#[repr(align(256))]
|
||||
fn foo() {}
|
||||
|
||||
#[repr(align(16))]
|
||||
fn bar() {}
|
||||
|
||||
#[repr(align(4))]
|
||||
fn baz() {}
|
||||
|
||||
fn main() {
|
||||
assert!((foo as usize).is_multiple_of(256));
|
||||
assert!((bar as usize).is_multiple_of(16));
|
||||
|
||||
// The maximum of `repr(align(N))` and `-Zmin-function-alignment=N` is used.
|
||||
assert!((baz as usize).is_multiple_of(8));
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// skip-filecheck
|
||||
//@ compile-flags: -Z validate-mir
|
||||
#![feature(let_chains)]
|
||||
//@ edition: 2024
|
||||
struct Droppy(u8);
|
||||
impl Drop for Droppy {
|
||||
fn drop(&mut self) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ fn test_complex() -> () {
|
|||
bb0: {
|
||||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
_2 = E::f() -> [return: bb1, unwind: bb34];
|
||||
_2 = E::f() -> [return: bb1, unwind: bb35];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
@ -42,7 +42,7 @@ fn test_complex() -> () {
|
|||
|
||||
bb5: {
|
||||
StorageLive(_4);
|
||||
_4 = always_true() -> [return: bb6, unwind: bb34];
|
||||
_4 = always_true() -> [return: bb6, unwind: bb35];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
|
|
@ -64,7 +64,7 @@ fn test_complex() -> () {
|
|||
}
|
||||
|
||||
bb9: {
|
||||
drop(_7) -> [return: bb11, unwind: bb34];
|
||||
drop(_7) -> [return: bb11, unwind: bb35];
|
||||
}
|
||||
|
||||
bb10: {
|
||||
|
|
@ -78,7 +78,7 @@ fn test_complex() -> () {
|
|||
}
|
||||
|
||||
bb12: {
|
||||
drop(_7) -> [return: bb13, unwind: bb34];
|
||||
drop(_7) -> [return: bb13, unwind: bb35];
|
||||
}
|
||||
|
||||
bb13: {
|
||||
|
|
@ -98,7 +98,7 @@ fn test_complex() -> () {
|
|||
}
|
||||
|
||||
bb15: {
|
||||
drop(_10) -> [return: bb17, unwind: bb34];
|
||||
drop(_10) -> [return: bb17, unwind: bb35];
|
||||
}
|
||||
|
||||
bb16: {
|
||||
|
|
@ -113,11 +113,12 @@ fn test_complex() -> () {
|
|||
|
||||
bb18: {
|
||||
_1 = const ();
|
||||
StorageDead(_2);
|
||||
goto -> bb22;
|
||||
}
|
||||
|
||||
bb19: {
|
||||
drop(_10) -> [return: bb20, unwind: bb34];
|
||||
drop(_10) -> [return: bb20, unwind: bb35];
|
||||
}
|
||||
|
||||
bb20: {
|
||||
|
|
@ -127,6 +128,7 @@ fn test_complex() -> () {
|
|||
}
|
||||
|
||||
bb21: {
|
||||
StorageDead(_2);
|
||||
_1 = const ();
|
||||
goto -> bb22;
|
||||
}
|
||||
|
|
@ -135,10 +137,9 @@ fn test_complex() -> () {
|
|||
StorageDead(_8);
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
StorageLive(_11);
|
||||
_11 = always_true() -> [return: bb23, unwind: bb34];
|
||||
_11 = always_true() -> [return: bb23, unwind: bb35];
|
||||
}
|
||||
|
||||
bb23: {
|
||||
|
|
@ -146,7 +147,7 @@ fn test_complex() -> () {
|
|||
}
|
||||
|
||||
bb24: {
|
||||
goto -> bb32;
|
||||
goto -> bb33;
|
||||
}
|
||||
|
||||
bb25: {
|
||||
|
|
@ -155,7 +156,7 @@ fn test_complex() -> () {
|
|||
|
||||
bb26: {
|
||||
StorageLive(_12);
|
||||
_12 = E::f() -> [return: bb27, unwind: bb34];
|
||||
_12 = E::f() -> [return: bb27, unwind: bb35];
|
||||
}
|
||||
|
||||
bb27: {
|
||||
|
|
@ -178,21 +179,26 @@ fn test_complex() -> () {
|
|||
|
||||
bb31: {
|
||||
_0 = const ();
|
||||
goto -> bb33;
|
||||
StorageDead(_12);
|
||||
goto -> bb34;
|
||||
}
|
||||
|
||||
bb32: {
|
||||
_0 = const ();
|
||||
StorageDead(_12);
|
||||
goto -> bb33;
|
||||
}
|
||||
|
||||
bb33: {
|
||||
_0 = const ();
|
||||
goto -> bb34;
|
||||
}
|
||||
|
||||
bb34: {
|
||||
StorageDead(_11);
|
||||
StorageDead(_12);
|
||||
return;
|
||||
}
|
||||
|
||||
bb34 (cleanup): {
|
||||
bb35 (cleanup): {
|
||||
resume;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
41
tests/pretty/autodiff/inherent_impl.pp
Normal file
41
tests/pretty/autodiff/inherent_impl.pp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#![feature(prelude_import)]
|
||||
#![no_std]
|
||||
//@ needs-enzyme
|
||||
|
||||
#![feature(autodiff)]
|
||||
#[prelude_import]
|
||||
use ::std::prelude::rust_2015::*;
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
//@ pretty-mode:expanded
|
||||
//@ pretty-compare-only
|
||||
//@ pp-exact:inherent_impl.pp
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
|
||||
struct Foo {
|
||||
a: f64,
|
||||
}
|
||||
|
||||
trait MyTrait {
|
||||
fn f(&self, x: f64)
|
||||
-> f64;
|
||||
fn df(&self, x: f64, seed: f64)
|
||||
-> (f64, f64);
|
||||
}
|
||||
|
||||
impl MyTrait for Foo {
|
||||
#[rustc_autodiff]
|
||||
#[inline(never)]
|
||||
fn f(&self, x: f64) -> f64 {
|
||||
self.a * 0.25 * (x * x - 1.0 - 2.0 * x.ln())
|
||||
}
|
||||
#[rustc_autodiff(Reverse, 1, Const, Active, Active)]
|
||||
#[inline(never)]
|
||||
fn df(&self, x: f64, dret: f64) -> (f64, f64) {
|
||||
unsafe { asm!("NOP", options(pure, nomem)); };
|
||||
::core::hint::black_box(self.f(x));
|
||||
::core::hint::black_box((dret,));
|
||||
::core::hint::black_box((self.f(x), f64::default()))
|
||||
}
|
||||
}
|
||||
24
tests/pretty/autodiff/inherent_impl.rs
Normal file
24
tests/pretty/autodiff/inherent_impl.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
//@ needs-enzyme
|
||||
|
||||
#![feature(autodiff)]
|
||||
//@ pretty-mode:expanded
|
||||
//@ pretty-compare-only
|
||||
//@ pp-exact:inherent_impl.pp
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
|
||||
struct Foo {
|
||||
a: f64,
|
||||
}
|
||||
|
||||
trait MyTrait {
|
||||
fn f(&self, x: f64) -> f64;
|
||||
fn df(&self, x: f64, seed: f64) -> (f64, f64);
|
||||
}
|
||||
|
||||
impl MyTrait for Foo {
|
||||
#[autodiff(df, Reverse, Const, Active, Active)]
|
||||
fn f(&self, x: f64) -> f64 {
|
||||
self.a * 0.25 * (x * x - 1.0 - 2.0 * x.ln())
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,11 @@ fn main() {
|
|||
if path.is_file()
|
||||
&& path.extension().is_some_and(|ext| ext == expected_extension)
|
||||
&& path.file_name().and_then(|name| name.to_str()).is_some_and(|name| {
|
||||
name.ends_with(".so") || name.ends_with(".dll") || name.ends_with(".dylib")
|
||||
if cfg!(target_os = "aix") {
|
||||
name.ends_with(".a")
|
||||
} else {
|
||||
name.ends_with(".so") || name.ends_with(".dll") || name.ends_with(".dylib")
|
||||
}
|
||||
})
|
||||
{
|
||||
rfs::remove_file(path);
|
||||
|
|
|
|||
54
tests/ui/borrowck/static-trait-bound-lost.rs
Normal file
54
tests/ui/borrowck/static-trait-bound-lost.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
// This test is a reduced version of a bug introduced during work on type-tests for Polonius.
|
||||
// The underlying problem is that the 'static bound is lost for a type parameter that is
|
||||
// threaded deeply enough, causing an error.
|
||||
// The bug was first observed in exr-1.4.1/src/image/read/mod.rs:124:5 during perf test.
|
||||
|
||||
//@ check-pass
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
struct ReadAllLayers<ReadChannels> {
|
||||
px: PhantomData<ReadChannels>,
|
||||
}
|
||||
|
||||
trait ReadLayers<'s> {}
|
||||
|
||||
impl<'s, C> ReadLayers<'s> for ReadAllLayers<C> where C: ReadChannels<'s> {}
|
||||
|
||||
fn make_builder<A, Set, Pixels>(
|
||||
_: Set,
|
||||
) -> ReadAllLayers<CollectPixels<A, Pixels, Set>>
|
||||
where
|
||||
Set: Fn(&mut Pixels),
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
struct CollectPixels<Pixel, PixelStorage, SetPixel> {
|
||||
px: PhantomData<(SetPixel, Pixel, PixelStorage)>,
|
||||
}
|
||||
|
||||
impl<'s, PixelStorage, SetPixel: 's> ReadChannels<'s>
|
||||
for CollectPixels<usize, PixelStorage, SetPixel>
|
||||
where
|
||||
SetPixel: Fn(&mut PixelStorage),
|
||||
{
|
||||
}
|
||||
|
||||
trait ReadChannels<'s> {}
|
||||
|
||||
fn from_file<L>(_: L)
|
||||
where
|
||||
for<'s> L: ReadLayers<'s>,
|
||||
{
|
||||
}
|
||||
|
||||
pub fn read_all_rgba_layers_from_file<Set: 'static, Pixels: 'static>(
|
||||
set_pixel: Set,
|
||||
) where
|
||||
Set: Fn(&mut Pixels),
|
||||
{
|
||||
from_file(make_builder(set_pixel)); // Error triggered.
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(let_chains)]
|
||||
//@ edition: 2024
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
//@ [e2024] edition: 2024
|
||||
//@ run-pass
|
||||
|
||||
#![feature(let_chains)]
|
||||
#![cfg_attr(e2021, feature(let_chains))]
|
||||
#![cfg_attr(e2021, warn(rust_2024_compatibility))]
|
||||
|
||||
fn t_bindings() {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
//@ [e2024] edition: 2024
|
||||
//@ run-pass
|
||||
|
||||
#![feature(let_chains)]
|
||||
#![cfg_attr(e2021, feature(let_chains))]
|
||||
#![cfg_attr(e2021, warn(rust_2024_compatibility))]
|
||||
|
||||
fn t_bindings() {
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@
|
|||
//@ compile-flags: -Z validate-mir
|
||||
//@ revisions: edition2021 edition2024
|
||||
//@ [edition2021] edition: 2021
|
||||
//@ [edition2024] compile-flags: -Z lint-mir
|
||||
//@ [edition2024] edition: 2024
|
||||
|
||||
#![feature(let_chains)]
|
||||
#![cfg_attr(edition2021, feature(let_chains))]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::convert::TryInto;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
//@ run-pass
|
||||
//@ edition:2024
|
||||
//@ compile-flags: -Z validate-mir
|
||||
|
||||
#![feature(let_chains)]
|
||||
//@ compile-flags: -Z validate-mir -Z lint-mir
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::convert::TryInto;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
//@ check-pass
|
||||
//@ compile-flags: -Z validate-mir
|
||||
#![feature(let_chains)]
|
||||
//@ revisions: edition2021 edition2024
|
||||
//@ [edition2021] edition: 2021
|
||||
//@ [edition2024] compile-flags: -Z lint-mir
|
||||
//@ [edition2024] edition: 2024
|
||||
|
||||
#![cfg_attr(edition2021, feature(let_chains))]
|
||||
|
||||
fn let_chains(entry: std::io::Result<std::fs::DirEntry>) {
|
||||
if let Ok(entry) = entry
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
//@ check-pass
|
||||
|
||||
#![feature(let_chains)]
|
||||
//@ edition:2024
|
||||
|
||||
#[cfg(false)]
|
||||
fn foo() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//@ check-pass
|
||||
//@ edition:2024
|
||||
|
||||
#![feature(let_chains)]
|
||||
#![allow(irrefutable_let_patterns)]
|
||||
fn main() {
|
||||
let _a = 0..1;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,15 @@
|
|||
macro_rules! m {
|
||||
($abi : expr) => { extern $abi } //~ ERROR expected expression, found keyword `extern`
|
||||
macro_rules! m1 {
|
||||
($abi: literal) => { extern $abi } //~ ERROR expected expression, found keyword `extern`
|
||||
}
|
||||
|
||||
macro_rules! m2 {
|
||||
($abi: expr) => { extern $abi } //~ ERROR expected expression, found keyword `extern`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
m!(-2)
|
||||
m1!(-2)
|
||||
}
|
||||
|
||||
fn f() {
|
||||
m2!(-2)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,24 @@
|
|||
error: expected expression, found keyword `extern`
|
||||
--> $DIR/reparse-expr-issue-139495.rs:2:22
|
||||
--> $DIR/reparse-expr-issue-139495.rs:2:24
|
||||
|
|
||||
LL | ($abi : expr) => { extern $abi }
|
||||
| ^^^^^^ expected expression
|
||||
LL | ($abi: literal) => { extern $abi }
|
||||
| ^^^^^^ expected expression
|
||||
...
|
||||
LL | m!(-2)
|
||||
| ------ in this macro invocation
|
||||
LL | m1!(-2)
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
= note: this error originates in the macro `m1` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error: expected expression, found keyword `extern`
|
||||
--> $DIR/reparse-expr-issue-139495.rs:6:21
|
||||
|
|
||||
LL | ($abi: expr) => { extern $abi }
|
||||
| ^^^^^^ expected expression
|
||||
...
|
||||
LL | m2!(-2)
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//@ check-pass
|
||||
//@ compile-flags: -Z validate-mir
|
||||
#![feature(let_chains)]
|
||||
//@ edition: 2024
|
||||
|
||||
fn lambda<T, U>() -> U
|
||||
where
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
// See `mir_drop_order.rs` for more information
|
||||
|
||||
#![feature(let_chains)]
|
||||
#![cfg_attr(edition2021, feature(let_chains))]
|
||||
#![allow(irrefutable_let_patterns)]
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
|
|
|||
31
tests/ui/nll/relate_tys/placeholder-outlives-existential.rs
Normal file
31
tests/ui/nll/relate_tys/placeholder-outlives-existential.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// Test that we correctly handle some cases of placeholder leaks.
|
||||
//
|
||||
//@ compile-flags:-Zno-leak-check
|
||||
|
||||
|
||||
struct Co<'a>(&'a ());
|
||||
struct Inv<'a>(*mut &'a ());
|
||||
struct Contra<'a>(fn(&'a ()));
|
||||
|
||||
// `exists<'e> forall<'p> 'p: 'e` -> ERROR
|
||||
fn p_outlives_e(
|
||||
x: for<'e> fn(for<'p> fn(fn(fn(Contra<'e>, Co<'p>)))),
|
||||
) -> fn(fn(fn(for<'unify> fn(Contra<'unify>, Co<'unify>)))) {
|
||||
x //~ ERROR mismatched types [E0308]
|
||||
}
|
||||
|
||||
// `exists<'e> forall<'p> 'e: 'p` -> Ok, 'e: 'static
|
||||
fn e_outlives_p_static(
|
||||
x: for<'e> fn(Inv<'e>, for<'p> fn(fn(fn(Contra<'p>, Co<'e>)))),
|
||||
) -> fn(Inv<'static>, fn(fn(for<'unify> fn(Contra<'unify>, Co<'unify>)))) {
|
||||
x
|
||||
}
|
||||
|
||||
// `exists<'e> forall<'p> 'e: 'p` -> Ok, 'e: 'static -> ERROR
|
||||
fn e_outlives_p_static_err<'not_static>(
|
||||
x: for<'e> fn(Inv<'e>, for<'p> fn(fn(fn(Contra<'p>, Co<'e>)))),
|
||||
) -> fn(Inv<'not_static>, fn(fn(for<'unify> fn(Contra<'unify>, Co<'unify>)))) {
|
||||
x //~ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/placeholder-outlives-existential.rs:14:5
|
||||
|
|
||||
LL | x
|
||||
| ^ one type is more general than the other
|
||||
|
|
||||
= note: expected fn pointer `fn(fn(fn(for<'unify> fn(Contra<'unify>, Co<'unify>))))`
|
||||
found fn pointer `for<'e> fn(for<'e, 'p> fn(for<'e, 'p> fn(for<'e, 'p> fn(Contra<'e>, Co<'p>))))`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/placeholder-outlives-existential.rs:28:5
|
||||
|
|
||||
LL | fn e_outlives_p_static_err<'not_static>(
|
||||
| ----------- lifetime `'not_static` defined here
|
||||
...
|
||||
LL | x
|
||||
| ^ returning this value requires that `'not_static` must outlive `'static`
|
||||
|
|
||||
= note: requirement occurs because of the type `Inv<'_>`, which makes the generic argument `'_` invariant
|
||||
= note: the struct `Inv<'a>` is invariant over the parameter `'a`
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// issue #117766
|
||||
//@ edition: 2024
|
||||
|
||||
#![feature(let_chains)]
|
||||
fn main() {
|
||||
if let () = ()
|
||||
&& let () = () {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(let_chains)]
|
||||
//@ edition: 2024
|
||||
trait Demo {}
|
||||
|
||||
impl dyn Demo {
|
||||
|
|
|
|||
22
tests/ui/parser/expr-rarrow-call-on-a-raw-pointer.rs
Normal file
22
tests/ui/parser/expr-rarrow-call-on-a-raw-pointer.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#![allow(
|
||||
dead_code,
|
||||
unused_must_use
|
||||
)]
|
||||
|
||||
struct Named {
|
||||
foo: usize,
|
||||
}
|
||||
|
||||
struct Unnamed(usize);
|
||||
|
||||
unsafe fn named_struct_field_access(named: *mut Named) {
|
||||
named->foo += 1; //~ ERROR `->` is not valid syntax for field accesses and method calls
|
||||
//~^ ERROR no field `foo` on type `*mut Named`
|
||||
}
|
||||
|
||||
unsafe fn unnamed_struct_field_access(unnamed: *mut Unnamed) {
|
||||
unnamed->0 += 1; //~ ERROR `->` is not valid syntax for field accesses and method calls
|
||||
//~^ ERROR no field `0` on type `*mut Unnamed`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
53
tests/ui/parser/expr-rarrow-call-on-a-raw-pointer.stderr
Normal file
53
tests/ui/parser/expr-rarrow-call-on-a-raw-pointer.stderr
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
error: `->` is not valid syntax for field accesses and method calls
|
||||
--> $DIR/expr-rarrow-call-on-a-raw-pointer.rs:13:10
|
||||
|
|
||||
LL | named->foo += 1;
|
||||
| ^^
|
||||
|
|
||||
= help: the `.` operator will automatically dereference the value, except if the value is a raw pointer
|
||||
help: try using `.` instead
|
||||
|
|
||||
LL - named->foo += 1;
|
||||
LL + named.foo += 1;
|
||||
|
|
||||
|
||||
error: `->` is not valid syntax for field accesses and method calls
|
||||
--> $DIR/expr-rarrow-call-on-a-raw-pointer.rs:18:12
|
||||
|
|
||||
LL | unnamed->0 += 1;
|
||||
| ^^
|
||||
|
|
||||
= help: the `.` operator will automatically dereference the value, except if the value is a raw pointer
|
||||
help: try using `.` instead
|
||||
|
|
||||
LL - unnamed->0 += 1;
|
||||
LL + unnamed.0 += 1;
|
||||
|
|
||||
|
||||
error[E0609]: no field `foo` on type `*mut Named`
|
||||
--> $DIR/expr-rarrow-call-on-a-raw-pointer.rs:13:12
|
||||
|
|
||||
LL | named->foo += 1;
|
||||
| ^^^ unknown field
|
||||
|
|
||||
help: `named` is a raw pointer; try dereferencing it
|
||||
|
|
||||
LL - named->foo += 1;
|
||||
LL + (*named).foo += 1;
|
||||
|
|
||||
|
||||
error[E0609]: no field `0` on type `*mut Unnamed`
|
||||
--> $DIR/expr-rarrow-call-on-a-raw-pointer.rs:18:14
|
||||
|
|
||||
LL | unnamed->0 += 1;
|
||||
| ^ unknown field
|
||||
|
|
||||
help: `unnamed` is a raw pointer; try dereferencing it
|
||||
|
|
||||
LL - unnamed->0 += 1;
|
||||
LL + (*unnamed).0 += 1;
|
||||
|
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0609`.
|
||||
|
|
@ -11,23 +11,23 @@ struct Named {
|
|||
struct Unnamed(usize);
|
||||
|
||||
fn named_struct_field_access(named: &Named) {
|
||||
named.foo; //~ ERROR `->` used for field access or method call
|
||||
named.foo; //~ ERROR `->` is not valid syntax for field accesses and method calls
|
||||
}
|
||||
|
||||
fn unnamed_struct_field_access(unnamed: &Unnamed) {
|
||||
unnamed.0; //~ ERROR `->` used for field access or method call
|
||||
unnamed.0; //~ ERROR `->` is not valid syntax for field accesses and method calls
|
||||
}
|
||||
|
||||
fn tuple_field_access(t: &(u8, u8)) {
|
||||
t.0; //~ ERROR `->` used for field access or method call
|
||||
t.1; //~ ERROR `->` used for field access or method call
|
||||
t.0; //~ ERROR `->` is not valid syntax for field accesses and method calls
|
||||
t.1; //~ ERROR `->` is not valid syntax for field accesses and method calls
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Foo;
|
||||
|
||||
fn method_call(foo: &Foo) {
|
||||
foo.clone(); //~ ERROR `->` used for field access or method call
|
||||
foo.clone(); //~ ERROR `->` is not valid syntax for field accesses and method calls
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -11,23 +11,23 @@ struct Named {
|
|||
struct Unnamed(usize);
|
||||
|
||||
fn named_struct_field_access(named: &Named) {
|
||||
named->foo; //~ ERROR `->` used for field access or method call
|
||||
named->foo; //~ ERROR `->` is not valid syntax for field accesses and method calls
|
||||
}
|
||||
|
||||
fn unnamed_struct_field_access(unnamed: &Unnamed) {
|
||||
unnamed->0; //~ ERROR `->` used for field access or method call
|
||||
unnamed->0; //~ ERROR `->` is not valid syntax for field accesses and method calls
|
||||
}
|
||||
|
||||
fn tuple_field_access(t: &(u8, u8)) {
|
||||
t->0; //~ ERROR `->` used for field access or method call
|
||||
t->1; //~ ERROR `->` used for field access or method call
|
||||
t->0; //~ ERROR `->` is not valid syntax for field accesses and method calls
|
||||
t->1; //~ ERROR `->` is not valid syntax for field accesses and method calls
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Foo;
|
||||
|
||||
fn method_call(foo: &Foo) {
|
||||
foo->clone(); //~ ERROR `->` used for field access or method call
|
||||
foo->clone(); //~ ERROR `->` is not valid syntax for field accesses and method calls
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,62 +1,62 @@
|
|||
error: `->` used for field access or method call
|
||||
error: `->` is not valid syntax for field accesses and method calls
|
||||
--> $DIR/expr-rarrow-call.rs:14:10
|
||||
|
|
||||
LL | named->foo;
|
||||
| ^^
|
||||
|
|
||||
= help: the `.` operator will dereference the value if needed
|
||||
= help: the `.` operator will automatically dereference the value, except if the value is a raw pointer
|
||||
help: try using `.` instead
|
||||
|
|
||||
LL - named->foo;
|
||||
LL + named.foo;
|
||||
|
|
||||
|
||||
error: `->` used for field access or method call
|
||||
error: `->` is not valid syntax for field accesses and method calls
|
||||
--> $DIR/expr-rarrow-call.rs:18:12
|
||||
|
|
||||
LL | unnamed->0;
|
||||
| ^^
|
||||
|
|
||||
= help: the `.` operator will dereference the value if needed
|
||||
= help: the `.` operator will automatically dereference the value, except if the value is a raw pointer
|
||||
help: try using `.` instead
|
||||
|
|
||||
LL - unnamed->0;
|
||||
LL + unnamed.0;
|
||||
|
|
||||
|
||||
error: `->` used for field access or method call
|
||||
error: `->` is not valid syntax for field accesses and method calls
|
||||
--> $DIR/expr-rarrow-call.rs:22:6
|
||||
|
|
||||
LL | t->0;
|
||||
| ^^
|
||||
|
|
||||
= help: the `.` operator will dereference the value if needed
|
||||
= help: the `.` operator will automatically dereference the value, except if the value is a raw pointer
|
||||
help: try using `.` instead
|
||||
|
|
||||
LL - t->0;
|
||||
LL + t.0;
|
||||
|
|
||||
|
||||
error: `->` used for field access or method call
|
||||
error: `->` is not valid syntax for field accesses and method calls
|
||||
--> $DIR/expr-rarrow-call.rs:23:6
|
||||
|
|
||||
LL | t->1;
|
||||
| ^^
|
||||
|
|
||||
= help: the `.` operator will dereference the value if needed
|
||||
= help: the `.` operator will automatically dereference the value, except if the value is a raw pointer
|
||||
help: try using `.` instead
|
||||
|
|
||||
LL - t->1;
|
||||
LL + t.1;
|
||||
|
|
||||
|
||||
error: `->` used for field access or method call
|
||||
error: `->` is not valid syntax for field accesses and method calls
|
||||
--> $DIR/expr-rarrow-call.rs:30:8
|
||||
|
|
||||
LL | foo->clone();
|
||||
| ^^
|
||||
|
|
||||
= help: the `.` operator will dereference the value if needed
|
||||
= help: the `.` operator will automatically dereference the value, except if the value is a raw pointer
|
||||
help: try using `.` instead
|
||||
|
|
||||
LL - foo->clone();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//@ edition: 2024
|
||||
//@ run-rustfix
|
||||
|
||||
#![feature(let_chains)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(irrefutable_let_patterns)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//@ edition: 2024
|
||||
//@ run-rustfix
|
||||
|
||||
#![feature(let_chains)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(irrefutable_let_patterns)]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ fn bar() -> String {
|
|||
attr::fn bar() -> String { //~ ERROR expected identifier, found keyword `fn`
|
||||
//~^ ERROR expected one of `(`, `.`, `::`, `;`, `?`, `}`, or an operator, found `{`
|
||||
//~| ERROR expected `;`, found `bar`
|
||||
//~| ERROR `->` used for field access or method call
|
||||
//~| ERROR `->` is not valid syntax for field accesses and method calls
|
||||
#[attr]
|
||||
[1, 2, 3].iter().map().collect::<String>()
|
||||
#[attr]
|
||||
|
|
|
|||
|
|
@ -33,13 +33,13 @@ LL | attr::fn bar() -> String {
|
|||
| |
|
||||
| help: add `;` here
|
||||
|
||||
error: `->` used for field access or method call
|
||||
error: `->` is not valid syntax for field accesses and method calls
|
||||
--> $DIR/issue-118530-ice.rs:5:20
|
||||
|
|
||||
LL | attr::fn bar() -> String {
|
||||
| ^^
|
||||
|
|
||||
= help: the `.` operator will dereference the value if needed
|
||||
= help: the `.` operator will automatically dereference the value, except if the value is a raw pointer
|
||||
help: try using `.` instead
|
||||
|
|
||||
LL - attr::fn bar() -> String {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
// Issue #117720
|
||||
|
||||
#![feature(let_chains)]
|
||||
//@ edition: 2024
|
||||
|
||||
fn main() {
|
||||
if let () = ()
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error: expected `{`, found `;`
|
||||
--> $DIR/semi-in-let-chain.rs:7:23
|
||||
--> $DIR/semi-in-let-chain.rs:6:23
|
||||
|
|
||||
LL | && let () = ();
|
||||
| ^ expected `{`
|
||||
|
|
||||
note: you likely meant to continue parsing the let-chain starting here
|
||||
--> $DIR/semi-in-let-chain.rs:8:9
|
||||
--> $DIR/semi-in-let-chain.rs:7:9
|
||||
|
|
||||
LL | && let () = ()
|
||||
| ^^^^^^
|
||||
|
|
@ -16,13 +16,13 @@ LL + && let () = ()
|
|||
|
|
||||
|
||||
error: expected `{`, found `;`
|
||||
--> $DIR/semi-in-let-chain.rs:15:20
|
||||
--> $DIR/semi-in-let-chain.rs:14:20
|
||||
|
|
||||
LL | && () == ();
|
||||
| ^ expected `{`
|
||||
|
|
||||
note: the `if` expression is missing a block after this condition
|
||||
--> $DIR/semi-in-let-chain.rs:14:8
|
||||
--> $DIR/semi-in-let-chain.rs:13:8
|
||||
|
|
||||
LL | if let () = ()
|
||||
| ________^
|
||||
|
|
@ -30,13 +30,13 @@ LL | | && () == ();
|
|||
| |___________________^
|
||||
|
||||
error: expected `{`, found `;`
|
||||
--> $DIR/semi-in-let-chain.rs:23:20
|
||||
--> $DIR/semi-in-let-chain.rs:22:20
|
||||
|
|
||||
LL | && () == ();
|
||||
| ^ expected `{`
|
||||
|
|
||||
note: you likely meant to continue parsing the let-chain starting here
|
||||
--> $DIR/semi-in-let-chain.rs:24:9
|
||||
--> $DIR/semi-in-let-chain.rs:23:9
|
||||
|
|
||||
LL | && let () = ()
|
||||
| ^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//@ edition: 2024
|
||||
#![feature(never_patterns)]
|
||||
#![feature(let_chains)]
|
||||
#![allow(incomplete_features)]
|
||||
#![deny(unreachable_patterns)]
|
||||
|
||||
|
|
|
|||
|
|
@ -15,11 +15,9 @@ fn _if_let_guard() {
|
|||
|
||||
() if true && let 0 = 1 => {}
|
||||
//~^ ERROR `if let` guards are experimental
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
|
||||
() if let 0 = 1 && true => {}
|
||||
//~^ ERROR `if let` guards are experimental
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
|
||||
() if (let 0 = 1) && true => {}
|
||||
//~^ ERROR expected expression, found `let` statement
|
||||
|
|
@ -33,8 +31,6 @@ fn _if_let_guard() {
|
|||
|
||||
() if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
//~^ ERROR `if let` guards are experimental
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
//~| ERROR expected expression, found `let` statement
|
||||
|
|
@ -42,7 +38,6 @@ fn _if_let_guard() {
|
|||
|
||||
() if let Range { start: _, end: _ } = (true..true) && false => {}
|
||||
//~^ ERROR `if let` guards are experimental
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,98 +25,98 @@ LL | () if (((let 0 = 1))) => {}
|
|||
| ^^^^^^^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:24:16
|
||||
--> $DIR/feature-gate.rs:22:16
|
||||
|
|
||||
LL | () if (let 0 = 1) && true => {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: only supported directly in conditions of `if` and `while` expressions
|
||||
note: `let`s wrapped in parentheses are not supported in a context with let chains
|
||||
--> $DIR/feature-gate.rs:24:16
|
||||
--> $DIR/feature-gate.rs:22:16
|
||||
|
|
||||
LL | () if (let 0 = 1) && true => {}
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:27:24
|
||||
--> $DIR/feature-gate.rs:25:24
|
||||
|
|
||||
LL | () if true && (let 0 = 1) => {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: only supported directly in conditions of `if` and `while` expressions
|
||||
note: `let`s wrapped in parentheses are not supported in a context with let chains
|
||||
--> $DIR/feature-gate.rs:27:24
|
||||
--> $DIR/feature-gate.rs:25:24
|
||||
|
|
||||
LL | () if true && (let 0 = 1) => {}
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:30:16
|
||||
--> $DIR/feature-gate.rs:28:16
|
||||
|
|
||||
LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: only supported directly in conditions of `if` and `while` expressions
|
||||
note: `let`s wrapped in parentheses are not supported in a context with let chains
|
||||
--> $DIR/feature-gate.rs:30:16
|
||||
--> $DIR/feature-gate.rs:28:16
|
||||
|
|
||||
LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:30:31
|
||||
--> $DIR/feature-gate.rs:28:31
|
||||
|
|
||||
LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: only supported directly in conditions of `if` and `while` expressions
|
||||
note: `let`s wrapped in parentheses are not supported in a context with let chains
|
||||
--> $DIR/feature-gate.rs:30:31
|
||||
--> $DIR/feature-gate.rs:28:31
|
||||
|
|
||||
LL | () if (let 0 = 1) && (let 0 = 1) => {}
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:34:42
|
||||
--> $DIR/feature-gate.rs:32:42
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: only supported directly in conditions of `if` and `while` expressions
|
||||
note: `let`s wrapped in parentheses are not supported in a context with let chains
|
||||
--> $DIR/feature-gate.rs:34:42
|
||||
--> $DIR/feature-gate.rs:32:42
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:34:55
|
||||
--> $DIR/feature-gate.rs:32:55
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: only supported directly in conditions of `if` and `while` expressions
|
||||
note: `let`s wrapped in parentheses are not supported in a context with let chains
|
||||
--> $DIR/feature-gate.rs:34:42
|
||||
--> $DIR/feature-gate.rs:32:42
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:34:68
|
||||
--> $DIR/feature-gate.rs:32:68
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: only supported directly in conditions of `if` and `while` expressions
|
||||
note: `let`s wrapped in parentheses are not supported in a context with let chains
|
||||
--> $DIR/feature-gate.rs:34:42
|
||||
--> $DIR/feature-gate.rs:32:42
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:60:16
|
||||
--> $DIR/feature-gate.rs:55:16
|
||||
|
|
||||
LL | use_expr!((let 0 = 1 && 0 == 0));
|
||||
| ^^^
|
||||
|
|
@ -124,7 +124,7 @@ LL | use_expr!((let 0 = 1 && 0 == 0));
|
|||
= note: only supported directly in conditions of `if` and `while` expressions
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:60:16
|
||||
--> $DIR/feature-gate.rs:55:16
|
||||
|
|
||||
LL | use_expr!((let 0 = 1 && 0 == 0));
|
||||
| ^^^
|
||||
|
|
@ -133,7 +133,7 @@ LL | use_expr!((let 0 = 1 && 0 == 0));
|
|||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:63:16
|
||||
--> $DIR/feature-gate.rs:58:16
|
||||
|
|
||||
LL | use_expr!((let 0 = 1));
|
||||
| ^^^
|
||||
|
|
@ -141,7 +141,7 @@ LL | use_expr!((let 0 = 1));
|
|||
= note: only supported directly in conditions of `if` and `while` expressions
|
||||
|
||||
error: expected expression, found `let` statement
|
||||
--> $DIR/feature-gate.rs:63:16
|
||||
--> $DIR/feature-gate.rs:58:16
|
||||
|
|
||||
LL | use_expr!((let 0 = 1));
|
||||
| ^^^
|
||||
|
|
@ -150,7 +150,7 @@ LL | use_expr!((let 0 = 1));
|
|||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: no rules expected keyword `let`
|
||||
--> $DIR/feature-gate.rs:72:15
|
||||
--> $DIR/feature-gate.rs:67:15
|
||||
|
|
||||
LL | macro_rules! use_expr {
|
||||
| --------------------- when calling this macro
|
||||
|
|
@ -159,7 +159,7 @@ LL | use_expr!(let 0 = 1);
|
|||
| ^^^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match meta-variable `$e:expr`
|
||||
--> $DIR/feature-gate.rs:53:10
|
||||
--> $DIR/feature-gate.rs:48:10
|
||||
|
|
||||
LL | ($e:expr) => {
|
||||
| ^^^^^^^
|
||||
|
|
@ -187,7 +187,7 @@ LL | () if true && let 0 = 1 => {}
|
|||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:20:12
|
||||
--> $DIR/feature-gate.rs:19:12
|
||||
|
|
||||
LL | () if let 0 = 1 && true => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -198,7 +198,7 @@ LL | () if let 0 = 1 && true => {}
|
|||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:34:12
|
||||
--> $DIR/feature-gate.rs:32:12
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -209,7 +209,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
|
|||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:43:12
|
||||
--> $DIR/feature-gate.rs:39:12
|
||||
|
|
||||
LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -220,7 +220,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
|
|||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `if let` guards are experimental
|
||||
--> $DIR/feature-gate.rs:68:12
|
||||
--> $DIR/feature-gate.rs:63:12
|
||||
|
|
||||
LL | () if let 0 = 1 => {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
@ -230,56 +230,6 @@ LL | () if let 0 = 1 => {}
|
|||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:16:23
|
||||
|
|
||||
LL | () if true && let 0 = 1 => {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:20:15
|
||||
|
|
||||
LL | () if let 0 = 1 && true => {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:34:15
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:34:28
|
||||
|
|
||||
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable
|
||||
--> $DIR/feature-gate.rs:43:15
|
||||
|
|
||||
LL | () if let Range { start: _, end: _ } = (true..true) && false => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` 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: aborting due to 25 previous errors
|
||||
error: aborting due to 20 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Expression macros can't expand to a let match guard.
|
||||
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(let_chains)]
|
||||
|
||||
macro_rules! m {
|
||||
($e:expr) => { let Some(x) = $e }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: expected expression, found `let` statement
|
||||
--> $DIR/macro-expanded.rs:7:20
|
||||
--> $DIR/macro-expanded.rs:6:20
|
||||
|
|
||||
LL | ($e:expr) => { let Some(x) = $e }
|
||||
| ^^^
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//@ edition: 2024
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(let_chains)]
|
||||
#![allow(irrefutable_let_patterns)]
|
||||
|
||||
fn same_pattern(c: bool) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//@ edition: 2024
|
||||
// Parenthesised let "expressions" are not allowed in guards
|
||||
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(let_chains)]
|
||||
|
||||
#[cfg(false)]
|
||||
fn un_cfged() {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// Check shadowing in if let guards works as expected.
|
||||
//@ check-pass
|
||||
//@ edition: 2024
|
||||
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(let_chains)]
|
||||
|
||||
fn main() {
|
||||
let x: Option<Option<i32>> = Some(Some(6));
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//@ run-pass
|
||||
//@ edition: 2024
|
||||
|
||||
#![feature(let_chains)]
|
||||
#![allow(irrefutable_let_patterns)]
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(let_chains)]
|
||||
//@ edition: 2024
|
||||
|
||||
fn let_or_guard(x: Result<Option<i32>, ()>) {
|
||||
match x {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
//@ edition: 2021
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! make_if {
|
||||
(($($tt:tt)*) { $body:expr } { $else:expr }) => {{
|
||||
if $($tt)* {
|
||||
$body
|
||||
} else {
|
||||
$else
|
||||
}
|
||||
}};
|
||||
(let ($expr:expr) { $body:expr } { $else:expr }) => {{
|
||||
if let None = $expr {
|
||||
$body
|
||||
} else {
|
||||
$else
|
||||
}
|
||||
}};
|
||||
(let ($expr:expr) let ($expr2:expr) { $body:expr } { $else:expr }) => {{
|
||||
if let None = $expr && let None = $expr2 {
|
||||
$body
|
||||
} else {
|
||||
$else
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
//@ edition: 2024
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! make_if {
|
||||
(($($tt:tt)*) { $body:expr } { $else:expr }) => {{
|
||||
if $($tt)* {
|
||||
$body
|
||||
} else {
|
||||
$else
|
||||
}
|
||||
}};
|
||||
(let ($expr:expr) { $body:expr } { $else:expr }) => {{
|
||||
if let None = $expr {
|
||||
$body
|
||||
} else {
|
||||
$else
|
||||
}
|
||||
}};
|
||||
(let ($expr:expr) let ($expr2:expr) { $body:expr } { $else:expr }) => {{
|
||||
if let None = $expr && let None = $expr2 {
|
||||
$body
|
||||
} else {
|
||||
$else
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/edition-gate-macro-error.rs:19:30
|
||||
|
|
||||
LL | macro_in_2021::make_if!((let Some(0) = None && let Some(0) = None) { never!() } { never!() });
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable
|
||||
--> $DIR/edition-gate-macro-error.rs:19:52
|
||||
|
|
||||
LL | macro_in_2021::make_if!((let Some(0) = None && let Some(0) = None) { never!() } { never!() });
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable
|
||||
--> $DIR/edition-gate-macro-error.rs:22:5
|
||||
|
|
||||
LL | macro_in_2021::make_if!(let (Some(0)) let (Some(0)) { never!() } { never!() });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: this error originates in the macro `macro_in_2021::make_if` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/edition-gate-macro-error.rs:22:5
|
||||
|
|
||||
LL | macro_in_2021::make_if!(let (Some(0)) let (Some(0)) { never!() } { never!() });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: this error originates in the macro `macro_in_2021::make_if` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/edition-gate-macro-error.rs:26:30
|
||||
|
|
||||
LL | macro_in_2024::make_if!((let Some(0) = None && let Some(0) = None) { never!() } { never!() });
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable
|
||||
--> $DIR/edition-gate-macro-error.rs:26:52
|
||||
|
|
||||
LL | macro_in_2024::make_if!((let Some(0) = None && let Some(0) = None) { never!() } { never!() });
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` 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: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/edition-gate-macro-error.rs:19:30
|
||||
|
|
||||
LL | macro_in_2021::make_if!((let Some(0) = None && let Some(0) = None) { never!() } { never!() });
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable
|
||||
--> $DIR/edition-gate-macro-error.rs:19:52
|
||||
|
|
||||
LL | macro_in_2021::make_if!((let Some(0) = None && let Some(0) = None) { never!() } { never!() });
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` 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]: `let` expressions in this position are unstable
|
||||
--> $DIR/edition-gate-macro-error.rs:22:5
|
||||
|
|
||||
LL | macro_in_2021::make_if!(let (Some(0)) let (Some(0)) { never!() } { never!() });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: this error originates in the macro `macro_in_2021::make_if` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/edition-gate-macro-error.rs:22:5
|
||||
|
|
||||
LL | macro_in_2021::make_if!(let (Some(0)) let (Some(0)) { never!() } { never!() });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: this error originates in the macro `macro_in_2021::make_if` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
//@ revisions: edition2021 edition2024
|
||||
//@ compile-flags: -Z lint-mir -Z validate-mir
|
||||
//@ [edition2021] edition: 2021
|
||||
//@ [edition2024] edition: 2024
|
||||
//@ aux-build:macro-in-2021.rs
|
||||
//@ aux-build:macro-in-2024.rs
|
||||
|
||||
use std::unreachable as never;
|
||||
|
||||
// Compiletest doesn't specify the needed --extern flags to make `extern crate` unneccessary
|
||||
extern crate macro_in_2021;
|
||||
extern crate macro_in_2024;
|
||||
|
||||
fn main() {
|
||||
// Gated on both 2021 and 2024 if the `if` comes from a 2021 macro
|
||||
// Gated only on 2021 if the `if` comes from a 2024 macro
|
||||
// No gating if both the `if` and the chain are from a 2024 macro
|
||||
|
||||
macro_in_2021::make_if!((let Some(0) = None && let Some(0) = None) { never!() } { never!() });
|
||||
//~^ ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
macro_in_2021::make_if!(let (Some(0)) let (Some(0)) { never!() } { never!() });
|
||||
//~^ ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
|
||||
macro_in_2024::make_if!((let Some(0) = None && let Some(0) = None) { never!() } { never!() });
|
||||
//[edition2021]~^ ERROR `let` expressions in this position are unstable
|
||||
//[edition2021]~| ERROR `let` expressions in this position are unstable
|
||||
macro_in_2024::make_if!(let (Some(0)) let (Some(0)) { never!() } { never!() });
|
||||
}
|
||||
76
tests/ui/rfcs/rfc-2497-if-let-chains/edition-gate-macro.rs
Normal file
76
tests/ui/rfcs/rfc-2497-if-let-chains/edition-gate-macro.rs
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
//@ revisions: edition2021 edition2024
|
||||
//@ compile-flags: -Z lint-mir -Z validate-mir
|
||||
//@ [edition2021] edition: 2021
|
||||
//@ [edition2024] edition: 2024
|
||||
//@ aux-build:macro-in-2021.rs
|
||||
//@ aux-build:macro-in-2024.rs
|
||||
//@ run-pass
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::unreachable as never;
|
||||
use std::cell::RefCell;
|
||||
use std::convert::TryInto;
|
||||
|
||||
// Compiletest doesn't specify the needed --extern flags to make `extern crate` unneccessary
|
||||
extern crate macro_in_2021;
|
||||
extern crate macro_in_2024;
|
||||
|
||||
#[derive(Default)]
|
||||
struct DropOrderCollector(RefCell<Vec<u32>>);
|
||||
|
||||
struct LoudDrop<'a>(&'a DropOrderCollector, u32);
|
||||
|
||||
impl Drop for LoudDrop<'_> {
|
||||
fn drop(&mut self) {
|
||||
println!("{}", self.1);
|
||||
self.0.0.borrow_mut().push(self.1);
|
||||
}
|
||||
}
|
||||
|
||||
impl DropOrderCollector {
|
||||
fn print(&self, n: u32) {
|
||||
println!("{n}");
|
||||
self.0.borrow_mut().push(n)
|
||||
}
|
||||
fn some_loud(&self, n: u32) -> Option<LoudDrop> {
|
||||
Some(LoudDrop(self, n))
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn validate(self) {
|
||||
assert!(
|
||||
self.0
|
||||
.into_inner()
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.all(|(idx, item)| idx + 1 == item.try_into().unwrap())
|
||||
);
|
||||
}
|
||||
fn with_macro_2021(self) {
|
||||
// Edition 2021 drop behaviour
|
||||
macro_in_2021::make_if!((let None = self.some_loud(2)) { never!() } {self.print(1) });
|
||||
macro_in_2021::make_if!(let (self.some_loud(4)) { never!() } { self.print(3) });
|
||||
self.validate();
|
||||
}
|
||||
fn with_macro_2024(self) {
|
||||
// Edition 2024 drop behaviour
|
||||
macro_in_2024::make_if!((let None = self.some_loud(1)) { never!() } { self.print(2) });
|
||||
macro_in_2024::make_if!(let (self.some_loud(3)) { never!() } { self.print(4) });
|
||||
self.validate();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// 2021 drop order if it's a 2021 macro creating the `if`
|
||||
// 2024 drop order if it's a 2024 macro creating the `if`
|
||||
|
||||
// Compare this with edition-gate-macro-error.rs: We want to avoid exposing 2021 drop order,
|
||||
// because it can create bad MIR (issue #104843)
|
||||
// This test doesn't contain any let chains at all: it should be understood
|
||||
// in combination with `edition-gate-macro-error.rs`
|
||||
|
||||
DropOrderCollector::default().with_macro_2021();
|
||||
DropOrderCollector::default().with_macro_2024();
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(let_chains)]
|
||||
//@ edition: 2024
|
||||
|
||||
fn main() {
|
||||
let opt = Some(1i32);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
//@ check-pass
|
||||
|
||||
#![feature(let_chains)]
|
||||
//@ edition: 2024
|
||||
|
||||
fn main() {
|
||||
let x = Some(vec!["test"]);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
//@ check-pass
|
||||
|
||||
#![feature(let_chains)]
|
||||
//@ edition:2024
|
||||
|
||||
fn main() {
|
||||
let opt = Some("foo bar");
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ fn main() {
|
|||
match true {
|
||||
_ if let true = true && true => {}
|
||||
//~^ ERROR `if let` guards are
|
||||
//~| ERROR `let` expressions in this
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,16 +9,6 @@ LL | _ if let true = true && true => {}
|
|||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/issue-93150.rs:3:14
|
||||
|
|
||||
LL | _ if let true = true && true => {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` 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: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//@ compile-flags: -Zvalidate-mir -C opt-level=3
|
||||
//@ build-pass
|
||||
#![feature(let_chains)]
|
||||
//@ edition: 2024
|
||||
|
||||
struct TupleIter<T, I: Iterator<Item = T>> {
|
||||
inner: I,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
//@ edition: 2024
|
||||
//@ check-pass
|
||||
|
||||
#![feature(let_chains)]
|
||||
#![allow(irrefutable_let_patterns)]
|
||||
|
||||
struct Pd;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
#![feature(dyn_star)]
|
||||
#![feature(explicit_tail_calls)]
|
||||
#![feature(gen_blocks)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(more_qualified_paths)]
|
||||
#![feature(never_patterns)]
|
||||
#![feature(never_type)]
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#![feature(dyn_star)]
|
||||
#![feature(explicit_tail_calls)]
|
||||
#![feature(gen_blocks)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(more_qualified_paths)]
|
||||
#![feature(never_patterns)]
|
||||
#![feature(never_type)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//@ compile-flags: -Zunpretty=expanded
|
||||
//@ edition:2024
|
||||
//@ check-pass
|
||||
//@ edition: 2015
|
||||
|
||||
// This test covers the AST pretty-printer's insertion of parentheses in some
|
||||
// macro metavariable edge cases. Synthetic parentheses (i.e. not appearing in
|
||||
|
|
@ -8,7 +8,6 @@
|
|||
// 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 {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
#![feature(prelude_import)]
|
||||
#![no_std]
|
||||
//@ compile-flags: -Zunpretty=expanded
|
||||
//@ edition:2024
|
||||
//@ check-pass
|
||||
//@ edition: 2015
|
||||
|
||||
// This test covers the AST pretty-printer's insertion of parentheses in some
|
||||
// macro metavariable edge cases. Synthetic parentheses (i.e. not appearing in
|
||||
|
|
@ -10,10 +9,9 @@
|
|||
// 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::*;
|
||||
use std::prelude::rust_2024::*;
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue