No fallback in structurally_resolve_types. Further refactoring.

Put all fallback in `apply_fallback_if_possible`.
This commit is contained in:
leonardo.yvens 2017-12-18 17:31:23 -02:00
parent f3cd4a7f64
commit 02084f3304
7 changed files with 59 additions and 54 deletions

View File

@ -393,7 +393,7 @@ fn trivial_cast_lint(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
pub fn check(mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
self.expr_ty = fcx.resolved_type(self.span, self.expr_ty);
self.cast_ty = fcx.resolved_type(self.span, self.cast_ty);
self.cast_ty = fcx.structurally_resolved_type(self.span, self.cast_ty);
debug!("check_cast({}, {:?} as {:?})",
self.expr.id,

View File

@ -2127,23 +2127,23 @@ fn resolve_generator_interiors(&self, def_id: DefId) {
}
}
fn apply_diverging_fallback_to_type(&self, ty: Ty<'tcx>) {
assert!(ty.is_ty_infer());
if self.type_var_diverges(ty) {
debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges", ty);
self.demand_eqtype(syntax_pos::DUMMY_SP, ty, self.tcx.mk_diverging_default());
}
}
fn apply_numeric_fallback_to_type(&self, ty: Ty<'tcx>) {
// Tries to apply a fallback to `ty` if it is an unsolved variable.
// Non-numerics get replaced with ! or () (depending on whether
// feature(never_type) is enabled), unconstrained ints with i32,
// unconstrained floats with f64.
// Defaulting inference variables becomes very dubious if we have
// encountered type-checking errors. In that case, fallback to TyError.
fn apply_fallback_if_possible(&self, ty: Ty<'tcx>) {
use rustc::ty::error::UnconstrainedNumeric::Neither;
use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
assert!(ty.is_ty_infer());
let fallback = match self.type_is_unconstrained_numeric(ty) {
_ if self.is_tainted_by_errors() => self.tcx().types.err,
UnconstrainedInt => self.tcx.types.i32,
UnconstrainedFloat => self.tcx.types.f64,
Neither => return,
Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
Neither => return
};
debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback);
self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
@ -2158,21 +2158,8 @@ fn select_all_obligations_or_error(&self) {
self.select_obligations_where_possible();
// Apply fallbacks to unsolved variables.
// Non-numerics get replaced with ! or () (depending on whether
// feature(never_type) is enabled), unconstrained ints with i32,
// unconstrained floats with f64.
for ty in &self.unsolved_variables() {
if self.is_tainted_by_errors() {
// Defaulting inference variables becomes very dubious if we have
// encountered type-checking errors. In that case,
// just resolve all uninstanted type variables to TyError.
debug!("default_type_parameters: defaulting `{:?}` to error", ty);
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx().types.err);
} else {
self.apply_diverging_fallback_to_type(ty);
self.apply_numeric_fallback_to_type(ty);
}
self.apply_fallback_if_possible(ty);
}
let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
@ -4942,18 +4929,11 @@ fn check_impl_trait(&self,
// If no resolution is possible, then an error is reported.
// Numeric inference variables may be left unresolved.
pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
let mut ty = self.resolve_type_vars_with_obligations(ty);
let ty = self.resolve_type_vars_with_obligations(ty);
if !ty.is_ty_var() {
ty
} else {
// Try divering fallback.
self.apply_diverging_fallback_to_type(ty);
ty = self.resolve_type_vars_with_obligations(ty);
if !ty.is_ty_var() {
ty
} else { // Fallback failed, error.
self.must_be_known_in_context(sp, ty)
}
self.must_be_known_in_context(sp, ty)
}
}
@ -4963,9 +4943,7 @@ pub fn resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
if !ty.is_ty_infer() {
return ty;
} else {
// Try diverging or numeric fallback.
self.apply_diverging_fallback_to_type(ty);
self.apply_numeric_fallback_to_type(ty);
self.apply_fallback_if_possible(ty);
ty = self.resolve_type_vars_with_obligations(ty);
if !ty.is_ty_infer() {
ty

View File

@ -7,6 +7,7 @@
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: --error-format=human
extern {
fn write(fildes: i32, buf: *const i8, nbyte: u64) -> i64;
@ -28,12 +29,7 @@ macro_rules! write {
}}
}
macro_rules! cast {
($x:expr) => ($x as ()) //~ ERROR non-primitive cast
}
fn main() {
let hello = ['H', 'e', 'y'];
write!(hello);
cast!(2);
}

View File

@ -0,0 +1,11 @@
error[E0308]: mismatched types
--> $DIR/issue-26480-1.rs:27:19
|
27 | $arr.len() * size_of($arr[0])); //~ ERROR mismatched types
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u64, found usize
...
34 | write!(hello);
| -------------- in this macro invocation
error: aborting due to previous error

View File

@ -0,0 +1,18 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: --error-format=human
macro_rules! cast {
($x:expr) => ($x as ()) //~ ERROR non-primitive cast
}
fn main() {
cast!(2);
}

View File

@ -0,0 +1,13 @@
error[E0605]: non-primitive cast: `i32` as `()`
--> $DIR/issue-26480-2.rs:13:19
|
13 | ($x:expr) => ($x as ()) //~ ERROR non-primitive cast
| ^^^^^^^^
...
17 | cast!(2);
| --------- in this macro invocation
|
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
error: aborting due to previous error

View File

@ -7,16 +7,5 @@ error[E0308]: mismatched types
37 | write!(hello);
| -------------- in this macro invocation
error[E0605]: non-primitive cast: `i32` as `()`
--> $DIR/issue-26480.rs:32:19
|
32 | ($x:expr) => ($x as ()) //~ ERROR non-primitive cast
| ^^^^^^^^
...
38 | cast!(2);
| --------- in this macro invocation
|
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
error: aborting due to 2 previous errors
error: aborting due to previous error