Skip to content

Commit 69a9a17

Browse files
jroeschJared Roesch
authored andcommitted
---
yaml --- r: 235837 b: refs/heads/stable c: b75f215 h: refs/heads/master i: 235835: b1af0f6 v: v3
1 parent 04aac7e commit 69a9a17

File tree

2 files changed

+68
-58
lines changed

2 files changed

+68
-58
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: afae2ff723393b3ab4ccffef6ac7c6d1809e2da0
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: f859507de8c410b648d934d8f5ec1c52daac971d
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: ee4392041073795f479365f34d40777eff69c378
32+
refs/heads/stable: b75f215e8244ae742ac2e5b3cfd27ab4a761ed9e
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/librustc_typeck/check/mod.rs

Lines changed: 67 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,43 +1784,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17841784
// variable would only be in `unbound_tyvars` and have a concrete value if
17851785
// it had been solved by previously applying a default.
17861786

1787-
// We take a snapshot for use in error reporting.
1788-
let snapshot = self.infcx().start_snapshot();
1789-
1790-
for ty in &unbound_tyvars {
1791-
if self.infcx().type_var_diverges(ty) {
1792-
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1793-
} else {
1794-
match self.infcx().type_is_unconstrained_numeric(ty) {
1795-
UnconstrainedInt => {
1796-
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1797-
},
1798-
UnconstrainedFloat => {
1799-
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1800-
}
1801-
Neither => {
1802-
if let Some(default) = default_map.get(ty) {
1803-
let default = default.clone();
1804-
match infer::mk_eqty(self.infcx(), false,
1805-
infer::Misc(default.origin_span),
1806-
ty, default.ty) {
1807-
Ok(()) => {}
1808-
Err(_) => {
1809-
conflicts.push((*ty, default));
1787+
// We wrap this in a transaction for error reporting, if we detect a conflict
1788+
// we will rollback the inference context to its prior state so we can probe
1789+
// for conflicts and correctly report them.
1790+
let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1791+
for ty in &unbound_tyvars {
1792+
if self.infcx().type_var_diverges(ty) {
1793+
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1794+
} else {
1795+
match self.infcx().type_is_unconstrained_numeric(ty) {
1796+
UnconstrainedInt => {
1797+
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1798+
},
1799+
UnconstrainedFloat => {
1800+
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1801+
}
1802+
Neither => {
1803+
if let Some(default) = default_map.get(ty) {
1804+
let default = default.clone();
1805+
match infer::mk_eqty(self.infcx(), false,
1806+
infer::Misc(default.origin_span),
1807+
ty, default.ty) {
1808+
Ok(()) => {}
1809+
Err(_) => {
1810+
conflicts.push((*ty, default));
1811+
}
18101812
}
18111813
}
18121814
}
18131815
}
18141816
}
18151817
}
1816-
}
18171818

1818-
// There are some errors to report
1819-
if conflicts.len() > 0 {
1820-
self.infcx().rollback_to(snapshot);
1819+
// If there are conflicts we rollback, otherwise commit
1820+
if conflicts.len() > 0 {
1821+
Err(())
1822+
} else {
1823+
Ok(())
1824+
}
1825+
});
18211826

1822-
// Loop through each conflicting default compute the conflict
1823-
// and then report the error.
1827+
if conflicts.len() > 0 {
1828+
// Loop through each conflicting default, figuring out the default that caused
1829+
// a unification failure and then report an error for each.
18241830
for (conflict, default) in conflicts {
18251831
let conflicting_default =
18261832
self.find_conflicting_default(
@@ -1832,13 +1838,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18321838
definition_span: codemap::DUMMY_SP
18331839
});
18341840

1835-
self.infcx().report_conflicting_default_types(
1836-
conflicting_default.origin_span,
1837-
conflicting_default,
1838-
default)
1841+
self.infcx().report_conflicting_default_types(
1842+
conflicting_default.origin_span,
1843+
conflicting_default,
1844+
default)
18391845
}
1840-
} else {
1841-
self.infcx().commit_from(snapshot)
18421846
}
18431847
}
18441848

@@ -1856,41 +1860,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18561860
-> Option<type_variable::Default<'tcx>> {
18571861
use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither};
18581862

1859-
// Ensure that the conflicting default is applied first
1863+
// Ensure that we apply the conflicting default first
18601864
let mut unbound_tyvars = Vec::with_capacity(unbound_vars.len() + 1);
18611865
unbound_tyvars.push(conflict);
18621866
unbound_tyvars.extend(unbound_vars.iter());
18631867

18641868
let mut result = None;
18651869
// We run the same code as above applying defaults in order, this time when
18661870
// we find the conflict we just return it for error reporting above.
1867-
for ty in &unbound_tyvars {
1868-
if self.infcx().type_var_diverges(ty) {
1869-
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1870-
} else {
1871-
match self.infcx().type_is_unconstrained_numeric(ty) {
1872-
UnconstrainedInt => {
1873-
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1874-
},
1875-
UnconstrainedFloat => {
1876-
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1877-
},
1878-
Neither => {
1879-
if let Some(default) = default_map.get(ty) {
1880-
let default = default.clone();
1881-
match infer::mk_eqty(self.infcx(), false,
1882-
infer::Misc(default.origin_span),
1883-
ty, default.ty) {
1884-
Ok(()) => {}
1885-
Err(_) => {
1886-
result = Some(default);
1871+
1872+
// We also run this inside snapshot that never commits so we can do error
1873+
// reporting for more then one conflict.
1874+
//let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
1875+
for ty in &unbound_tyvars {
1876+
if self.infcx().type_var_diverges(ty) {
1877+
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
1878+
} else {
1879+
match self.infcx().type_is_unconstrained_numeric(ty) {
1880+
UnconstrainedInt => {
1881+
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
1882+
},
1883+
UnconstrainedFloat => {
1884+
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
1885+
},
1886+
Neither => {
1887+
if let Some(default) = default_map.get(ty) {
1888+
let default = default.clone();
1889+
match infer::mk_eqty(self.infcx(), false,
1890+
infer::Misc(default.origin_span),
1891+
ty, default.ty) {
1892+
Ok(()) => {}
1893+
Err(_) => {
1894+
result = Some(default);
1895+
}
18871896
}
18881897
}
18891898
}
18901899
}
18911900
}
18921901
}
1893-
}
1902+
// let result: Result<(), ()> = Err(()); result
1903+
//});
18941904

18951905
return result;
18961906
}

0 commit comments

Comments
 (0)