Skip to content

Commit b46ce08

Browse files
authored
Auto merge of #37678 - eddyb:rollup, r=eddyb
Rollup of 5 pull requests - Successful merges: #37402, #37412, #37661, #37664, #37667 - Failed merges:
2 parents 0b46947 + 3a5b45a commit b46ce08

File tree

148 files changed

+1827
-2524
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

148 files changed

+1827
-2524
lines changed

src/doc/book/syntax-index.md

+2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
* `|=` (`var |= expr`): bitwise or & assignment. Overloadable (`BitOrAssign`).
9595
* `||` (`expr || expr`): logical or.
9696
* `_`: "ignored" pattern binding (see [Patterns (Ignoring bindings)]). Also used to make integer-literals readable (see [Reference (Integer literals)]).
97+
* `?` (`expr?`): Error propagation. Returns early when `Err(_)` is encountered, unwraps otherwise. Similar to the [`try!` macro].
9798

9899
## Other Syntax
99100

@@ -210,6 +211,7 @@
210211
[Functions]: functions.html
211212
[Generics]: generics.html
212213
[Iterators]: iterators.html
214+
[`try!` macro]: error-handling.html#the-try-macro
213215
[Lifetimes]: lifetimes.html
214216
[Loops (`for`)]: loops.html#for
215217
[Loops (`loop`)]: loops.html#loop

src/doc/reference.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -2863,8 +2863,8 @@ assert_eq!(x, y);
28632863

28642864
### Unary operator expressions
28652865

2866-
Rust defines the following unary operators. They are all written as prefix operators,
2867-
before the expression they apply to.
2866+
Rust defines the following unary operators. With the exception of `?`, they are
2867+
all written as prefix operators, before the expression they apply to.
28682868

