Skip to content

Commit ad0e8dd

Browse files
committed
Cleanup opaque_type_cycle_error
1 parent 8247594 commit ad0e8dd

File tree

1 file changed

+94
-101
lines changed
  • compiler/rustc_hir_analysis/src/check

1 file changed

+94
-101
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

+94-101
Original file line numberDiff line numberDiff line change
@@ -1716,121 +1716,114 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, opaque_def_id: LocalDefId) -> ErrorG
17161716
let span = tcx.def_span(opaque_def_id);
17171717
let mut err = struct_span_code_err!(tcx.dcx(), span, E0720, "cannot resolve opaque type");
17181718

1719-
let mut label = false;
1720-
if let Some((def_id, visitor)) = get_owner_return_paths(tcx, opaque_def_id) {
1721-
let typeck_results = tcx.typeck(def_id);
1722-
if visitor
1719+
let Some((def_id, visitor)) = get_owner_return_paths(tcx, opaque_def_id) else {
1720+
return err.emit();
1721+
};
1722+
1723+
let typeck_results = tcx.typeck(def_id);
1724+
if visitor
1725+
.returns
1726+
.iter()
1727+
.filter_map(|expr| typeck_results.node_type_opt(expr.hir_id))
1728+
.all(|ty| matches!(ty.kind(), ty::Never))
1729+
{
1730+
let spans = visitor
17231731
.returns
17241732
.iter()
1725-
.filter_map(|expr| typeck_results.node_type_opt(expr.hir_id))
1726-
.all(|ty| matches!(ty.kind(), ty::Never))
1727-
{
1728-
let spans = visitor
1729-
.returns
1730-
.iter()
1731-
.filter(|expr| typeck_results.node_type_opt(expr.hir_id).is_some())
1732-
.map(|expr| expr.span)
1733-
.collect::<Vec<Span>>();
1734-
let span_len = spans.len();
1735-
if span_len == 1 {
1736-
err.span_label(spans[0], "this returned value is of `!` type");
1737-
} else {
1738-
let mut multispan: MultiSpan = spans.clone().into();
1739-
for span in spans {
1740-
multispan.push_span_label(span, "this returned value is of `!` type");
1741-
}
1742-
err.span_note(multispan, "these returned values have a concrete \"never\" type");
1743-
}
1744-
err.help("this error will resolve once the item's body returns a concrete type");
1733+
.filter(|expr| typeck_results.node_type_opt(expr.hir_id).is_some())
1734+
.map(|expr| expr.span)
1735+
.collect::<Vec<Span>>();
1736+
if let &[span] = &spans[..] {
1737+
err.span_label(span, "this returned value is of `!` type");
17451738
} else {
1746-
let mut seen = FxHashSet::default();
1747-
seen.insert(span);
1748-
err.span_label(span, "recursive opaque type");
1749-
label = true;
1750-
for (sp, ty) in visitor
1751-
.returns
1752-
.iter()
1753-
.filter_map(|e| typeck_results.node_type_opt(e.hir_id).map(|t| (e.span, t)))
1754-
.filter(|(_, ty)| !matches!(ty.kind(), ty::Never))
1755-
{
1756-
#[derive(Default)]
1757-
struct OpaqueTypeCollector {
1758-
opaques: Vec<DefId>,
1759-
closures: Vec<DefId>,
1760-
}
1761-
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector {
1762-
fn visit_ty(&mut self, t: Ty<'tcx>) {
1763-
match *t.kind() {
1764-
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
1765-
self.opaques.push(def);
1766-
}
1767-
ty::Closure(def_id, ..) | ty::Coroutine(def_id, ..) => {
1768-
self.closures.push(def_id);
1769-
t.super_visit_with(self);
1770-
}
1771-
_ => t.super_visit_with(self),
1772-
}
1773-
}
1774-
}
1739+
let mut multispan = MultiSpan::from(spans.clone());
1740+
for span in spans {
1741+
multispan.push_span_label(span, "this returned value is of `!` type");
1742+
}
1743+
err.span_note(multispan, "these returned values have a concrete \"never\" type");
1744+
}
1745+
err.help("this error will resolve once the item's body returns a concrete type");
1746+
return err.emit();
1747+
}
17751748

1776-
let mut visitor = OpaqueTypeCollector::default();
1777-
ty.visit_with(&mut visitor);
1778-
for def_id in visitor.opaques {
1779-
let ty_span = tcx.def_span(def_id);
1780-
if !seen.contains(&ty_span) {
1781-
let descr = if ty.is_impl_trait() { "opaque " } else { "" };
1782-
err.span_label(ty_span, format!("returning this {descr}type `{ty}`"));
1783-
seen.insert(ty_span);
1749+
let mut seen = FxHashSet::default();
1750+
seen.insert(span);
1751+
err.span_label(span, "recursive opaque type");
1752+
for (sp, ty) in visitor
1753+
.returns
1754+
.iter()
1755+
.filter_map(|e| typeck_results.node_type_opt(e.hir_id).map(|t| (e.span, t)))
1756+
.filter(|(_, ty)| !matches!(ty.kind(), ty::Never))
1757+
{
1758+
#[derive(Default)]
1759+
struct OpaqueTypeCollector {
1760+
opaques: Vec<DefId>,
1761+
closures: Vec<DefId>,
1762+
}
1763+
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector {
1764+
fn visit_ty(&mut self, t: Ty<'tcx>) {
1765+
match *t.kind() {
1766+
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
1767+
self.opaques.push(def);
17841768
}
1785-
err.span_label(sp, format!("returning here with type `{ty}`"));
1769+
ty::Closure(def_id, ..) | ty::Coroutine(def_id, ..) => {
1770+
self.closures.push(def_id);
1771+
t.super_visit_with(self);
1772+
}
1773+
_ => t.super_visit_with(self),
17861774
}
1775+
}
1776+
}
17871777

1788-
for closure_def_id in visitor.closures {
1789-
let Some(closure_local_did) = closure_def_id.as_local() else {
1790-
continue;
1791-
};
1792-
let typeck_results = tcx.typeck(closure_local_did);
1793-
1794-
let mut label_match = |ty: Ty<'_>, span| {
1795-
for arg in ty.walk() {
1796-
if let ty::GenericArgKind::Type(ty) = arg.unpack()
1797-
&& let ty::Alias(
1798-
ty::Opaque,
1799-
ty::AliasTy { def_id: captured_def_id, .. },
1800-
) = *ty.kind()
1801-
&& captured_def_id == opaque_def_id.to_def_id()
1802-
{
1803-
err.span_label(
1804-
span,
1805-
format!(
1806-
"{} captures itself here",
1807-
tcx.def_descr(closure_def_id)
1808-
),
1809-
);
1810-
}
1811-
}
1812-
};
1778+
let mut visitor = OpaqueTypeCollector::default();
1779+
ty.visit_with(&mut visitor);
1780+
for def_id in visitor.opaques {
1781+
let ty_span = tcx.def_span(def_id);
1782+
if !seen.contains(&ty_span) {
1783+
let descr = if ty.is_impl_trait() { "opaque " } else { "" };
1784+
err.span_label(ty_span, format!("returning this {descr}type `{ty}`"));
1785+
seen.insert(ty_span);
1786+
}
1787+
err.span_label(sp, format!("returning here with type `{ty}`"));
1788+
}
18131789

1814-
// Label any closure upvars that capture the opaque
1815-
for capture in typeck_results.closure_min_captures_flattened(closure_local_did)
1816-
{
1817-
label_match(capture.place.ty(), capture.get_path_span(tcx));
1818-
}
1819-
// Label any coroutine locals that capture the opaque
1820-
if tcx.is_coroutine(closure_def_id)
1821-
&& let Some(coroutine_layout) = tcx.mir_coroutine_witnesses(closure_def_id)
1790+
for closure_def_id in visitor.closures {
1791+
let Some(closure_local_did) = closure_def_id.as_local() else {
1792+
continue;
1793+
};
1794+
let typeck_results = tcx.typeck(closure_local_did);
1795+
1796+
let mut label_match = |ty: Ty<'_>, span| {
1797+
for arg in ty.walk() {
1798+
if let ty::GenericArgKind::Type(ty) = arg.unpack()
1799+
&& let ty::Alias(ty::Opaque, ty::AliasTy { def_id: captured_def_id, .. }) =
1800+
*ty.kind()
1801+
&& captured_def_id == opaque_def_id.to_def_id()
18221802
{
1823-
for interior_ty in &coroutine_layout.field_tys {
1824-
label_match(interior_ty.ty, interior_ty.source_info.span);
1825-
}
1803+
err.span_label(
1804+
span,
1805+
format!("{} captures itself here", tcx.def_descr(closure_def_id)),
1806+
);
18261807
}
18271808
}
1809+
};
1810+
1811+
// Label any closure upvars that capture the opaque
1812+
for capture in typeck_results.closure_min_captures_flattened(closure_local_did) {
1813+
label_match(capture.place.ty(), capture.get_path_span(tcx));
1814+
}
1815+
// Label any coroutine locals that capture the opaque
1816+
if tcx.is_coroutine(closure_def_id)
1817+
&& let Some(coroutine_layout) = tcx.mir_coroutine_witnesses(closure_def_id)
1818+
{
1819+
for interior_ty in &coroutine_layout.field_tys {
1820+
label_match(interior_ty.ty, interior_ty.source_info.span);
1821+
}
18281822
}
18291823
}
18301824
}
1831-
if !label {
1832-
err.span_label(span, "cannot resolve opaque type");
1833-
}
1825+
1826+
err.span_label(span, "cannot resolve opaque type");
18341827
err.emit()
18351828
}
18361829

0 commit comments

Comments
 (0)