enhance check_pat_lit with TopInfo

This commit is contained in:
Mazdak Farrokhzad 2020-02-25 04:10:58 +01:00
parent 9b6e0e8b94
commit 5da3a2f354
5 changed files with 27 additions and 6 deletions

View File

@ -43,7 +43,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> {
let cause = &self.misc(sp);
self.demand_suptype_with_origin(&self.misc(sp), expected, actual)
}
pub fn demand_suptype_with_origin(
&self,
cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> {
match self.at(cause, self.param_env).sup(expected, actual) {
Ok(InferOk { obligations, value: () }) => {
self.register_predicates(obligations);

View File

@ -9,7 +9,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
use rustc_hir::{HirId, Pat, PatKind};
use rustc_infer::infer;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::traits::Pattern;
use rustc_infer::traits::{ObligationCause, Pattern};
use rustc_span::hygiene::DesugaringKind;
use rustc_span::source_map::{Span, Spanned};
use syntax::ast;
@ -66,6 +66,11 @@ struct TopInfo<'tcx> {
}
impl<'tcx> FnCtxt<'_, 'tcx> {
fn pattern_cause(&self, ti: TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> {
let code = Pattern { span: ti.span, root_ty: ti.expected, origin_expr: ti.origin_expr };
self.cause(cause_span, code)
}
fn demand_eqtype_pat_diag(
&self,
cause_span: Span,
@ -73,9 +78,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
actual: Ty<'tcx>,
ti: TopInfo<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> {
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)
self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)
}
fn demand_eqtype_pat(
@ -379,7 +382,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// &'static str <: expected
//
// then that's equivalent to there existing a LUB.
if let Some(mut err) = self.demand_suptype_diag(span, expected, pat_ty) {
let cause = self.pattern_cause(ti, span);
if let Some(mut err) = self.demand_suptype_with_origin(&cause, expected, pat_ty) {
err.emit_unless(
ti.span
.filter(|&s| {

View File

@ -1,6 +1,9 @@
error[E0308]: mismatched types
--> $DIR/match-ill-type2.rs:4:9
|
LL | match 1i32 {
| ---- this expression has type `i32`
LL | 1i32 => 1,
LL | 2u32 => 1,
| ^^^^ expected `i32`, found `u32`

View File

@ -1,6 +1,8 @@
error[E0308]: mismatched types
--> $DIR/lit.rs:7:13
|
LL | match &s {
| -- this expression has type `&&str`
LL | "abc" => true,
| ^^^^^ expected `&str`, found `str`
|
@ -10,6 +12,8 @@ LL | "abc" => true,
error[E0308]: mismatched types
--> $DIR/lit.rs:16:9
|
LL | match &s {
| -- this expression has type `&&[u8]`
LL | b"abc" => true,
| ^^^^^^ expected `&[u8]`, found array `[u8; 3]`
|

View File

@ -1,6 +1,8 @@
error[E0308]: mismatched types
--> $DIR/slightly-nice-generic-literal-messages.rs:7:9
|
LL | match Foo(1.1, marker::PhantomData) {
| ----------------------------- this expression has type `Foo<{float}, _>`
LL | 1 => {}
| ^ expected struct `Foo`, found integer
|