Skip to content

Commit c7a0687

Browse files
committed
Fixed rust-lang#30.
A stack overflow was caused by circular references in analyzed item types, since mismatch computation didn't keep track of item pairs *currently being matched*. This is now fixed using two sets of old and new types.
1 parent 32cb8fa commit c7a0687

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

src/semcheck/mismatch.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc::ty::subst::Substs;
1313

1414
use semcheck::mapping::IdMapping;
1515

16-
use std::collections::{HashMap, VecDeque};
16+
use std::collections::{HashMap, HashSet, VecDeque};
1717

1818
/// A relation searching for items appearing at the same spot in a type.
1919
///
@@ -27,6 +27,10 @@ pub struct MismatchRelation<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
2727
item_queue: VecDeque<(DefId, DefId)>,
2828
/// The id mapping to use.
2929
id_mapping: &'a mut IdMapping,
30+
/// Type cache holding all old types currently being processed to avoid loops.
31+
current_old_types: HashSet<Ty<'tcx>>,
32+
/// Type cache holding all new types currently being processed to avoid loops.
33+
current_new_types: HashSet<Ty<'tcx>>,
3034
}
3135

3236
impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> MismatchRelation<'a, 'gcx, 'tcx> {
@@ -37,6 +41,8 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> MismatchRelation<'a, 'gcx, 'tcx> {
3741
tcx: tcx,
3842
item_queue: id_mapping.toplevel_queue(),
3943
id_mapping: id_mapping,
44+
current_old_types: Default::default(),
45+
current_new_types: Default::default(),
4046
}
4147
}
4248

@@ -100,6 +106,13 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for MismatchRelation<'a, 'gcx,
100106
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
101107
use rustc::ty::TypeVariants::*;
102108

109+
if self.current_old_types.contains(a) || self.current_new_types.contains(b) {
110+
return Ok(self.tcx.types.err);
111+
}
112+
113+
self.current_old_types.insert(a);
114+
self.current_new_types.insert(b);
115+
103116
debug!("tys: mismatch relation: a: {:?}, b: {:?}", a, b);
104117
let matching = match (&a.sty, &b.sty) {
105118
(&TyAdt(a_def, a_substs), &TyAdt(b_def, b_substs)) => {
@@ -193,6 +206,9 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for MismatchRelation<'a, 'gcx,
193206
_ => None,
194207
};
195208

209+
self.current_old_types.remove(a);
210+
self.current_new_types.remove(b);
211+
196212
if let Some((old_def_id, new_def_id)) = matching {
197213
if !self.id_mapping.contains_old_id(old_def_id) &&
198214
self.id_mapping.in_old_crate(old_def_id) {

0 commit comments

Comments
 (0)