From acae7a6aaedf5af8fd49095a8def69a9f538cbd4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 3 Nov 2020 18:32:27 -0800 Subject: Emit diagnostic on cyclic structs --- syntax/toposort.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'syntax/toposort.rs') diff --git a/syntax/toposort.rs b/syntax/toposort.rs index 918d939c..7c210f23 100644 --- a/syntax/toposort.rs +++ b/syntax/toposort.rs @@ -12,7 +12,7 @@ pub fn sort<'a>(cx: &mut Errors, apis: &'a [Api], types: &Types<'a>) -> Vec<&'a let ref mut marks = Map::new(); for api in apis { if let Api::Struct(strct) = api { - visit(cx, strct, &mut sorted, marks, types); + let _ = visit(cx, strct, &mut sorted, marks, types); } } sorted @@ -24,11 +24,11 @@ fn visit<'a>( sorted: &mut Vec<&'a Struct>, marks: &mut Map<*const Struct, Mark>, types: &Types<'a>, -) { +) -> Result<(), ()> { match marks.entry(strct) { Entry::Occupied(entry) => match entry.get() { - Mark::Visiting => panic!("not a DAG"), // FIXME - Mark::Visited => return, + Mark::Visiting => return Err(()), // not a DAG + Mark::Visited => return Ok(()), }, Entry::Vacant(entry) => { entry.insert(Mark::Visiting); @@ -37,10 +37,13 @@ fn visit<'a>( for field in &strct.fields { if let Type::Ident(ident) = &field.ty { if let Some(inner) = types.structs.get(&ident.rust) { - visit(cx, inner, sorted, marks, types); + if visit(cx, inner, sorted, marks, types).is_err() { + cx.error(field, "unsupported cyclic data structure"); + } } } } marks.insert(strct, Mark::Visited); sorted.push(strct); + Ok(()) } -- cgit v1.2.3