From 73db83aa70bea7973fa4bb1f025de199a19d5282 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 06:53:02 +0100 Subject: [PATCH 01/29] cleanup check_pat --- src/librustc_typeck/check/pat.rs | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 2f53378303b58..397f8682ede73 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -72,7 +72,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let is_nrp = self.is_non_ref_pat(pat, path_resolution.map(|(res, ..)| res)); let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, is_nrp); - let ty = match &pat.kind { + let ty = match pat.kind { PatKind::Wild => expected, PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, discrim_span), PatKind::Range(begin, end, _) => { @@ -82,50 +82,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } PatKind::Binding(ba, var_id, _, sub) => { - let sub = sub.as_deref(); - self.check_pat_ident(pat, *ba, *var_id, sub, expected, def_bm, discrim_span) + self.check_pat_ident(pat, ba, var_id, sub, expected, def_bm, discrim_span) } - PatKind::TupleStruct(qpath, subpats, ddpos) => self.check_pat_tuple_struct( + PatKind::TupleStruct(ref qpath, subpats, ddpos) => self.check_pat_tuple_struct( pat, qpath, subpats, - *ddpos, + ddpos, expected, def_bm, discrim_span, ), - PatKind::Path(qpath) => { + PatKind::Path(ref qpath) => { self.check_pat_path(pat, path_resolution.unwrap(), qpath, expected) } - PatKind::Struct(qpath, fields, etc) => { - self.check_pat_struct(pat, qpath, fields, *etc, expected, def_bm, discrim_span) + PatKind::Struct(ref qpath, fields, etc) => { + self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, discrim_span) } PatKind::Or(pats) => { - for pat in *pats { + for pat in pats { self.check_pat(pat, expected, def_bm, discrim_span); } expected } PatKind::Tuple(elements, ddpos) => { - self.check_pat_tuple(pat.span, *elements, *ddpos, expected, def_bm, discrim_span) + self.check_pat_tuple(pat.span, elements, ddpos, expected, def_bm, discrim_span) } PatKind::Box(inner) => { self.check_pat_box(pat.span, inner, expected, def_bm, discrim_span) } PatKind::Ref(inner, mutbl) => { - self.check_pat_ref(pat, inner, *mutbl, expected, def_bm, discrim_span) + self.check_pat_ref(pat, inner, mutbl, expected, def_bm, discrim_span) } PatKind::Slice(before, slice, after) => { - let slice = slice.as_deref(); - self.check_pat_slice( - pat.span, - *before, - slice, - *after, - expected, - def_bm, - discrim_span, - ) + self.check_pat_slice(pat.span, before, slice, after, expected, def_bm, discrim_span) } }; From ab050d6a83a9bdc5856a20402b6ea440d474638c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 07:02:24 +0100 Subject: [PATCH 02/29] MatchExpressionArmPattern: Use more generic wording. The existing wording was inappropriate for e.g. `if let Ok(_) = expr { .. }`. The diagnostic would leak the fact that we desugar to a `match`. --- src/librustc/infer/error_reporting/mod.rs | 2 +- src/test/ui/block-result/issue-13624.stderr | 2 +- src/test/ui/error-codes/E0308-4.stderr | 2 +- ...exclusive_range_pattern_syntax_collision.stderr | 2 +- ...xclusive_range_pattern_syntax_collision2.stderr | 2 +- ...xclusive_range_pattern_syntax_collision3.stderr | 4 ++-- src/test/ui/issues/issue-11844.stderr | 2 +- src/test/ui/issues/issue-12552.stderr | 2 +- src/test/ui/issues/issue-13466.stderr | 4 ++-- src/test/ui/issues/issue-15896.stderr | 2 +- src/test/ui/issues/issue-16401.stderr | 2 +- src/test/ui/issues/issue-3680.stderr | 2 +- src/test/ui/issues/issue-5100.stderr | 2 +- src/test/ui/issues/issue-5358-1.stderr | 2 +- src/test/ui/issues/issue-57741-1.stderr | 4 ++-- src/test/ui/issues/issue-57741.stderr | 8 ++++---- src/test/ui/issues/issue-7092.stderr | 2 +- src/test/ui/match/match-struct.stderr | 2 +- src/test/ui/match/match-tag-unary.stderr | 2 +- src/test/ui/parser/pat-tuple-5.stderr | 2 +- src/test/ui/pattern/pattern-error-continue.stderr | 2 +- src/test/ui/pattern/pattern-tyvar.stderr | 2 +- .../disallowed-positions.stderr | 14 +++++++------- .../structure-constructor-type-mismatch.stderr | 6 +++--- 24 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 027143a3d22c0..f0f0e2cdeb9c1 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -584,7 +584,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ObligationCauseCode::MatchExpressionArmPattern { span, ty } => { if ty.is_suggestable() { // don't show type `_` - err.span_label(span, format!("this match expression has type `{}`", ty)); + err.span_label(span, format!("this expression has type `{}`", ty)); } if let Some(ty::error::ExpectedFound { found, .. }) = exp_found { if ty.is_box() && ty.boxed_ty() == found { diff --git a/src/test/ui/block-result/issue-13624.stderr b/src/test/ui/block-result/issue-13624.stderr index 90ffb4b2e52bc..416f055251b04 100644 --- a/src/test/ui/block-result/issue-13624.stderr +++ b/src/test/ui/block-result/issue-13624.stderr @@ -10,7 +10,7 @@ error[E0308]: mismatched types --> $DIR/issue-13624.rs:20:9 | LL | match enum_struct_variant { - | ------------------- this match expression has type `()` + | ------------------- this expression has type `()` LL | a::Enum::EnumStructVariant { x, y, z } => { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found enum `a::Enum` diff --git a/src/test/ui/error-codes/E0308-4.stderr b/src/test/ui/error-codes/E0308-4.stderr index 46805d6e13b7c..39c0676373794 100644 --- a/src/test/ui/error-codes/E0308-4.stderr +++ b/src/test/ui/error-codes/E0308-4.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/E0308-4.rs:4:15 | LL | match x { - | - this match expression has type `u8` + | - this expression has type `u8` LL | 0u8..=3i8 => (), | --- ^^^ expected `u8`, found `i8` | | diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr index 04538cd74b195..580c80f66c3ca 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr @@ -8,7 +8,7 @@ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13 | LL | match [5..4, 99..105, 43..44] { - | ----------------------- this match expression has type `std::ops::Range<{integer}>` + | ----------------------- this expression has type `std::ops::Range<{integer}>` LL | [_, 99.., _] => {}, | ^^ expected struct `std::ops::Range`, found integer | diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr index c918d0a385c75..88d45f16ff6c9 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr @@ -14,7 +14,7 @@ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13 | LL | match [5..4, 99..105, 43..44] { - | ----------------------- this match expression has type `std::ops::Range<{integer}>` + | ----------------------- this expression has type `std::ops::Range<{integer}>` LL | [_, 99..] => {}, | ^^ expected struct `std::ops::Range`, found integer | diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr index e6ee3817b3558..6abba7d7cab10 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr @@ -8,7 +8,7 @@ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:12 | LL | match [5..4, 99..105, 43..44] { - | ----------------------- this match expression has type `std::ops::Range<{integer}>` + | ----------------------- this expression has type `std::ops::Range<{integer}>` LL | [..9, 99..100, _] => {}, | ^ expected struct `std::ops::Range`, found integer | @@ -19,7 +19,7 @@ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:15 | LL | match [5..4, 99..105, 43..44] { - | ----------------------- this match expression has type `std::ops::Range<{integer}>` + | ----------------------- this expression has type `std::ops::Range<{integer}>` LL | [..9, 99..100, _] => {}, | ^^ --- this is of type `{integer}` | | diff --git a/src/test/ui/issues/issue-11844.stderr b/src/test/ui/issues/issue-11844.stderr index 1b22d6f45cf20..57533ba5e370b 100644 --- a/src/test/ui/issues/issue-11844.stderr +++ b/src/test/ui/issues/issue-11844.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-11844.rs:6:9 | LL | match a { - | - this match expression has type `std::option::Option>` + | - this expression has type `std::option::Option>` LL | Ok(a) => | ^^^^^ expected enum `std::option::Option`, found enum `std::result::Result` | diff --git a/src/test/ui/issues/issue-12552.stderr b/src/test/ui/issues/issue-12552.stderr index ecafef259d3c9..60c4cceac51be 100644 --- a/src/test/ui/issues/issue-12552.stderr +++ b/src/test/ui/issues/issue-12552.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-12552.rs:6:5 | LL | match t { - | - this match expression has type `std::result::Result<_, {integer}>` + | - this expression has type `std::result::Result<_, {integer}>` LL | Some(k) => match k { | ^^^^^^^ expected enum `std::result::Result`, found enum `std::option::Option` | diff --git a/src/test/ui/issues/issue-13466.stderr b/src/test/ui/issues/issue-13466.stderr index fc20615757aa8..52d9e2a91b971 100644 --- a/src/test/ui/issues/issue-13466.stderr +++ b/src/test/ui/issues/issue-13466.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-13466.rs:8:9 | LL | let _x: usize = match Some(1) { - | ------- this match expression has type `std::option::Option<{integer}>` + | ------- this expression has type `std::option::Option<{integer}>` LL | Ok(u) => u, | ^^^^^ expected enum `std::option::Option`, found enum `std::result::Result` | @@ -13,7 +13,7 @@ error[E0308]: mismatched types --> $DIR/issue-13466.rs:14:9 | LL | let _x: usize = match Some(1) { - | ------- this match expression has type `std::option::Option<{integer}>` + | ------- this expression has type `std::option::Option<{integer}>` ... LL | Err(e) => panic!(e) | ^^^^^^ expected enum `std::option::Option`, found enum `std::result::Result` diff --git a/src/test/ui/issues/issue-15896.stderr b/src/test/ui/issues/issue-15896.stderr index f553be9df55eb..0ad49ea1e7fe5 100644 --- a/src/test/ui/issues/issue-15896.stderr +++ b/src/test/ui/issues/issue-15896.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-15896.rs:11:11 | LL | let u = match e { - | - this match expression has type `main::R` + | - this expression has type `main::R` LL | E::B( LL | Tau{t: x}, | ^^^^^^^^^ expected enum `main::R`, found struct `main::Tau` diff --git a/src/test/ui/issues/issue-16401.stderr b/src/test/ui/issues/issue-16401.stderr index d3d6108be9d1d..f8ea0907099a5 100644 --- a/src/test/ui/issues/issue-16401.stderr +++ b/src/test/ui/issues/issue-16401.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-16401.rs:8:9 | LL | match () { - | -- this match expression has type `()` + | -- this expression has type `()` LL | Slice { data: data, len: len } => (), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Slice` | diff --git a/src/test/ui/issues/issue-3680.stderr b/src/test/ui/issues/issue-3680.stderr index 8856f0e3a4844..713e4b5ccd575 100644 --- a/src/test/ui/issues/issue-3680.stderr +++ b/src/test/ui/issues/issue-3680.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-3680.rs:3:9 | LL | match None { - | ---- this match expression has type `std::option::Option<_>` + | ---- this expression has type `std::option::Option<_>` LL | Err(_) => () | ^^^^^^ expected enum `std::option::Option`, found enum `std::result::Result` | diff --git a/src/test/ui/issues/issue-5100.stderr b/src/test/ui/issues/issue-5100.stderr index 9e1011496c45d..c47e8689436ee 100644 --- a/src/test/ui/issues/issue-5100.stderr +++ b/src/test/ui/issues/issue-5100.stderr @@ -29,7 +29,7 @@ error[E0308]: mismatched types --> $DIR/issue-5100.rs:33:9 | LL | match (true, false) { - | ------------- this match expression has type `(bool, bool)` + | ------------- this expression has type `(bool, bool)` LL | box (true, false) => () | ^^^^^^^^^^^^^^^^^ expected tuple, found struct `std::boxed::Box` | diff --git a/src/test/ui/issues/issue-5358-1.stderr b/src/test/ui/issues/issue-5358-1.stderr index ec79d874d0339..314d1fddbd76a 100644 --- a/src/test/ui/issues/issue-5358-1.stderr +++ b/src/test/ui/issues/issue-5358-1.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-5358-1.rs:6:9 | LL | match S(Either::Left(5)) { - | ------------------ this match expression has type `S` + | ------------------ this expression has type `S` LL | Either::Right(_) => {} | ^^^^^^^^^^^^^^^^ expected struct `S`, found enum `Either` | diff --git a/src/test/ui/issues/issue-57741-1.stderr b/src/test/ui/issues/issue-57741-1.stderr index db6fa9db8ff47..a4f1ac94825d5 100644 --- a/src/test/ui/issues/issue-57741-1.stderr +++ b/src/test/ui/issues/issue-57741-1.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-57741-1.rs:14:9 | LL | let y = match x { - | - this match expression has type `std::boxed::Box` + | - this expression has type `std::boxed::Box` LL | S::A { a } | S::B { b: a } => a, | ^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S` | @@ -13,7 +13,7 @@ error[E0308]: mismatched types --> $DIR/issue-57741-1.rs:14:22 | LL | let y = match x { - | - this match expression has type `std::boxed::Box` + | - this expression has type `std::boxed::Box` LL | S::A { a } | S::B { b: a } => a, | ^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S` | diff --git a/src/test/ui/issues/issue-57741.stderr b/src/test/ui/issues/issue-57741.stderr index c36dea7bf5547..6f9e5b08a833f 100644 --- a/src/test/ui/issues/issue-57741.stderr +++ b/src/test/ui/issues/issue-57741.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | let y = match x { | - | | - | this match expression has type `std::boxed::Box` + | this expression has type `std::boxed::Box` | help: consider dereferencing the boxed value: `*x` LL | T::A(a) | T::B(a) => a, | ^^^^^^^ expected struct `std::boxed::Box`, found enum `T` @@ -18,7 +18,7 @@ error[E0308]: mismatched types LL | let y = match x { | - | | - | this match expression has type `std::boxed::Box` + | this expression has type `std::boxed::Box` | help: consider dereferencing the boxed value: `*x` LL | T::A(a) | T::B(a) => a, | ^^^^^^^ expected struct `std::boxed::Box`, found enum `T` @@ -32,7 +32,7 @@ error[E0308]: mismatched types LL | let y = match x { | - | | - | this match expression has type `std::boxed::Box` + | this expression has type `std::boxed::Box` | help: consider dereferencing the boxed value: `*x` LL | S::A { a } | S::B { b: a } => a, | ^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S` @@ -46,7 +46,7 @@ error[E0308]: mismatched types LL | let y = match x { | - | | - | this match expression has type `std::boxed::Box` + | this expression has type `std::boxed::Box` | help: consider dereferencing the boxed value: `*x` LL | S::A { a } | S::B { b: a } => a, | ^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S` diff --git a/src/test/ui/issues/issue-7092.stderr b/src/test/ui/issues/issue-7092.stderr index 05c00da16b1b1..590dd40c65364 100644 --- a/src/test/ui/issues/issue-7092.stderr +++ b/src/test/ui/issues/issue-7092.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-7092.rs:6:9 | LL | match x { - | - this match expression has type `Whatever` + | - this expression has type `Whatever` LL | Some(field) => | ^^^^^^^^^^^ expected enum `Whatever`, found enum `std::option::Option` | diff --git a/src/test/ui/match/match-struct.stderr b/src/test/ui/match/match-struct.stderr index c23451d51ec5a..a475bd5e5819c 100644 --- a/src/test/ui/match/match-struct.stderr +++ b/src/test/ui/match/match-struct.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/match-struct.rs:6:9 | LL | match (S { a: 1 }) { - | ------------ this match expression has type `S` + | ------------ this expression has type `S` LL | E::C(_) => (), | ^^^^^^^ expected struct `S`, found enum `E` diff --git a/src/test/ui/match/match-tag-unary.stderr b/src/test/ui/match/match-tag-unary.stderr index db5dcd2be3b51..31f77bdff8b1f 100644 --- a/src/test/ui/match/match-tag-unary.stderr +++ b/src/test/ui/match/match-tag-unary.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn main() { let x: A = A::A(0); match x { B::B(y) => { } } } | - ^^^^^^^ expected enum `A`, found enum `B` | | - | this match expression has type `A` + | this expression has type `A` error: aborting due to previous error diff --git a/src/test/ui/parser/pat-tuple-5.stderr b/src/test/ui/parser/pat-tuple-5.stderr index 5b0253cd2738a..8ff4f948a05ec 100644 --- a/src/test/ui/parser/pat-tuple-5.stderr +++ b/src/test/ui/parser/pat-tuple-5.stderr @@ -17,7 +17,7 @@ error[E0308]: mismatched types --> $DIR/pat-tuple-5.rs:5:10 | LL | match (0, 1) { - | ------ this match expression has type `({integer}, {integer})` + | ------ this expression has type `({integer}, {integer})` LL | (PAT ..) => {} | ^^^ expected tuple, found `u8` | diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr index 2f9fe1981bcbc..60f76796c0396 100644 --- a/src/test/ui/pattern/pattern-error-continue.stderr +++ b/src/test/ui/pattern/pattern-error-continue.stderr @@ -28,7 +28,7 @@ error[E0308]: mismatched types --> $DIR/pattern-error-continue.rs:22:9 | LL | match 'c' { - | --- this match expression has type `char` + | --- this expression has type `char` LL | S { .. } => (), | ^^^^^^^^ expected `char`, found struct `S` diff --git a/src/test/ui/pattern/pattern-tyvar.stderr b/src/test/ui/pattern/pattern-tyvar.stderr index b2afeacdf68c2..1e671e8d8eff3 100644 --- a/src/test/ui/pattern/pattern-tyvar.stderr +++ b/src/test/ui/pattern/pattern-tyvar.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/pattern-tyvar.rs:5:18 | LL | match t { - | - this match expression has type `std::option::Option>` + | - this expression has type `std::option::Option>` LL | Bar::T1(_, Some::(x)) => { | ^^^^^^^^^^^^^^^^ expected struct `std::vec::Vec`, found `isize` | diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr index 1143bddfe45a3..a69011d745080 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr @@ -630,7 +630,7 @@ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:67:12 | LL | if let Range { start: _, end: _ } = true..true && false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this match expression has type `bool` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` | | | expected `bool`, found struct `std::ops::Range` | @@ -650,7 +650,7 @@ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:71:12 | LL | if let Range { start: _, end: _ } = true..true || false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this match expression has type `bool` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` | | | expected `bool`, found struct `std::ops::Range` | @@ -697,7 +697,7 @@ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:86:12 | LL | if let Range { start: true, end } = t..&&false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this match expression has type `bool` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `bool` | | | expected `bool`, found struct `std::ops::Range` | @@ -818,7 +818,7 @@ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:131:15 | LL | while let Range { start: _, end: _ } = true..true && false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this match expression has type `bool` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` | | | expected `bool`, found struct `std::ops::Range` | @@ -838,7 +838,7 @@ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:135:15 | LL | while let Range { start: _, end: _ } = true..true || false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this match expression has type `bool` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` | | | expected `bool`, found struct `std::ops::Range` | @@ -885,7 +885,7 @@ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:150:15 | LL | while let Range { start: true, end } = t..&&false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this match expression has type `bool` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `bool` | | | expected `bool`, found struct `std::ops::Range` | @@ -961,7 +961,7 @@ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:198:10 | LL | (let Range { start: _, end: _ } = true..true || false); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this match expression has type `bool` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` | | | expected `bool`, found struct `std::ops::Range` | diff --git a/src/test/ui/structs/structure-constructor-type-mismatch.stderr b/src/test/ui/structs/structure-constructor-type-mismatch.stderr index 4bd3acac532df..8cfa118a2dac2 100644 --- a/src/test/ui/structs/structure-constructor-type-mismatch.stderr +++ b/src/test/ui/structs/structure-constructor-type-mismatch.stderr @@ -86,7 +86,7 @@ error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:54:9 | LL | match (Point { x: 1, y: 2 }) { - | ---------------------- this match expression has type `Point<{integer}>` + | ---------------------- this expression has type `Point<{integer}>` LL | PointF:: { .. } => {} | ^^^^^^^^^^^^^^^^^^^^ expected integer, found `f32` | @@ -97,7 +97,7 @@ error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:59:9 | LL | match (Point { x: 1, y: 2 }) { - | ---------------------- this match expression has type `Point<{integer}>` + | ---------------------- this expression has type `Point<{integer}>` LL | PointF { .. } => {} | ^^^^^^^^^^^^^ expected integer, found `f32` | @@ -108,7 +108,7 @@ error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:67:9 | LL | match (Pair { x: 1, y: 2 }) { - | --------------------- this match expression has type `Pair<{integer}, {integer}>` + | --------------------- this expression has type `Pair<{integer}, {integer}>` LL | PairF:: { .. } => {} | ^^^^^^^^^^^^^^^^^^^ expected integer, found `f32` | From 960acb044bcefc46520cee263b6877160fd296ca Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 07:27:56 +0100 Subject: [PATCH 03/29] Show scrutinee expr type for struct fields. TODO: The type is wrong and will be fixed in later commits. --- src/librustc_typeck/check/pat.rs | 15 ++++++++++++--- .../ui/pattern/pat-struct-field-expr-has-type.rs | 9 +++++++++ .../pattern/pat-struct-field-expr-has-type.stderr | 14 ++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/pattern/pat-struct-field-expr-has-type.rs create mode 100644 src/test/ui/pattern/pat-struct-field-expr-has-type.stderr diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 397f8682ede73..1f374c3fe2089 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -577,8 +577,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.demand_eqtype_pat(pat.span, expected, pat_ty, discrim_span); // Type-check subpatterns. - if self.check_struct_pat_fields(pat_ty, pat.hir_id, pat.span, variant, fields, etc, def_bm) - { + if self.check_struct_pat_fields( + pat_ty, + pat.hir_id, + pat.span, + variant, + fields, + etc, + def_bm, + discrim_span, + ) { pat_ty } else { self.tcx.types.err @@ -859,6 +867,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fields: &'tcx [hir::FieldPat<'tcx>], etc: bool, def_bm: BindingMode, + discrim_span: Option, ) -> bool { let tcx = self.tcx; @@ -908,7 +917,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - self.check_pat(&field.pat, field_ty, def_bm, None); + self.check_pat(&field.pat, field_ty, def_bm, discrim_span); } let mut unmentioned_fields = variant diff --git a/src/test/ui/pattern/pat-struct-field-expr-has-type.rs b/src/test/ui/pattern/pat-struct-field-expr-has-type.rs new file mode 100644 index 0000000000000..1d18214de7f08 --- /dev/null +++ b/src/test/ui/pattern/pat-struct-field-expr-has-type.rs @@ -0,0 +1,9 @@ +struct S { + f: u8, +} + +fn main() { + match (S { f: 42 }) { + S { f: Ok(_) } => {} //~ ERROR mismatched types + } +} diff --git a/src/test/ui/pattern/pat-struct-field-expr-has-type.stderr b/src/test/ui/pattern/pat-struct-field-expr-has-type.stderr new file mode 100644 index 0000000000000..7962c376a92a8 --- /dev/null +++ b/src/test/ui/pattern/pat-struct-field-expr-has-type.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/pat-struct-field-expr-has-type.rs:7:16 + | +LL | match (S { f: 42 }) { + | ------------- this expression has type `u8` +LL | S { f: Ok(_) } => {} + | ^^^^^ expected `u8`, found enum `std::result::Result` + | + = note: expected type `u8` + found enum `std::result::Result<_, _>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From e952377ddc7bdddfee03ee09f3530a1c025f1d99 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 07:42:46 +0100 Subject: [PATCH 04/29] MatchExpressionArmPattern -> Pattern Current name is too specific for incoming changes. --- src/librustc/infer/error_reporting/mod.rs | 2 +- src/librustc/traits/error_reporting.rs | 2 +- src/librustc/traits/mod.rs | 4 ++-- src/librustc/traits/structural_impls.rs | 4 +--- src/librustc_typeck/check/demand.rs | 5 +---- 5 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index f0f0e2cdeb9c1..ae629adf8fb53 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -581,7 +581,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { exp_found: Option>>, ) { match cause.code { - ObligationCauseCode::MatchExpressionArmPattern { span, ty } => { + ObligationCauseCode::Pattern { span, ty } => { if ty.is_suggestable() { // don't show type `_` err.span_label(span, format!("this expression has type `{}`", ty)); diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 878675f981259..5819e7aa5c25d 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -2580,7 +2580,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { match *cause_code { ObligationCauseCode::ExprAssignable | ObligationCauseCode::MatchExpressionArm { .. } - | ObligationCauseCode::MatchExpressionArmPattern { .. } + | ObligationCauseCode::Pattern { .. } | ObligationCauseCode::IfExpression { .. } | ObligationCauseCode::IfExpressionWithNoElse | ObligationCauseCode::MainFunctionType diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index e6ecf1b676e85..6142dc25f2228 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -249,8 +249,8 @@ pub enum ObligationCauseCode<'tcx> { /// Computing common supertype in the arms of a match expression MatchExpressionArm(Box>), - /// Computing common supertype in the pattern guard for the arms of a match expression - MatchExpressionArmPattern { + /// Type error arising from type checking a pattern against an expected type. + Pattern { span: Span, ty: Ty<'tcx>, }, diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index ed0842d80988f..cfc27438b50fd 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -521,9 +521,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { discrim_hir_id, }) }), - super::MatchExpressionArmPattern { span, ty } => { - tcx.lift(&ty).map(|ty| super::MatchExpressionArmPattern { span, ty }) - } + super::Pattern { span, ty } => tcx.lift(&ty).map(|ty| super::Pattern { span, ty }), super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }) => { Some(super::IfExpression(box super::IfExpressionCause { then, outer, semicolon })) } diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 68f2943e9e1d2..c11bd6704e4c3 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -87,10 +87,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match_expr_span: Option, ) -> Option> { let cause = if let Some(span) = match_expr_span { - self.cause( - cause_span, - ObligationCauseCode::MatchExpressionArmPattern { span, ty: expected }, - ) + self.cause(cause_span, ObligationCauseCode::Pattern { span, ty: expected }) } else { self.misc(cause_span) }; From 6137ad49e45713c7bdd3703814829d6362bf1dd1 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 07:48:16 +0100 Subject: [PATCH 05/29] move demand_eqtype_pat* to pat.rs --- src/librustc_typeck/check/demand.rs | 28 +--------------------------- src/librustc_typeck/check/pat.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index c11bd6704e4c3..8120183e6e135 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -1,6 +1,6 @@ use crate::check::FnCtxt; use rustc::infer::InferOk; -use rustc::traits::{self, ObligationCause, ObligationCauseCode}; +use rustc::traits::{self, ObligationCause}; use errors::{Applicability, DiagnosticBuilder}; use rustc::hir::{self, is_range_literal, print, Node}; @@ -79,32 +79,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn demand_eqtype_pat_diag( - &self, - cause_span: Span, - expected: Ty<'tcx>, - actual: Ty<'tcx>, - match_expr_span: Option, - ) -> Option> { - let cause = if let Some(span) = match_expr_span { - self.cause(cause_span, ObligationCauseCode::Pattern { span, ty: expected }) - } else { - self.misc(cause_span) - }; - self.demand_eqtype_with_origin(&cause, expected, actual) - } - - pub fn demand_eqtype_pat( - &self, - cause_span: Span, - expected: Ty<'tcx>, - actual: Ty<'tcx>, - match_expr_span: Option, - ) { - self.demand_eqtype_pat_diag(cause_span, expected, actual, match_expr_span) - .map(|mut err| err.emit()); - } - pub fn demand_coerce( &self, expr: &hir::Expr<'_>, diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 1f374c3fe2089..c7986311242b4 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -6,6 +6,7 @@ use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc::hir::{self, HirId, Pat, PatKind}; use rustc::infer; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc::traits::Pattern; use rustc::ty::subst::GenericArg; use rustc::ty::{self, BindingMode, Ty, TypeFoldable}; use syntax::ast; @@ -29,6 +30,34 @@ pointers. If you encounter this error you should try to avoid dereferencing the You can read more about trait objects in the Trait Objects section of the Reference: \ https://doc.rust-lang.org/reference/types.html#trait-objects"; +impl<'tcx> FnCtxt<'_, 'tcx> { + fn demand_eqtype_pat_diag( + &self, + cause_span: Span, + expected: Ty<'tcx>, + actual: Ty<'tcx>, + match_expr_span: Option, + ) -> Option> { + let cause = if let Some(span) = match_expr_span { + self.cause(cause_span, Pattern { span, ty: expected }) + } else { + self.misc(cause_span) + }; + self.demand_eqtype_with_origin(&cause, expected, actual) + } + + fn demand_eqtype_pat( + &self, + cause_span: Span, + expected: Ty<'tcx>, + actual: Ty<'tcx>, + match_expr_span: Option, + ) { + self.demand_eqtype_pat_diag(cause_span, expected, actual, match_expr_span) + .map(|mut err| err.emit()); + } +} + impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn check_pat_top( &self, From f35840f77cbb496dc35645331318f4b52c9a5b2a Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 08:17:32 +0100 Subject: [PATCH 06/29] Pass the span of `` in `let = ;` when type checking ``. --- src/librustc_typeck/check/mod.rs | 10 +++++----- src/librustc_typeck/check/pat.rs | 9 ++------- src/test/ui/issues/issue-14541.stderr | 4 +++- src/test/ui/issues/issue-16338.stderr | 4 +++- src/test/ui/issues/issue-37026.stderr | 4 +++- ...ssue-67037-pat-tup-scrut-ty-diff-less-fields.stderr | 4 +++- 6 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c6c3ada49e312..583a0409fb9f4 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4275,17 +4275,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) { - let t = self.local_ty(local.span, local.hir_id).decl_ty; - self.write_ty(local.hir_id, t); + let ty = self.local_ty(local.span, local.hir_id).decl_ty; + self.write_ty(local.hir_id, ty); if let Some(ref init) = local.init { let init_ty = self.check_decl_initializer(local, &init); - self.overwrite_local_ty_if_err(local, t, init_ty); + self.overwrite_local_ty_if_err(local, ty, init_ty); } - self.check_pat_top(&local.pat, t, None); + self.check_pat_top(&local.pat, ty, local.init.map(|init| init.span)); let pat_ty = self.node_ty(local.pat.hir_id); - self.overwrite_local_ty_if_err(local, t, pat_ty); + self.overwrite_local_ty_if_err(local, ty, pat_ty); } fn overwrite_local_ty_if_err( diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index c7986311242b4..b18a7ac75a282 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -59,14 +59,9 @@ impl<'tcx> FnCtxt<'_, 'tcx> { } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub fn check_pat_top( - &self, - pat: &'tcx Pat<'tcx>, - expected: Ty<'tcx>, - discrim_span: Option, - ) { + pub fn check_pat_top(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, span: Option) { let def_bm = BindingMode::BindByValue(hir::Mutability::Not); - self.check_pat(pat, expected, def_bm, discrim_span); + self.check_pat(pat, expected, def_bm, span); } /// `discrim_span` argument having a `Span` indicates that this pattern is part of a match diff --git a/src/test/ui/issues/issue-14541.stderr b/src/test/ui/issues/issue-14541.stderr index c5512e03007df..cf155f428c6a0 100644 --- a/src/test/ui/issues/issue-14541.stderr +++ b/src/test/ui/issues/issue-14541.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/issue-14541.rs:5:9 | LL | let Vec3 { y: _, z: _ } = v; - | ^^^^^^^^^^^^^^^^^^^ expected struct `Vec2`, found struct `Vec3` + | ^^^^^^^^^^^^^^^^^^^ - this expression has type `Vec2` + | | + | expected struct `Vec2`, found struct `Vec3` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-16338.stderr b/src/test/ui/issues/issue-16338.stderr index c35edb0c8c0e3..03eb93821b5f2 100644 --- a/src/test/ui/issues/issue-16338.stderr +++ b/src/test/ui/issues/issue-16338.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/issue-16338.rs:7:9 | LL | let Slice { data: data, len: len } = "foo"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `str`, found struct `Slice` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----- this expression has type `str` + | | + | expected `str`, found struct `Slice` | = note: expected type `str` found struct `Slice<_>` diff --git a/src/test/ui/issues/issue-37026.stderr b/src/test/ui/issues/issue-37026.stderr index 00952356b1830..361369e68bc08 100644 --- a/src/test/ui/issues/issue-37026.stderr +++ b/src/test/ui/issues/issue-37026.stderr @@ -8,7 +8,9 @@ error[E0308]: mismatched types --> $DIR/issue-37026.rs:7:9 | LL | let empty_struct::XEmpty6(..) = (); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `empty_struct::XEmpty6` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -- this expression has type `()` + | | + | expected `()`, found struct `empty_struct::XEmpty6` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr b/src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr index 521dd0256f7d5..6e8ea6bf618f2 100644 --- a/src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr +++ b/src/test/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:9 | LL | let P() = U {}; - | ^^^ expected struct `U`, found struct `P` + | ^^^ ---- this expression has type `U` + | | + | expected struct `U`, found struct `P` | = note: expected struct `U` found struct `P<_>` From d7e2f3aee5508538c5de14211ab5b31362e1164a Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 09:08:18 +0100 Subject: [PATCH 07/29] refactor and fix this-expression-has-type note --- src/librustc/infer/error_reporting/mod.rs | 1 + src/librustc_typeck/check/pat.rs | 173 +++++++++--------- src/test/ui/destructure-trait-ref.stderr | 4 +- ...sive_range_pattern_syntax_collision.stderr | 2 +- ...ive_range_pattern_syntax_collision2.stderr | 2 +- ...ive_range_pattern_syntax_collision3.stderr | 6 +- src/test/ui/issues/issue-15896.stderr | 2 +- src/test/ui/issues/issue-16338.stderr | 2 +- src/test/ui/mismatched_types/E0409.stderr | 2 + .../ui/or-patterns/already-bound-name.stderr | 4 +- .../ui/or-patterns/inconsistent-modes.stderr | 8 +- .../ui/or-patterns/or-pattern-mismatch.stderr | 2 +- src/test/ui/parser/recover-range-pats.stderr | 15 +- .../pat-struct-field-expr-has-type.stderr | 2 +- src/test/ui/pattern/pattern-tyvar.stderr | 2 +- .../resolve-inconsistent-binding-mode.stderr | 6 + .../resolve/resolve-inconsistent-names.stderr | 2 + .../disallowed-positions.stderr | 4 +- 18 files changed, 135 insertions(+), 104 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index ae629adf8fb53..5c561a87b0547 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -582,6 +582,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) { match cause.code { ObligationCauseCode::Pattern { span, ty } => { + let ty = self.resolve_vars_if_possible(&ty); if ty.is_suggestable() { // don't show type `_` err.span_label(span, format!("this expression has type `{}`", ty)); diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index b18a7ac75a282..a3ef41f0de5b5 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -30,16 +30,48 @@ pointers. If you encounter this error you should try to avoid dereferencing the You can read more about trait objects in the Trait Objects section of the Reference: \ https://doc.rust-lang.org/reference/types.html#trait-objects"; +/// Information about the expected type at the top level of type checking a pattern. +/// +/// **NOTE:** This is only for use by diagnostics. Do NOT use for type checking logic! +#[derive(Copy, Clone)] +struct TopInfo<'tcx> { + /// The `expected` type at the top level of type checking a pattern. + expected: Ty<'tcx>, + /// The span giving rise to the `expected` type, if one could be provided. + /// + /// This is the span of the scrutinee as in: + /// + /// - `match scrutinee { ... }` + /// - `let _ = scrutinee;` + /// + /// This is used to point to add context in type errors. + /// In the following example, `span` corresponds to the `a + b` expression: + /// + /// ```text + /// error[E0308]: mismatched types + /// --> src/main.rs:L:C + /// | + /// L | let temp: usize = match a + b { + /// | ----- this expression has type `usize` + /// L | Ok(num) => num, + /// | ^^^^^^^ expected `usize`, found enum `std::result::Result` + /// | + /// = note: expected type `usize` + /// found type `std::result::Result<_, _>` + /// ``` + span: Option, +} + impl<'tcx> FnCtxt<'_, 'tcx> { fn demand_eqtype_pat_diag( &self, cause_span: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - match_expr_span: Option, + ti: TopInfo<'tcx>, ) -> Option> { - let cause = if let Some(span) = match_expr_span { - self.cause(cause_span, Pattern { span, ty: expected }) + let cause = if let Some(span) = ti.span { + self.cause(cause_span, Pattern { span, ty: ti.expected }) } else { self.misc(cause_span) }; @@ -51,41 +83,33 @@ impl<'tcx> FnCtxt<'_, 'tcx> { cause_span: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - match_expr_span: Option, + ti: TopInfo<'tcx>, ) { - self.demand_eqtype_pat_diag(cause_span, expected, actual, match_expr_span) - .map(|mut err| err.emit()); + self.demand_eqtype_pat_diag(cause_span, expected, actual, ti).map(|mut err| err.emit()); } } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { + /// Type check the given top level pattern against the `expected` type. + /// + /// If a `Some(span)` is provided, then the `span` represents the scrutinee's span. + /// The scrutinee is found in e.g. `match scrutinee { ... }` and `let pat = scrutinee;`. pub fn check_pat_top(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, span: Option) { let def_bm = BindingMode::BindByValue(hir::Mutability::Not); - self.check_pat(pat, expected, def_bm, span); + self.check_pat(pat, expected, def_bm, TopInfo { expected, span }); } - /// `discrim_span` argument having a `Span` indicates that this pattern is part of a match - /// expression arm guard, and it points to the match discriminant to add context in type errors. - /// In the following example, `discrim_span` corresponds to the `a + b` expression: + /// Type check the given `pat` against the `expected` type + /// with the provided `def_bm` (default binding mode). /// - /// ```text - /// error[E0308]: mismatched types - /// --> src/main.rs:5:9 - /// | - /// 4 | let temp: usize = match a + b { - /// | ----- this expression has type `usize` - /// 5 | Ok(num) => num, - /// | ^^^^^^^ expected `usize`, found enum `std::result::Result` - /// | - /// = note: expected type `usize` - /// found type `std::result::Result<_, _>` - /// ``` + /// Outside of this module, `check_pat_top` should always be used. + /// Conversely, inside this module, `check_pat_top` should never be used. fn check_pat( &self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, def_bm: BindingMode, - discrim_span: Option, + ti: TopInfo<'tcx>, ) { debug!("check_pat(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm); @@ -98,48 +122,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = match pat.kind { PatKind::Wild => expected, - PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, discrim_span), + PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, ti), PatKind::Range(begin, end, _) => { - match self.check_pat_range(pat.span, begin, end, expected, discrim_span) { + match self.check_pat_range(pat.span, begin, end, expected, ti) { None => return, Some(ty) => ty, } } PatKind::Binding(ba, var_id, _, sub) => { - self.check_pat_ident(pat, ba, var_id, sub, expected, def_bm, discrim_span) + self.check_pat_ident(pat, ba, var_id, sub, expected, def_bm, ti) + } + PatKind::TupleStruct(ref qpath, subpats, ddpos) => { + self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, def_bm, ti) } - PatKind::TupleStruct(ref qpath, subpats, ddpos) => self.check_pat_tuple_struct( - pat, - qpath, - subpats, - ddpos, - expected, - def_bm, - discrim_span, - ), PatKind::Path(ref qpath) => { self.check_pat_path(pat, path_resolution.unwrap(), qpath, expected) } PatKind::Struct(ref qpath, fields, etc) => { - self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, discrim_span) + self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, ti) } PatKind::Or(pats) => { for pat in pats { - self.check_pat(pat, expected, def_bm, discrim_span); + self.check_pat(pat, expected, def_bm, ti); } expected } PatKind::Tuple(elements, ddpos) => { - self.check_pat_tuple(pat.span, elements, ddpos, expected, def_bm, discrim_span) - } - PatKind::Box(inner) => { - self.check_pat_box(pat.span, inner, expected, def_bm, discrim_span) + self.check_pat_tuple(pat.span, elements, ddpos, expected, def_bm, ti) } + PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, def_bm, ti), PatKind::Ref(inner, mutbl) => { - self.check_pat_ref(pat, inner, mutbl, expected, def_bm, discrim_span) + self.check_pat_ref(pat, inner, mutbl, expected, def_bm, ti) } PatKind::Slice(before, slice, after) => { - self.check_pat_slice(pat.span, before, slice, after, expected, def_bm, discrim_span) + self.check_pat_slice(pat.span, before, slice, after, expected, def_bm, ti) } }; @@ -316,7 +332,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, lt: &hir::Expr<'tcx>, expected: Ty<'tcx>, - discrim_span: Option, + ti: TopInfo<'tcx>, ) -> Ty<'tcx> { // We've already computed the type above (when checking for a non-ref pat), // so avoid computing it again. @@ -350,7 +366,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // then that's equivalent to there existing a LUB. if let Some(mut err) = self.demand_suptype_diag(span, expected, pat_ty) { err.emit_unless( - discrim_span + ti.span .filter(|&s| { // In the case of `if`- and `while`-expressions we've already checked // that `scrutinee: bool`. We know that the pattern is `true`, @@ -370,7 +386,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lhs: &'tcx hir::Expr<'tcx>, rhs: &'tcx hir::Expr<'tcx>, expected: Ty<'tcx>, - discrim_span: Option, + ti: TopInfo<'tcx>, ) -> Option> { let lhs_ty = self.check_expr(lhs); let rhs_ty = self.check_expr(rhs); @@ -391,7 +407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Subtyping doesn't matter here, as the value is some kind of scalar. let demand_eqtype = |x_span, y_span, x_ty, y_ty| { - self.demand_eqtype_pat_diag(x_span, expected, x_ty, discrim_span).map(|mut err| { + self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti).map(|mut err| { self.endpoint_has_type(&mut err, y_span, y_ty); err.emit(); }); @@ -465,7 +481,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sub: Option<&'tcx Pat<'tcx>>, expected: Ty<'tcx>, def_bm: BindingMode, - discrim_span: Option, + ti: TopInfo<'tcx>, ) -> Ty<'tcx> { // Determine the binding mode... let bm = match ba { @@ -495,17 +511,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected } }; - self.demand_eqtype_pat(pat.span, eq_ty, local_ty, discrim_span); + self.demand_eqtype_pat(pat.span, eq_ty, local_ty, ti); // If there are multiple arms, make sure they all agree on // what the type of the binding `x` ought to be. if var_id != pat.hir_id { let vt = self.local_ty(pat.span, var_id).decl_ty; - self.demand_eqtype_pat(pat.span, vt, local_ty, discrim_span); + self.demand_eqtype_pat(pat.span, vt, local_ty, ti); } if let Some(p) = sub { - self.check_pat(&p, expected, def_bm, discrim_span); + self.check_pat(&p, expected, def_bm, ti); } local_ty @@ -584,7 +600,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { etc: bool, expected: Ty<'tcx>, def_bm: BindingMode, - discrim_span: Option, + ti: TopInfo<'tcx>, ) -> Ty<'tcx> { // Resolve the path and check the definition for errors. let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.hir_id) @@ -592,25 +608,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { variant_ty } else { for field in fields { - self.check_pat(&field.pat, self.tcx.types.err, def_bm, discrim_span); + self.check_pat(&field.pat, self.tcx.types.err, def_bm, ti); } return self.tcx.types.err; }; // Type-check the path. - self.demand_eqtype_pat(pat.span, expected, pat_ty, discrim_span); + self.demand_eqtype_pat(pat.span, expected, pat_ty, ti); // Type-check subpatterns. - if self.check_struct_pat_fields( - pat_ty, - pat.hir_id, - pat.span, - variant, - fields, - etc, - def_bm, - discrim_span, - ) { + if self + .check_struct_pat_fields(pat_ty, pat.hir_id, pat.span, variant, fields, etc, def_bm, ti) + { pat_ty } else { self.tcx.types.err @@ -660,12 +669,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ddpos: Option, expected: Ty<'tcx>, def_bm: BindingMode, - match_arm_pat_span: Option, + ti: TopInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; let on_error = || { for pat in subpats { - self.check_pat(&pat, tcx.types.err, def_bm, match_arm_pat_span); + self.check_pat(&pat, tcx.types.err, def_bm, ti); } }; let report_unexpected_res = |res: Res| { @@ -726,7 +735,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let pat_ty = pat_ty.no_bound_vars().expect("expected fn type"); // Type-check the tuple struct pattern against the expected type. - let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, match_arm_pat_span); + let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, ti); let had_err = diag.is_some(); diag.map(|mut err| err.emit()); @@ -740,7 +749,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) { let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs); - self.check_pat(&subpat, field_ty, def_bm, match_arm_pat_span); + self.check_pat(&subpat, field_ty, def_bm, ti); self.tcx.check_stability(variant.fields[i].did, Some(pat.hir_id), subpat.span); } @@ -844,7 +853,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ddpos: Option, expected: Ty<'tcx>, def_bm: BindingMode, - discrim_span: Option, + ti: TopInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; let mut expected_len = elements.len(); @@ -871,12 +880,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // further errors being emitted when using the bindings. #50333 let element_tys_iter = (0..max_len).map(|_| tcx.types.err); for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { - self.check_pat(elem, &tcx.types.err, def_bm, discrim_span); + self.check_pat(elem, &tcx.types.err, def_bm, ti); } tcx.mk_tup(element_tys_iter) } else { for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { - self.check_pat(elem, &element_tys[i].expect_ty(), def_bm, discrim_span); + self.check_pat(elem, &element_tys[i].expect_ty(), def_bm, ti); } pat_ty } @@ -891,7 +900,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fields: &'tcx [hir::FieldPat<'tcx>], etc: bool, def_bm: BindingMode, - discrim_span: Option, + ti: TopInfo<'tcx>, ) -> bool { let tcx = self.tcx; @@ -941,7 +950,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - self.check_pat(&field.pat, field_ty, def_bm, discrim_span); + self.check_pat(&field.pat, field_ty, def_bm, ti); } let mut unmentioned_fields = variant @@ -1118,7 +1127,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { inner: &'tcx Pat<'tcx>, expected: Ty<'tcx>, def_bm: BindingMode, - discrim_span: Option, + ti: TopInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; let (box_ty, inner_ty) = if self.check_dereferenceable(span, expected, &inner) { @@ -1129,12 +1138,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: inner.span, }); let box_ty = tcx.mk_box(inner_ty); - self.demand_eqtype_pat(span, expected, box_ty, discrim_span); + self.demand_eqtype_pat(span, expected, box_ty, ti); (box_ty, inner_ty) } else { (tcx.types.err, tcx.types.err) }; - self.check_pat(&inner, inner_ty, def_bm, discrim_span); + self.check_pat(&inner, inner_ty, def_bm, ti); box_ty } @@ -1145,7 +1154,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mutbl: hir::Mutability, expected: Ty<'tcx>, def_bm: BindingMode, - discrim_span: Option, + ti: TopInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; let expected = self.shallow_resolve(expected); @@ -1180,7 +1189,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { (tcx.types.err, tcx.types.err) }; - self.check_pat(&inner, inner_ty, def_bm, discrim_span); + self.check_pat(&inner, inner_ty, def_bm, ti); rptr_ty } @@ -1209,7 +1218,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { after: &'tcx [&'tcx Pat<'tcx>], expected: Ty<'tcx>, def_bm: BindingMode, - discrim_span: Option, + ti: TopInfo<'tcx>, ) -> Ty<'tcx> { let err = self.tcx.types.err; let expected = self.structurally_resolved_type(span, expected); @@ -1234,15 +1243,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Type check all the patterns before `slice`. for elt in before { - self.check_pat(&elt, inner_ty, def_bm, discrim_span); + self.check_pat(&elt, inner_ty, def_bm, ti); } // Type check the `slice`, if present, against its expected type. if let Some(slice) = slice { - self.check_pat(&slice, slice_ty, def_bm, discrim_span); + self.check_pat(&slice, slice_ty, def_bm, ti); } // Type check the elements after `slice`, if present. for elt in after { - self.check_pat(&elt, inner_ty, def_bm, discrim_span); + self.check_pat(&elt, inner_ty, def_bm, ti); } expected } diff --git a/src/test/ui/destructure-trait-ref.stderr b/src/test/ui/destructure-trait-ref.stderr index f77291969d2db..c78166f411d28 100644 --- a/src/test/ui/destructure-trait-ref.stderr +++ b/src/test/ui/destructure-trait-ref.stderr @@ -44,7 +44,9 @@ error[E0308]: mismatched types --> $DIR/destructure-trait-ref.rs:42:13 | LL | let box box x = box 1isize as Box; - | ^^^^^ expected trait `T`, found struct `std::boxed::Box` + | ^^^^^ ------------------------ this expression has type `std::boxed::Box` + | | + | expected trait `T`, found struct `std::boxed::Box` | = note: expected trait object `dyn T` found struct `std::boxed::Box<_>` diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr index 580c80f66c3ca..76ae7241ff277 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr @@ -8,7 +8,7 @@ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13 | LL | match [5..4, 99..105, 43..44] { - | ----------------------- this expression has type `std::ops::Range<{integer}>` + | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` LL | [_, 99.., _] => {}, | ^^ expected struct `std::ops::Range`, found integer | diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr index 88d45f16ff6c9..5c96f8041feb2 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr @@ -14,7 +14,7 @@ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13 | LL | match [5..4, 99..105, 43..44] { - | ----------------------- this expression has type `std::ops::Range<{integer}>` + | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` LL | [_, 99..] => {}, | ^^ expected struct `std::ops::Range`, found integer | diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr index 6abba7d7cab10..17e10324db181 100644 --- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr +++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr @@ -8,7 +8,7 @@ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:12 | LL | match [5..4, 99..105, 43..44] { - | ----------------------- this expression has type `std::ops::Range<{integer}>` + | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` LL | [..9, 99..100, _] => {}, | ^ expected struct `std::ops::Range`, found integer | @@ -19,7 +19,7 @@ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:15 | LL | match [5..4, 99..105, 43..44] { - | ----------------------- this expression has type `std::ops::Range<{integer}>` + | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` LL | [..9, 99..100, _] => {}, | ^^ --- this is of type `{integer}` | | @@ -32,7 +32,7 @@ error[E0308]: mismatched types --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:19 | LL | match [5..4, 99..105, 43..44] { - | ----------------------- this match expression has type `std::ops::Range<{integer}>` + | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]` LL | [..9, 99..100, _] => {}, | -- ^^^ expected struct `std::ops::Range`, found integer | | diff --git a/src/test/ui/issues/issue-15896.stderr b/src/test/ui/issues/issue-15896.stderr index 0ad49ea1e7fe5..b3f0907b81d25 100644 --- a/src/test/ui/issues/issue-15896.stderr +++ b/src/test/ui/issues/issue-15896.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-15896.rs:11:11 | LL | let u = match e { - | - this expression has type `main::R` + | - this expression has type `main::E` LL | E::B( LL | Tau{t: x}, | ^^^^^^^^^ expected enum `main::R`, found struct `main::Tau` diff --git a/src/test/ui/issues/issue-16338.stderr b/src/test/ui/issues/issue-16338.stderr index 03eb93821b5f2..6878600b02983 100644 --- a/src/test/ui/issues/issue-16338.stderr +++ b/src/test/ui/issues/issue-16338.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-16338.rs:7:9 | LL | let Slice { data: data, len: len } = "foo"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----- this expression has type `str` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----- this expression has type `&str` | | | expected `str`, found struct `Slice` | diff --git a/src/test/ui/mismatched_types/E0409.stderr b/src/test/ui/mismatched_types/E0409.stderr index 098fd74a39da6..2306fb352738f 100644 --- a/src/test/ui/mismatched_types/E0409.stderr +++ b/src/test/ui/mismatched_types/E0409.stderr @@ -9,6 +9,8 @@ LL | (0, ref y) | (y, 0) => {} error[E0308]: mismatched types --> $DIR/E0409.rs:5:23 | +LL | match x { + | - this expression has type `({integer}, {integer})` LL | (0, ref y) | (y, 0) => {} | ^ expected `&{integer}`, found integer diff --git a/src/test/ui/or-patterns/already-bound-name.stderr b/src/test/ui/or-patterns/already-bound-name.stderr index 360699a873938..948c91370d0d4 100644 --- a/src/test/ui/or-patterns/already-bound-name.stderr +++ b/src/test/ui/or-patterns/already-bound-name.stderr @@ -94,7 +94,9 @@ error[E0308]: mismatched types --> $DIR/already-bound-name.rs:33:31 | LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1)); - | ^ expected integer, found enum `E` + | ^ ------- this expression has type `E>` + | | + | expected integer, found enum `E` | = note: expected type `{integer}` found type `E<{integer}>` diff --git a/src/test/ui/or-patterns/inconsistent-modes.stderr b/src/test/ui/or-patterns/inconsistent-modes.stderr index 0a36ed5548e5b..80d914b8d236c 100644 --- a/src/test/ui/or-patterns/inconsistent-modes.stderr +++ b/src/test/ui/or-patterns/inconsistent-modes.stderr @@ -60,7 +60,9 @@ error[E0308]: mismatched types --> $DIR/inconsistent-modes.rs:13:25 | LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0); - | ^^^^^^^^^ types differ in mutability + | ^^^^^^^^^ ------ this expression has type `std::result::Result<&u8, &mut u8>` + | | + | types differ in mutability | = note: expected type `&&u8` found type `&mut &mut u8` @@ -69,7 +71,9 @@ error[E0308]: mismatched types --> $DIR/inconsistent-modes.rs:16:31 | LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0)); - | ^^^^^^^^^ types differ in mutability + | ^^^^^^^^^ ----------- this expression has type `std::result::Result<({integer}, &{integer}), (_, _)>` + | | + | types differ in mutability | = note: expected type `&{integer}` found type `&mut _` diff --git a/src/test/ui/or-patterns/or-pattern-mismatch.stderr b/src/test/ui/or-patterns/or-pattern-mismatch.stderr index 253f3ef772525..bc288e0625075 100644 --- a/src/test/ui/or-patterns/or-pattern-mismatch.stderr +++ b/src/test/ui/or-patterns/or-pattern-mismatch.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/or-pattern-mismatch.rs:3:68 | LL | fn main() { match Blah::A(1, 1, 2) { Blah::A(_, x, y) | Blah::B(x, y) => { } } } - | ^ expected `usize`, found `isize` + | ---------------- this expression has type `Blah` ^ expected `usize`, found `isize` error: aborting due to previous error diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr index 50a44192707f0..3fed64c191a8a 100644 --- a/src/test/ui/parser/recover-range-pats.stderr +++ b/src/test/ui/parser/recover-range-pats.stderr @@ -425,8 +425,9 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:23:16 | LL | if let X.. .0 = 0 {} - | - ^^ expected integer, found floating-point number - | | + | - ^^ - this expression has type `u8` + | | | + | | expected integer, found floating-point number | this is of type `u8` error[E0029]: only char and numeric types are allowed in range patterns @@ -457,8 +458,9 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:36:16 | LL | if let X..=.0 = 0 {} - | - ^^ expected integer, found floating-point number - | | + | - ^^ - this expression has type `u8` + | | | + | | expected integer, found floating-point number | this is of type `u8` error[E0029]: only char and numeric types are allowed in range patterns @@ -489,8 +491,9 @@ error[E0308]: mismatched types --> $DIR/recover-range-pats.rs:52:17 | LL | if let X... .0 = 0 {} - | - ^^ expected integer, found floating-point number - | | + | - ^^ - this expression has type `u8` + | | | + | | expected integer, found floating-point number | this is of type `u8` error[E0029]: only char and numeric types are allowed in range patterns diff --git a/src/test/ui/pattern/pat-struct-field-expr-has-type.stderr b/src/test/ui/pattern/pat-struct-field-expr-has-type.stderr index 7962c376a92a8..d57a8a0dbc181 100644 --- a/src/test/ui/pattern/pat-struct-field-expr-has-type.stderr +++ b/src/test/ui/pattern/pat-struct-field-expr-has-type.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/pat-struct-field-expr-has-type.rs:7:16 | LL | match (S { f: 42 }) { - | ------------- this expression has type `u8` + | ------------- this expression has type `S` LL | S { f: Ok(_) } => {} | ^^^^^ expected `u8`, found enum `std::result::Result` | diff --git a/src/test/ui/pattern/pattern-tyvar.stderr b/src/test/ui/pattern/pattern-tyvar.stderr index 1e671e8d8eff3..15425da69bcc4 100644 --- a/src/test/ui/pattern/pattern-tyvar.stderr +++ b/src/test/ui/pattern/pattern-tyvar.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/pattern-tyvar.rs:5:18 | LL | match t { - | - this expression has type `std::option::Option>` + | - this expression has type `Bar` LL | Bar::T1(_, Some::(x)) => { | ^^^^^^^^^^^^^^^^ expected struct `std::vec::Vec`, found `isize` | diff --git a/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr b/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr index 58455024d3827..61d1001ce9154 100644 --- a/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr +++ b/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr @@ -23,18 +23,24 @@ LL | Opts::A(ref mut i) | Opts::B(ref i) => {} error[E0308]: mismatched types --> $DIR/resolve-inconsistent-binding-mode.rs:7:32 | +LL | match x { + | - this expression has type `Opts` LL | Opts::A(ref i) | Opts::B(i) => {} | ^ expected `&isize`, found `isize` error[E0308]: mismatched types --> $DIR/resolve-inconsistent-binding-mode.rs:16:32 | +LL | match x { + | - this expression has type `Opts` LL | Opts::A(ref i) | Opts::B(i) => {} | ^ expected `&isize`, found `isize` error[E0308]: mismatched types --> $DIR/resolve-inconsistent-binding-mode.rs:25:36 | +LL | match x { + | - this expression has type `Opts` LL | Opts::A(ref mut i) | Opts::B(ref i) => {} | ^^^^^ types differ in mutability | diff --git a/src/test/ui/resolve/resolve-inconsistent-names.stderr b/src/test/ui/resolve/resolve-inconsistent-names.stderr index 271495012dab5..5c87f7c684f3b 100644 --- a/src/test/ui/resolve/resolve-inconsistent-names.stderr +++ b/src/test/ui/resolve/resolve-inconsistent-names.stderr @@ -86,6 +86,8 @@ LL | (CONST1, _) | (_, Const2) => () error[E0308]: mismatched types --> $DIR/resolve-inconsistent-names.rs:19:19 | +LL | match x { + | - this expression has type `(E, E)` LL | (A, B) | (ref B, c) | (c, A) => () | ^^^^^ expected enum `E`, found `&E` diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr index a69011d745080..7170adca60dc3 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr @@ -697,7 +697,7 @@ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:86:12 | LL | if let Range { start: true, end } = t..&&false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `bool` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool` | | | expected `bool`, found struct `std::ops::Range` | @@ -885,7 +885,7 @@ error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:150:15 | LL | while let Range { start: true, end } = t..&&false {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `bool` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool` | | | expected `bool`, found struct `std::ops::Range` | From f2c6a19c0d9ad11620a6f617c1b851e98dad5cb2 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 09:40:44 +0100 Subject: [PATCH 08/29] check_fn: simplify --- src/librustc_typeck/check/mod.rs | 74 ++++++++++++++++---------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 583a0409fb9f4..41313ffbab6cf 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1242,13 +1242,17 @@ fn check_fn<'a, 'tcx>( let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id); *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id); + let tcx = fcx.tcx; + let sess = tcx.sess; + let hir = tcx.hir(); + let declared_ret_ty = fn_sig.output(); fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType); let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span()); debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty); fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty))); - fn_sig = fcx.tcx.mk_fn_sig( + fn_sig = tcx.mk_fn_sig( fn_sig.inputs().iter().cloned(), revealed_ret_ty, fn_sig.c_variadic, @@ -1258,7 +1262,7 @@ fn check_fn<'a, 'tcx>( let span = body.value.span; - fn_maybe_err(fcx.tcx, span, fn_sig.abi); + fn_maybe_err(tcx, span, fn_sig.abi); if body.generator_kind.is_some() && can_be_generator.is_some() { let yield_ty = fcx @@ -1267,23 +1271,23 @@ fn check_fn<'a, 'tcx>( fcx.yield_ty = Some(yield_ty); } - let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id(fn_id)); - let outer_hir_id = fcx.tcx.hir().as_local_hir_id(outer_def_id).unwrap(); + let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id)); + let outer_hir_id = hir.as_local_hir_id(outer_def_id).unwrap(); GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body); // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` // (as it's created inside the body itself, not passed in from outside). let maybe_va_list = if fn_sig.c_variadic { - let va_list_did = fcx.tcx.require_lang_item( + let va_list_did = tcx.require_lang_item( lang_items::VaListTypeLangItem, Some(body.params.last().unwrap().span), ); - let region = fcx.tcx.mk_region(ty::ReScope(region::Scope { + let region = tcx.mk_region(ty::ReScope(region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::CallSite, })); - Some(fcx.tcx.type_of(va_list_did).subst(fcx.tcx, &[region.into()])) + Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()])) } else { None }; @@ -1297,7 +1301,7 @@ fn check_fn<'a, 'tcx>( // The check for a non-trivial pattern is a hack to avoid duplicate warnings // for simple cases like `fn foo(x: Trait)`, // where we would error once on the parameter as a whole, and once on the binding `x`. - if param.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals { + if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals { fcx.require_type_is_sized(param_ty, decl.output.span(), traits::SizedArgumentType); } @@ -1358,11 +1362,11 @@ fn check_fn<'a, 'tcx>( fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty); // Check that the main return type implements the termination trait. - if let Some(term_id) = fcx.tcx.lang_items().termination() { - if let Some((def_id, EntryFnType::Main)) = fcx.tcx.entry_fn(LOCAL_CRATE) { - let main_id = fcx.tcx.hir().as_local_hir_id(def_id).unwrap(); + if let Some(term_id) = tcx.lang_items().termination() { + if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) { + let main_id = hir.as_local_hir_id(def_id).unwrap(); if main_id == fn_id { - let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]); + let substs = tcx.mk_substs_trait(declared_ret_ty, &[]); let trait_ref = ty::TraitRef::new(term_id, substs); let return_ty_span = decl.output.span(); let cause = traits::ObligationCause::new( @@ -1381,15 +1385,15 @@ fn check_fn<'a, 'tcx>( } // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !` - if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() { - if panic_impl_did == fcx.tcx.hir().local_def_id(fn_id) { - if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() { + if let Some(panic_impl_did) = tcx.lang_items().panic_impl() { + if panic_impl_did == hir.local_def_id(fn_id) { + if let Some(panic_info_did) = tcx.lang_items().panic_info() { if declared_ret_ty.kind != ty::Never { - fcx.tcx.sess.span_err(decl.output.span(), "return type should be `!`"); + sess.span_err(decl.output.span(), "return type should be `!`"); } let inputs = fn_sig.inputs(); - let span = fcx.tcx.hir().span(fn_id); + let span = hir.span(fn_id); if inputs.len() == 1 { let arg_is_panic_info = match inputs[0].kind { ty::Ref(region, ty, mutbl) => match ty.kind { @@ -1404,38 +1408,36 @@ fn check_fn<'a, 'tcx>( }; if !arg_is_panic_info { - fcx.tcx - .sess - .span_err(decl.inputs[0].span, "argument should be `&PanicInfo`"); + sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`"); } - if let Node::Item(item) = fcx.tcx.hir().get(fn_id) { + if let Node::Item(item) = hir.get(fn_id) { if let ItemKind::Fn(_, ref generics, _) = item.kind { if !generics.params.is_empty() { - fcx.tcx.sess.span_err(span, "should have no type parameters"); + sess.span_err(span, "should have no type parameters"); } } } } else { - let span = fcx.tcx.sess.source_map().def_span(span); - fcx.tcx.sess.span_err(span, "function should have one argument"); + let span = sess.source_map().def_span(span); + sess.span_err(span, "function should have one argument"); } } else { - fcx.tcx.sess.err("language item required, but not found: `panic_info`"); + sess.err("language item required, but not found: `panic_info`"); } } } // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !` - if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() { - if alloc_error_handler_did == fcx.tcx.hir().local_def_id(fn_id) { - if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() { + if let Some(alloc_error_handler_did) = tcx.lang_items().oom() { + if alloc_error_handler_did == hir.local_def_id(fn_id) { + if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() { if declared_ret_ty.kind != ty::Never { - fcx.tcx.sess.span_err(decl.output.span(), "return type should be `!`"); + sess.span_err(decl.output.span(), "return type should be `!`"); } let inputs = fn_sig.inputs(); - let span = fcx.tcx.hir().span(fn_id); + let span = hir.span(fn_id); if inputs.len() == 1 { let arg_is_alloc_layout = match inputs[0].kind { ty::Adt(ref adt, _) => adt.did == alloc_layout_did, @@ -1443,13 +1445,13 @@ fn check_fn<'a, 'tcx>( }; if !arg_is_alloc_layout { - fcx.tcx.sess.span_err(decl.inputs[0].span, "argument should be `Layout`"); + sess.span_err(decl.inputs[0].span, "argument should be `Layout`"); } - if let Node::Item(item) = fcx.tcx.hir().get(fn_id) { + if let Node::Item(item) = hir.get(fn_id) { if let ItemKind::Fn(_, ref generics, _) = item.kind { if !generics.params.is_empty() { - fcx.tcx.sess.span_err( + sess.span_err( span, "`#[alloc_error_handler]` function should have no type \ parameters", @@ -1458,11 +1460,11 @@ fn check_fn<'a, 'tcx>( } } } else { - let span = fcx.tcx.sess.source_map().def_span(span); - fcx.tcx.sess.span_err(span, "function should have one argument"); + let span = sess.source_map().def_span(span); + sess.span_err(span, "function should have one argument"); } } else { - fcx.tcx.sess.err("language item required, but not found: `alloc_layout`"); + sess.err("language item required, but not found: `alloc_layout`"); } } } From f8d2cce0ce24981269e6994c332bff7f033b59e0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 11:39:13 +0100 Subject: [PATCH 09/29] Blame user type in pat type error. --- src/librustc/infer/error_reporting/mod.rs | 7 ++- src/librustc/traits/mod.rs | 8 ++- src/librustc/traits/structural_impls.rs | 4 +- src/librustc_typeck/check/_match.rs | 2 +- src/librustc_typeck/check/mod.rs | 21 ++++++-- src/librustc_typeck/check/pat.rs | 29 +++++++---- src/librustc_typeck/lib.rs | 1 + .../ui/or-patterns/inconsistent-modes.stderr | 2 +- .../ui/pattern/pat-type-err-formal-param.rs | 8 +++ .../pattern/pat-type-err-formal-param.stderr | 11 +++++ src/test/ui/pattern/pat-type-err-let-stmt.rs | 16 ++++++ .../ui/pattern/pat-type-err-let-stmt.stderr | 49 +++++++++++++++++++ 12 files changed, 138 insertions(+), 20 deletions(-) create mode 100644 src/test/ui/pattern/pat-type-err-formal-param.rs create mode 100644 src/test/ui/pattern/pat-type-err-formal-param.stderr create mode 100644 src/test/ui/pattern/pat-type-err-let-stmt.rs create mode 100644 src/test/ui/pattern/pat-type-err-let-stmt.stderr diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 5c561a87b0547..7254bb52d7039 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -581,8 +581,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { exp_found: Option>>, ) { match cause.code { - ObligationCauseCode::Pattern { span, ty } => { - let ty = self.resolve_vars_if_possible(&ty); + ObligationCauseCode::Pattern { origin_expr: true, span: Some(span), root_ty } => { + let ty = self.resolve_vars_if_possible(&root_ty); if ty.is_suggestable() { // don't show type `_` err.span_label(span, format!("this expression has type `{}`", ty)); @@ -600,6 +600,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } } + ObligationCauseCode::Pattern { origin_expr: false, span: Some(span), .. } => { + err.span_label(span, "expected due to this"); + } ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { source, ref prior_arms, diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 6142dc25f2228..f726a52946ed8 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -251,8 +251,12 @@ pub enum ObligationCauseCode<'tcx> { /// Type error arising from type checking a pattern against an expected type. Pattern { - span: Span, - ty: Ty<'tcx>, + /// The span of the scrutinee or type expression which caused the `root_ty` type. + span: Option, + /// The root expected type induced by a scrutinee or type expression. + root_ty: Ty<'tcx>, + /// Whether the `Span` came from an expression or a type expression. + origin_expr: bool, }, /// Constants in patterns must have `Structural` type. diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index cfc27438b50fd..7b14ada8469a9 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -521,7 +521,9 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { discrim_hir_id, }) }), - super::Pattern { span, ty } => tcx.lift(&ty).map(|ty| super::Pattern { span, ty }), + super::Pattern { span, root_ty, origin_expr } => { + tcx.lift(&root_ty).map(|root_ty| super::Pattern { span, root_ty, origin_expr }) + } super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }) => { Some(super::IfExpression(box super::IfExpressionCause { then, outer, semicolon })) } diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 0d7ddd0fc4819..e4cf54f629c59 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -61,7 +61,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|arm| { let mut all_pats_diverge = Diverges::WarnedAlways; self.diverges.set(Diverges::Maybe); - self.check_pat_top(&arm.pat, discrim_ty, Some(discrim.span)); + self.check_pat_top(&arm.pat, discrim_ty, Some(discrim.span), true); all_pats_diverge &= self.diverges.get(); // As discussed with @eddyb, this is for disabling unreachable_code diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 41313ffbab6cf..2a1297966a94e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1293,9 +1293,11 @@ fn check_fn<'a, 'tcx>( }; // Add formal parameters. - for (param_ty, param) in fn_sig.inputs().iter().copied().chain(maybe_va_list).zip(body.params) { + let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs); + let inputs_fn = fn_sig.inputs().iter().copied(); + for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() { // Check the pattern. - fcx.check_pat_top(¶m.pat, param_ty, None); + fcx.check_pat_top(¶m.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false); // Check that argument is Sized. // The check for a non-trivial pattern is a hack to avoid duplicate warnings @@ -4276,16 +4278,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// Type check a `let` statement. pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) { + // Determine and write the type which we'll check the pattern against. let ty = self.local_ty(local.span, local.hir_id).decl_ty; self.write_ty(local.hir_id, ty); + // Type check the initializer. if let Some(ref init) = local.init { let init_ty = self.check_decl_initializer(local, &init); self.overwrite_local_ty_if_err(local, ty, init_ty); } - self.check_pat_top(&local.pat, ty, local.init.map(|init| init.span)); + // Does the expected pattern type originate from an expression and what is the span? + let (origin_expr, ty_span) = match (local.ty, local.init) { + (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type. + (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee. + _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained. + }; + + // Type check the pattern. Override if necessary to avoid knock-on errors. + self.check_pat_top(&local.pat, ty, ty_span, origin_expr); let pat_ty = self.node_ty(local.pat.hir_id); self.overwrite_local_ty_if_err(local, ty, pat_ty); } @@ -4297,7 +4310,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty: Ty<'tcx>, ) { if ty.references_error() { - // Override the types everywhere with `types.err` to avoid knock down errors. + // Override the types everywhere with `types.err` to avoid knock on errors. self.write_ty(local.hir_id, ty); self.write_ty(local.pat.hir_id, ty); let local_ty = LocalTy { decl_ty, revealed_ty: ty }; diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index a3ef41f0de5b5..7591189339603 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -37,9 +37,13 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"; struct TopInfo<'tcx> { /// The `expected` type at the top level of type checking a pattern. expected: Ty<'tcx>, + /// Was the origin of the `span` from a scrutinee expression? + /// + /// Otherwise there is no scrutinee and it could be e.g. from the type of a formal parameter. + origin_expr: bool, /// The span giving rise to the `expected` type, if one could be provided. /// - /// This is the span of the scrutinee as in: + /// If `origin_expr` is `true`, then this is the span of the scrutinee as in: /// /// - `match scrutinee { ... }` /// - `let _ = scrutinee;` @@ -70,11 +74,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> { actual: Ty<'tcx>, ti: TopInfo<'tcx>, ) -> Option> { - let cause = if let Some(span) = ti.span { - self.cause(cause_span, Pattern { span, ty: ti.expected }) - } else { - self.misc(cause_span) - }; + let code = Pattern { span: ti.span, root_ty: ti.expected, origin_expr: ti.origin_expr }; + let cause = self.cause(cause_span, code); self.demand_eqtype_with_origin(&cause, expected, actual) } @@ -92,11 +93,21 @@ impl<'tcx> FnCtxt<'_, 'tcx> { impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Type check the given top level pattern against the `expected` type. /// - /// If a `Some(span)` is provided, then the `span` represents the scrutinee's span. + /// If a `Some(span)` is provided and `origin_expr` holds, + /// then the `span` represents the scrutinee's span. /// The scrutinee is found in e.g. `match scrutinee { ... }` and `let pat = scrutinee;`. - pub fn check_pat_top(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, span: Option) { + /// + /// Otherwise, `Some(span)` represents the span of a type expression + /// which originated the `expected` type. + pub fn check_pat_top( + &self, + pat: &'tcx Pat<'tcx>, + expected: Ty<'tcx>, + span: Option, + origin_expr: bool, + ) { let def_bm = BindingMode::BindByValue(hir::Mutability::Not); - self.check_pat(pat, expected, def_bm, TopInfo { expected, span }); + self.check_pat(pat, expected, def_bm, TopInfo { expected, origin_expr, span }); } /// Type check the given `pat` against the `expected` type diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index d9b7e98ea75c3..f06fe1e4bf211 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -65,6 +65,7 @@ This API is completely unstable and subject to change. #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(slice_patterns)] +#![feature(try_blocks)] #![feature(never_type)] #![recursion_limit = "256"] diff --git a/src/test/ui/or-patterns/inconsistent-modes.stderr b/src/test/ui/or-patterns/inconsistent-modes.stderr index 80d914b8d236c..7c1638ff94d0f 100644 --- a/src/test/ui/or-patterns/inconsistent-modes.stderr +++ b/src/test/ui/or-patterns/inconsistent-modes.stderr @@ -60,7 +60,7 @@ error[E0308]: mismatched types --> $DIR/inconsistent-modes.rs:13:25 | LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0); - | ^^^^^^^^^ ------ this expression has type `std::result::Result<&u8, &mut u8>` + | ^^^^^^^^^ -------------------- expected due to this | | | types differ in mutability | diff --git a/src/test/ui/pattern/pat-type-err-formal-param.rs b/src/test/ui/pattern/pat-type-err-formal-param.rs new file mode 100644 index 0000000000000..54336b3492321 --- /dev/null +++ b/src/test/ui/pattern/pat-type-err-formal-param.rs @@ -0,0 +1,8 @@ +// Test the `.span_label(..)` to the type when there's a +// type error in a pattern due to a the formal parameter. + +fn main() {} + +struct Tuple(u8); + +fn foo(Tuple(_): String) {} //~ ERROR mismatched types diff --git a/src/test/ui/pattern/pat-type-err-formal-param.stderr b/src/test/ui/pattern/pat-type-err-formal-param.stderr new file mode 100644 index 0000000000000..2d7eb62faef2b --- /dev/null +++ b/src/test/ui/pattern/pat-type-err-formal-param.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/pat-type-err-formal-param.rs:8:8 + | +LL | fn foo(Tuple(_): String) {} + | ^^^^^^^^ ------ expected due to this + | | + | expected struct `std::string::String`, found struct `Tuple` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/pattern/pat-type-err-let-stmt.rs b/src/test/ui/pattern/pat-type-err-let-stmt.rs new file mode 100644 index 0000000000000..6e9850b655cb9 --- /dev/null +++ b/src/test/ui/pattern/pat-type-err-let-stmt.rs @@ -0,0 +1,16 @@ +// Test the `.span_label` to the type / scrutinee +// when there's a type error in checking a pattern. + +fn main() { + // We want to point at the `Option`. + let Ok(0): Option = 42u8; + //~^ ERROR mismatched types + //~| ERROR mismatched types + + // We want to point at the `Option`. + let Ok(0): Option; + //~^ ERROR mismatched types + + // We want to point at the scrutinee. + let Ok(0) = 42u8; //~ ERROR mismatched types +} diff --git a/src/test/ui/pattern/pat-type-err-let-stmt.stderr b/src/test/ui/pattern/pat-type-err-let-stmt.stderr new file mode 100644 index 0000000000000..d75fa3f247c45 --- /dev/null +++ b/src/test/ui/pattern/pat-type-err-let-stmt.stderr @@ -0,0 +1,49 @@ +error[E0308]: mismatched types + --> $DIR/pat-type-err-let-stmt.rs:6:29 + | +LL | let Ok(0): Option = 42u8; + | ---------- ^^^^ + | | | + | | expected enum `std::option::Option`, found `u8` + | | help: try using a variant of the expected enum: `Some(42u8)` + | expected due to this + | + = note: expected enum `std::option::Option` + found type `u8` + +error[E0308]: mismatched types + --> $DIR/pat-type-err-let-stmt.rs:6:9 + | +LL | let Ok(0): Option = 42u8; + | ^^^^^ ---------- expected due to this + | | + | expected enum `std::option::Option`, found enum `std::result::Result` + | + = note: expected enum `std::option::Option` + found enum `std::result::Result<_, _>` + +error[E0308]: mismatched types + --> $DIR/pat-type-err-let-stmt.rs:11:9 + | +LL | let Ok(0): Option; + | ^^^^^ ---------- expected due to this + | | + | expected enum `std::option::Option`, found enum `std::result::Result` + | + = note: expected enum `std::option::Option` + found enum `std::result::Result<_, _>` + +error[E0308]: mismatched types + --> $DIR/pat-type-err-let-stmt.rs:15:9 + | +LL | let Ok(0) = 42u8; + | ^^^^^ ---- this expression has type `u8` + | | + | expected `u8`, found enum `std::result::Result` + | + = note: expected type `u8` + found enum `std::result::Result<_, _>` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. From 63dc0e41dbf6d939741238a7c71bf5a63ae3ce55 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 12:48:48 +0100 Subject: [PATCH 10/29] discriminant -> scrutinee --- src/librustc/infer/error_reporting/mod.rs | 10 +++--- src/librustc/traits/mod.rs | 2 +- src/librustc/traits/structural_impls.rs | 4 +-- src/librustc_typeck/check/_match.rs | 38 +++++++++++------------ 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 7254bb52d7039..b3a79c0883358 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -607,7 +607,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { source, ref prior_arms, last_ty, - discrim_hir_id, + scrut_hir_id, .. }) => match source { hir::MatchSource::IfLetDesugar { .. } => { @@ -616,16 +616,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } hir::MatchSource::TryDesugar => { if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found { - let discrim_expr = self.tcx.hir().expect_expr(discrim_hir_id); - let discrim_ty = if let hir::ExprKind::Call(_, args) = &discrim_expr.kind { + let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id); + let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind { let arg_expr = args.first().expect("try desugaring call w/out arg"); self.in_progress_tables .and_then(|tables| tables.borrow().expr_ty_opt(arg_expr)) } else { - bug!("try desugaring w/out call expr as discriminant"); + bug!("try desugaring w/out call expr as scrutinee"); }; - match discrim_ty { + match scrut_ty { Some(ty) if expected == ty => { let source_map = self.tcx.sess.source_map(); err.span_suggestion( diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index f726a52946ed8..fe373e02e10f3 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -315,7 +315,7 @@ pub struct MatchExpressionArmCause<'tcx> { pub source: hir::MatchSource, pub prior_arms: Vec, pub last_ty: Ty<'tcx>, - pub discrim_hir_id: hir::HirId, + pub scrut_hir_id: hir::HirId, } #[derive(Clone, Debug, PartialEq, Eq, Hash)] diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 7b14ada8469a9..c439f20d64002 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -511,14 +511,14 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { source, ref prior_arms, last_ty, - discrim_hir_id, + scrut_hir_id, }) => tcx.lift(&last_ty).map(|last_ty| { super::MatchExpressionArm(box super::MatchExpressionArmCause { arm_span, source, prior_arms: prior_arms.clone(), last_ty, - discrim_hir_id, + scrut_hir_id, }) }), super::Pattern { span, root_ty, origin_expr } => { diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index e4cf54f629c59..841dd226b4058 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -11,7 +11,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn check_match( &self, expr: &'tcx hir::Expr<'tcx>, - discrim: &'tcx hir::Expr<'tcx>, + scrut: &'tcx hir::Expr<'tcx>, arms: &'tcx [hir::Arm<'tcx>], expected: Expectation<'tcx>, match_src: hir::MatchSource, @@ -27,7 +27,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Type check the descriminant and get its type. - let discrim_ty = if force_scrutinee_bool { + let scrut_ty = if force_scrutinee_bool { // Here we want to ensure: // // 1. That default match bindings are *not* accepted in the condition of an @@ -36,9 +36,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 2. By expecting `bool` for `expr` we get nice diagnostics for e.g. `if x = y { .. }`. // // FIXME(60707): Consider removing hack with principled solution. - self.check_expr_has_type_or_error(discrim, self.tcx.types.bool, |_| {}) + self.check_expr_has_type_or_error(scrut, self.tcx.types.bool, |_| {}) } else { - self.demand_discriminant_type(arms, discrim) + self.demand_scrutinee_type(arms, scrut) }; // If there are no arms, that is a diverging match; a special case. @@ -51,7 +51,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Otherwise, we have to union together the types that the // arms produce and so forth. - let discrim_diverges = self.diverges.get(); + let scrut_diverges = self.diverges.get(); self.diverges.set(Diverges::Maybe); // rust-lang/rust#55810: Typecheck patterns first (via eager @@ -61,7 +61,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|arm| { let mut all_pats_diverge = Diverges::WarnedAlways; self.diverges.set(Diverges::Maybe); - self.check_pat_top(&arm.pat, discrim_ty, Some(discrim.span), true); + self.check_pat_top(&arm.pat, scrut_ty, Some(scrut.span), true); all_pats_diverge &= self.diverges.get(); // As discussed with @eddyb, this is for disabling unreachable_code @@ -157,7 +157,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { source: match_src, prior_arms: other_arms.clone(), last_ty: prior_arm_ty.unwrap(), - discrim_hir_id: discrim.hir_id, + scrut_hir_id: scrut.hir_id, }), ), }; @@ -186,8 +186,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; } - // We won't diverge unless the discriminant or all arms diverge. - self.diverges.set(discrim_diverges | all_arms_diverge); + // We won't diverge unless the scrutinee or all arms diverge. + self.diverges.set(scrut_diverges | all_arms_diverge); coercion.complete(self) } @@ -388,14 +388,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } - fn demand_discriminant_type( + fn demand_scrutinee_type( &self, arms: &'tcx [hir::Arm<'tcx>], - discrim: &'tcx hir::Expr<'tcx>, + scrut: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { // Not entirely obvious: if matches may create ref bindings, we want to - // use the *precise* type of the discriminant, *not* some supertype, as - // the "discriminant type" (issue #23116). + // use the *precise* type of the scrutinee, *not* some supertype, as + // the "scrutinee type" (issue #23116). // // arielb1 [writes here in this comment thread][c] that there // is certainly *some* potential danger, e.g., for an example @@ -454,17 +454,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); if let Some(m) = contains_ref_bindings { - self.check_expr_with_needs(discrim, Needs::maybe_mut_place(m)) + self.check_expr_with_needs(scrut, Needs::maybe_mut_place(m)) } else { // ...but otherwise we want to use any supertype of the - // discriminant. This is sort of a workaround, see note (*) in + // scrutinee. This is sort of a workaround, see note (*) in // `check_pat` for some details. - let discrim_ty = self.next_ty_var(TypeVariableOrigin { + let scrut_ty = self.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, - span: discrim.span, + span: scrut.span, }); - self.check_expr_has_type_or_error(discrim, discrim_ty, |_| {}); - discrim_ty + self.check_expr_has_type_or_error(scrut, scrut_ty, |_| {}); + scrut_ty } } } From 7f9cc88f4a2226521d68f4b54f6d641978bb73e6 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sun, 29 Dec 2019 19:50:43 +0800 Subject: [PATCH 11/29] Add symbol normalization for proc_macro_server. --- src/librustc_expand/proc_macro_server.rs | 2 ++ src/librustc_parse/lexer/mod.rs | 20 ++++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs index 790e1f0edc01b..b41490011af3f 100644 --- a/src/librustc_expand/proc_macro_server.rs +++ b/src/librustc_expand/proc_macro_server.rs @@ -1,5 +1,6 @@ use crate::base::ExtCtxt; +use rustc_parse::lexer::nfc_normalize; use rustc_parse::{nt_to_tokenstream, parse_stream_from_source_str}; use syntax::ast; use syntax::print::pprust; @@ -327,6 +328,7 @@ impl Ident { } } fn new(sym: Symbol, is_raw: bool, span: Span) -> Ident { + let sym = nfc_normalize(&sym.as_str()); let string = sym.as_str(); if !Self::is_valid(&string) { panic!("`{:?}` is not a valid identifier", string) diff --git a/src/librustc_parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs index d69cd14d544db..b981e8d066fcd 100644 --- a/src/librustc_parse/lexer/mod.rs +++ b/src/librustc_parse/lexer/mod.rs @@ -471,16 +471,9 @@ impl<'a> StringReader<'a> { /// As symbol_from, with the text normalized into Unicode NFC form. fn nfc_symbol_from(&self, start: BytePos) -> Symbol { - use unicode_normalization::{is_nfc_quick, IsNormalized, UnicodeNormalization}; debug!("taking an normalized ident from {:?} to {:?}", start, self.pos); let sym = self.str_from(start); - match is_nfc_quick(sym.chars()) { - IsNormalized::Yes => Symbol::intern(sym), - _ => { - let sym_str: String = sym.chars().nfc().collect(); - Symbol::intern(&sym_str) - } - } + nfc_normalize(sym) } /// Slice of the source text spanning from `start` up to but excluding `end`. @@ -651,3 +644,14 @@ impl<'a> StringReader<'a> { } } } + +pub fn nfc_normalize(string: &str) -> Symbol { + use unicode_normalization::{is_nfc_quick, IsNormalized, UnicodeNormalization}; + match is_nfc_quick(string.chars()) { + IsNormalized::Yes => Symbol::intern(string), + _ => { + let normalized_str: String = string.chars().nfc().collect(); + Symbol::intern(&normalized_str) + } + } +} From 8f84d9e1de91261682d5e4ef8f046c9491802dee Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Mon, 30 Dec 2019 20:00:05 +0800 Subject: [PATCH 12/29] Inline and remove `nfc_symbol_from` method. --- src/librustc_parse/lexer/mod.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/librustc_parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs index b981e8d066fcd..30ec202e0ffe3 100644 --- a/src/librustc_parse/lexer/mod.rs +++ b/src/librustc_parse/lexer/mod.rs @@ -220,7 +220,7 @@ impl<'a> StringReader<'a> { if is_raw_ident { ident_start = ident_start + BytePos(2); } - let sym = self.nfc_symbol_from(ident_start); + let sym = nfc_normalize(self.str_from(ident_start)); if is_raw_ident { let span = self.mk_sp(start, self.pos); if !sym.can_be_raw() { @@ -469,13 +469,6 @@ impl<'a> StringReader<'a> { Symbol::intern(self.str_from_to(start, end)) } - /// As symbol_from, with the text normalized into Unicode NFC form. - fn nfc_symbol_from(&self, start: BytePos) -> Symbol { - debug!("taking an normalized ident from {:?} to {:?}", start, self.pos); - let sym = self.str_from(start); - nfc_normalize(sym) - } - /// Slice of the source text spanning from `start` up to but excluding `end`. fn str_from_to(&self, start: BytePos, end: BytePos) -> &str { &self.src[self.src_index(start)..self.src_index(end)] From 2091062bf685ec2a64cafdffb72ae8479ff41890 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 14:56:57 +0100 Subject: [PATCH 13/29] parser: call .struct_span_err directly --- src/librustc_parse/parser/attr.rs | 7 ++--- src/librustc_parse/parser/diagnostics.rs | 26 ++++++++---------- src/librustc_parse/parser/expr.rs | 3 +- src/librustc_parse/parser/item.rs | 20 ++++++-------- src/librustc_parse/parser/module.rs | 7 ++--- src/librustc_parse/parser/pat.rs | 26 ++++++++---------- src/librustc_parse/parser/path.rs | 35 ++++++++++++------------ 7 files changed, 56 insertions(+), 68 deletions(-) diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs index 4b7f1e9a4d833..d26677a6c32c0 100644 --- a/src/librustc_parse/parser/attr.rs +++ b/src/librustc_parse/parser/attr.rs @@ -133,7 +133,7 @@ impl<'a> Parser<'a> { "previous outer attribute" }; - let mut diagnostic = self.diagnostic().struct_span_err(attr_sp, reason); + let mut diagnostic = self.struct_span_err(attr_sp, reason); if let Some(prev_attr_sp) = prev_attr_sp { diagnostic @@ -231,8 +231,7 @@ impl<'a> Parser<'a> { if !lit.kind.is_unsuffixed() { let msg = "suffixed literals are not allowed in attributes"; - self.diagnostic() - .struct_span_err(lit.span, msg) + self.struct_span_err(lit.span, msg) .help( "instead of using a suffixed literal \ (1u8, 1.0f32, etc.), use an unsuffixed version \ @@ -332,6 +331,6 @@ impl<'a> Parser<'a> { let found = pprust::token_to_string(&self.token); let msg = format!("expected unsuffixed literal or identifier, found `{}`", found); - Err(self.diagnostic().struct_span_err(self.token.span, &msg)) + Err(self.struct_span_err(self.token.span, &msg)) } } diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 578f816be58c8..d091cceb932fc 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -502,18 +502,17 @@ impl<'a> Parser<'a> { let span = lo.until(self.token.span); let total_num_of_gt = number_of_gt + number_of_shr * 2; - self.diagnostic() - .struct_span_err( - span, - &format!("unmatched angle bracket{}", pluralize!(total_num_of_gt)), - ) - .span_suggestion( - span, - &format!("remove extra angle bracket{}", pluralize!(total_num_of_gt)), - String::new(), - Applicability::MachineApplicable, - ) - .emit(); + self.struct_span_err( + span, + &format!("unmatched angle bracket{}", pluralize!(total_num_of_gt)), + ) + .span_suggestion( + span, + &format!("remove extra angle bracket{}", pluralize!(total_num_of_gt)), + String::new(), + Applicability::MachineApplicable, + ) + .emit(); } } @@ -762,8 +761,7 @@ impl<'a> Parser<'a> { path.span = ty_span.to(self.prev_span); let ty_str = self.span_to_snippet(ty_span).unwrap_or_else(|_| pprust::ty_to_string(&ty)); - self.diagnostic() - .struct_span_err(path.span, "missing angle brackets in associated item path") + self.struct_span_err(path.span, "missing angle brackets in associated item path") .span_suggestion( // This is a best-effort recovery. path.span, diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index b51a4465b159e..5566407963a5b 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1915,8 +1915,7 @@ impl<'a> Parser<'a> { return; } - self.diagnostic() - .struct_span_err(self.token.span, "expected `:`, found `=`") + self.struct_span_err(self.token.span, "expected `:`, found `=`") .span_suggestion( field_name.span.shrink_to_hi().to(self.token.span), "replace equals symbol with a colon", diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 343c6667d47d5..424483292b66e 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -306,8 +306,7 @@ impl<'a> Parser<'a> { // possible public struct definition where `struct` was forgotten let ident = self.parse_ident().unwrap(); let msg = format!("add `struct` here to parse `{}` as a public struct", ident); - let mut err = - self.diagnostic().struct_span_err(sp, "missing `struct` for struct definition"); + let mut err = self.struct_span_err(sp, "missing `struct` for struct definition"); err.span_suggestion_short( sp, &msg, @@ -335,7 +334,7 @@ impl<'a> Parser<'a> { }; let msg = format!("missing `{}` for {} definition", kw, kw_name); - let mut err = self.diagnostic().struct_span_err(sp, &msg); + let mut err = self.struct_span_err(sp, &msg); if !ambiguous { self.consume_block(token::Brace, ConsumeClosingDelim::Yes); let suggestion = @@ -375,7 +374,7 @@ impl<'a> Parser<'a> { ("fn` or `struct", "function or struct", true) }; let msg = format!("missing `{}` for {} definition", kw, kw_name); - let mut err = self.diagnostic().struct_span_err(sp, &msg); + let mut err = self.struct_span_err(sp, &msg); if !ambiguous { err.span_suggestion_short( sp, @@ -466,7 +465,7 @@ impl<'a> Parser<'a> { _ => "expected item after attributes", }; - let mut err = self.diagnostic().struct_span_err(self.prev_span, message); + let mut err = self.struct_span_err(self.prev_span, message); if attrs.last().unwrap().is_doc_comment() { err.span_label(self.prev_span, "this doc comment doesn't document anything"); } @@ -536,7 +535,6 @@ impl<'a> Parser<'a> { // ^^ `sp` below will point to this let sp = prev_span.between(self.prev_span); let mut err = self - .diagnostic() .struct_span_err(sp, &format!("{} for {}-item declaration", expected_kinds, item_type)); err.span_label(sp, expected_kinds); err @@ -1603,9 +1601,8 @@ impl<'a> Parser<'a> { VisibilityKind::Inherited => {} _ => { let mut err = if self.token.is_keyword(sym::macro_rules) { - let mut err = self - .diagnostic() - .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`"); + let mut err = + self.struct_span_err(sp, "can't qualify macro_rules invocation with `pub`"); err.span_suggestion( sp, "try exporting the macro", @@ -1614,9 +1611,8 @@ impl<'a> Parser<'a> { ); err } else { - let mut err = self - .diagnostic() - .struct_span_err(sp, "can't qualify macro invocation with `pub`"); + let mut err = + self.struct_span_err(sp, "can't qualify macro invocation with `pub`"); err.help("try adjusting the macro to put `pub` inside the invocation"); err }; diff --git a/src/librustc_parse/parser/module.rs b/src/librustc_parse/parser/module.rs index 3f54e0b6de031..7f5104d260d6a 100644 --- a/src/librustc_parse/parser/module.rs +++ b/src/librustc_parse/parser/module.rs @@ -129,7 +129,7 @@ impl<'a> Parser<'a> { DirectoryOwnership::UnownedViaBlock => { let msg = "Cannot declare a non-inline module inside a block \ unless it has a path attribute"; - let mut err = self.diagnostic().struct_span_err(id_sp, msg); + let mut err = self.struct_span_err(id_sp, msg); if paths.path_exists { let msg = format!( "Maybe `use` the module `{}` instead of redeclaring it", @@ -140,9 +140,8 @@ impl<'a> Parser<'a> { Err(err) } DirectoryOwnership::UnownedViaMod => { - let mut err = self - .diagnostic() - .struct_span_err(id_sp, "cannot declare a new module at this location"); + let mut err = + self.struct_span_err(id_sp, "cannot declare a new module at this location"); if !id_sp.is_dummy() { let src_path = self.sess.source_map().span_to_filename(id_sp); if let FileName::Real(src_path) = src_path { diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index d2288b27a0c40..6a98d29675e73 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -699,8 +699,7 @@ impl<'a> Parser<'a> { let range_span = lo.to(end.span); let begin = self.mk_expr(range_span, ExprKind::Err, AttrVec::new()); - self.diagnostic() - .struct_span_err(range_span, &format!("`{}X` range patterns are not supported", form)) + self.struct_span_err(range_span, &format!("`{}X` range patterns are not supported", form)) .span_suggestion( range_span, "try using the minimum value for the type", @@ -722,18 +721,17 @@ impl<'a> Parser<'a> { // Parsing e.g. `X..`. let range_span = begin.span.to(self.prev_span); - self.diagnostic() - .struct_span_err( - range_span, - &format!("`X{}` range patterns are not supported", form), - ) - .span_suggestion( - range_span, - "try using the maximum value for the type", - format!("{}{}MAX", pprust::expr_to_string(&begin), form), - Applicability::HasPlaceholders, - ) - .emit(); + self.struct_span_err( + range_span, + &format!("`X{}` range patterns are not supported", form), + ) + .span_suggestion( + range_span, + "try using the maximum value for the type", + format!("{}{}MAX", pprust::expr_to_string(&begin), form), + Applicability::HasPlaceholders, + ) + .emit(); Ok(self.mk_expr(range_span, ExprKind::Err, AttrVec::new())) } diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index e6c7d50fb4cf6..ef22628a5e06d 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -325,24 +325,23 @@ impl<'a> Parser<'a> { // Make a span over ${unmatched angle bracket count} characters. let span = lo.with_hi(lo.lo() + BytePos(snapshot.unmatched_angle_bracket_count)); - self.diagnostic() - .struct_span_err( - span, - &format!( - "unmatched angle bracket{}", - pluralize!(snapshot.unmatched_angle_bracket_count) - ), - ) - .span_suggestion( - span, - &format!( - "remove extra angle bracket{}", - pluralize!(snapshot.unmatched_angle_bracket_count) - ), - String::new(), - Applicability::MachineApplicable, - ) - .emit(); + self.struct_span_err( + span, + &format!( + "unmatched angle bracket{}", + pluralize!(snapshot.unmatched_angle_bracket_count) + ), + ) + .span_suggestion( + span, + &format!( + "remove extra angle bracket{}", + pluralize!(snapshot.unmatched_angle_bracket_count) + ), + String::new(), + Applicability::MachineApplicable, + ) + .emit(); // Try again without unmatched angle bracket characters. self.parse_generic_args() From b6fc87c5b9af5d626e2b85d008c7146a29733536 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 15:09:42 +0100 Subject: [PATCH 14/29] de-fatalize some errors --- src/librustc_parse/parser/diagnostics.rs | 4 ---- src/librustc_parse/parser/expr.rs | 6 +++++- src/librustc_parse/parser/item.rs | 2 +- src/librustc_parse/parser/path.rs | 2 +- src/librustc_parse/parser/stmt.rs | 3 ++- src/test/ui/parser/attr-stmt-expr-attr-bad.rs | 1 + src/test/ui/parser/attr-stmt-expr-attr-bad.stderr | 8 +++++++- 7 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index d091cceb932fc..2e58b702d925b 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -177,10 +177,6 @@ impl<'a> Parser<'a> { self.sess.span_diagnostic.span_bug(self.token.span, m) } - pub(super) fn span_err>(&self, sp: S, m: &str) { - self.sess.span_diagnostic.span_err(sp, m) - } - pub fn struct_span_err>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> { self.sess.span_diagnostic.struct_span_err(sp, m) } diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 5566407963a5b..f5cefeca3391a 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -822,7 +822,11 @@ impl<'a> Parser<'a> { } else { // Field access `expr.f` if let Some(args) = segment.args { - self.span_err(args.span(), "field expressions may not have generic arguments"); + self.struct_span_err( + args.span(), + "field expressions may not have generic arguments", + ) + .emit(); } let span = lo.to(self.prev_span); diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 424483292b66e..64482f09edec7 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -617,7 +617,7 @@ impl<'a> Parser<'a> { // This notably includes paths passed through `ty` macro fragments (#46438). TyKind::Path(None, path) => path, _ => { - self.span_err(ty_first.span, "expected a trait, found type"); + self.struct_span_err(ty_first.span, "expected a trait, found type").emit(); err_path(ty_first.span) } }; diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index ef22628a5e06d..6f24dfcd027c5 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -93,7 +93,7 @@ impl<'a> Parser<'a> { maybe_whole!(self, NtPath, |path| { if style == PathStyle::Mod && path.segments.iter().any(|segment| segment.args.is_some()) { - self.diagnostic().span_err(path.span, "unexpected generic arguments in path"); + self.struct_span_err(path.span, "unexpected generic arguments in path").emit(); } path }); diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index 8270da6c0234f..1d0897a3cf3f7 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -193,7 +193,8 @@ impl<'a> Parser<'a> { if self.prev_token_kind == PrevTokenKind::DocComment { self.span_fatal_err(self.prev_span, Error::UselessDocComment).emit(); } else if attrs.iter().any(|a| a.style == AttrStyle::Outer) { - self.span_err(self.token.span, "expected statement after outer attribute"); + self.struct_span_err(self.token.span, "expected statement after outer attribute") + .emit(); } } } diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.rs b/src/test/ui/parser/attr-stmt-expr-attr-bad.rs index 6e1d72cd2f6e2..f6d2bee0e1560 100644 --- a/src/test/ui/parser/attr-stmt-expr-attr-bad.rs +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.rs @@ -112,3 +112,4 @@ fn main() {} #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } } //~^ ERROR expected statement after outer attribute #[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } } +//~^ ERROR expected statement after outer attribute diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr index 371d3f575a418..0123006418a3a 100644 --- a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr @@ -410,5 +410,11 @@ error: expected statement after outer attribute LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } } | ^ -error: aborting due to 56 previous errors +error: expected statement after outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:114:45 + | +LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } } + | ^ + +error: aborting due to 57 previous errors From 5a64ba63862906588b0dcd8ea2ed9884ec44f4a8 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 31 Dec 2019 00:20:41 +0100 Subject: [PATCH 15/29] parser: span_fatal -> struct_span_err --- src/librustc_parse/parser/diagnostics.rs | 6 +----- src/librustc_parse/parser/expr.rs | 2 +- src/librustc_parse/parser/item.rs | 4 +--- src/librustc_parse/parser/module.rs | 2 +- src/librustc_parse/parser/pat.rs | 4 +++- src/librustc_parse/parser/stmt.rs | 2 +- 6 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 2e58b702d925b..630087fb7e80d 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -158,11 +158,7 @@ crate enum ConsumeClosingDelim { impl<'a> Parser<'a> { pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> { - self.span_fatal(self.token.span, m) - } - - crate fn span_fatal>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> { - self.sess.span_diagnostic.struct_span_fatal(sp, m) + self.sess.span_diagnostic.struct_span_fatal(self.token.span, m) } pub(super) fn span_fatal_err>( diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index f5cefeca3391a..49ca5abe97f64 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1137,7 +1137,7 @@ impl<'a> Parser<'a> { pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> { self.parse_opt_lit().ok_or_else(|| { let msg = format!("unexpected token: {}", super::token_descr(&self.token)); - self.span_fatal(self.token.span, &msg) + self.struct_span_err(self.token.span, &msg) }) } diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 64482f09edec7..d7b242f610129 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -445,9 +445,7 @@ impl<'a> Parser<'a> { // FAILURE TO PARSE ITEM match visibility.node { VisibilityKind::Inherited => {} - _ => { - return Err(self.span_fatal(self.prev_span, "unmatched visibility `pub`")); - } + _ => return Err(self.struct_span_err(self.prev_span, "unmatched visibility `pub`")), } if !attributes_allowed && !attrs.is_empty() { diff --git a/src/librustc_parse/parser/module.rs b/src/librustc_parse/parser/module.rs index 7f5104d260d6a..1b7d54a1c1e0f 100644 --- a/src/librustc_parse/parser/module.rs +++ b/src/librustc_parse/parser/module.rs @@ -262,7 +262,7 @@ impl<'a> Parser<'a> { err.push_str(" -> "); } err.push_str(&path.to_string_lossy()); - return Err(self.span_fatal(id_sp, &err[..])); + return Err(self.struct_span_err(id_sp, &err[..])); } included_mod_stack.push(path.clone()); drop(included_mod_stack); diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index 6a98d29675e73..4895d5428df34 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -796,7 +796,9 @@ impl<'a> Parser<'a> { // binding mode then we do not end up here, because the lookahead // will direct us over to `parse_enum_variant()`. if self.token == token::OpenDelim(token::Paren) { - return Err(self.span_fatal(self.prev_span, "expected identifier, found enum pattern")); + return Err( + self.struct_span_err(self.prev_span, "expected identifier, found enum pattern") + ); } Ok(PatKind::Ident(binding_mode, ident, sub)) diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index 1d0897a3cf3f7..1f72c66ea03d6 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -325,7 +325,7 @@ impl<'a> Parser<'a> { fn error_block_no_opening_brace(&mut self) -> PResult<'a, T> { let sp = self.token.span; let tok = super::token_descr(&self.token); - let mut e = self.span_fatal(sp, &format!("expected `{{`, found {}", tok)); + let mut e = self.struct_span_err(sp, &format!("expected `{{`, found {}", tok)); let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon; // Check to see if the user has written something like From 85dbbaa492c83a390d9ab4bac20e20b672565431 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 31 Dec 2019 00:25:30 +0100 Subject: [PATCH 16/29] process_potential_macro_variable: de-fatalize an error --- src/librustc_parse/parser/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 103bbe5dd763e..322c8dda64793 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -1056,8 +1056,7 @@ impl<'a> Parser<'a> { _ => unreachable!(), }; let span = self.prev_span.to(self.token.span); - self.diagnostic() - .struct_span_fatal(span, &format!("unknown macro variable `{}`", name)) + self.struct_span_err(span, &format!("unknown macro variable `{}`", name)) .span_label(span, "unknown macro variable") .emit(); self.bump(); From 46ec6becf2f27cd04729e41616528751abe64d80 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 31 Dec 2019 01:13:00 +0100 Subject: [PATCH 17/29] parser::attr: remove .fatal calls --- src/librustc_parse/parser/attr.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs index d26677a6c32c0..26df4f1c090d6 100644 --- a/src/librustc_parse/parser/attr.rs +++ b/src/librustc_parse/parser/attr.rs @@ -46,7 +46,8 @@ impl<'a> Parser<'a> { token::DocComment(s) => { let attr = self.mk_doc_comment(s); if attr.style != ast::AttrStyle::Outer { - let mut err = self.fatal("expected outer doc comment"); + let span = self.token.span; + let mut err = self.struct_span_err(span, "expected outer doc comment"); err.note( "inner doc comments like this (starting with \ `//!` or `/*!`) can only appear before items", @@ -156,7 +157,8 @@ impl<'a> Parser<'a> { } _ => { let token_str = pprust::token_to_string(&self.token); - return Err(self.fatal(&format!("expected `#`, found `{}`", token_str))); + let msg = &format!("expected `#`, found `{}`", token_str); + return Err(self.struct_span_err(self.token.span, msg)); } }; From 13ca924988b05d894b8259b0ecd81656f5b3db5c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 31 Dec 2019 01:19:53 +0100 Subject: [PATCH 18/29] parser::item: remove .fatal calls --- src/librustc_parse/parser/item.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index d7b242f610129..e5a7361b12ab7 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -1345,10 +1345,11 @@ impl<'a> Parser<'a> { body } else { let token_str = super::token_descr(&self.token); - let mut err = self.fatal(&format!( + let msg = &format!( "expected `where`, `{{`, `(`, or `;` after struct name, found {}", token_str - )); + ); + let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, "expected `where`, `{`, `(`, or `;` after struct name"); return Err(err); }; @@ -1371,8 +1372,8 @@ impl<'a> Parser<'a> { VariantData::Struct(fields, recovered) } else { let token_str = super::token_descr(&self.token); - let mut err = self - .fatal(&format!("expected `where` or `{{` after union name, found {}", token_str)); + let msg = &format!("expected `where` or `{{` after union name, found {}", token_str); + let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, "expected `where` or `{` after union name"); return Err(err); }; @@ -1408,10 +1409,8 @@ impl<'a> Parser<'a> { self.eat(&token::CloseDelim(token::Brace)); } else { let token_str = super::token_descr(&self.token); - let mut err = self.fatal(&format!( - "expected `where`, or `{{` after struct name, found {}", - token_str - )); + let msg = &format!("expected `where`, or `{{` after struct name, found {}", token_str); + let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, "expected `where`, or `{` after struct name"); return Err(err); } From 51fb5998493366a7f0257855d1d9be7836aad30f Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 31 Dec 2019 01:28:10 +0100 Subject: [PATCH 19/29] parser::module: remove .fatal calls --- src/librustc_parse/parser/module.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_parse/parser/module.rs b/src/librustc_parse/parser/module.rs index 1b7d54a1c1e0f..84ffa6f7fcd8f 100644 --- a/src/librustc_parse/parser/module.rs +++ b/src/librustc_parse/parser/module.rs @@ -81,7 +81,8 @@ impl<'a> Parser<'a> { if !self.eat(term) { let token_str = super::token_descr(&self.token); if !self.maybe_consume_incorrect_semicolon(&items) { - let mut err = self.fatal(&format!("expected item, found {}", token_str)); + let msg = &format!("expected item, found {}", token_str); + let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, "expected item"); return Err(err); } From 6fba12591217cd4f1980e0d6fc5b2dee897799d1 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 31 Dec 2019 01:57:42 +0100 Subject: [PATCH 20/29] parser::path: remove .fatal calls --- src/librustc_parse/parser/expr.rs | 4 +--- src/librustc_parse/parser/path.rs | 8 +++++--- src/librustc_parse/parser/stmt.rs | 13 +++++++++---- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 49ca5abe97f64..9a4bef3776865 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1450,9 +1450,7 @@ impl<'a> Parser<'a> { self.struct_span_err(sp, "missing condition for `if` expression") .span_label(sp, "expected if condition here") .emit(); - let expr = self.mk_expr_err(span); - let stmt = self.mk_stmt(span, ast::StmtKind::Expr(expr)); - self.mk_block(vec![stmt], BlockCheckMode::Default, span) + self.mk_block_err(span) } /// Parses the condition of a `if` or `while` expression. diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index 6f24dfcd027c5..325ad56cd2a43 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -406,9 +406,11 @@ impl<'a> Parser<'a> { if self.token.is_bool_lit() { self.parse_literal_maybe_minus()? } else { - return Err( - self.fatal("identifiers may currently not be used for const generics") - ); + let span = self.token.span; + let msg = "identifiers may currently not be used for const generics"; + self.struct_span_err(span, msg).emit(); + let block = self.mk_block_err(span); + self.mk_expr(span, ast::ExprKind::Block(block, None), ast::AttrVec::new()) } } else { self.parse_literal_maybe_minus()? diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index 1f72c66ea03d6..bf092ed14e342 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -398,10 +398,7 @@ impl<'a> Parser<'a> { self.maybe_annotate_with_ascription(&mut err, false); err.emit(); self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore); - Some(self.mk_stmt( - self.token.span, - StmtKind::Expr(self.mk_expr_err(self.token.span)), - )) + Some(self.mk_stmt_err(self.token.span)) } Ok(stmt) => stmt, }; @@ -479,4 +476,12 @@ impl<'a> Parser<'a> { pub(super) fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt { Stmt { id: DUMMY_NODE_ID, kind, span } } + + fn mk_stmt_err(&self, span: Span) -> Stmt { + self.mk_stmt(span, StmtKind::Expr(self.mk_expr_err(span))) + } + + pub(super) fn mk_block_err(&self, span: Span) -> P { + self.mk_block(vec![self.mk_stmt_err(span)], BlockCheckMode::Default, span) + } } From 2e812c1c5f1502487bdcbeef938c3dbe6a0d7e05 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 31 Dec 2019 03:36:45 +0100 Subject: [PATCH 21/29] parser::pat: remove .fatal calls --- src/librustc_parse/parser/pat.rs | 26 +++++++++++-------- ...brace-after-qualified-path-in-match.stderr | 4 ++- ...paren-after-qualified-path-in-match.stderr | 4 ++- .../suggestions/vec-macro-in-pattern.stderr | 3 ++- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index 4895d5428df34..e608b86c76a29 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -673,7 +673,7 @@ impl<'a> Parser<'a> { let expected = expected.unwrap_or("pattern"); let msg = format!("expected {}, found {}", expected, super::token_descr(&self.token)); - let mut err = self.fatal(&msg); + let mut err = self.struct_span_err(self.token.span, &msg); err.span_label(self.token.span, format!("expected {}", expected)); let sp = self.sess.source_map().start_point(self.token.span); @@ -807,12 +807,8 @@ impl<'a> Parser<'a> { /// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`). fn parse_pat_struct(&mut self, qself: Option, path: Path) -> PResult<'a, PatKind> { if qself.is_some() { - let msg = "unexpected `{` after qualified path"; - let mut err = self.fatal(msg); - err.span_label(self.token.span, msg); - return Err(err); + return self.error_qpath_before_pat(&path, "{"); } - self.bump(); let (fields, etc) = self.parse_pat_fields().unwrap_or_else(|mut e| { e.emit(); @@ -826,15 +822,22 @@ impl<'a> Parser<'a> { /// Parse tuple struct or tuple variant pattern (e.g. `Foo(...)` or `Foo::Bar(...)`). fn parse_pat_tuple_struct(&mut self, qself: Option, path: Path) -> PResult<'a, PatKind> { if qself.is_some() { - let msg = "unexpected `(` after qualified path"; - let mut err = self.fatal(msg); - err.span_label(self.token.span, msg); - return Err(err); + return self.error_qpath_before_pat(&path, "("); } let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or_inner())?; Ok(PatKind::TupleStruct(path, fields)) } + /// Error when there's a qualified path, e.g. `::Baz` + /// as the path of e.g., a tuple or record struct pattern. + fn error_qpath_before_pat(&mut self, path: &Path, token: &str) -> PResult<'a, PatKind> { + let msg = &format!("unexpected `{}` after qualified path", token); + let mut err = self.struct_span_err(self.token.span, msg); + err.span_label(self.token.span, msg); + err.span_label(path.span, "the qualified path"); + Err(err) + } + /// Parses the fields of a struct-like pattern. fn parse_pat_fields(&mut self) -> PResult<'a, (Vec, bool)> { let mut fields = Vec::new(); @@ -877,7 +880,8 @@ impl<'a> Parser<'a> { break; } let token_str = super::token_descr(&self.token); - let mut err = self.fatal(&format!("expected `}}`, found {}", token_str)); + let msg = &format!("expected `}}`, found {}", token_str); + let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, "expected `}`"); let mut comma_sp = None; diff --git a/src/test/ui/parser/brace-after-qualified-path-in-match.stderr b/src/test/ui/parser/brace-after-qualified-path-in-match.stderr index 4c49e3122c702..d6fdf353f07af 100644 --- a/src/test/ui/parser/brace-after-qualified-path-in-match.stderr +++ b/src/test/ui/parser/brace-after-qualified-path-in-match.stderr @@ -2,7 +2,9 @@ error: unexpected `{` after qualified path --> $DIR/brace-after-qualified-path-in-match.rs:3:27 | LL | ::Type{key: value} => (), - | ^ unexpected `{` after qualified path + | ------------------^ unexpected `{` after qualified path + | | + | the qualified path error: aborting due to previous error diff --git a/src/test/ui/parser/paren-after-qualified-path-in-match.stderr b/src/test/ui/parser/paren-after-qualified-path-in-match.stderr index 79460e01f257b..af21f9195467a 100644 --- a/src/test/ui/parser/paren-after-qualified-path-in-match.stderr +++ b/src/test/ui/parser/paren-after-qualified-path-in-match.stderr @@ -2,7 +2,9 @@ error: unexpected `(` after qualified path --> $DIR/paren-after-qualified-path-in-match.rs:3:27 | LL | ::Type(2) => (), - | ^ unexpected `(` after qualified path + | ------------------^ unexpected `(` after qualified path + | | + | the qualified path error: aborting due to previous error diff --git a/src/test/ui/suggestions/vec-macro-in-pattern.stderr b/src/test/ui/suggestions/vec-macro-in-pattern.stderr index 59ca8ebbf6339..1634fdde7d295 100644 --- a/src/test/ui/suggestions/vec-macro-in-pattern.stderr +++ b/src/test/ui/suggestions/vec-macro-in-pattern.stderr @@ -5,11 +5,12 @@ LL | Some(vec![_x]) => (), | ^^^^^^^^ | | | unexpected `(` after qualified path + | the qualified path | in this macro invocation | help: use a slice pattern here instead: `[_x]` | = help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html - = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to previous error From 4ae9c1c3ecbba91d39e74ca97cac349b2fe6dcc3 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 31 Dec 2019 04:21:58 +0100 Subject: [PATCH 22/29] parser::diagnostics: remove fn fatal --- src/librustc_expand/mbe/macro_parser.rs | 10 ++++++---- src/librustc_parse/parser/diagnostics.rs | 9 +++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs index 24253e1bdc2cd..37374d7071927 100644 --- a/src/librustc_expand/mbe/macro_parser.rs +++ b/src/librustc_expand/mbe/macro_parser.rs @@ -890,12 +890,12 @@ fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a, Ok(match name { sym::item => match p.parse_item()? { Some(i) => token::NtItem(i), - None => return Err(p.fatal("expected an item keyword")), + None => return Err(p.struct_span_err(p.token.span, "expected an item keyword")), }, sym::block => token::NtBlock(p.parse_block()?), sym::stmt => match p.parse_stmt()? { Some(s) => token::NtStmt(s), - None => return Err(p.fatal("expected a statement")), + None => return Err(p.struct_span_err(p.token.span, "expected a statement")), }, sym::pat => token::NtPat(p.parse_pat(None)?), sym::expr => token::NtExpr(p.parse_expr()?), @@ -909,7 +909,8 @@ fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a, token::NtIdent(Ident::new(name, span), is_raw) } else { let token_str = pprust::token_to_string(&p.token); - return Err(p.fatal(&format!("expected ident, found {}", &token_str))); + let msg = &format!("expected ident, found {}", &token_str); + return Err(p.struct_span_err(p.token.span, msg)); } } sym::path => token::NtPath(p.parse_path(PathStyle::Type)?), @@ -920,7 +921,8 @@ fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a, token::NtLifetime(p.expect_lifetime().ident) } else { let token_str = pprust::token_to_string(&p.token); - return Err(p.fatal(&format!("expected a lifetime, found `{}`", &token_str))); + let msg = &format!("expected a lifetime, found `{}`", &token_str); + return Err(p.struct_span_err(p.token.span, msg)); } } // this is not supposed to happen, since it has been checked diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 630087fb7e80d..778f24fad6d49 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -157,10 +157,6 @@ crate enum ConsumeClosingDelim { } impl<'a> Parser<'a> { - pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> { - self.sess.span_diagnostic.struct_span_fatal(self.token.span, m) - } - pub(super) fn span_fatal_err>( &self, sp: S, @@ -290,7 +286,7 @@ impl<'a> Parser<'a> { ) }; self.last_unexpected_token_span = Some(self.token.span); - let mut err = self.fatal(&msg_exp); + let mut err = self.struct_span_err(self.token.span, &msg_exp); let sp = if self.token == token::Eof { // This is EOF; don't want to point at the following char, but rather the last token. self.prev_span @@ -1261,7 +1257,8 @@ impl<'a> Parser<'a> { pub(super) fn expected_semi_or_open_brace(&mut self) -> PResult<'a, T> { let token_str = super::token_descr(&self.token); - let mut err = self.fatal(&format!("expected `;` or `{{`, found {}", token_str)); + let msg = &format!("expected `;` or `{{`, found {}", token_str); + let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, "expected `;` or `{`"); Err(err) } From 2e7806146c008742919124bf6ac9a37c3ece51bb Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 31 Dec 2019 04:30:55 +0100 Subject: [PATCH 23/29] parser: bug -> span_bug --- src/librustc_parse/parser/diagnostics.rs | 4 ---- src/librustc_parse/parser/expr.rs | 2 +- src/librustc_parse/parser/mod.rs | 3 ++- src/librustc_parse/parser/ty.rs | 4 +++- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 778f24fad6d49..05754357bc822 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -165,10 +165,6 @@ impl<'a> Parser<'a> { err.span_err(sp, self.diagnostic()) } - pub(super) fn bug(&self, m: &str) -> ! { - self.sess.span_diagnostic.span_bug(self.token.span, m) - } - pub fn struct_span_err>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> { self.sess.span_diagnostic.struct_span_err(sp, m) } diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 9a4bef3776865..ab7c156e3706d 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -283,7 +283,7 @@ impl<'a> Parser<'a> { self.mk_expr(span, aopexpr, AttrVec::new()) } AssocOp::As | AssocOp::Colon | AssocOp::DotDot | AssocOp::DotDotEq => { - self.bug("AssocOp should have been handled by special case") + self.span_bug(span, "AssocOp should have been handled by special case") } }; diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 322c8dda64793..ec6468f4f0a32 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -884,7 +884,8 @@ impl<'a> Parser<'a> { pub fn bump(&mut self) { if self.prev_token_kind == PrevTokenKind::Eof { // Bumping after EOF is a bad sign, usually an infinite loop. - self.bug("attempted to bump the parser past EOF (may be stuck in a loop)"); + let msg = "attempted to bump the parser past EOF (may be stuck in a loop)"; + self.span_bug(self.token.span, msg); } self.prev_span = self.meta_var_span.take().unwrap_or(self.token.span); diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index 049c077c3cea3..4f7bcf01e1b82 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -175,7 +175,9 @@ impl<'a> Parser<'a> { { let path = match bounds.remove(0) { GenericBound::Trait(pt, ..) => pt.trait_ref.path, - GenericBound::Outlives(..) => self.bug("unexpected lifetime bound"), + GenericBound::Outlives(..) => { + self.span_bug(ty.span, "unexpected lifetime bound") + } }; self.parse_remaining_bounds(Vec::new(), path, lo, true) } From b40dc30a3ea218caae39052eb0ef57fb15493072 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 30 Dec 2019 21:35:13 -0800 Subject: [PATCH 24/29] Use function attribute "frame-pointer" instead of "no-frame-pointer-elim" LLVM 8 (D56351) introduced "frame-pointer". In LLVM 10 (D71863), "no-frame-pointer-elim"/"no-frame-pointer-elim-non-leaf" will be ignored. --- src/librustc_codegen_llvm/attributes.rs | 21 +++++++++++++++------ src/test/codegen/force-frame-pointers.rs | 4 ++-- src/test/codegen/instrument-mcount.rs | 3 ++- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 816f5baddcbee..942ba9f868c60 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -66,12 +66,21 @@ fn naked(val: &'ll Value, is_naked: bool) { pub fn set_frame_pointer_elimination(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { if cx.sess().must_not_eliminate_frame_pointers() { - llvm::AddFunctionAttrStringValue( - llfn, - llvm::AttributePlace::Function, - const_cstr!("no-frame-pointer-elim"), - const_cstr!("true"), - ); + if llvm_util::get_major_version() >= 8 { + llvm::AddFunctionAttrStringValue( + llfn, + llvm::AttributePlace::Function, + const_cstr!("frame-pointer"), + const_cstr!("all"), + ); + } else { + llvm::AddFunctionAttrStringValue( + llfn, + llvm::AttributePlace::Function, + const_cstr!("no-frame-pointer-elim"), + const_cstr!("true"), + ); + } } } diff --git a/src/test/codegen/force-frame-pointers.rs b/src/test/codegen/force-frame-pointers.rs index c6c1da2c1b05e..4c94a601f33fd 100644 --- a/src/test/codegen/force-frame-pointers.rs +++ b/src/test/codegen/force-frame-pointers.rs @@ -1,7 +1,7 @@ -// +// min-llvm-version 8.0 // compile-flags: -C no-prepopulate-passes -C force-frame-pointers=y #![crate_type="lib"] -// CHECK: attributes #{{.*}} "no-frame-pointer-elim"="true" +// CHECK: attributes #{{.*}} "frame-pointer"="all" pub fn foo() {} diff --git a/src/test/codegen/instrument-mcount.rs b/src/test/codegen/instrument-mcount.rs index c72d09f7a03d2..e4e6d5ca2b850 100644 --- a/src/test/codegen/instrument-mcount.rs +++ b/src/test/codegen/instrument-mcount.rs @@ -1,7 +1,8 @@ +// min-llvm-version 8.0 // ignore-tidy-linelength // compile-flags: -Z instrument-mcount #![crate_type = "lib"] -// CHECK: attributes #{{.*}} "instrument-function-entry-inlined"="{{.*}}mcount{{.*}}" "no-frame-pointer-elim"="true" +// CHECK: attributes #{{.*}} "frame-pointer"="all" "instrument-function-entry-inlined"="{{.*}}mcount{{.*}}" pub fn foo() {} From 954c432a87fc5069ac10cc5a92fd44106be1e7fd Mon Sep 17 00:00:00 2001 From: Lukas Lueg Date: Sat, 28 Dec 2019 21:33:36 +0100 Subject: [PATCH 25/29] Constify Result --- src/libcore/lib.rs | 1 + src/libcore/result.rs | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 590f4e46c1d2f..8e1273c3172d3 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -76,6 +76,7 @@ #![feature(const_fn_union)] #![feature(const_generics)] #![feature(const_ptr_offset_from)] +#![feature(const_result)] #![feature(const_type_name)] #![feature(custom_inner_attributes)] #![feature(decl_macro)] diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 5628658c5bdf5..5cfc81097dd44 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -278,9 +278,10 @@ impl Result { /// assert_eq!(x.is_ok(), false); /// ``` #[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"] + #[rustc_const_unstable(feature = "const_result", issue = "67520")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_ok(&self) -> bool { + pub const fn is_ok(&self) -> bool { match *self { Ok(_) => true, Err(_) => false, @@ -303,9 +304,10 @@ impl Result { /// assert_eq!(x.is_err(), true); /// ``` #[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"] + #[rustc_const_unstable(feature = "const_result", issue = "67520")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_err(&self) -> bool { + pub const fn is_err(&self) -> bool { !self.is_ok() } @@ -446,8 +448,9 @@ impl Result { /// assert_eq!(x.as_ref(), Err(&"Error")); /// ``` #[inline] + #[rustc_const_unstable(feature = "const_result", issue = "67520")] #[stable(feature = "rust1", since = "1.0.0")] - pub fn as_ref(&self) -> Result<&T, &E> { + pub const fn as_ref(&self) -> Result<&T, &E> { match *self { Ok(ref x) => Ok(x), Err(ref x) => Err(x), From ce8dbf05f9072dfcf2580fb8f5c6d8c54ca4c7e9 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 22 Dec 2019 18:08:34 +0100 Subject: [PATCH 26/29] librustc_ast_lowering: move the files. --- src/{librustc/hir/lowering => librustc_ast_lowering}/expr.rs | 0 src/{librustc/hir/lowering => librustc_ast_lowering}/item.rs | 0 src/{librustc/hir/lowering.rs => librustc_ast_lowering/lib.rs} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/{librustc/hir/lowering => librustc_ast_lowering}/expr.rs (100%) rename src/{librustc/hir/lowering => librustc_ast_lowering}/item.rs (100%) rename src/{librustc/hir/lowering.rs => librustc_ast_lowering/lib.rs} (100%) diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc_ast_lowering/expr.rs similarity index 100% rename from src/librustc/hir/lowering/expr.rs rename to src/librustc_ast_lowering/expr.rs diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc_ast_lowering/item.rs similarity index 100% rename from src/librustc/hir/lowering/item.rs rename to src/librustc_ast_lowering/item.rs diff --git a/src/librustc/hir/lowering.rs b/src/librustc_ast_lowering/lib.rs similarity index 100% rename from src/librustc/hir/lowering.rs rename to src/librustc_ast_lowering/lib.rs From 7b6ef2b369db3adef6f6fa33750c87c1ff1fe3fe Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 22 Dec 2019 18:12:56 +0100 Subject: [PATCH 27/29] librustc_ast_lowering: cargo changes. --- Cargo.lock | 18 ++++++++++++++++++ src/librustc_ast_lowering/Cargo.toml | 22 ++++++++++++++++++++++ src/librustc_interface/Cargo.toml | 1 + src/librustc_resolve/Cargo.toml | 3 ++- 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/librustc_ast_lowering/Cargo.toml diff --git a/Cargo.lock b/Cargo.lock index 8a76ffcbe7249..947c0b8f465b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3358,6 +3358,22 @@ dependencies = [ "core", ] +[[package]] +name = "rustc_ast_lowering" +version = "0.0.0" +dependencies = [ + "log", + "rustc", + "rustc_data_structures", + "rustc_error_codes", + "rustc_errors", + "rustc_index", + "rustc_span", + "rustc_target", + "smallvec 1.0.0", + "syntax", +] + [[package]] name = "rustc_builtin_macros" version = "0.0.0" @@ -3578,6 +3594,7 @@ dependencies = [ "once_cell", "rustc", "rustc-rayon", + "rustc_ast_lowering", "rustc_builtin_macros", "rustc_codegen_llvm", "rustc_codegen_ssa", @@ -3783,6 +3800,7 @@ dependencies = [ "bitflags", "log", "rustc", + "rustc_ast_lowering", "rustc_data_structures", "rustc_error_codes", "rustc_errors", diff --git a/src/librustc_ast_lowering/Cargo.toml b/src/librustc_ast_lowering/Cargo.toml new file mode 100644 index 0000000000000..664d41c45f2a2 --- /dev/null +++ b/src/librustc_ast_lowering/Cargo.toml @@ -0,0 +1,22 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_ast_lowering" +version = "0.0.0" +edition = "2018" + +[lib] +name = "rustc_ast_lowering" +path = "lib.rs" +doctest = false + +[dependencies] +log = { version = "0.4", features = ["release_max_level_info", "std"] } +rustc = { path = "../librustc" } +rustc_target = { path = "../librustc_target" } +rustc_data_structures = { path = "../librustc_data_structures" } +rustc_index = { path = "../librustc_index" } +rustc_span = { path = "../librustc_span" } +rustc_error_codes = { path = "../librustc_error_codes" } +rustc_errors = { path = "../librustc_errors" } +syntax = { path = "../libsyntax" } +smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index 73ff0cd52d7e2..4926cb230814d 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -20,6 +20,7 @@ rustc_parse = { path = "../librustc_parse" } syntax_pos = { path = "../librustc_span", package = "rustc_span" } rustc_serialize = { path = "../libserialize", package = "serialize" } rustc = { path = "../librustc" } +rustc_ast_lowering = { path = "../librustc_ast_lowering" } rustc_incremental = { path = "../librustc_incremental" } rustc_traits = { path = "../librustc_traits" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index 0efc0de3a670a..00ca06872c99e 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -15,10 +15,11 @@ bitflags = "1.2.1" log = "0.4" syntax = { path = "../libsyntax" } rustc_expand = { path = "../librustc_expand" } -rustc = { path = "../librustc" } arena = { path = "../libarena" } errors = { path = "../librustc_errors", package = "rustc_errors" } syntax_pos = { path = "../librustc_span", package = "rustc_span" } +rustc = { path = "../librustc" } +rustc_ast_lowering = { path = "../librustc_ast_lowering" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_feature = { path = "../librustc_feature" } rustc_metadata = { path = "../librustc_metadata" } From 52179c56be0df07d817a143577d3e082e0a7cfa5 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 22 Dec 2019 18:15:02 +0100 Subject: [PATCH 28/29] librustc_ast_lowering: fix misc fallout. --- src/librustc/hir/mod.rs | 3 +- src/librustc/lib.rs | 1 - src/librustc/lint/builtin.rs | 2 +- src/librustc_ast_lowering/expr.rs | 18 ++++---- src/librustc_ast_lowering/item.rs | 39 ++++++++-------- src/librustc_ast_lowering/lib.rs | 72 +++++++++++++++-------------- src/librustc_interface/passes.rs | 11 +++-- src/librustc_lint/types.rs | 2 +- src/librustc_resolve/lib.rs | 4 +- src/librustc_typeck/check/demand.rs | 2 +- 10 files changed, 78 insertions(+), 76 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index f56c9f8e72c2d..dfd06da969b57 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -39,7 +39,6 @@ pub mod def; pub mod def_id; pub mod intravisit; pub mod itemlikevisit; -pub mod lowering; pub mod map; pub mod pat_util; pub mod print; @@ -599,7 +598,7 @@ pub enum SyntheticTyParamKind { pub struct WhereClause<'hir> { pub predicates: &'hir [WherePredicate<'hir>], // Only valid if predicates isn't empty. - span: Span, + pub span: Span, } impl WhereClause<'_> { diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 4e7913b8dfc0e..76588dfa5e25e 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -28,7 +28,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(arbitrary_self_types)] -#![feature(array_value_iter)] #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 1da9661cbf270..fa6e93d867b4e 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -523,7 +523,7 @@ pub enum BuiltinLintDiagnostics { DeprecatedMacro(Option, Span), } -pub(crate) fn add_elided_lifetime_in_path_suggestion( +pub fn add_elided_lifetime_in_path_suggestion( sess: &Session, db: &mut DiagnosticBuilder<'_>, n: usize, diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs index 3911f09a22792..0125e9e2c8304 100644 --- a/src/librustc_ast_lowering/expr.rs +++ b/src/librustc_ast_lowering/expr.rs @@ -1,16 +1,16 @@ use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs}; -use crate::hir; -use crate::hir::def::Res; +use rustc::bug; +use rustc::hir; +use rustc::hir::def::Res; use rustc_data_structures::thin_vec::ThinVec; - +use rustc_error_codes::*; +use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned}; +use rustc_span::symbol::{sym, Symbol}; use syntax::ast::*; use syntax::attr; use syntax::ptr::P as AstP; -use syntax::source_map::{respan, DesugaringKind, Span, Spanned}; -use syntax::symbol::{sym, Symbol}; - -use rustc_error_codes::*; +use syntax::{span_err, struct_span_err}; impl<'hir> LoweringContext<'_, 'hir> { fn lower_exprs(&mut self, exprs: &[AstP]) -> &'hir [hir::Expr<'hir>] { @@ -836,8 +836,8 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn lower_label(&mut self, label: Option