Skip to content

Commit 44d848a

Browse files
authored
Merge pull request #241 from xFrednet/052-expressions-question-mark
API: Rename `QuestionMarkExpr` -> `TryExpr` (Breaking change)
2 parents 970b863 + 4bbb318 commit 44d848a

File tree

5 files changed

+55
-21
lines changed

5 files changed

+55
-21
lines changed

marker_api/src/ast/expr.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub enum ExprKind<'ast> {
6161
UnaryOp(&'ast UnaryOpExpr<'ast>),
6262
Ref(&'ast RefExpr<'ast>),
6363
BinaryOp(&'ast BinaryOpExpr<'ast>),
64-
QuestionMark(&'ast QuestionMarkExpr<'ast>),
64+
Try(&'ast TryExpr<'ast>),
6565
Assign(&'ast AssignExpr<'ast>),
6666
As(&'ast AsExpr<'ast>),
6767
Path(&'ast PathExpr<'ast>),
@@ -180,7 +180,7 @@ pub enum ExprPrecedence {
180180
Fn = 0x1000_0000,
181181
Index = 0x1000_0001,
182182

183-
QuestionMark = 0x0F00_0000,
183+
Try = 0x0F00_0000,
184184

185185
/// The unary `-` operator
186186
Neg = 0x0E00_0000,
@@ -249,7 +249,7 @@ macro_rules! impl_expr_kind_fn {
249249
impl_expr_kind_fn!((ExprKind) $method() -> $return_ty,
250250
IntLit, FloatLit, StrLit, CharLit, BoolLit,
251251
Block, Closure,
252-
UnaryOp, Ref, BinaryOp, QuestionMark, As, Assign,
252+
UnaryOp, Ref, BinaryOp, Try, As, Assign,
253253
Path, Index, Field,
254254
Call, Method,
255255
Array, Tuple, Ctor, Range,
@@ -384,7 +384,7 @@ mod test {
384384
assert_eq!(40, size_of::<UnaryOpExpr<'_>>(), "UnaryOpExpr<'_>");
385385
assert_eq!(40, size_of::<RefExpr<'_>>(), "RefExpr<'_>");
386386
assert_eq!(56, size_of::<BinaryOpExpr<'_>>(), "BinaryOpExpr<'_>");
387-
assert_eq!(32, size_of::<QuestionMarkExpr<'_>>(), "QuestionMarkExpr<'_>");
387+
assert_eq!(32, size_of::<TryExpr<'_>>(), "TryExpr<'_>");
388388
assert_eq!(80, size_of::<AssignExpr<'_>>(), "AssignExpr<'_>");
389389
assert_eq!(48, size_of::<AsExpr<'_>>(), "AsExpr<'_>");
390390
assert_eq!(96, size_of::<PathExpr<'_>>(), "PathExpr<'_>");

marker_api/src/ast/expr/op_exprs.rs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,23 +142,57 @@ impl<'ast> RefExpr<'ast> {
142142
}
143143
}
144144

145+
/// The `?` operator that unwraps valid values or propagates erroneous values to
146+
/// the the calling function.
147+
///
148+
/// Here is an example of the operator:
149+
///
150+
/// ```
151+
/// fn try_option_example(opt: Option<i32>) -> Option<String> {
152+
/// // The `?` operator unwraps the value if `opt` is `Some` or
153+
/// // propagates `None` if `opt` is empty.
154+
/// // v
155+
/// let value = opt?;
156+
/// // `value` has the type `i32`
157+
///
158+
/// // [...]
159+
/// # Some(value.to_string())
160+
/// }
161+
///
162+
/// fn try_result_example(res: Result<i32, ()>) -> Result<String, ()> {
163+
/// // The `?` operator unwraps the value if `res` is `Ok` or
164+
/// // propagates the value of `Err` if `res` is an error.
165+
/// // v
166+
/// let value = res?;
167+
/// // `value` has the type `i32`
168+
///
169+
/// // [...]
170+
/// # Ok(value.to_string())
171+
/// }
172+
/// ```
173+
///
174+
/// This operator is also known as the *question mark* or *error propagation* operator.
175+
///
176+
/// See <https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator>
145177
#[repr(C)]
146178
#[derive(Debug)]
147-
pub struct QuestionMarkExpr<'ast> {
179+
pub struct TryExpr<'ast> {
148180
data: CommonExprData<'ast>,
149181
expr: ExprKind<'ast>,
150182
}
151183

152-
impl<'ast> QuestionMarkExpr<'ast> {
184+
impl<'ast> TryExpr<'ast> {
185+
/// The expression that might produce an error, that would be propagated by
186+
/// this operator.
153187
pub fn expr(&self) -> ExprKind<'ast> {
154188
self.expr
155189
}
156190
}
157191

158-
super::impl_expr_data!(QuestionMarkExpr<'ast>, QuestionMark);
192+
super::impl_expr_data!(TryExpr<'ast>, Try);
159193

160194
#[cfg(feature = "driver-api")]
161-
impl<'ast> QuestionMarkExpr<'ast> {
195+
impl<'ast> TryExpr<'ast> {
162196
pub fn new(data: CommonExprData<'ast>, expr: ExprKind<'ast>) -> Self {
163197
Self { data, expr }
164198
}

marker_rustc_driver/src/conversion/marker/expr.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use marker_api::{
44
ArrayExpr, AsExpr, AssignExpr, AwaitExpr, BinaryOpExpr, BinaryOpKind, BlockExpr, BoolLitExpr, BreakExpr,
55
CallExpr, CaptureKind, CharLitExpr, ClosureExpr, ClosureParam, CommonExprData, ConstExpr, ContinueExpr,
66
CtorExpr, CtorField, ExprKind, ExprPrecedence, FieldExpr, FloatLitExpr, FloatSuffix, ForExpr, IfExpr,
7-
IndexExpr, IntLitExpr, IntSuffix, LetExpr, LoopExpr, MatchArm, MatchExpr, MethodExpr, PathExpr,
8-
QuestionMarkExpr, RangeExpr, RefExpr, ReturnExpr, StrLitData, StrLitExpr, TupleExpr, UnaryOpExpr,
9-
UnaryOpKind, UnstableExpr, WhileExpr,
7+
IndexExpr, IntLitExpr, IntSuffix, LetExpr, LoopExpr, MatchArm, MatchExpr, MethodExpr, PathExpr, RangeExpr,
8+
RefExpr, ReturnExpr, StrLitData, StrLitExpr, TryExpr, TupleExpr, UnaryOpExpr, UnaryOpKind, UnstableExpr,
9+
WhileExpr,
1010
},
1111
pat::PatKind,
1212
Ident, Safety, Syncness,
@@ -210,7 +210,7 @@ impl<'ast, 'tcx> MarkerConverterInner<'ast, 'tcx> {
210210
ExprKind::Match(self.alloc(MatchExpr::new(data, self.to_expr(scrutinee), self.to_match_arms(arms))))
211211
},
212212
hir::ExprKind::Match(_scrutinee, [_early_return, _continue], hir::MatchSource::TryDesugar(_)) => {
213-
ExprKind::QuestionMark(self.alloc(self.to_try_expr_from_desugar(expr)))
213+
ExprKind::Try(self.alloc(self.to_try_expr_from_desugar(expr)))
214214
},
215215
hir::ExprKind::Match(_scrutinee, [_awaitee_arm], hir::MatchSource::AwaitDesugar) => {
216216
ExprKind::Await(self.alloc(self.to_await_expr_from_desugar(expr)))
@@ -552,10 +552,10 @@ impl<'ast, 'tcx> MarkerConverterInner<'ast, 'tcx> {
552552
}
553553
}
554554

555-
fn to_try_expr_from_desugar(&self, try_desugar: &hir::Expr<'tcx>) -> QuestionMarkExpr<'ast> {
555+
fn to_try_expr_from_desugar(&self, try_desugar: &hir::Expr<'tcx>) -> TryExpr<'ast> {
556556
if let hir::ExprKind::Match(scrutinee, [_ret, _con], hir::MatchSource::TryDesugar(_)) = try_desugar.kind {
557557
if let hir::ExprKind::Call(_try_path, [tested_expr]) = scrutinee.kind {
558-
return QuestionMarkExpr::new(
558+
return TryExpr::new(
559559
CommonExprData::new(self.to_expr_id(try_desugar.hir_id), self.to_span_id(try_desugar.span)),
560560
self.to_expr(tested_expr),
561561
);

marker_uilints/tests/ui/print_cond_expr.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,8 +1018,8 @@ warning: print test
10181018
48 | let _print_option_match = x?;
10191019
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
10201020
|
1021-
= note: QuestionMark(
1022-
QuestionMarkExpr {
1021+
= note: Try(
1022+
TryExpr {
10231023
data: CommonExprData {
10241024
_lifetime: PhantomData<&()>,
10251025
id: ExprId(..),
@@ -1063,8 +1063,8 @@ warning: print test
10631063
54 | let _print_result_match = x?;
10641064
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
10651065
|
1066-
= note: QuestionMark(
1067-
QuestionMarkExpr {
1066+
= note: Try(
1067+
TryExpr {
10681068
data: CommonExprData {
10691069
_lifetime: PhantomData<&()>,
10701070
id: ExprId(..),

marker_utils/src/visitor.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ pub fn traverse_expr<'ast, B>(
248248
traverse_expr(cx, visitor, e.left())?;
249249
traverse_expr(cx, visitor, e.right())?;
250250
},
251-
ExprKind::QuestionMark(e) => {
251+
ExprKind::Try(e) => {
252252
traverse_expr(cx, visitor, e.expr())?;
253253
},
254254
ExprKind::Assign(e) => {
@@ -448,14 +448,14 @@ impl_traversable_for!(&'ast Body<'ast>, traverse_body);
448448
pub trait BoolTraversable<'ast>: Traversable<'ast, bool> {
449449
/// Checks if the given node contains an early return, in the form of an
450450
/// [`ReturnExpr`](marker_api::ast::expr::ReturnExpr) or
451-
/// [`QuestionMarkExpr`](marker_api::ast::expr::QuestionMarkExpr).
451+
/// [`TryExpr`](marker_api::ast::expr::TryExpr).
452452
///
453453
/// This function is useful, for lints which suggest moving code snippets into
454454
/// a closure or different function. Return statements might prevent the suggested
455455
/// refactoring.
456456
fn contains_return(&self, cx: &'ast AstContext<'ast>) -> bool {
457457
self.for_each_expr(cx, |expr| {
458-
if matches!(expr, ExprKind::Return(_) | ExprKind::QuestionMark(_)) {
458+
if matches!(expr, ExprKind::Return(_) | ExprKind::Try(_)) {
459459
ControlFlow::Break(true)
460460
} else {
461461
ControlFlow::Continue(())

0 commit comments

Comments
 (0)