- assert!(!cycle.is_empty());
-
- let mut err = struct_span_err!(self.sess, span, E0391,
- "unsupported cyclic reference between types/traits detected");
- err.span_label(span, &format!("cyclic reference"));
-
- err.span_note(cycle[0].0, &format!("the cycle begins when {}...",
- cycle[0].1.describe(self)));
-
- for &(span, ref query) in &cycle[1..] {
- err.span_note(span, &format!("...which then requires {}...",
- query.describe(self)));
- }
+ // Subtle: release the refcell lock before invoking `describe()`
+ // below by dropping `cycle`.
+ let stack = cycle.to_vec();
+ mem::drop(cycle);
+
+ assert!(!stack.is_empty());
+
+ // Disable naming impls with types in this path, since that
+ // sometimes cycles itself, leading to extra cycle errors.
+ // (And cycle errors around impls tend to occur during the
+ // collect/coherence phases anyhow.)
+ item_path::with_forced_impl_filename_line(|| {
+ let mut err =
+ struct_span_err!(self.sess, span, E0391,
+ "unsupported cyclic reference between types/traits detected");
+ err.span_label(span, &format!("cyclic reference"));
+
+ err.span_note(stack[0].0, &format!("the cycle begins when {}...",
+ stack[0].1.describe(self)));
+
+ for &(span, ref query) in &stack[1..] {
+ err.span_note(span, &format!("...which then requires {}...",
+ query.describe(self)));
+ }