Skip to content

Commit 4643ced

Browse files
authored
Merge pull request #931 from Y-Nak/trait-solve
Fe type/trait system
2 parents 7929eaa + f822ca2 commit 4643ced

File tree

106 files changed

+6828
-457
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+6828
-457
lines changed

Diff for: Cargo.lock

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[workspace]
22
members = ["crates/*"]
3+
resolver = "2"
34

45
[profile.dev.package.solc]
56
opt-level = 3

Diff for: crates/analyzer/src/db/queries/contracts.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ pub fn contract_public_function_map(
126126
contract
127127
.functions(db)
128128
.iter()
129-
.filter_map(|(name, func)| func.is_public(db).then(|| (name.clone(), *func)))
129+
.filter(|(_, func)| func.is_public(db))
130+
.map(|(name, func)| (name.clone(), *func))
130131
.collect(),
131132
)
132133
}

Diff for: crates/analyzer/src/db/queries/structs.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,8 @@ pub fn struct_field_map(
8484

8585
let mut labels = fields
8686
.iter()
87-
.filter_map(|(_, field)| {
88-
field
89-
.is_indexed(db)
90-
.then(|| Label::primary(field.span(db), String::new()))
91-
})
87+
.filter(|(_, field)| field.is_indexed(db))
88+
.map(|(_, field)| Label::primary(field.span(db), String::new()))
9289
.collect::<Vec<Label>>();
9390
labels.last_mut().unwrap().message = format!("{indexed_count} indexed fields");
9491

Diff for: crates/common2/src/diagnostics.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,16 @@ pub struct Span {
9191

9292
impl PartialOrd for Span {
9393
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
94-
match self.file.cmp(&other.file) {
95-
std::cmp::Ordering::Equal => self.range.start().partial_cmp(&other.range.start()),
96-
ord => Some(ord),
97-
}
94+
Some(self.cmp(other))
9895
}
9996
}
10097

10198
impl Ord for Span {
10299
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
103-
self.partial_cmp(other).unwrap()
100+
match self.file.cmp(&other.file) {
101+
std::cmp::Ordering::Equal => self.range.start().cmp(&other.range.start()),
102+
ord => ord,
103+
}
104104
}
105105
}
106106

@@ -144,7 +144,10 @@ pub enum DiagnosticPass {
144144

145145
NameResolution,
146146

147-
TyCheck,
147+
TypeDefinition,
148+
TraitDefinition,
149+
ImplTraitDefinition,
150+
TraitSatisfaction,
148151

149152
ExternalAnalysis(ExternalAnalysisKey),
150153
}
@@ -154,8 +157,10 @@ impl DiagnosticPass {
154157
match self {
155158
Self::Parse => 1,
156159
Self::NameResolution => 2,
157-
158-
Self::TyCheck => 3,
160+
Self::TypeDefinition => 3,
161+
Self::TraitDefinition => 4,
162+
Self::ImplTraitDefinition => 5,
163+
Self::TraitSatisfaction => 6,
159164

160165
Self::ExternalAnalysis(_) => std::u16::MAX,
161166
}

Diff for: crates/driver2/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use hir::{
1717
};
1818
use hir_analysis::{
1919
name_resolution::{DefConflictAnalysisPass, ImportAnalysisPass, PathAnalysisPass},
20+
ty::{ImplTraitAnalysisPass, TraitAnalysisPass, TypeAliasAnalysisPass, TypeDefAnalysisPass},
2021
HirAnalysisDb,
2122
};
2223

@@ -144,5 +145,9 @@ fn initialize_analysis_pass(db: &DriverDataBase) -> AnalysisPassManager<'_> {
144145
pass_manager.add_module_pass(Box::new(DefConflictAnalysisPass::new(db)));
145146
pass_manager.add_module_pass(Box::new(ImportAnalysisPass::new(db)));
146147
pass_manager.add_module_pass(Box::new(PathAnalysisPass::new(db)));
148+
pass_manager.add_module_pass(Box::new(TypeDefAnalysisPass::new(db)));
149+
pass_manager.add_module_pass(Box::new(TypeAliasAnalysisPass::new(db)));
150+
pass_manager.add_module_pass(Box::new(TraitAnalysisPass::new(db)));
151+
pass_manager.add_module_pass(Box::new(ImplTraitAnalysisPass::new(db)));
147152
pass_manager
148153
}

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

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ rustc-hash = "1.1.0"
1414
either = "1.8"
1515
derive_more = "0.99"
1616
itertools = "0.10"
17+
ena = "0.14"
1718

