Skip to content

Commit 87b37f2

Browse files
author
Grant Wuerker
committed
hacking
1 parent f822ca2 commit 87b37f2

File tree

6 files changed

+106
-34
lines changed

6 files changed

+106
-34
lines changed

Diff for: crates/hir-analysis/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ either = "1.8"
1515
derive_more = "0.99"
1616
itertools = "0.10"
1717
ena = "0.14"
18-
18+
indexmap = "1.6.2"
1919
hir = { path = "../hir", package = "fe-hir" }
2020
common = { path = "../common2", package = "fe-common2" }
2121
macros = { path = "../macros", package = "fe-macros" }

Diff for: crates/hir-analysis/src/ty/def_analysis.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -439,10 +439,7 @@ fn check_recursive_adt_impl(
439439
for (ty_idx, ty) in field.iter_types(db).enumerate() {
440440
for field_adt_ref in ty.collect_direct_adts(db) {
441441
if participants.contains(&field_adt_ref) && participants.contains(&adt) {
442-
let diag = TyLowerDiag::recursive_type(
443-
adt.name_span(db),
444-
adt_def.variant_ty_span(db, field_idx, ty_idx),
445-
);
442+
let diag = TyLowerDiag::recursive_type(field_adt_ref, adt);
446443
return Some(diag.into());
447444
}
448445
}

Diff for: crates/hir-analysis/src/ty/diagnostics.rs

+16-22
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::HirAnalysisDb;
1212

1313
use super::{
1414
constraint::PredicateId,
15-
ty_def::{Kind, TyId},
15+
ty_def::{AdtRefId, Kind, TyId},
1616
};
1717

1818
#[salsa::accumulator]
@@ -46,8 +46,8 @@ pub enum TyLowerDiag {
4646
NotFullyAppliedType(DynLazySpan),
4747
InvalidTypeArgKind(DynLazySpan, String),
4848
RecursiveType {
49-
primary_span: DynLazySpan,
50-
field_span: DynLazySpan,
49+
to: AdtRefId,
50+
from: AdtRefId,
5151
},
5252

5353
UnboundTypeAliasParam {
@@ -95,11 +95,8 @@ impl TyLowerDiag {
9595
Self::InvalidTypeArgKind(span, msg)
9696
}
9797

98-
pub(super) fn recursive_type(primary_span: DynLazySpan, field_span: DynLazySpan) -> Self {
99-
Self::RecursiveType {
100-
primary_span,
101-
field_span,
102-
}
98+
pub(super) fn recursive_type(to: AdtRefId, from: AdtRefId) -> Self {
99+
Self::RecursiveType { to, from }
103100
}
104101

105102
pub(super) fn unbound_type_alias_param(
@@ -179,21 +176,18 @@ impl TyLowerDiag {
179176
span.resolve(db),
180177
)],
181178

182-
Self::RecursiveType {
183-
primary_span,
184-
field_span,
185-
} => {
179+
Self::RecursiveType { to, from } => {
186180
vec![
187-
SubDiagnostic::new(
188-
LabelStyle::Primary,
189-
"recursive type definition".to_string(),
190-
primary_span.resolve(db),
191-
),
192-
SubDiagnostic::new(
193-
LabelStyle::Secondary,
194-
"recursion occurs here".to_string(),
195-
field_span.resolve(db),
196-
),
181+
// SubDiagnostic::new(
182+
// LabelStyle::Primary,
183+
// "recursive type definition".to_string(),
184+
// primary_span.resolve(db),
185+
// ),
186+
// SubDiagnostic::new(
187+
// LabelStyle::Secondary,
188+
// "recursion occurs here".to_string(),
189+
// field_span.resolve(db),
190+
// ),
197191
]
198192
}
199193

Diff for: crates/hir-analysis/src/ty/mod.rs

+80-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use crate::HirAnalysisDb;
22
use hir::{analysis_pass::ModuleAnalysisPass, hir_def::TopLevelMod};
3+
use indexmap::{indexmap, IndexMap};
34

45
use self::{
56
def_analysis::{analyze_adt, analyze_impl_trait, analyze_trait, analyze_type_alias},
67
diagnostics::{
7-
AdtDefDiagAccumulator, ImplTraitDefDiagAccumulator, TraitDefDiagAccumulator,
8+
AdtDefDiagAccumulator, ImplTraitDefDiagAccumulator, TraitDefDiagAccumulator, TyLowerDiag,
89
TypeAliasDefDiagAccumulator,
910
},
1011
ty_def::AdtRefId,
@@ -57,11 +58,84 @@ impl<'db> ModuleAnalysisPass for TypeDefAnalysisPass<'db> {
5758
.map(|c| AdtRefId::from_contract(self.db, *c)),
5859
);
5960

60-
adts.flat_map(|adt| {
61-
analyze_adt::accumulated::<AdtDefDiagAccumulator>(self.db, adt).into_iter()
62-
})
63-
.map(|diag| diag.to_voucher())
64-
.collect()
61+
let mut cycles = vec![];
62+
let mut diags = adts
63+
.flat_map(|adt| {
64+
analyze_adt::accumulated::<AdtDefDiagAccumulator>(self.db, adt).into_iter()
65+
})
66+
.fold(vec![], |mut accum, diag| match diag {
67+
diagnostics::TyDiagCollection::Ty(TyLowerDiag::RecursiveType { to, from }) => {
68+
cycles.push(Cycle::new(to, from));
69+
accum
70+
}
71+
_ => {
72+
accum.push(diag);
73+
accum
74+
}
75+
})
76+
.iter()
77+
.map(|diag| diag.to_voucher())
78+
.collect();
79+
if !cycles.is_empty() {
80+
merge_cycles(&mut cycles);
81+
panic!("{:#?}", cycles);
82+
}
83+
diags
84+
}
85+
}
86+
87+
#[derive(Clone, Debug)]
88+
struct Cycle {
89+
pub path: Vec<(AdtRefId, AdtRefId)>,
90+
}
91+
92+
impl Cycle {
93+
pub fn new(a: AdtRefId, b: AdtRefId) -> Self {
94+
Self { path: vec![(a, b)] }
95+
}
96+
97+
pub fn merge(&mut self, other: &mut Self) {
98+
assert_eq!(self.end(), other.start());
99+
self.path.append(&mut other.path);
100+
}
101+
102+
pub fn is_complete(&self) -> bool {
103+
self.start() == self.end()
104+
}
105+
106+
pub fn start(&self) -> AdtRefId {
107+
self.path[0].0
108+
}
109+
110+
pub fn end(&self) -> AdtRefId {
111+
self.path[self.path.len() - 1].1
112+
}
113+
}
114+
115+
fn merge_cycles(cycles: &mut Vec<Cycle>) {
116+
let mut complete = false;
117+
118+
while !complete {
119+
complete = true;
120+
121+
for i in 0..cycles.len() {
122+
if !cycles[i].is_complete() {
123+
complete = false;
124+
125+
for j in 0..cycles.len() {
126+
if cycles[i].end() == cycles[j].start() {
127+
let mut j_clone = cycles[j].clone();
128+
cycles[i].merge(&mut j_clone);
129+
cycles.remove(j);
130+
break;
131+
}
132+
}
133+
134+
if !complete {
135+
break;
136+
}
137+
}
138+
}
65139
}
66140
}
67141

Diff for: crates/uitest/fixtures/ty/def/recursive_type.fe

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ pub struct S5<T> {
2121

2222
pub struct S6 {
2323
s: S5<S6>
24-
}
24+
}
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
source: crates/uitest/tests/ty.rs
3+
assertion_line: 17
4+
expression: diags
5+
input_file: crates/uitest/fixtures/ty/def/recursive_type.fe
6+
---
7+

0 commit comments

Comments
 (0)