No fallback in structurally_resolve_types
. Further refactoring.
Put all fallback in `apply_fallback_if_possible`.
This commit is contained in:
parent
f3cd4a7f64
commit
02084f3304
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
11
src/test/ui/mismatched_types/issue-26480-1.stderr
Normal file
11
src/test/ui/mismatched_types/issue-26480-1.stderr
Normal 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
|
||||
|
18
src/test/ui/mismatched_types/issue-26480-2.rs
Normal file
18
src/test/ui/mismatched_types/issue-26480-2.rs
Normal 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);
|
||||
}
|
13
src/test/ui/mismatched_types/issue-26480-2.stderr
Normal file
13
src/test/ui/mismatched_types/issue-26480-2.stderr
Normal 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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user