1819
hir = { path = "../hir", package = "fe-hir" }
1920
common = { path = "../common2", package = "fe-common2" }

Diff for: crates/hir-analysis/src/lib.rs

+49
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,54 @@ pub struct Jar(
77
name_resolution::resolve_imports,
88
name_resolution::diagnostics::NameResolutionDiagAccumulator,
99
name_resolution::diagnostics::ImportResolutionDiagAccumulator,
10+
/// Type system.
11+
ty::ty_def::TyId,
12+
ty::ty_def::ty_kind,
13+
ty::ty_def::free_inference_keys,
14+
ty::ty_def::pretty_print_ty,
15+
ty::ty_def::AdtDef,
16+
ty::ty_def::AdtRefId,
17+
/// Type lowering.
18+
ty::ty_lower::lower_hir_ty,
19+
ty::ty_lower::lower_adt,
20+
ty::ty_lower::lower_type_alias,
21+
ty::ty_lower::collect_generic_params,
22+
ty::ty_lower::GenericParamOwnerId,
23+
/// Trait lowering.
24+
ty::trait_lower::lower_trait,
25+
ty::trait_lower::lower_trait_ref,
26+
ty::trait_lower::collect_trait_impls,
27+
ty::trait_lower::lower_impl_trait,
28+
/// Item Definition analysis.
29+
ty::def_analysis::check_recursive_adt,
30+
ty::def_analysis::analyze_adt,
31+
ty::def_analysis::analyze_type_alias,
32+
ty::def_analysis::analyze_trait,
33+
ty::def_analysis::analyze_impl_trait,
34+
/// Trait system.
35+
ty::trait_def::TraitDef,
36+
ty::trait_def::TraitInstId,
37+
ty::trait_def::Implementor,
38+
ty::trait_def::ingot_trait_env,
39+
ty::trait_def::trait_implementors,
40+
ty::constraint::collect_super_traits,
41+
ty::constraint::collect_trait_constraints,
42+
ty::constraint::collect_adt_constraints,
43+
ty::constraint::collect_implementor_constraints,
44+
ty::constraint::super_trait_insts,
45+
ty::constraint::compute_super_assumptions,
46+
ty::constraint::ty_constraints,
47+
ty::constraint::trait_inst_constraints,
48+
ty::constraint::PredicateId,
49+
ty::constraint::PredicateListId,
50+
ty::constraint_solver::is_goal_satisfiable,
51+
ty::constraint_solver::check_ty_app_sat,
52+
ty::constraint_solver::check_trait_inst_sat,
53+
/// Diagnostic accumulators.
54+
ty::diagnostics::AdtDefDiagAccumulator,
55+
ty::diagnostics::TypeAliasDefDiagAccumulator,
56+
ty::diagnostics::TraitDefDiagAccumulator,
57+
ty::diagnostics::ImplTraitDefDiagAccumulator,
1058
);
1159