28692869
* `-`
28702870
: Negation. Signed integer types and floating-point types support negation. It
@@ -2893,6 +2893,10 @@ before the expression they apply to.
28932893
If the `&` or `&mut` operators are applied to an rvalue, a
28942894
temporary value is created; the lifetime of this temporary value
28952895
is defined by [syntactic rules](#temporary-lifetimes).
2896+
* `?`
2897+
: Propagating errors if applied to `Err(_)` and unwrapping if
2898+
applied to `Ok(_)`. Only works on the `Result<T, E>` type,
2899+
and written in postfix notation.
28962900

28972901
### Binary operator expressions
28982902

src/libpanic_abort/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8),
5353
// now hopefully.
5454
#[no_mangle]
5555
pub unsafe extern fn __rust_start_panic(_data: usize, _vtable: usize) -> u32 {
56-
return abort();
56+
abort();
5757

5858
#[cfg(unix)]
5959
unsafe fn abort() -> ! {

src/librustc/cfg/construct.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,25 @@ struct LoopScope {
3333
}
3434

3535
pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
36-
blk: &hir::Block) -> CFG {
36+
body: &hir::Expr) -> CFG {
3737
let mut graph = graph::Graph::new();
3838
let entry = graph.add_node(CFGNodeData::Entry);
3939

4040
// `fn_exit` is target of return exprs, which lies somewhere
41-
// outside input `blk`. (Distinguishing `fn_exit` and `block_exit`
41+
// outside input `body`. (Distinguishing `fn_exit` and `body_exit`
4242
// also resolves chicken-and-egg problem that arises if you try to
43-
// have return exprs jump to `block_exit` during construction.)
43+
// have return exprs jump to `body_exit` during construction.)
4444
let fn_exit = graph.add_node(CFGNodeData::Exit);
45-
let block_exit;
45+
let body_exit;
4646

4747
let mut cfg_builder = CFGBuilder {
4848
graph: graph,
4949
fn_exit: fn_exit,
5050
tcx: tcx,
5151
loop_scopes: Vec::new()
5252
};
53-
block_exit = cfg_builder.block(blk, entry);
54-
cfg_builder.add_contained_edge(block_exit, fn_exit);
53+
body_exit = cfg_builder.expr(body, entry);
54+
cfg_builder.add_contained_edge(body_exit, fn_exit);
5555
let CFGBuilder {graph, ..} = cfg_builder;
5656
CFG {graph: graph,
5757
entry: entry,

src/librustc/cfg/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ pub type CFGEdge = graph::Edge<CFGEdgeData>;
5959

6060
impl CFG {
6161
pub fn new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
62-
blk: &hir::Block) -> CFG {
63-
construct::construct(tcx, blk)
62+
body: &hir::Expr) -> CFG {
63+
construct::construct(tcx, body)
6464
}
6565

6666
pub fn node_is_reachable(&self, id: ast::NodeId) -> bool {

src/librustc/dep_graph/dep_node.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,11 @@ pub enum DepNode<D: Clone + Debug> {
103103
// nodes. Often we map multiple tables to the same node if there
104104
// is no point in distinguishing them (e.g., both the type and
105105
// predicates for an item wind up in `ItemSignature`).
106-
ImplOrTraitItems(D),
106+
AssociatedItems(D),
107107
ItemSignature(D),
108108
FieldTy(D),
109109
SizedConstraint(D),
110-
ImplOrTraitItemDefIds(D),
110+
AssociatedItemDefIds(D),
111111
InherentImpls(D),
112112

113113
// The set of impls for a given trait. Ultimately, it would be
@@ -153,10 +153,10 @@ impl<D: Clone + Debug> DepNode<D> {
153153
TransCrateItem,
154154
TypeckItemType,
155155
TypeckItemBody,
156-
ImplOrTraitItems,
156+
AssociatedItems,
157157
ItemSignature,
158158
FieldTy,
159-
ImplOrTraitItemDefIds,
159+
AssociatedItemDefIds,
160160
InherentImpls,
161161
TraitImpls,
162162
ReprHints,
@@ -219,11 +219,11 @@ impl<D: Clone + Debug> DepNode<D> {
219219
RvalueCheck(ref d) => op(d).map(RvalueCheck),
220220
TransCrateItem(ref d) => op(d).map(TransCrateItem),
221221
TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
222-
ImplOrTraitItems(ref d) => op(d).map(ImplOrTraitItems),
222+
AssociatedItems(ref d) => op(d).map(AssociatedItems),
223223
ItemSignature(ref d) => op(d).map(ItemSignature),
224224
FieldTy(ref d) => op(d).map(FieldTy),
225225
SizedConstraint(ref d) => op(d).map(SizedConstraint),
226-
ImplOrTraitItemDefIds(ref d) => op(d).map(ImplOrTraitItemDefIds),
226+
AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds),
227227
InherentImpls(ref d) => op(d).map(InherentImpls),
228228
TraitImpls(ref d) => op(d).map(TraitImpls),
229229
TraitItems(ref d) => op(d).map(TraitItems),

src/librustc/diagnostics.rs

-114
Original file line numberDiff line numberDiff line change
@@ -672,120 +672,6 @@ extern "C" {
672672
```
673673
"##,
674674

675-
E0269: r##"
676-
A returned value was expected but not all control paths return one.
677-
678-
Erroneous code example:
679-
680-
```compile_fail,E0269
681-
fn abracada_FAIL() -> String {
682-
"this won't work".to_string();
683-
// error: not all control paths return a value
684-
}
685-
```
686-
687-
In the previous code, the function is supposed to return a `String`, however,
688-
the code returns nothing (because of the ';'). Another erroneous code would be:
689-
690-
```compile_fail
691-
fn abracada_FAIL(b: bool) -> u32 {
692-
if b {
693-
0
694-
} else {
695-
"a" // It fails because an `u32` was expected and something else is
696-
// returned.
697-
}
698-
}
699-
```
700-
701-
It is advisable to find out what the unhandled cases are and check for them,
702-
returning an appropriate value or panicking if necessary. Check if you need
703-
to remove a semicolon from the last expression, like in the first erroneous
704-
code example.
705-
"##,
706-
707-
E0270: r##"
708-
Rust lets you define functions which are known to never return, i.e. are
709-
'diverging', by marking its return type as `!`.
710-
711-
For example, the following functions never return:
712-
713-
```no_run
714-
fn foo() -> ! {
715-
loop {}
716-
}
717-
718-
fn bar() -> ! {
719-
foo() // foo() is diverging, so this will diverge too
720-
}
721-
722-
fn baz() -> ! {
723-
panic!(); // this macro internally expands to a call to a diverging function
724-
}
725-
```
726-
727-
Such functions can be used in a place where a value is expected without
728-
returning a value of that type, for instance:
729-
730-
```no_run
731-
fn foo() -> ! {
732-
loop {}
733-
}
734-
735-
let x = 3;
736-
737-
let y = match x {
738-
1 => 1,
739-
2 => 4,
740-
_ => foo() // diverging function called here
741-
};
742-
743-
println!("{}", y)
744-
```
745-
746-
If the third arm of the match block is reached, since `foo()` doesn't ever
747-
return control to the match block, it is fine to use it in a place where an
748-
integer was expected. The `match` block will never finish executing, and any
749-
point where `y` (like the print statement) is needed will not be reached.
750-
751-
However, if we had a diverging function that actually does finish execution:
752-
753-
```ignore
754-
fn foo() -> ! {
755-
loop {break;}
756-
}
757-
```
758-
759-
Then we would have an unknown value for `y` in the following code:
760-
761-
```no_run
762-
fn foo() -> ! {
763-
loop {}
764-
}
765-
766-
let x = 3;
767-
768-
let y = match x {
769-
1 => 1,
770-
2 => 4,
771-
_ => foo()
772-
};
773-
774-
println!("{}", y);
775-
```
776-
777-
In the previous example, the print statement was never reached when the
778-
wildcard match arm was hit, so we were okay with `foo()` not returning an
779-
integer that we could set to `y`. But in this example, `foo()` actually does
780-
return control, so the print statement will be executed with an uninitialized
781-
value.
782-
783-
Obviously we cannot have functions which are allowed to be used in such
784-
positions and yet can return control. So, if you are defining a function that
785-
returns `!`, make sure that there is no way for it to actually finish
786-
executing.
787-
"##,
788-
789675
E0271: r##"
790676
This is because of a type mismatch between the associated type of some
791677
trait (e.g. `T::Bar`, where `T` implements `trait Quux { type Bar; }`)

src/librustc/hir/intravisit.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ pub trait Visitor<'v> : Sized {
138138
fn visit_where_predicate(&mut self, predicate: &'v WherePredicate) {
139139
walk_where_predicate(self, predicate)
140140
}
141-
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, id: NodeId) {
141+
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Expr, s: Span, id: NodeId) {
142142
walk_fn(self, fk, fd, b, s, id)
143143
}
144144
fn visit_trait_item(&mut self, ti: &'v TraitItem) {
@@ -635,13 +635,13 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'
635635
pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
636636
function_kind: FnKind<'v>,
637637
function_declaration: &'v FnDecl,
638-
function_body: &'v Block,
638+
function_body: &'v Expr,
639639
_span: Span,
640640
id: NodeId) {
641641
visitor.visit_id(id);
642642
walk_fn_decl(visitor, function_declaration);
643643
walk_fn_kind(visitor, function_kind);
644-
visitor.visit_block(function_body)
644+
visitor.visit_expr(function_body)
645645
}
646646

647647
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
@@ -925,7 +925,7 @@ impl<'v> Visitor<'v> for IdRangeComputingVisitor {
925925
/// Computes the id range for a single fn body, ignoring nested items.
926926
pub fn compute_id_range_for_fn_body(fk: FnKind,
927927
decl: &FnDecl,
928-
body: &Block,
928+
body: &Expr,
929929
sp: Span,
930930
id: NodeId)
931931
-> IdRange {

src/librustc/hir/lowering.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -595,12 +595,13 @@ impl<'a> LoweringContext<'a> {
595595
hir::ItemConst(self.lower_ty(t), self.lower_expr(e))
596596
}
597597
ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
598+
let body = self.lower_block(body);
598599
hir::ItemFn(self.lower_fn_decl(decl),
599600
self.lower_unsafety(unsafety),
600601
self.lower_constness(constness),
601602
abi,
602603
self.lower_generics(generics),
603-
self.lower_block(body))
604+
self.expr_block(body, ThinVec::new()))
604605
}
605606
ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)),
606607
ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)),
@@ -665,7 +666,10 @@ impl<'a> LoweringContext<'a> {
665666
}
666667
TraitItemKind::Method(ref sig, ref body) => {
667668
hir::MethodTraitItem(this.lower_method_sig(sig),
668-
body.as_ref().map(|x| this.lower_block(x)))
669+
body.as_ref().map(|x| {
670+
let body = this.lower_block(x);
671+
this.expr_block(body, ThinVec::new())
672+
}))
669673
}
670674
TraitItemKind::Type(ref bounds, ref default) => {
671675
hir::TypeTraitItem(this.lower_bounds(bounds),
@@ -691,8 +695,9 @@ impl<'a> LoweringContext<'a> {
691695
hir::ImplItemKind::Const(this.lower_ty(ty), this.lower_expr(expr))
692696
}
693697
ImplItemKind::Method(ref sig, ref body) => {
698+
let body = this.lower_block(body);
694699
hir::ImplItemKind::Method(this.lower_method_sig(sig),
695-
this.lower_block(body))
700+
this.expr_block(body, ThinVec::new()))
696701
}
697702
ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)),
698703
ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
@@ -1110,7 +1115,7 @@ impl<'a> LoweringContext<'a> {
11101115
self.with_parent_def(e.id, |this| {
11111116
hir::ExprClosure(this.lower_capture_clause(capture_clause),
11121117
this.lower_fn_decl(decl),
1113-
this.lower_block(body),
1118+
this.lower_expr(body),
11141119
fn_decl_span)
11151120
})
11161121
}

0 commit comments

Comments
 (0)