Skip to content

Commit

Permalink
hacking
Browse files Browse the repository at this point in the history
  • Loading branch information
Grant Wuerker committed Nov 25, 2023
1 parent f822ca2 commit 87b37f2
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 34 deletions.
2 changes: 1 addition & 1 deletion crates/hir-analysis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ either = "1.8"
derive_more = "0.99"
itertools = "0.10"
ena = "0.14"

indexmap = "1.6.2"
hir = { path = "../hir", package = "fe-hir" }
common = { path = "../common2", package = "fe-common2" }
macros = { path = "../macros", package = "fe-macros" }
Expand Down
5 changes: 1 addition & 4 deletions crates/hir-analysis/src/ty/def_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,10 +439,7 @@ fn check_recursive_adt_impl(
for (ty_idx, ty) in field.iter_types(db).enumerate() {
for field_adt_ref in ty.collect_direct_adts(db) {
if participants.contains(&field_adt_ref) && participants.contains(&adt) {
let diag = TyLowerDiag::recursive_type(
adt.name_span(db),
adt_def.variant_ty_span(db, field_idx, ty_idx),
);
let diag = TyLowerDiag::recursive_type(field_adt_ref, adt);
return Some(diag.into());
}
}
Expand Down
38 changes: 16 additions & 22 deletions crates/hir-analysis/src/ty/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::HirAnalysisDb;

use super::{
constraint::PredicateId,
ty_def::{Kind, TyId},
ty_def::{AdtRefId, Kind, TyId},
};

#[salsa::accumulator]
Expand Down Expand Up @@ -46,8 +46,8 @@ pub enum TyLowerDiag {
NotFullyAppliedType(DynLazySpan),
InvalidTypeArgKind(DynLazySpan, String),
RecursiveType {
primary_span: DynLazySpan,
field_span: DynLazySpan,
to: AdtRefId,
from: AdtRefId,
},

UnboundTypeAliasParam {
Expand Down Expand Up @@ -95,11 +95,8 @@ impl TyLowerDiag {
Self::InvalidTypeArgKind(span, msg)
}

pub(super) fn recursive_type(primary_span: DynLazySpan, field_span: DynLazySpan) -> Self {
Self::RecursiveType {
primary_span,
field_span,
}
pub(super) fn recursive_type(to: AdtRefId, from: AdtRefId) -> Self {
Self::RecursiveType { to, from }
}

pub(super) fn unbound_type_alias_param(
Expand Down Expand Up @@ -179,21 +176,18 @@ impl TyLowerDiag {
span.resolve(db),
)],

Self::RecursiveType {
primary_span,
field_span,
} => {
Self::RecursiveType { to, from } => {
vec![
SubDiagnostic::new(
LabelStyle::Primary,
"recursive type definition".to_string(),
primary_span.resolve(db),
),
SubDiagnostic::new(
LabelStyle::Secondary,
"recursion occurs here".to_string(),
field_span.resolve(db),
),
// SubDiagnostic::new(
// LabelStyle::Primary,
// "recursive type definition".to_string(),
// primary_span.resolve(db),
// ),
// SubDiagnostic::new(
// LabelStyle::Secondary,
// "recursion occurs here".to_string(),
// field_span.resolve(db),
// ),
]
}

Expand Down
86 changes: 80 additions & 6 deletions crates/hir-analysis/src/ty/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::HirAnalysisDb;
use hir::{analysis_pass::ModuleAnalysisPass, hir_def::TopLevelMod};
use indexmap::{indexmap, IndexMap};

use self::{
def_analysis::{analyze_adt, analyze_impl_trait, analyze_trait, analyze_type_alias},
diagnostics::{
AdtDefDiagAccumulator, ImplTraitDefDiagAccumulator, TraitDefDiagAccumulator,
AdtDefDiagAccumulator, ImplTraitDefDiagAccumulator, TraitDefDiagAccumulator, TyLowerDiag,
TypeAliasDefDiagAccumulator,
},
ty_def::AdtRefId,
Expand Down Expand Up @@ -57,11 +58,84 @@ impl<'db> ModuleAnalysisPass for TypeDefAnalysisPass<'db> {
.map(|c| AdtRefId::from_contract(self.db, *c)),
);

adts.flat_map(|adt| {
analyze_adt::accumulated::<AdtDefDiagAccumulator>(self.db, adt).into_iter()
})
.map(|diag| diag.to_voucher())
.collect()
let mut cycles = vec![];
let mut diags = adts
.flat_map(|adt| {
analyze_adt::accumulated::<AdtDefDiagAccumulator>(self.db, adt).into_iter()
})
.fold(vec![], |mut accum, diag| match diag {
diagnostics::TyDiagCollection::Ty(TyLowerDiag::RecursiveType { to, from }) => {
cycles.push(Cycle::new(to, from));
accum
}
_ => {
accum.push(diag);
accum
}
})
.iter()
.map(|diag| diag.to_voucher())
.collect();
if !cycles.is_empty() {
merge_cycles(&mut cycles);
panic!("{:#?}", cycles);
}
diags
}
}

#[derive(Clone, Debug)]
struct Cycle {
pub path: Vec<(AdtRefId, AdtRefId)>,
}

impl Cycle {
pub fn new(a: AdtRefId, b: AdtRefId) -> Self {
Self { path: vec![(a, b)] }
}

pub fn merge(&mut self, other: &mut Self) {
assert_eq!(self.end(), other.start());
self.path.append(&mut other.path);
}

pub fn is_complete(&self) -> bool {
self.start() == self.end()
}

pub fn start(&self) -> AdtRefId {
self.path[0].0
}

pub fn end(&self) -> AdtRefId {
self.path[self.path.len() - 1].1
}
}

fn merge_cycles(cycles: &mut Vec<Cycle>) {
let mut complete = false;

while !complete {
complete = true;

for i in 0..cycles.len() {
if !cycles[i].is_complete() {
complete = false;

for j in 0..cycles.len() {
if cycles[i].end() == cycles[j].start() {
let mut j_clone = cycles[j].clone();
cycles[i].merge(&mut j_clone);
cycles.remove(j);
break;
}
}

if !complete {
break;
}
}
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/uitest/fixtures/ty/def/recursive_type.fe
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ pub struct S5<T> {

pub struct S6 {
s: S5<S6>
}
}
7 changes: 7 additions & 0 deletions crates/uitest/fixtures/ty/def/recursive_type.snap.new
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
source: crates/uitest/tests/ty.rs
assertion_line: 17
expression: diags
input_file: crates/uitest/fixtures/ty/def/recursive_type.fe
---

0 comments on commit 87b37f2

Please sign in to comment.