Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
73db83a
cleanup check_pat
Centril Dec 30, 2019
ab050d6
MatchExpressionArmPattern: Use more generic wording.
Centril Dec 30, 2019
960acb0
Show scrutinee expr type for struct fields.
Centril Dec 30, 2019
e952377
MatchExpressionArmPattern -> Pattern
Centril Dec 30, 2019
6137ad4
move demand_eqtype_pat* to pat.rs
Centril Dec 30, 2019
f35840f
Pass the span of `<init>` in `let <pat> = <init>;`
Centril Dec 30, 2019
d7e2f3a
refactor and fix this-expression-has-type note
Centril Dec 30, 2019
f2c6a19
check_fn: simplify
Centril Dec 30, 2019
f8d2cce
Blame user type in pat type error.
Centril Dec 30, 2019
63dc0e4
discriminant -> scrutinee
Centril Dec 30, 2019
7f9cc88
Add symbol normalization for proc_macro_server.
crlf0710 Dec 29, 2019
8f84d9e
Inline and remove `nfc_symbol_from` method.
crlf0710 Dec 30, 2019
2091062
parser: call .struct_span_err directly
Centril Dec 30, 2019
b6fc87c
de-fatalize some errors
Centril Dec 30, 2019
5a64ba6
parser: span_fatal -> struct_span_err
Centril Dec 30, 2019
85dbbaa
process_potential_macro_variable: de-fatalize an error
Centril Dec 30, 2019
46ec6be
parser::attr: remove .fatal calls
Centril Dec 31, 2019
13ca924
parser::item: remove .fatal calls
Centril Dec 31, 2019
51fb599
parser::module: remove .fatal calls
Centril Dec 31, 2019
6fba125
parser::path: remove .fatal calls
Centril Dec 31, 2019
2e812c1
parser::pat: remove .fatal calls
Centril Dec 31, 2019
4ae9c1c
parser::diagnostics: remove fn fatal
Centril Dec 31, 2019
2e78061
parser: bug -> span_bug
Centril Dec 31, 2019
b40dc30
Use function attribute "frame-pointer" instead of "no-frame-pointer-e…
MaskRay Dec 31, 2019
954c432
Constify Result
lukaslueg Dec 28, 2019
ce8dbf0
librustc_ast_lowering: move the files.
Centril Dec 22, 2019
7b6ef2b
librustc_ast_lowering: cargo changes.
Centril Dec 22, 2019
52179c5
librustc_ast_lowering: fix misc fallout.
Centril Dec 22, 2019
70eca99
nix `lower_label` identity function.
Centril Dec 24, 2019
3cf2bc0
Rollup merge of #67574 - Centril:librustc_lowering, r=Mark-Simulacrum
Centril Dec 31, 2019
89fbed9
Rollup merge of #67685 - lukaslueg:const_result, r=oli-obk
Centril Dec 31, 2019
bc5963d
Rollup merge of #67702 - crlf0710:normalize_ident2, r=petrochenkov
Centril Dec 31, 2019
50fb848
Rollup merge of #67730 - Centril:typeck-pat-cleanup, r=estebank
Centril Dec 31, 2019
3cca3c6
Rollup merge of #67744 - Centril:reduce-diversity, r=petrochenkov
Centril Dec 31, 2019
40579d1
Rollup merge of #67748 - MaskRay:frame-pointer, r=rkruppe
Centril Dec 31, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Blame user type in pat type error.
  • Loading branch information
Centril committed Dec 30, 2019
commit f8d2cce0ce24981269e6994c332bff7f033b59e0
7 changes: 5 additions & 2 deletions src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,8 +581,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
exp_found: Option<ty::error::ExpectedFound<Ty<'tcx>>>,
) {
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));
Expand All @@ -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,
Expand Down
8 changes: 6 additions & 2 deletions src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Span>,
/// 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.
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/traits/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }))
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 17 additions & 4 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(&param.pat, param_ty, None);
fcx.check_pat_top(&param.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
Expand Down Expand Up @@ -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);
}
Expand All @@ -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 };
Expand Down
29 changes: 20 additions & 9 deletions src/librustc_typeck/check/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;`
Expand Down Expand Up @@ -70,11 +74,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
actual: Ty<'tcx>,
ti: TopInfo<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> {
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)
}

Expand All @@ -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<Span>) {
///
/// 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<Span>,
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
Expand Down
1 change: 1 addition & 0 deletions src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/or-patterns/inconsistent-modes.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
|
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/pattern/pat-type-err-formal-param.rs
Original file line number Diff line number Diff line change
@@ -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
11 changes: 11 additions & 0 deletions src/test/ui/pattern/pat-type-err-formal-param.stderr
Original file line number Diff line number Diff line change
@@ -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`.
16 changes: 16 additions & 0 deletions src/test/ui/pattern/pat-type-err-let-stmt.rs
Original file line number Diff line number Diff line change
@@ -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<u8>`.
let Ok(0): Option<u8> = 42u8;
//~^ ERROR mismatched types
//~| ERROR mismatched types

// We want to point at the `Option<u8>`.
let Ok(0): Option<u8>;
//~^ ERROR mismatched types

// We want to point at the scrutinee.
let Ok(0) = 42u8; //~ ERROR mismatched types
}
49 changes: 49 additions & 0 deletions src/test/ui/pattern/pat-type-err-let-stmt.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
error[E0308]: mismatched types
--> $DIR/pat-type-err-let-stmt.rs:6:29
|
LL | let Ok(0): Option<u8> = 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<u8>`
found type `u8`

error[E0308]: mismatched types
--> $DIR/pat-type-err-let-stmt.rs:6:9
|
LL | let Ok(0): Option<u8> = 42u8;
| ^^^^^ ---------- expected due to this
| |
| expected enum `std::option::Option`, found enum `std::result::Result`
|
= note: expected enum `std::option::Option<u8>`
found enum `std::result::Result<_, _>`

error[E0308]: mismatched types
--> $DIR/pat-type-err-let-stmt.rs:11:9
|
LL | let Ok(0): Option<u8>;
| ^^^^^ ---------- expected due to this
| |
| expected enum `std::option::Option`, found enum `std::result::Result`
|
= note: expected enum `std::option::Option<u8>`
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`.