1260
pub trait HirAnalysisDb: salsa::DbWithJar<Jar> + HirDb {
@@ -17,6 +65,7 @@ pub trait HirAnalysisDb: salsa::DbWithJar<Jar> + HirDb {
1765
impl<DB> HirAnalysisDb for DB where DB: ?Sized + salsa::DbWithJar<Jar> + HirDb {}
1866

1967
pub mod name_resolution;
68+
pub mod ty;
2069

2170
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2271
pub struct Spanned<T> {

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

+17-7
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ mod visibility_checker;
88
use either::Either;
99
pub use import_resolver::ResolvedImports;
1010
pub use name_resolver::{
11-
NameDerivation, NameDomain, NameQuery, NameRes, NameResBucket, QueryDirective,
11+
NameDerivation, NameDomain, NameQuery, NameRes, NameResBucket, NameResKind, QueryDirective,
1212
};
1313
pub use path_resolver::EarlyResolvedPath;
1414

1515
use hir::{
1616
analysis_pass::ModuleAnalysisPass,
1717
diagnostics::DiagnosticVoucher,
1818
hir_def::{
19-
scope_graph::ScopeId, Expr, ExprId, IdentId, IngotId, ItemKind, Partial, Pat, PatId,
20-
PathId, TopLevelMod, TypeBound, TypeId,
19+
scope_graph::ScopeId, Expr, ExprId, GenericArgListId, IdentId, IngotId, ItemKind, Partial,
20+
Pat, PatId, PathId, TopLevelMod, TraitRefId, TypeId,
2121
},
2222
visitor::prelude::*,
2323
};
@@ -361,13 +361,13 @@ impl<'db, 'a> Visitor for EarlyPathVisitor<'db, 'a> {
361361
self.path_ctxt.pop();
362362
}
363363

364-
fn visit_type_bound(
364+
fn visit_trait_ref(
365365
&mut self,
366-
ctxt: &mut VisitorCtxt<'_, LazyTypeBoundSpan>,
367-
bound: &TypeBound,
366+
ctxt: &mut VisitorCtxt<'_, LazyTraitRefSpan>,
367+
trait_ref: TraitRefId,
368368
) {
369369
self.path_ctxt.push(ExpectedPathKind::Trait);
370-
walk_type_bound(self, ctxt, bound);
370+
walk_trait_ref(self, ctxt, trait_ref);
371371
self.path_ctxt.pop();
372372
}
373373

@@ -401,6 +401,16 @@ impl<'db, 'a> Visitor for EarlyPathVisitor<'db, 'a> {
401401
walk_generic_param(self, ctxt, param);
402402
}
403403

404+
fn visit_generic_arg_list(
405+
&mut self,
406+
ctxt: &mut VisitorCtxt<'_, LazyGenericArgListSpan>,
407+
args: GenericArgListId,
408+
) {
409+
self.path_ctxt.push(ExpectedPathKind::Type);
410+
walk_generic_arg_list(self, ctxt, args);
411+
self.path_ctxt.pop();
412+
}
413+
404414
fn visit_ty(&mut self, ctxt: &mut VisitorCtxt<'_, LazyTySpan>, ty: TypeId) {
405415
self.path_ctxt.push(ExpectedPathKind::Type);
406416
walk_ty(self, ctxt, ty);

Diff for: crates/hir-analysis/src/name_resolution/name_resolver.rs

+29-28
Original file line numberDiff line numberDiff line change
@@ -442,32 +442,38 @@ impl NameDerivation {
442442

443443
impl PartialOrd for NameDerivation {
444444
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
445+
Some(self.cmp(other))
446+
}
447+
}
448+
449+
impl Ord for NameDerivation {
450+
fn cmp(&self, other: &Self) -> cmp::Ordering {
445451
match (self, other) {
446-
(NameDerivation::Def, NameDerivation::Def) => Some(cmp::Ordering::Equal),
447-
(NameDerivation::Def, _) => Some(cmp::Ordering::Greater),
448-
(_, NameDerivation::Def) => Some(cmp::Ordering::Less),
452+
(NameDerivation::Def, NameDerivation::Def) => cmp::Ordering::Equal,
453+
(NameDerivation::Def, _) => cmp::Ordering::Greater,
454+
(_, NameDerivation::Def) => cmp::Ordering::Less,
449455

450456
(NameDerivation::NamedImported(_), NameDerivation::NamedImported(_)) => {
451-
Some(cmp::Ordering::Equal)
457+
cmp::Ordering::Equal
452458
}
453-
(NameDerivation::NamedImported(_), _) => Some(cmp::Ordering::Greater),
454-
(_, NameDerivation::NamedImported(_)) => Some(cmp::Ordering::Less),
459+
(NameDerivation::NamedImported(_), _) => cmp::Ordering::Greater,
460+
(_, NameDerivation::NamedImported(_)) => cmp::Ordering::Less,
455461

456462
(NameDerivation::GlobImported(_), NameDerivation::GlobImported(_)) => {
457-
Some(cmp::Ordering::Equal)
463+
cmp::Ordering::Equal
458464
}
459-
(NameDerivation::GlobImported(_), _) => Some(cmp::Ordering::Greater),
460-
(_, NameDerivation::GlobImported(_)) => Some(cmp::Ordering::Less),
465+
(NameDerivation::GlobImported(_), _) => cmp::Ordering::Greater,
466+
(_, NameDerivation::GlobImported(_)) => cmp::Ordering::Less,
461467

462-
(NameDerivation::Lex(lhs), NameDerivation::Lex(rhs)) => lhs.partial_cmp(rhs),
463-
(NameDerivation::Lex(_), _) => Some(cmp::Ordering::Greater),
464-
(_, NameDerivation::Lex(_)) => Some(cmp::Ordering::Less),
468+
(NameDerivation::Lex(lhs), NameDerivation::Lex(rhs)) => lhs.cmp(rhs),
469+
(NameDerivation::Lex(_), _) => cmp::Ordering::Greater,
470+
(_, NameDerivation::Lex(_)) => cmp::Ordering::Less,
465471

466-
(NameDerivation::External, NameDerivation::External) => Some(cmp::Ordering::Equal),
467-
(NameDerivation::External, _) => Some(cmp::Ordering::Greater),
468-
(_, NameDerivation::External) => Some(cmp::Ordering::Less),
472+
(NameDerivation::External, NameDerivation::External) => cmp::Ordering::Equal,
473+
(NameDerivation::External, _) => cmp::Ordering::Greater,
474+
(_, NameDerivation::External) => cmp::Ordering::Less,
469475

470-
(NameDerivation::Prim, NameDerivation::Prim) => Some(cmp::Ordering::Equal),
476+
(NameDerivation::Prim, NameDerivation::Prim) => cmp::Ordering::Equal,
471477
}
472478
}
473479
}
@@ -504,6 +510,7 @@ impl<'db, 'a> NameResolver<'db, 'a> {
504510
}
505511

506512
pub(crate) fn resolve_query(&mut self, query: NameQuery) -> NameResBucket {
513+
let hir_db = self.db.as_hir_db();
507514
// If the query is already resolved, return the cached result.
508515
if let Some(resolved) = self.cache_store.get(query) {
509516
return resolved.clone();
@@ -519,7 +526,7 @@ impl<'db, 'a> NameResolver<'db, 'a> {
519526

520527
// 1. Look for the name in the current scope.
521528
let mut found_scopes = FxHashSet::default();
522-
for edge in query.scope.edges(self.db.as_hir_db()) {
529+
for edge in query.scope.edges(hir_db) {
523530
match edge.kind.propagate(&query) {
524531
PropagationResult::Terminated => {
525532
if found_scopes.insert(edge.dest) {
@@ -577,16 +584,16 @@ impl<'db, 'a> NameResolver<'db, 'a> {
577584
// 5. Look for the name in the external ingots.
578585
query
579586
.scope
580-
.top_mod(self.db.as_hir_db())
581-
.ingot(self.db.as_hir_db())
582-
.external_ingots(self.db.as_hir_db())
587+
.top_mod(hir_db)
588+
.ingot(hir_db)
589+
.external_ingots(hir_db)
583590
.iter()
584-
.for_each(|(name, root_mod)| {
591+
.for_each(|(name, ingot)| {
585592
if *name == query.name {
586593
// We don't care about the result of `push` because we assume ingots are
587594
// guaranteed to be unique.
588595
bucket.push(&NameRes::new_from_scope(
589-
ScopeId::from_item((*root_mod).into()),
596+
ScopeId::from_item((ingot.root_mod(hir_db)).into()),
590597
NameDomain::Type,
591598
NameDerivation::External,
592599
))
@@ -735,12 +742,6 @@ impl<'db, 'a> NameResolver<'db, 'a> {
735742
}
736743
}
737744

738-
impl Ord for NameDerivation {
739-
fn cmp(&self, other: &Self) -> cmp::Ordering {
740-
self.partial_cmp(other).unwrap()
741-
}
742-
}
743-
744745
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
745746
pub enum NameResolutionError {
746747
/// The name is not found.

0 commit comments

Comments
 (0)