Skip to content

Commit 89fe4df

Browse files
Unify both conflicting default searches into one.
1 parent 155ef41 commit 89fe4df

File tree

1 file changed

+50
-83
lines changed
  • src/librustc_typeck/check

1 file changed

+50
-83
lines changed

src/librustc_typeck/check/mod.rs

+50-83
Original file line numberDiff line numberDiff line change
@@ -2007,37 +2007,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
20072007
// we will rollback the inference context to its prior state so we can probe
20082008
// for conflicts and correctly report them.
20092009

2010-
20112010
let _ = self.commit_if_ok(|_: &infer::CombinedSnapshot| {
2012-
for ty in &unbound_tyvars {
2013-
if self.type_var_diverges(ty) {
2014-
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2015-
self.tcx.mk_diverging_default());
2016-
} else {
2017-
match self.type_is_unconstrained_numeric(ty) {
2018-
UnconstrainedInt => {
2019-
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
2020-
},
2021-
UnconstrainedFloat => {
2022-
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2023-
}
2024-
Neither => {
2025-
if let Some(default) = default_map.get(ty) {
2026-
let default = default.clone();
2027-
let default_ty = self.normalize_associated_types_in(
2028-
default.origin_span, &default.ty);
2029-
match self.eq_types(false,
2030-
&self.misc(default.origin_span),
2031-
ty,
2032-
default_ty) {
2033-
Ok(ok) => self.register_infer_ok_obligations(ok),
2034-
Err(_) => conflicts.push((*ty, default)),
2035-
}
2036-
}
2037-
}
2038-
}
2039-
}
2040-
}
2011+
conflicts.extend(
2012+
self.apply_defaults_and_return_conflicts(&unbound_tyvars, &default_map, None)
2013+
);
20412014

20422015
// If there are conflicts we rollback, otherwise commit
20432016
if conflicts.len() > 0 {
@@ -2047,37 +2020,41 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
20472020
}
20482021
});
20492022

2050-
if conflicts.len() > 0 {
2051-
// Loop through each conflicting default, figuring out the default that caused
2052-
// a unification failure and then report an error for each.
2053-
for (conflict, default) in conflicts {
2054-
let conflicting_default =
2055-
self.find_conflicting_default(&unbound_tyvars, &default_map, conflict)
2056-
.unwrap_or(type_variable::Default {
2057-
ty: self.next_ty_var(
2058-
TypeVariableOrigin::MiscVariable(syntax_pos::DUMMY_SP)),
2059-
origin_span: syntax_pos::DUMMY_SP,
2060-
// what do I put here?
2061-
def_id: self.tcx.hir.local_def_id(ast::CRATE_NODE_ID)
2062-
});
2063-
2064-
// This is to ensure that we elimnate any non-determinism from the error
2065-
// reporting by fixing an order, it doesn't matter what order we choose
2066-
// just that it is consistent.
2067-
let (first_default, second_default) =
2068-
if default.def_id < conflicting_default.def_id {
2069-
(default, conflicting_default)
2070-
} else {
2071-
(conflicting_default, default)
2072-
};
2023+
// Loop through each conflicting default, figuring out the default that caused
2024+
// a unification failure and then report an error for each.
2025+
for (conflict, default) in conflicts {
2026+
let conflicting_default =
2027+
self.apply_defaults_and_return_conflicts(
2028+
&unbound_tyvars,
2029+
&default_map,
2030+
Some(conflict)
2031+
)
2032+
.last()
2033+
.map(|(_, tv)| tv)
2034+
.unwrap_or(type_variable::Default {
2035+
ty: self.next_ty_var(
2036+
TypeVariableOrigin::MiscVariable(syntax_pos::DUMMY_SP)),
2037+
origin_span: syntax_pos::DUMMY_SP,
2038+
// what do I put here?
2039+
def_id: self.tcx.hir.local_def_id(ast::CRATE_NODE_ID)
2040+
});
2041+
2042+
// This is to ensure that we elimnate any non-determinism from the error
2043+
// reporting by fixing an order, it doesn't matter what order we choose
2044+
// just that it is consistent.
2045+
let (first_default, second_default) =
2046+
if default.def_id < conflicting_default.def_id {
2047+
(default, conflicting_default)
2048+
} else {
2049+
(conflicting_default, default)
2050+
};
20732051

20742052

2075-
self.report_conflicting_default_types(
2076-
first_default.origin_span,
2077-
self.body_id,
2078-
first_default,
2079-
second_default)
2080-
}
2053+
self.report_conflicting_default_types(
2054+
first_default.origin_span,
2055+
self.body_id,
2056+
first_default,
2057+
second_default)
20812058
}
20822059
}
20832060

