Skip to content

Commit 02084f3

Browse files
committed
No fallback in structurally_resolve_types. Further refactoring.
Put all fallback in `apply_fallback_if_possible`.
1 parent f3cd4a7 commit 02084f3

File tree

7 files changed

+59
-54
lines changed

7 files changed

+59
-54
lines changed

src/librustc_typeck/check/cast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
393393

394394
pub fn check(mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
395395
self.expr_ty = fcx.resolved_type(self.span, self.expr_ty);
396-
self.cast_ty = fcx.resolved_type(self.span, self.cast_ty);
396+
self.cast_ty = fcx.structurally_resolved_type(self.span, self.cast_ty);
397397

398398
debug!("check_cast({}, {:?} as {:?})",
399399
self.expr.id,

src/librustc_typeck/check/mod.rs

Lines changed: 14 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2127,23 +2127,23 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
21272127
}
21282128
}
21292129

2130-
fn apply_diverging_fallback_to_type(&self, ty: Ty<'tcx>) {
2131-
assert!(ty.is_ty_infer());
2132-
if self.type_var_diverges(ty) {
2133-
debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges", ty);
2134-
self.demand_eqtype(syntax_pos::DUMMY_SP, ty, self.tcx.mk_diverging_default());
2135-
}
2136-
}
2137-
2138-
fn apply_numeric_fallback_to_type(&self, ty: Ty<'tcx>) {
2130+
// Tries to apply a fallback to `ty` if it is an unsolved variable.
2131+
// Non-numerics get replaced with ! or () (depending on whether
2132+
// feature(never_type) is enabled), unconstrained ints with i32,
2133+
// unconstrained floats with f64.
2134+
// Defaulting inference variables becomes very dubious if we have
2135+
// encountered type-checking errors. In that case, fallback to TyError.
2136+
fn apply_fallback_if_possible(&self, ty: Ty<'tcx>) {
21392137
use rustc::ty::error::UnconstrainedNumeric::Neither;
21402138
use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
21412139

21422140
assert!(ty.is_ty_infer());
21432141
let fallback = match self.type_is_unconstrained_numeric(ty) {
2142+
_ if self.is_tainted_by_errors() => self.tcx().types.err,
21442143
UnconstrainedInt => self.tcx.types.i32,
21452144
UnconstrainedFloat => self.tcx.types.f64,
2146-
Neither => return,
2145+
Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
2146+
Neither => return
21472147
};
21482148
debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback);
21492149
self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback);
@@ -2158,21 +2158,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
21582158

21592159
self.select_obligations_where_possible();
21602160

2161-
// Apply fallbacks to unsolved variables.
2162-
// Non-numerics get replaced with ! or () (depending on whether
2163-
// feature(never_type) is enabled), unconstrained ints with i32,
2164-
// unconstrained floats with f64.
21652161
for ty in &self.unsolved_variables() {
2166-
if self.is_tainted_by_errors() {
2167-
// Defaulting inference variables becomes very dubious if we have
2168-
// encountered type-checking errors. In that case,
2169-
// just resolve all uninstanted type variables to TyError.
2170-
debug!("default_type_parameters: defaulting `{:?}` to error", ty);
2171-
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx().types.err);
2172-
} else {
2173-
self.apply_diverging_fallback_to_type(ty);
2174-
self.apply_numeric_fallback_to_type(ty);
2175-
}
2162+
self.apply_fallback_if_possible(ty);
21762163
}
21772164

21782165
let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
@@ -4942,18 +4929,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
49424929
// If no resolution is possible, then an error is reported.
49434930
// Numeric inference variables may be left unresolved.
49444931
pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
4945-
let mut ty = self.resolve_type_vars_with_obligations(ty);
4932+
let ty = self.resolve_type_vars_with_obligations(ty);
49464933
if !ty.is_ty_var() {
49474934
ty
49484935
} else {
4949-
// Try divering fallback.
4950-
self.apply_diverging_fallback_to_type(ty);
4951-
ty = self.resolve_type_vars_with_obligations(ty);
4952-
if !ty.is_ty_var() {
4953-
ty
4954-
} else { // Fallback failed, error.
4955-
self.must_be_known_in_context(sp, ty)
4956-
}
4936+
self.must_be_known_in_context(sp, ty)
49574937
}
49584938
}
49594939

@@ -4963,9 +4943,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
49634943
if !ty.is_ty_infer() {
49644944
return ty;
49654945
} else {
4966-
// Try diverging or numeric fallback.
4967-
self.apply_diverging_fallback_to_type(ty);
4968-
self.apply_numeric_fallback_to_type(ty);
4946+
self.apply_fallback_if_possible(ty);
49694947
ty = self.resolve_type_vars_with_obligations(ty);
49704948
if !ty.is_ty_infer() {
49714949
ty

src/test/ui/mismatched_types/issue-26480.rs renamed to src/test/ui/mismatched_types/issue-26480-1.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
10+
// compile-flags: --error-format=human
1011

1112
extern {
1213
fn write(fildes: i32, buf: *const i8, nbyte: u64) -> i64;
@@ -28,12 +29,7 @@ macro_rules! write {
2829
}}
2930
}
3031

31-
macro_rules! cast {
32-
($x:expr) => ($x as ()) //~ ERROR non-primitive cast
33-
}
34-
3532
fn main() {
3633
let hello = ['H', 'e', 'y'];
3734
write!(hello);
38-
cast!(2);
3935
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-26480-1.rs:27:19
3+
|
4+
27 | $arr.len() * size_of($arr[0])); //~ ERROR mismatched types
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u64, found usize
6+
...
7+
34 | write!(hello);
8+
| -------------- in this macro invocation
9+
10+
error: aborting due to previous error
11+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
// compile-flags: --error-format=human
11+
12+
macro_rules! cast {
13+
($x:expr) => ($x as ()) //~ ERROR non-primitive cast
14+
}
15+
16+
fn main() {
17+
cast!(2);
18+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0605]: non-primitive cast: `i32` as `()`
2+
--> $DIR/issue-26480-2.rs:13:19
3+
|
4+
13 | ($x:expr) => ($x as ()) //~ ERROR non-primitive cast
5+
| ^^^^^^^^
6+
...
7+
17 | cast!(2);
8+
| --------- in this macro invocation
9+
|
10+
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
11+
12+
error: aborting due to previous error
13+

src/test/ui/mismatched_types/issue-26480.stderr

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,5 @@ error[E0308]: mismatched types
77
37 | write!(hello);
88
| -------------- in this macro invocation
99

10-
error[E0605]: non-primitive cast: `i32` as `()`
11-
--> $DIR/issue-26480.rs:32:19
12-
|
13-
32 | ($x:expr) => ($x as ()) //~ ERROR non-primitive cast
14-
| ^^^^^^^^
15-
...
16-
38 | cast!(2);
17-
| --------- in this macro invocation
18-
|
19-
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
20-
21-
error: aborting due to 2 previous errors
10+
error: aborting due to previous error
2211

0 commit comments

Comments
 (0)