Auto merge of #118433 - matthiaskrgr:rollup-fi9lrwg, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #116839 (Implement thread parking for xous) - #118265 (remove the memcpy-on-equal-ptrs assumption) - #118269 (Unify `TraitRefs` and `PolyTraitRefs` in `ValuePairs`) - #118394 (Remove HIR opkinds) - #118398 (Add proper cfgs in std) - #118419 (Eagerly return `ExprKind::Err` on `yield`/`await` in wrong coroutine context) - #118422 (Fix coroutine validation for mixed panic strategy) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
ec1f21cb04
@ -817,7 +817,7 @@ pub enum BorrowKind {
|
||||
Raw,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
|
||||
pub enum BinOpKind {
|
||||
/// The `+` operator (addition)
|
||||
Add,
|
||||
@ -858,9 +858,9 @@ pub enum BinOpKind {
|
||||
}
|
||||
|
||||
impl BinOpKind {
|
||||
pub fn to_string(&self) -> &'static str {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
use BinOpKind::*;
|
||||
match *self {
|
||||
match self {
|
||||
Add => "+",
|
||||
Sub => "-",
|
||||
Mul => "*",
|
||||
@ -881,19 +881,25 @@ pub fn to_string(&self) -> &'static str {
|
||||
Gt => ">",
|
||||
}
|
||||
}
|
||||
pub fn lazy(&self) -> bool {
|
||||
|
||||
pub fn is_lazy(&self) -> bool {
|
||||
matches!(self, BinOpKind::And | BinOpKind::Or)
|
||||
}
|
||||
|
||||
pub fn is_comparison(&self) -> bool {
|
||||
use BinOpKind::*;
|
||||
// Note for developers: please keep this as is;
|
||||
// Note for developers: please keep this match exhaustive;
|
||||
// we want compilation to fail if another variant is added.
|
||||
match *self {
|
||||
Eq | Lt | Le | Ne | Gt | Ge => true,
|
||||
And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the binary operator takes its arguments by value.
|
||||
pub fn is_by_value(self) -> bool {
|
||||
!self.is_comparison()
|
||||
}
|
||||
}
|
||||
|
||||
pub type BinOp = Spanned<BinOpKind>;
|
||||
@ -901,7 +907,7 @@ pub fn is_comparison(&self) -> bool {
|
||||
/// Unary operator.
|
||||
///
|
||||
/// Note that `&data` is not an operator, it's an `AddrOf` expression.
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Copy)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
|
||||
pub enum UnOp {
|
||||
/// The `*` operator for dereferencing
|
||||
Deref,
|
||||
@ -912,13 +918,18 @@ pub enum UnOp {
|
||||
}
|
||||
|
||||
impl UnOp {
|
||||
pub fn to_string(op: UnOp) -> &'static str {
|
||||
match op {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
UnOp::Deref => "*",
|
||||
UnOp::Not => "!",
|
||||
UnOp::Neg => "-",
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the unary operator takes its argument by value.
|
||||
pub fn is_by_value(self) -> bool {
|
||||
matches!(self, Self::Neg | Self::Not)
|
||||
}
|
||||
}
|
||||
|
||||
/// A statement
|
||||
|
@ -72,7 +72,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
|
||||
let kind = match &e.kind {
|
||||
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
|
||||
ExprKind::ConstBlock(c) => {
|
||||
let c = self.with_new_scopes(|this| hir::ConstBlock {
|
||||
let c = self.with_new_scopes(c.value.span, |this| hir::ConstBlock {
|
||||
def_id: this.local_def_id(c.id),
|
||||
hir_id: this.lower_node_id(c.id),
|
||||
body: this.lower_const_body(c.value.span, Some(&c.value)),
|
||||
@ -189,7 +189,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
|
||||
None,
|
||||
e.span,
|
||||
hir::CoroutineSource::Block,
|
||||
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
|
||||
|this| this.with_new_scopes(e.span, |this| this.lower_block_expr(block)),
|
||||
),
|
||||
ExprKind::Await(expr, await_kw_span) => self.lower_expr_await(*await_kw_span, expr),
|
||||
ExprKind::Closure(box Closure {
|
||||
@ -323,7 +323,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
|
||||
None,
|
||||
e.span,
|
||||
hir::CoroutineSource::Block,
|
||||
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
|
||||
|this| this.with_new_scopes(e.span, |this| this.lower_block_expr(block)),
|
||||
),
|
||||
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
|
||||
ExprKind::Err => hir::ExprKind::Err(
|
||||
@ -350,30 +350,8 @@ fn lower_unop(&mut self, u: UnOp) -> hir::UnOp {
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_binop(&mut self, b: BinOp) -> hir::BinOp {
|
||||
Spanned {
|
||||
node: match b.node {
|
||||
BinOpKind::Add => hir::BinOpKind::Add,
|
||||
BinOpKind::Sub => hir::BinOpKind::Sub,
|
||||
BinOpKind::Mul => hir::BinOpKind::Mul,
|
||||
BinOpKind::Div => hir::BinOpKind::Div,
|
||||
BinOpKind::Rem => hir::BinOpKind::Rem,
|
||||
BinOpKind::And => hir::BinOpKind::And,
|
||||
BinOpKind::Or => hir::BinOpKind::Or,
|
||||
BinOpKind::BitXor => hir::BinOpKind::BitXor,
|
||||
BinOpKind::BitAnd => hir::BinOpKind::BitAnd,
|
||||
BinOpKind::BitOr => hir::BinOpKind::BitOr,
|
||||
BinOpKind::Shl => hir::BinOpKind::Shl,
|
||||
BinOpKind::Shr => hir::BinOpKind::Shr,
|
||||
BinOpKind::Eq => hir::BinOpKind::Eq,
|
||||
BinOpKind::Lt => hir::BinOpKind::Lt,
|
||||
BinOpKind::Le => hir::BinOpKind::Le,
|
||||
BinOpKind::Ne => hir::BinOpKind::Ne,
|
||||
BinOpKind::Ge => hir::BinOpKind::Ge,
|
||||
BinOpKind::Gt => hir::BinOpKind::Gt,
|
||||
},
|
||||
span: self.lower_span(b.span),
|
||||
}
|
||||
fn lower_binop(&mut self, b: BinOp) -> BinOp {
|
||||
Spanned { node: b.node, span: self.lower_span(b.span) }
|
||||
}
|
||||
|
||||
fn lower_legacy_const_generics(
|
||||
@ -781,10 +759,10 @@ fn lower_expr_await(&mut self, await_kw_span: Span, expr: &Expr) -> hir::ExprKin
|
||||
match self.coroutine_kind {
|
||||
Some(hir::CoroutineKind::Async(_)) => {}
|
||||
Some(hir::CoroutineKind::Coroutine) | Some(hir::CoroutineKind::Gen(_)) | None => {
|
||||
self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
|
||||
return hir::ExprKind::Err(self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
|
||||
await_kw_span,
|
||||
item_span: self.current_item,
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
let span = self.mark_span_with_reason(DesugaringKind::Await, await_kw_span, None);
|
||||
@ -944,9 +922,7 @@ fn lower_expr_closure(
|
||||
) -> hir::ExprKind<'hir> {
|
||||
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
|
||||
|
||||
let (body_id, coroutine_option) = self.with_new_scopes(move |this| {
|
||||
let prev = this.current_item;
|
||||
this.current_item = Some(fn_decl_span);
|
||||
let (body_id, coroutine_option) = self.with_new_scopes(fn_decl_span, move |this| {
|
||||
let mut coroutine_kind = None;
|
||||
let body_id = this.lower_fn_body(decl, |this| {
|
||||
let e = this.lower_expr_mut(body);
|
||||
@ -955,7 +931,6 @@ fn lower_expr_closure(
|
||||
});
|
||||
let coroutine_option =
|
||||
this.coroutine_movability_for_fn(decl, fn_decl_span, coroutine_kind, movability);
|
||||
this.current_item = prev;
|
||||
(body_id, coroutine_option)
|
||||
});
|
||||
|
||||
@ -1041,7 +1016,7 @@ fn lower_expr_async_closure(
|
||||
let outer_decl =
|
||||
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
|
||||
|
||||
let body = self.with_new_scopes(|this| {
|
||||
let body = self.with_new_scopes(fn_decl_span, |this| {
|
||||
// FIXME(cramertj): allow `async` non-`move` closures with arguments.
|
||||
if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
|
||||
this.tcx.sess.emit_err(AsyncNonMoveClosureNotSupported { fn_decl_span });
|
||||
@ -1063,7 +1038,7 @@ fn lower_expr_async_closure(
|
||||
async_ret_ty,
|
||||
body.span,
|
||||
hir::CoroutineSource::Closure,
|
||||
|this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
|
||||
|this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)),
|
||||
);
|
||||
let hir_id = this.lower_node_id(inner_closure_id);
|
||||
this.maybe_forward_track_caller(body.span, closure_hir_id, hir_id);
|
||||
@ -1503,7 +1478,9 @@ fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::Expr
|
||||
match self.coroutine_kind {
|
||||
Some(hir::CoroutineKind::Gen(_)) => {}
|
||||
Some(hir::CoroutineKind::Async(_)) => {
|
||||
self.tcx.sess.emit_err(AsyncCoroutinesNotSupported { span });
|
||||
return hir::ExprKind::Err(
|
||||
self.tcx.sess.emit_err(AsyncCoroutinesNotSupported { span }),
|
||||
);
|
||||
}
|
||||
Some(hir::CoroutineKind::Coroutine) | None => {
|
||||
if !self.tcx.features().coroutines {
|
||||
|
@ -202,9 +202,7 @@ fn lower_item_kind(
|
||||
body,
|
||||
..
|
||||
}) => {
|
||||
self.with_new_scopes(|this| {
|
||||
this.current_item = Some(ident.span);
|
||||
|
||||
self.with_new_scopes(ident.span, |this| {
|
||||
// Note: we don't need to change the return type from `T` to
|
||||
// `impl Future<Output = T>` here because lower_body
|
||||
// only cares about the input argument patterns in the function
|
||||
@ -837,7 +835,6 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
|
||||
},
|
||||
),
|
||||
AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
|
||||
self.current_item = Some(i.span);
|
||||
let asyncness = sig.header.asyncness;
|
||||
let body_id = self.lower_maybe_async_body(
|
||||
i.span,
|
||||
|
@ -878,7 +878,10 @@ fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -
|
||||
result
|
||||
}
|
||||
|
||||
fn with_new_scopes<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
|
||||
fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {
|
||||
let current_item = self.current_item;
|
||||
self.current_item = Some(scope_span);
|
||||
|
||||
let was_in_loop_condition = self.is_in_loop_condition;
|
||||
self.is_in_loop_condition = false;
|
||||
|
||||
@ -890,6 +893,8 @@ fn with_new_scopes<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
|
||||
|
||||
self.is_in_loop_condition = was_in_loop_condition;
|
||||
|
||||
self.current_item = current_item;
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
@ -1239,7 +1244,7 @@ fn lower_generic_arg(
|
||||
tokens: None,
|
||||
};
|
||||
|
||||
let ct = self.with_new_scopes(|this| hir::AnonConst {
|
||||
let ct = self.with_new_scopes(span, |this| hir::AnonConst {
|
||||
def_id,
|
||||
hir_id: this.lower_node_id(node_id),
|
||||
body: this.lower_const_body(path_expr.span, Some(&path_expr)),
|
||||
@ -2246,7 +2251,7 @@ fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
|
||||
}
|
||||
|
||||
fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
|
||||
self.with_new_scopes(|this| hir::AnonConst {
|
||||
self.with_new_scopes(c.value.span, |this| hir::AnonConst {
|
||||
def_id: this.local_def_id(c.id),
|
||||
hir_id: this.lower_node_id(c.id),
|
||||
body: this.lower_const_body(c.value.span, Some(&c.value)),
|
||||
|
@ -255,12 +255,12 @@ fn print_expr_binary(&mut self, op: ast::BinOp, lhs: &ast::Expr, rhs: &ast::Expr
|
||||
|
||||
self.print_expr_maybe_paren(lhs, left_prec);
|
||||
self.space();
|
||||
self.word_space(op.node.to_string());
|
||||
self.word_space(op.node.as_str());
|
||||
self.print_expr_maybe_paren(rhs, right_prec)
|
||||
}
|
||||
|
||||
fn print_expr_unary(&mut self, op: ast::UnOp, expr: &ast::Expr) {
|
||||
self.word(ast::UnOp::to_string(op));
|
||||
self.word(op.as_str());
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
|
||||
}
|
||||
|
||||
@ -470,7 +470,7 @@ pub(super) fn print_expr_outer_attr_style(&mut self, expr: &ast::Expr, is_inline
|
||||
let prec = AssocOp::Assign.precedence() as i8;
|
||||
self.print_expr_maybe_paren(lhs, prec + 1);
|
||||
self.space();
|
||||
self.word(op.node.to_string());
|
||||
self.word(op.node.as_str());
|
||||
self.word_space("=");
|
||||
self.print_expr_maybe_paren(rhs, prec);
|
||||
}
|
||||
|
@ -653,3 +653,4 @@
|
||||
// E0721, // `await` keyword
|
||||
// E0723, // unstable feature in `const` context
|
||||
// E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
|
||||
// E0744, // merged into E0728
|
||||
|
@ -1,8 +1,10 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
An unsupported expression was used inside a const context.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,edition2018,E0744
|
||||
```ignore (removed error code)
|
||||
const _: i32 = {
|
||||
async { 0 }.await
|
||||
};
|
||||
|
@ -7,8 +7,8 @@
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy};
|
||||
pub use rustc_ast::{BindingAnnotation, BorrowKind, ByRef, ImplPolarity, IsAuto};
|
||||
pub use rustc_ast::{CaptureBy, Movability, Mutability};
|
||||
pub use rustc_ast::{BinOp, BinOpKind, BindingAnnotation, BorrowKind, ByRef, CaptureBy};
|
||||
pub use rustc_ast::{ImplPolarity, IsAuto, Movability, Mutability, UnOp};
|
||||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
@ -1174,155 +1174,6 @@ pub enum PatKind<'hir> {
|
||||
Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
|
||||
pub enum BinOpKind {
|
||||
/// The `+` operator (addition).
|
||||
Add,
|
||||
/// The `-` operator (subtraction).
|
||||
Sub,
|
||||
/// The `*` operator (multiplication).
|
||||
Mul,
|
||||
/// The `/` operator (division).
|
||||
Div,
|
||||
/// The `%` operator (modulus).
|
||||
Rem,
|
||||
/// The `&&` operator (logical and).
|
||||
And,
|
||||
/// The `||` operator (logical or).
|
||||
Or,
|
||||
/// The `^` operator (bitwise xor).
|
||||
BitXor,
|
||||
/// The `&` operator (bitwise and).
|
||||
BitAnd,
|
||||
/// The `|` operator (bitwise or).
|
||||
BitOr,
|
||||
/// The `<<` operator (shift left).
|
||||
Shl,
|
||||
/// The `>>` operator (shift right).
|
||||
Shr,
|
||||
/// The `==` operator (equality).
|
||||
Eq,
|
||||
/// The `<` operator (less than).
|
||||
Lt,
|
||||
/// The `<=` operator (less than or equal to).
|
||||
Le,
|
||||
/// The `!=` operator (not equal to).
|
||||
Ne,
|
||||
/// The `>=` operator (greater than or equal to).
|
||||
Ge,
|
||||
/// The `>` operator (greater than).
|
||||
Gt,
|
||||
}
|
||||
|
||||
impl BinOpKind {
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
BinOpKind::Add => "+",
|
||||
BinOpKind::Sub => "-",
|
||||
BinOpKind::Mul => "*",
|
||||
BinOpKind::Div => "/",
|
||||
BinOpKind::Rem => "%",
|
||||
BinOpKind::And => "&&",
|
||||
BinOpKind::Or => "||",
|
||||
BinOpKind::BitXor => "^",
|
||||
BinOpKind::BitAnd => "&",
|
||||
BinOpKind::BitOr => "|",
|
||||
BinOpKind::Shl => "<<",
|
||||
BinOpKind::Shr => ">>",
|
||||
BinOpKind::Eq => "==",
|
||||
BinOpKind::Lt => "<",
|
||||
BinOpKind::Le => "<=",
|
||||
BinOpKind::Ne => "!=",
|
||||
BinOpKind::Ge => ">=",
|
||||
BinOpKind::Gt => ">",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_lazy(self) -> bool {
|
||||
matches!(self, BinOpKind::And | BinOpKind::Or)
|
||||
}
|
||||
|
||||
pub fn is_comparison(self) -> bool {
|
||||
match self {
|
||||
BinOpKind::Eq
|
||||
| BinOpKind::Lt
|
||||
| BinOpKind::Le
|
||||
| BinOpKind::Ne
|
||||
| BinOpKind::Gt
|
||||
| BinOpKind::Ge => true,
|
||||
BinOpKind::And
|
||||
| BinOpKind::Or
|
||||
| BinOpKind::Add
|
||||
| BinOpKind::Sub
|
||||
| BinOpKind::Mul
|
||||
| BinOpKind::Div
|
||||
| BinOpKind::Rem
|
||||
| BinOpKind::BitXor
|
||||
| BinOpKind::BitAnd
|
||||
| BinOpKind::BitOr
|
||||
| BinOpKind::Shl
|
||||
| BinOpKind::Shr => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the binary operator takes its arguments by value.
|
||||
pub fn is_by_value(self) -> bool {
|
||||
!self.is_comparison()
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<ast::BinOpKind> for BinOpKind {
|
||||
fn into(self) -> ast::BinOpKind {
|
||||
match self {
|
||||
BinOpKind::Add => ast::BinOpKind::Add,
|
||||
BinOpKind::Sub => ast::BinOpKind::Sub,
|
||||
BinOpKind::Mul => ast::BinOpKind::Mul,
|
||||
BinOpKind::Div => ast::BinOpKind::Div,
|
||||
BinOpKind::Rem => ast::BinOpKind::Rem,
|
||||
BinOpKind::And => ast::BinOpKind::And,
|
||||
BinOpKind::Or => ast::BinOpKind::Or,
|
||||
BinOpKind::BitXor => ast::BinOpKind::BitXor,
|
||||
BinOpKind::BitAnd => ast::BinOpKind::BitAnd,
|
||||
BinOpKind::BitOr => ast::BinOpKind::BitOr,
|
||||
BinOpKind::Shl => ast::BinOpKind::Shl,
|
||||
BinOpKind::Shr => ast::BinOpKind::Shr,
|
||||
BinOpKind::Eq => ast::BinOpKind::Eq,
|
||||
BinOpKind::Lt => ast::BinOpKind::Lt,
|
||||
BinOpKind::Le => ast::BinOpKind::Le,
|
||||
BinOpKind::Ne => ast::BinOpKind::Ne,
|
||||
BinOpKind::Ge => ast::BinOpKind::Ge,
|
||||
BinOpKind::Gt => ast::BinOpKind::Gt,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type BinOp = Spanned<BinOpKind>;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
|
||||
pub enum UnOp {
|
||||
/// The `*` operator (dereferencing).
|
||||
Deref,
|
||||
/// The `!` operator (logical negation).
|
||||
Not,
|
||||
/// The `-` operator (negation).
|
||||
Neg,
|
||||
}
|
||||
|
||||
impl UnOp {
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
Self::Deref => "*",
|
||||
Self::Not => "!",
|
||||
Self::Neg => "-",
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the unary operator takes its argument by value.
|
||||
pub fn is_by_value(self) -> bool {
|
||||
matches!(self, Self::Neg | Self::Not)
|
||||
}
|
||||
}
|
||||
|
||||
/// A statement.
|
||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||
pub struct Stmt<'hir> {
|
||||
|
@ -448,7 +448,11 @@ fn to_trace(
|
||||
) -> TypeTrace<'tcx> {
|
||||
TypeTrace {
|
||||
cause: cause.clone(),
|
||||
values: TraitRefs(ExpectedFound::new(a_is_expected, a, b)),
|
||||
values: PolyTraitRefs(ExpectedFound::new(
|
||||
a_is_expected,
|
||||
ty::Binder::dummy(a),
|
||||
ty::Binder::dummy(b),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1667,9 +1667,7 @@ enum Mismatch<'a> {
|
||||
.report(diag);
|
||||
(false, Mismatch::Fixed("signature"))
|
||||
}
|
||||
ValuePairs::TraitRefs(_) | ValuePairs::PolyTraitRefs(_) => {
|
||||
(false, Mismatch::Fixed("trait"))
|
||||
}
|
||||
ValuePairs::PolyTraitRefs(_) => (false, Mismatch::Fixed("trait")),
|
||||
ValuePairs::Aliases(infer::ExpectedFound { expected, .. }) => {
|
||||
(false, Mismatch::Fixed(self.tcx.def_descr(expected.def_id)))
|
||||
}
|
||||
@ -2219,18 +2217,6 @@ fn values_str(
|
||||
infer::Aliases(exp_found) => self.expected_found_str(exp_found),
|
||||
infer::ExistentialTraitRef(exp_found) => self.expected_found_str(exp_found),
|
||||
infer::ExistentialProjection(exp_found) => self.expected_found_str(exp_found),
|
||||
infer::TraitRefs(exp_found) => {
|
||||
let pretty_exp_found = ty::error::ExpectedFound {
|
||||
expected: exp_found.expected.print_only_trait_path(),
|
||||
found: exp_found.found.print_only_trait_path(),
|
||||
};
|
||||
match self.expected_found_str(pretty_exp_found) {
|
||||
Some((expected, found, _, _)) if expected == found => {
|
||||
self.expected_found_str(exp_found)
|
||||
}
|
||||
ret => ret,
|
||||
}
|
||||
}
|
||||
infer::PolyTraitRefs(exp_found) => {
|
||||
let pretty_exp_found = ty::error::ExpectedFound {
|
||||
expected: exp_found.expected.print_only_trait_path(),
|
||||
|
@ -197,11 +197,6 @@ fn try_report_trait_placeholder_mismatch(
|
||||
value_pairs: &ValuePairs<'tcx>,
|
||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||
let (expected_args, found_args, trait_def_id) = match value_pairs {
|
||||
ValuePairs::TraitRefs(ExpectedFound { expected, found })
|
||||
if expected.def_id == found.def_id =>
|
||||
{
|
||||
(expected.args, found.args, expected.def_id)
|
||||
}
|
||||
ValuePairs::PolyTraitRefs(ExpectedFound { expected, found })
|
||||
if expected.def_id() == found.def_id() =>
|
||||
{
|
||||
|
@ -384,7 +384,6 @@ pub enum ValuePairs<'tcx> {
|
||||
Regions(ExpectedFound<ty::Region<'tcx>>),
|
||||
Terms(ExpectedFound<ty::Term<'tcx>>),
|
||||
Aliases(ExpectedFound<ty::AliasTy<'tcx>>),
|
||||
TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
|
||||
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
|
||||
PolySigs(ExpectedFound<ty::PolyFnSig<'tcx>>),
|
||||
ExistentialTraitRef(ExpectedFound<ty::PolyExistentialTraitRef<'tcx>>),
|
||||
|
@ -656,7 +656,7 @@ fn is_expr_delims_necessary(
|
||||
) -> bool {
|
||||
if followed_by_else {
|
||||
match inner.kind {
|
||||
ast::ExprKind::Binary(op, ..) if op.node.lazy() => return true,
|
||||
ast::ExprKind::Binary(op, ..) if op.node.is_lazy() => return true,
|
||||
_ if classify::expr_trailing_brace(inner).is_some() => return true,
|
||||
_ => {}
|
||||
}
|
||||
@ -1016,7 +1016,7 @@ fn check_unused_delims_expr(
|
||||
rustc_span::source_map::Spanned { node, .. },
|
||||
_,
|
||||
_,
|
||||
) if node.lazy()))
|
||||
) if node.is_lazy()))
|
||||
{
|
||||
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos, is_kw)
|
||||
}
|
||||
|
@ -51,7 +51,6 @@
|
||||
//! Otherwise it drops all the values in scope at the last suspension point.
|
||||
|
||||
use crate::abort_unwinding_calls;
|
||||
use crate::add_call_guards;
|
||||
use crate::deref_separator::deref_finder;
|
||||
use crate::errors;
|
||||
use crate::pass_manager as pm;
|
||||
@ -1168,18 +1167,9 @@ fn create_coroutine_drop_shim<'tcx>(
|
||||
simplify::remove_dead_blocks(&mut body);
|
||||
|
||||
// Update the body's def to become the drop glue.
|
||||
// This needs to be updated before the AbortUnwindingCalls pass.
|
||||
let coroutine_instance = body.source.instance;
|
||||
let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None);
|
||||
let drop_instance = InstanceDef::DropGlue(drop_in_place, Some(coroutine_ty));
|
||||
body.source.instance = drop_instance;
|
||||
|
||||
pm::run_passes_no_validate(
|
||||
tcx,
|
||||
&mut body,
|
||||
&[&abort_unwinding_calls::AbortUnwindingCalls, &add_call_guards::CriticalCallEdges],
|
||||
None,
|
||||
);
|
||||
|
||||
// Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible
|
||||
// filename.
|
||||
|
@ -74,11 +74,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
|
||||
let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args);
|
||||
debug!("make_shim({:?}) = {:?}", instance, body);
|
||||
|
||||
// Run empty passes to mark phase change and perform validation.
|
||||
pm::run_passes(
|
||||
tcx,
|
||||
&mut body,
|
||||
&[],
|
||||
&[
|
||||
&abort_unwinding_calls::AbortUnwindingCalls,
|
||||
&add_call_guards::CriticalCallEdges,
|
||||
],
|
||||
Some(MirPhase::Runtime(RuntimePhase::Optimized)),
|
||||
);
|
||||
|
||||
|
@ -384,10 +384,10 @@ fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
|
||||
|
||||
fn check_let_else_init_bool_expr(&self, init: &ast::Expr) {
|
||||
if let ast::ExprKind::Binary(op, ..) = init.kind {
|
||||
if op.node.lazy() {
|
||||
if op.node.is_lazy() {
|
||||
self.sess.emit_err(errors::InvalidExpressionInLetElse {
|
||||
span: init.span,
|
||||
operator: op.node.to_string(),
|
||||
operator: op.node.as_str(),
|
||||
sugg: errors::WrapExpressionInParentheses {
|
||||
left: init.span.shrink_to_lo(),
|
||||
right: init.span.shrink_to_hi(),
|
||||
|
@ -17,7 +17,7 @@
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::{sym, Span, Symbol};
|
||||
|
||||
use crate::errors::{ExprNotAllowedInContext, SkippingConstChecks};
|
||||
use crate::errors::SkippingConstChecks;
|
||||
|
||||
/// An expression that is not *always* legal in a const context.
|
||||
#[derive(Clone, Copy)]
|
||||
@ -138,11 +138,10 @@ fn const_check_violated(&self, expr: NonConstExpr, span: Span) {
|
||||
|
||||
match missing_gates.as_slice() {
|
||||
[] => {
|
||||
tcx.sess.emit_err(ExprNotAllowedInContext {
|
||||
span_bug!(
|
||||
span,
|
||||
expr: expr.name(),
|
||||
context: const_kind.keyword_name(),
|
||||
});
|
||||
"we should not have reached this point, since `.await` is denied earlier"
|
||||
);
|
||||
}
|
||||
|
||||
[missing_primary, ref missing_secondary @ ..] => {
|
||||
|
@ -1005,15 +1005,6 @@ pub struct FeaturePreviouslyDeclared<'a, 'b> {
|
||||
pub prev_declared: &'b str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_expr_not_allowed_in_context, code = "E0744")]
|
||||
pub struct ExprNotAllowedInContext<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub expr: String,
|
||||
pub context: &'a str,
|
||||
}
|
||||
|
||||
pub struct BreakNonLoop<'a> {
|
||||
pub span: Span,
|
||||
pub head: Option<Span>,
|
||||
|
@ -423,12 +423,14 @@ pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
/// Specialize clones into pre-allocated, uninitialized memory.
|
||||
/// Used by `Box::clone` and `Rc`/`Arc::make_mut`.
|
||||
pub(crate) trait WriteCloneIntoRaw: Sized {
|
||||
unsafe fn write_clone_into_raw(&self, target: *mut Self);
|
||||
}
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
impl<T: Clone> WriteCloneIntoRaw for T {
|
||||
#[inline]
|
||||
default unsafe fn write_clone_into_raw(&self, target: *mut Self) {
|
||||
@ -438,6 +440,7 @@ impl<T: Clone> WriteCloneIntoRaw for T {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
impl<T: Copy> WriteCloneIntoRaw for T {
|
||||
#[inline]
|
||||
unsafe fn write_clone_into_raw(&self, target: *mut Self) {
|
||||
|
@ -148,6 +148,7 @@ fn fmt(
|
||||
|
||||
/// An intermediate trait for specialization of `Extend`.
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
trait SpecExtend<I: IntoIterator> {
|
||||
/// Extends `self` with the contents of the given iterator.
|
||||
fn spec_extend(&mut self, iter: I);
|
||||
|
@ -2023,6 +2023,7 @@ unsafe fn allocate_for_slice_in(len: usize, alloc: &A) -> *mut RcBox<[T]> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
/// Specialization trait used for `From<&[T]>`.
|
||||
trait RcFromSlice<T> {
|
||||
fn from_slice(slice: &[T]) -> Self;
|
||||
|
@ -3503,6 +3503,7 @@ fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
/// Specialization trait used for collecting into `Arc<[T]>`.
|
||||
trait ToArcSlice<T>: Iterator<Item = T> + Sized {
|
||||
fn to_arc_slice(self) -> Arc<[T]>;
|
||||
|
@ -58,6 +58,7 @@
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt;
|
||||
use core::hash::{Hash, Hasher};
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
use core::iter;
|
||||
use core::marker::PhantomData;
|
||||
use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
|
||||
@ -101,6 +102,7 @@
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
use self::is_zero::IsZero;
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
mod is_zero;
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
@ -2599,6 +2601,7 @@ pub fn from_elem_in<T: Clone, A: Allocator>(elem: T, n: usize, alloc: A) -> Vec<
|
||||
<T as SpecFromElem>::from_elem(elem, n, alloc)
|
||||
}
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
trait ExtendFromWithinSpec {
|
||||
/// # Safety
|
||||
///
|
||||
@ -2607,6 +2610,7 @@ trait ExtendFromWithinSpec {
|
||||
unsafe fn spec_extend_from_within(&mut self, src: Range<usize>);
|
||||
}
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
|
||||
default unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
|
||||
// SAFETY:
|
||||
@ -2626,6 +2630,7 @@ impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
|
||||
unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
|
||||
let count = src.len();
|
||||
|
@ -24,9 +24,8 @@
|
||||
//! which are generated by Rust codegen backends. Additionally, this library can make explicit
|
||||
//! calls to `strlen`. Their signatures are the same as found in C, but there are extra
|
||||
//! assumptions about their semantics: For `memcpy`, `memmove`, `memset`, `memcmp`, and `bcmp`, if
|
||||
//! the `n` parameter is 0, the function is assumed to not be UB. Furthermore, for `memcpy`, if
|
||||
//! source and target pointer are equal, the function is assumed to not be UB.
|
||||
//! (Note that these are standard assumptions among compilers:
|
||||
//! the `n` parameter is 0, the function is assumed to not be UB, even if the pointers are NULL or
|
||||
//! dangling. (Note that making extra assumptions about these functions is common among compilers:
|
||||
//! [clang](https://reviews.llvm.org/D86993) and [GCC](https://gcc.gnu.org/onlinedocs/gcc/Standards.html#C-Language) do the same.)
|
||||
//! These functions are often provided by the system libc, but can also be provided by the
|
||||
//! [compiler-builtins crate](https://crates.io/crates/compiler_builtins).
|
||||
|
@ -336,6 +336,7 @@
|
||||
#![feature(portable_simd)]
|
||||
#![feature(prelude_2024)]
|
||||
#![feature(ptr_as_uninit)]
|
||||
#![feature(ptr_from_ref)]
|
||||
#![feature(raw_os_nonzero)]
|
||||
#![feature(round_ties_even)]
|
||||
#![feature(slice_internals)]
|
||||
|
@ -28,7 +28,6 @@
|
||||
pub mod stdio;
|
||||
pub mod thread;
|
||||
pub mod thread_local_key;
|
||||
#[path = "../unsupported/thread_parking.rs"]
|
||||
pub mod thread_parking;
|
||||
pub mod time;
|
||||
|
||||
|
94
library/std/src/sys/xous/thread_parking.rs
Normal file
94
library/std/src/sys/xous/thread_parking.rs
Normal file
@ -0,0 +1,94 @@
|
||||
use crate::os::xous::ffi::{blocking_scalar, scalar};
|
||||
use crate::os::xous::services::{ticktimer_server, TicktimerScalar};
|
||||
use crate::pin::Pin;
|
||||
use crate::ptr;
|
||||
use crate::sync::atomic::{
|
||||
AtomicI8,
|
||||
Ordering::{Acquire, Release},
|
||||
};
|
||||
use crate::time::Duration;
|
||||
|
||||
const NOTIFIED: i8 = 1;
|
||||
const EMPTY: i8 = 0;
|
||||
const PARKED: i8 = -1;
|
||||
|
||||
pub struct Parker {
|
||||
state: AtomicI8,
|
||||
}
|
||||
|
||||
impl Parker {
|
||||
pub unsafe fn new_in_place(parker: *mut Parker) {
|
||||
unsafe { parker.write(Parker { state: AtomicI8::new(EMPTY) }) }
|
||||
}
|
||||
|
||||
fn index(&self) -> usize {
|
||||
ptr::from_ref(self).addr()
|
||||
}
|
||||
|
||||
pub unsafe fn park(self: Pin<&Self>) {
|
||||
// Change NOTIFIED to EMPTY and EMPTY to PARKED.
|
||||
let state = self.state.fetch_sub(1, Acquire);
|
||||
if state == NOTIFIED {
|
||||
return;
|
||||
}
|
||||
|
||||
// The state was set to PARKED. Wait until the `unpark` wakes us up.
|
||||
blocking_scalar(
|
||||
ticktimer_server(),
|
||||
TicktimerScalar::WaitForCondition(self.index(), 0).into(),
|
||||
)
|
||||
.expect("failed to send WaitForCondition command");
|
||||
|
||||
self.state.swap(EMPTY, Acquire);
|
||||
}
|
||||
|
||||
pub unsafe fn park_timeout(self: Pin<&Self>, timeout: Duration) {
|
||||
// Change NOTIFIED to EMPTY and EMPTY to PARKED.
|
||||
let state = self.state.fetch_sub(1, Acquire);
|
||||
if state == NOTIFIED {
|
||||
return;
|
||||
}
|
||||
|
||||
// A value of zero indicates an indefinite wait. Clamp the number of
|
||||
// milliseconds to the allowed range.
|
||||
let millis = usize::max(timeout.as_millis().try_into().unwrap_or(usize::MAX), 1);
|
||||
|
||||
let was_timeout = blocking_scalar(
|
||||
ticktimer_server(),
|
||||
TicktimerScalar::WaitForCondition(self.index(), millis).into(),
|
||||
)
|
||||
.expect("failed to send WaitForCondition command")[0]
|
||||
!= 0;
|
||||
|
||||
let state = self.state.swap(EMPTY, Acquire);
|
||||
if was_timeout && state == NOTIFIED {
|
||||
// The state was set to NOTIFIED after we returned from the wait
|
||||
// but before we reset the state. Therefore, a wakeup is on its
|
||||
// way, which we need to consume here.
|
||||
// NOTICE: this is a priority hole.
|
||||
blocking_scalar(
|
||||
ticktimer_server(),
|
||||
TicktimerScalar::WaitForCondition(self.index(), 0).into(),
|
||||
)
|
||||
.expect("failed to send WaitForCondition command");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unpark(self: Pin<&Self>) {
|
||||
let state = self.state.swap(NOTIFIED, Release);
|
||||
if state == PARKED {
|
||||
// The thread is parked, wake it up.
|
||||
blocking_scalar(
|
||||
ticktimer_server(),
|
||||
TicktimerScalar::NotifyCondition(self.index(), 1).into(),
|
||||
)
|
||||
.expect("failed to send NotifyCondition command");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Parker {
|
||||
fn drop(&mut self) {
|
||||
scalar(ticktimer_server(), TicktimerScalar::FreeCondition(self.index()).into()).ok();
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note};
|
||||
use clippy_utils::is_span_if;
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind, UnOp};
|
||||
use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
@ -144,7 +144,7 @@ fn check_assign(cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
let eq_span = lhs.span.between(rhs.span);
|
||||
if let ExprKind::Unary(op, ref sub_rhs) = rhs.kind {
|
||||
if let Some(eq_snippet) = snippet_opt(cx, eq_span) {
|
||||
let op = UnOp::to_string(op);
|
||||
let op = op.as_str();
|
||||
let eqop_span = lhs.span.between(sub_rhs.span);
|
||||
if eq_snippet.ends_with('=') {
|
||||
span_lint_and_note(
|
||||
@ -177,11 +177,11 @@ fn check_unop(cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
&& let unop_operand_span = rhs.span.until(un_rhs.span)
|
||||
&& let Some(binop_snippet) = snippet_opt(cx, binop_span)
|
||||
&& let Some(unop_operand_snippet) = snippet_opt(cx, unop_operand_span)
|
||||
&& let binop_str = BinOpKind::to_string(&binop.node)
|
||||
&& let binop_str = binop.node.as_str()
|
||||
// no space after BinOp operator and space after UnOp operator
|
||||
&& binop_snippet.ends_with(binop_str) && unop_operand_snippet.ends_with(' ')
|
||||
{
|
||||
let unop_str = UnOp::to_string(op);
|
||||
let unop_str = op.as_str();
|
||||
let eqop_span = lhs.span.between(un_rhs.span);
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
|
@ -78,7 +78,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
let sugg = format!(
|
||||
"({}) {} ({})",
|
||||
snippet_with_applicability(cx, left.span, "..", &mut applicability),
|
||||
op.to_string(),
|
||||
op.as_str(),
|
||||
snippet_with_applicability(cx, right.span, "..", &mut applicability)
|
||||
);
|
||||
span_sugg(expr, sugg, applicability);
|
||||
@ -87,7 +87,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
let sugg = format!(
|
||||
"({}) {} {}",
|
||||
snippet_with_applicability(cx, left.span, "..", &mut applicability),
|
||||
op.to_string(),
|
||||
op.as_str(),
|
||||
snippet_with_applicability(cx, right.span, "..", &mut applicability)
|
||||
);
|
||||
span_sugg(expr, sugg, applicability);
|
||||
@ -96,7 +96,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
let sugg = format!(
|
||||
"{} {} ({})",
|
||||
snippet_with_applicability(cx, left.span, "..", &mut applicability),
|
||||
op.to_string(),
|
||||
op.as_str(),
|
||||
snippet_with_applicability(cx, right.span, "..", &mut applicability)
|
||||
);
|
||||
span_sugg(expr, sugg, applicability);
|
||||
|
@ -298,7 +298,7 @@ fn replace_left_sugg(
|
||||
) -> String {
|
||||
format!(
|
||||
"{left_suggestion} {} {}",
|
||||
binop.op.to_string(),
|
||||
binop.op.as_str(),
|
||||
snippet_with_applicability(cx, binop.right.span, "..", applicability),
|
||||
)
|
||||
}
|
||||
@ -312,7 +312,7 @@ fn replace_right_sugg(
|
||||
format!(
|
||||
"{} {} {right_suggestion}",
|
||||
snippet_with_applicability(cx, binop.left.span, "..", applicability),
|
||||
binop.op.to_string(),
|
||||
binop.op.as_str(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -382,7 +382,7 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String {
|
||||
| AssocOp::GreaterEqual => {
|
||||
format!(
|
||||
"{lhs} {} {rhs}",
|
||||
op.to_ast_binop().expect("Those are AST ops").to_string()
|
||||
op.to_ast_binop().expect("Those are AST ops").as_str()
|
||||
)
|
||||
},
|
||||
AssocOp::Assign => format!("{lhs} = {rhs}"),
|
||||
|
@ -1933,7 +1933,7 @@ fn rewrite_unary_op(
|
||||
shape: Shape,
|
||||
) -> Option<String> {
|
||||
// For some reason, an UnOp is not spanned like BinOp!
|
||||
rewrite_unary_prefix(context, ast::UnOp::to_string(op), expr, shape)
|
||||
rewrite_unary_prefix(context, op.as_str(), expr, shape)
|
||||
}
|
||||
|
||||
pub(crate) enum RhsAssignKind<'ast> {
|
||||
|
@ -339,7 +339,7 @@ fn flatten(
|
||||
if let Some(pop) = stack.pop() {
|
||||
match pop.kind {
|
||||
ast::ExprKind::Binary(op, _, ref rhs) => {
|
||||
separators.push(op.node.to_string());
|
||||
separators.push(op.node.as_str());
|
||||
node = rhs;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
@ -3,9 +3,6 @@
|
||||
async fn fun() {
|
||||
[1; ().await];
|
||||
//~^ error: `await` is only allowed inside `async` functions and blocks
|
||||
//~| error: `.await` is not allowed in a `const`
|
||||
//~| error: `.await` is not allowed in a `const`
|
||||
//~| error: `()` is not a future
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,37 +1,12 @@
|
||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||
--> $DIR/issue-70594.rs:4:12
|
||||
|
|
||||
LL | async fn fun() {
|
||||
| --- this is not `async`
|
||||
LL | [1; ().await];
|
||||
| ^^^^^ only allowed inside `async` functions and blocks
|
||||
| ---^^^^^
|
||||
| | |
|
||||
| | only allowed inside `async` functions and blocks
|
||||
| this is not `async`
|
||||
|
||||
error[E0744]: `.await` is not allowed in a `const`
|
||||
--> $DIR/issue-70594.rs:4:9
|
||||
|
|
||||
LL | [1; ().await];
|
||||
| ^^^^^^^^
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error[E0744]: `.await` is not allowed in a `const`
|
||||
--> $DIR/issue-70594.rs:4:12
|
||||
|
|
||||
LL | [1; ().await];
|
||||
| ^^^^^
|
||||
|
||||
error[E0277]: `()` is not a future
|
||||
--> $DIR/issue-70594.rs:4:12
|
||||
|
|
||||
LL | [1; ().await];
|
||||
| -^^^^^
|
||||
| ||
|
||||
| |`()` is not a future
|
||||
| help: remove the `.await`
|
||||
|
|
||||
= help: the trait `Future` is not implemented for `()`
|
||||
= note: () must be a future or must implement `IntoFuture` to be awaited
|
||||
= note: required for `()` to implement `IntoFuture`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0728, E0744.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
For more information about this error, try `rustc --explain E0728`.
|
||||
|
@ -11,5 +11,4 @@ fn main() {
|
||||
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||
(|_| 2333).await;
|
||||
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||
//~| ERROR is not a future
|
||||
}
|
||||
|
@ -24,20 +24,6 @@ LL | fn main() {
|
||||
LL | (|_| 2333).await;
|
||||
| ^^^^^ only allowed inside `async` functions and blocks
|
||||
|
||||
error[E0277]: `{closure@$DIR/issue-62009-1.rs:12:6: 12:9}` is not a future
|
||||
--> $DIR/issue-62009-1.rs:12:16
|
||||
|
|
||||
LL | (|_| 2333).await;
|
||||
| -^^^^^
|
||||
| ||
|
||||
| |`{closure@$DIR/issue-62009-1.rs:12:6: 12:9}` is not a future
|
||||
| help: remove the `.await`
|
||||
|
|
||||
= help: the trait `Future` is not implemented for closure `{closure@$DIR/issue-62009-1.rs:12:6: 12:9}`
|
||||
= note: {closure@$DIR/issue-62009-1.rs:12:6: 12:9} must be a future or must implement `IntoFuture` to be awaited
|
||||
= note: required for `{closure@$DIR/issue-62009-1.rs:12:6: 12:9}` to implement `IntoFuture`
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0728.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
For more information about this error, try `rustc --explain E0728`.
|
||||
|
11
tests/ui/coroutine/auxiliary/unwind-aux.rs
Normal file
11
tests/ui/coroutine/auxiliary/unwind-aux.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// compile-flags: -Cpanic=unwind --crate-type=lib
|
||||
// no-prefer-dynamic
|
||||
// edition:2021
|
||||
|
||||
#![feature(coroutines)]
|
||||
pub fn run<T>(a: T) {
|
||||
let _ = move || {
|
||||
drop(a);
|
||||
yield;
|
||||
};
|
||||
}
|
13
tests/ui/coroutine/unwind-abort-mix.rs
Normal file
13
tests/ui/coroutine/unwind-abort-mix.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// Ensure that coroutine drop glue is valid when mixing different panic
|
||||
// strategies. Regression test for #116953.
|
||||
//
|
||||
// no-prefer-dynamic
|
||||
// build-pass
|
||||
// aux-build:unwind-aux.rs
|
||||
// compile-flags: -Cpanic=abort
|
||||
// needs-unwind
|
||||
extern crate unwind_aux;
|
||||
|
||||
pub fn main() {
|
||||
unwind_aux::run(String::new());
|
||||
}
|
Loading…
Reference in New Issue
Block a user