@@ -2088,39 +2065,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
20882065
// apply the default that caused conflict first to a local version of the type variable
20892066
// table then apply defaults until we find a conflict. That default must be the one
20902067
// that caused conflict earlier.
2091-
fn find_conflicting_default(&self,
2092-
unbound_vars: &FxHashSet<Ty<'tcx>>,
2093-
default_map: &FxHashMap<&Ty<'tcx>, type_variable::Default<'tcx>>,
2094-
conflict: Ty<'tcx>)
2095-
-> Option<type_variable::Default<'tcx>> {
2068+
fn apply_defaults_and_return_conflicts<'b>(
2069+
&'b self,
2070+
unbound_vars: &'b FxHashSet<Ty<'tcx>>,
2071+
default_map: &'b FxHashMap<&'b Ty<'tcx>, type_variable::Default<'tcx>>,
2072+
conflict: Option<Ty<'tcx>>,
2073+
) -> impl Iterator<Item=(Ty<'tcx>, type_variable::Default<'tcx>)> + 'b {
20962074
use rustc::ty::error::UnconstrainedNumeric::Neither;
20972075
use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
20982076

2099-
// Ensure that we apply the conflicting default first
2100-
let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
2101-
unbound_tyvars.push(conflict);
2102-
unbound_tyvars.extend(unbound_vars.iter());
2103-
2104-
let mut result = None;
2105-
// We run the same code as above applying defaults in order, this time when
2106-
// we find the conflict we just return it for error reporting above.
2107-
2108-
// We also run this inside snapshot that never commits so we can do error
2109-
// reporting for more then one conflict.
2110-
for ty in &unbound_tyvars {
2077+
conflict.into_iter().chain(unbound_vars.iter().cloned()).flat_map(move |ty| {
21112078
if self.type_var_diverges(ty) {
2112-
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty,
2079+
self.demand_eqtype(syntax_pos::DUMMY_SP, ty,
21132080
self.tcx.mk_diverging_default());
21142081
} else {
21152082
match self.type_is_unconstrained_numeric(ty) {
21162083
UnconstrainedInt => {
2117-
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.i32)
2084+
self.demand_eqtype(syntax_pos::DUMMY_SP, ty, self.tcx.types.i32)
21182085
},
21192086
UnconstrainedFloat => {
2120-
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.f64)
2087+
self.demand_eqtype(syntax_pos::DUMMY_SP, ty, self.tcx.types.f64)
21212088
},
21222089
Neither => {
2123-
if let Some(default) = default_map.get(ty) {
2090+
if let Some(default) = default_map.get(&ty) {
21242091
let default = default.clone();
21252092
let default_ty = self.normalize_associated_types_in(
21262093
default.origin_span, &default.ty);
@@ -2130,16 +2097,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
21302097
default_ty) {
21312098
Ok(ok) => self.register_infer_ok_obligations(ok),
21322099
Err(_) => {
2133-
result = Some(default);
2100+
return Some((ty, default));
21342101
}
21352102
}
21362103
}
21372104
}
21382105
}
21392106
}
2140-
}
21412107

2142-
return result;
2108+
None
2109+
})
21432110
}
21442111

21452112
fn select_all_obligations_or_error(&self) {

0 commit comments

Comments
 (0)