Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor resolution to use hierarchical namespaces #1312

Closed
wants to merge 80 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
016153c
wip
sezna Mar 14, 2024
b8a801e
wip
sezna Mar 18, 2024
a83a1e9
wip
sezna Mar 18, 2024
5d6a33a
wip
sezna Mar 18, 2024
e5ec193
wip
sezna Mar 18, 2024
a18ef5d
it builds??
sezna Mar 19, 2024
a041e58
wip
sezna Mar 19, 2024
4a644ef
wip: add nested namespace structure
sezna Mar 19, 2024
ac8745d
Switch to using new namespace API
sezna Mar 19, 2024
bf6561b
doc comment
sezna Mar 20, 2024
c571f2e
start working on converting HIR to new structure
sezna Mar 20, 2024
21fac31
wip: refactor core namespaces into namespace ids
sezna Mar 20, 2024
f52ed17
wip
sezna Mar 21, 2024
e6c15ba
wip
sezna Mar 21, 2024
2b1e51d
wip
sezna Mar 21, 2024
422542b
Refactor new namespace work into qsc_data_structures
sezna Mar 21, 2024
0b4069a
add more namespace ids
sezna Mar 25, 2024
b2c0f2f
Merge branch 'main' of github.com:microsoft/qsharp into alex/hns
sezna Mar 25, 2024
38327a9
wip: continue refactor of namespaceids
sezna Mar 25, 2024
261aa8a
update methods for namespace tree node
sezna Mar 25, 2024
3e6d39d
finish lining up types for completion lists
sezna Mar 26, 2024
71e3ddd
fmT
sezna Mar 26, 2024
dd1e312
introduce vecident to qsc_fir
sezna Mar 26, 2024
51eefa1
lower VecIdent for fir and hir
sezna Mar 26, 2024
2187506
remove todos from name locator and hover in lang service
sezna Mar 26, 2024
50ddf45
include prelude namespace IDs in default opens
sezna Mar 26, 2024
ee532c0
refactor opens to use string identifiers for namespaces instead of ids
sezna Mar 26, 2024
8713435
remove todos in completions
sezna Mar 26, 2024
0bcd526
implement get in name resolution
sezna Mar 26, 2024
a78fe73
continue work on resolve.rs
sezna Mar 26, 2024
5da2fb9
bind opens with namespace ids
sezna Mar 27, 2024
7c5b9d6
finish removing TODOs; work on unit testing
sezna Mar 27, 2024
01bcddc
namespace root traversals are working
sezna Mar 27, 2024
105e625
fmt
sezna Mar 27, 2024
f62b977
refactor namespaces into their own files
sezna Mar 27, 2024
8a11e1d
add forgotten test file
sezna Mar 27, 2024
a41952e
parsing tests pass
sezna Mar 27, 2024
81d1c6c
Working on making katas tests pass. WIP. Need to sort out how to hand…
sezna Mar 27, 2024
3719610
namespaces seem to be...working?
sezna Mar 28, 2024
86e99b9
mid-opens-refactor, might need to revert this
sezna Apr 1, 2024
d5e7011
Revert "mid-opens-refactor, might need to revert this"
sezna Apr 1, 2024
966ab4b
hierarchical opens work
sezna Apr 1, 2024
9fe7bde
fix display in duplicate definition error
sezna Apr 1, 2024
467beeb
implicit hierarchy works
sezna Apr 1, 2024
71b5a55
improve test clarity
sezna Apr 1, 2024
1a25d48
it works -- but tons of debug stuff everywhere
sezna Apr 2, 2024
2e7293b
Merge branch 'main' of github.com:microsoft/qsharp into alex/hns
sezna Apr 2, 2024
1a3c838
remove lots of debug cruft
sezna Apr 2, 2024
5f0d8ba
fmt and add hierarchical namespace resolution back in
sezna Apr 2, 2024
149070e
fix interpolation tests
sezna Apr 2, 2024
f725bc0
simplify beefy part of resolve function
sezna Apr 2, 2024
69a5137
fix renamer for namespaces
sezna Apr 2, 2024
1206b0b
just need to sort out shadowing
sezna Apr 2, 2024
8c08c61
fix shadowing rules
sezna Apr 3, 2024
7eae708
fix removal of unimplemented items from resolution
sezna Apr 3, 2024
552f346
fix ambiguous prelude
sezna Apr 3, 2024
a1be75b
refactor symbol finder to be generic; fix ambiguous opens test
sezna Apr 3, 2024
e80f154
fmt
sezna Apr 3, 2024
2674be3
replicate merged namespace alias behavior
sezna Apr 4, 2024
70faf28
all frontend tests pass
sezna Apr 4, 2024
4c04a17
Merge branch 'main' of github.com:microsoft/qsharp into alex/hns
sezna Apr 4, 2024
d9c6c7e
clear up warnings
sezna Apr 4, 2024
3c13840
remove dead code
sezna Apr 4, 2024
42a9051
clippy on frontend
sezna Apr 4, 2024
eb33cd4
wip on clippy
sezna Apr 4, 2024
24a8a22
fix all clippy warnings in compiler subdir
sezna Apr 4, 2024
ef1d739
fix language service open namespace text edit issue
sezna Apr 4, 2024
f235671
deduplicate prelude definition
sezna Apr 4, 2024
9a69246
simpify resolve fn
sezna Apr 4, 2024
ad12a62
simplify resolution
sezna Apr 4, 2024
36d7a31
further simplify resolution algorithms
sezna Apr 4, 2024
804f4e7
Fix interpreter test case for printing stack traces
sezna Apr 4, 2024
8016603
fix katas test
sezna Apr 4, 2024
5d60bfa
fix katas shadowing rules and doc gen tests
sezna Apr 4, 2024
992791d
Merge branch 'main' of github.com:microsoft/qsharp into alex/hns
sezna Apr 4, 2024
b2cf9c6
Fix resolve and RCA tests
sezna Apr 5, 2024
42e6ec9
update not available test
sezna Apr 5, 2024
fe267f8
cargo fmt
sezna Apr 5, 2024
03027ce
format string sample
sezna Apr 6, 2024
499283a
revert sample changes
sezna Apr 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ __pycache__/
/fuzz/Cargo.lock
.mypy_cache/
.pytest_cache/
.idea/
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion compiler/qsc/src/interpret/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ fn get_item_file_name(store: &PackageStore, id: StoreItemId) -> Option<String> {
#[must_use]
fn get_ns_name(item: &Item) -> Option<String> {
if let ItemKind::Namespace(ns, _) = &item.kind {
Some(ns.name.to_string())
Some(ns.name().to_string())
} else {
None
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/qsc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub mod project {
pub use qsc_project::{DirEntry, EntryType, FileSystem, Manifest, ManifestDescriptor};
}

pub use qsc_data_structures::{language_features::LanguageFeatures, span::Span};
pub use qsc_data_structures::{language_features::LanguageFeatures, namespaces::*, span::Span};

pub use qsc_passes::{PackageType, PassContext};

Expand Down
86 changes: 83 additions & 3 deletions compiler/qsc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ pub struct Namespace {
/// The documentation.
pub doc: Rc<str>,
/// The namespace name.
pub name: Box<Ident>,
pub name: VecIdent,
/// The items in the namespace.
pub items: Box<[Box<Item>]>,
}
Expand Down Expand Up @@ -259,7 +259,7 @@ pub enum ItemKind {
#[default]
Err,
/// An `open` item for a namespace with an optional alias.
Open(Box<Ident>, Option<Box<Ident>>),
Open(VecIdent, Option<Box<Ident>>),
/// A `newtype` declaration.
Ty(Box<Ident>, Box<TyDef>),
}
Expand Down Expand Up @@ -1273,7 +1273,7 @@ pub struct Path {
/// The span.
pub span: Span,
/// The namespace.
pub namespace: Option<Box<Ident>>,
pub namespace: Option<VecIdent>,
/// The declaration name.
pub name: Box<Ident>,
}
Expand Down Expand Up @@ -1306,6 +1306,86 @@ pub struct Ident {
pub name: Rc<str>,
}

/// A [`VecIdent`] represents a sequence of idents. It provides a helpful abstraction
/// that is more powerful than a simple `Vec<Ident>`, and is primarily used to represent
/// dot-separated paths.
#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
pub struct VecIdent(pub Vec<Ident>);

impl From<VecIdent> for Vec<Rc<str>> {
fn from(v: VecIdent) -> Self {
v.0.iter().map(|i| i.name.clone()).collect()
}
}

impl From<&VecIdent> for Vec<Rc<str>> {
fn from(v: &VecIdent) -> Self {
v.0.iter().map(|i| i.name.clone()).collect()
}
}

impl From<Vec<Ident>> for VecIdent {
fn from(v: Vec<Ident>) -> Self {
VecIdent(v)
}
}

impl From<VecIdent> for Vec<Ident> {
fn from(v: VecIdent) -> Self {
v.0
}
}

impl Display for VecIdent {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let mut buf = Vec::with_capacity(self.0.len());

for ident in &self.0 {
buf.push(format!("{ident}"));
}
if buf.len() > 1 {
// use square brackets only if there are more than one ident
write!(f, "[{}]", buf.join(", "))
} else {
write!(f, "{}", buf[0])
}
}
}

impl<'a> IntoIterator for &'a VecIdent {
type IntoIter = std::slice::Iter<'a, Ident>;
type Item = &'a Ident;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl VecIdent {
/// constructs an iter over the [Ident]s that this contains.
pub fn iter(&self) -> std::slice::Iter<'_, Ident> {
self.0.iter()
}

/// the conjoined span of all idents in the `VecIdent`
#[must_use]
pub fn span(&self) -> Span {
Span {
lo: self.0.first().map(|i| i.span.lo).unwrap_or_default(),
hi: self.0.last().map(|i| i.span.hi).unwrap_or_default(),
}
}

/// The stringified dot-separated path of the idents in this [`VecIdent`]
/// E.g. `a.b.c`
#[must_use]
pub fn name(&self) -> String {
self.0
.iter()
.map(|i| i.name.to_string())
.collect::<Vec<String>>()
.join(".")
}
}

impl Default for Ident {
fn default() -> Self {
Ident {
Expand Down
20 changes: 17 additions & 3 deletions compiler/qsc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ pub trait MutVisitor: Sized {
fn visit_ident(&mut self, ident: &mut Ident) {
walk_ident(self, ident);
}
fn visit_vec_ident(&mut self, ident: &mut crate::ast::VecIdent) {
walk_vec_ident(self, ident);
}

fn visit_span(&mut self, _: &mut Span) {}
}
Expand All @@ -89,7 +92,8 @@ pub fn walk_package(vis: &mut impl MutVisitor, package: &mut Package) {

pub fn walk_namespace(vis: &mut impl MutVisitor, namespace: &mut Namespace) {
vis.visit_span(&mut namespace.span);
vis.visit_ident(&mut namespace.name);
vis.visit_vec_ident(&mut namespace.name);

namespace.items.iter_mut().for_each(|i| vis.visit_item(i));
}

Expand All @@ -104,7 +108,7 @@ pub fn walk_item(vis: &mut impl MutVisitor, item: &mut Item) {
ItemKind::Callable(decl) => vis.visit_callable_decl(decl),
ItemKind::Err => {}
ItemKind::Open(ns, alias) => {
vis.visit_ident(ns);
vis.visit_vec_ident(ns);
alias.iter_mut().for_each(|a| vis.visit_ident(a));
}
ItemKind::Ty(ident, def) => {
Expand Down Expand Up @@ -333,10 +337,20 @@ pub fn walk_qubit_init(vis: &mut impl MutVisitor, init: &mut QubitInit) {

pub fn walk_path(vis: &mut impl MutVisitor, path: &mut Path) {
vis.visit_span(&mut path.span);
path.namespace.iter_mut().for_each(|n| vis.visit_ident(n));
if let Some(ref mut namespace) = path.namespace {
vis.visit_vec_ident(namespace);
}
if let Some(ref mut ns) = path.namespace {
vis.visit_vec_ident(ns);
}
vis.visit_ident(&mut path.name);
}

pub fn walk_ident(vis: &mut impl MutVisitor, ident: &mut Ident) {
vis.visit_span(&mut ident.span);
}
pub fn walk_vec_ident(vis: &mut impl MutVisitor, ident: &mut crate::ast::VecIdent) {
for ref mut ident in &mut ident.0 {
vis.visit_ident(ident);
}
}
12 changes: 8 additions & 4 deletions compiler/qsc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::ast::{
Attr, Block, CallableBody, CallableDecl, Expr, ExprKind, FunctorExpr, FunctorExprKind, Ident,
Item, ItemKind, Namespace, Package, Pat, PatKind, Path, QubitInit, QubitInitKind, SpecBody,
SpecDecl, Stmt, StmtKind, StringComponent, TopLevelNode, Ty, TyDef, TyDefKind, TyKind,
Visibility,
VecIdent, Visibility,
};

pub trait Visitor<'a>: Sized {
Expand Down Expand Up @@ -72,6 +72,8 @@ pub trait Visitor<'a>: Sized {
}

fn visit_ident(&mut self, _: &'a Ident) {}

fn visit_vec_ident(&mut self, _: &'a VecIdent) {}
}

pub fn walk_package<'a>(vis: &mut impl Visitor<'a>, package: &'a Package) {
Expand All @@ -83,7 +85,7 @@ pub fn walk_package<'a>(vis: &mut impl Visitor<'a>, package: &'a Package) {
}

pub fn walk_namespace<'a>(vis: &mut impl Visitor<'a>, namespace: &'a Namespace) {
vis.visit_ident(&namespace.name);
vis.visit_vec_ident(&namespace.name);
namespace.items.iter().for_each(|i| vis.visit_item(i));
}

Expand All @@ -94,7 +96,7 @@ pub fn walk_item<'a>(vis: &mut impl Visitor<'a>, item: &'a Item) {
ItemKind::Err => {}
ItemKind::Callable(decl) => vis.visit_callable_decl(decl),
ItemKind::Open(ns, alias) => {
vis.visit_ident(ns);
vis.visit_vec_ident(ns);
alias.iter().for_each(|a| vis.visit_ident(a));
}
ItemKind::Ty(ident, def) => {
Expand Down Expand Up @@ -300,6 +302,8 @@ pub fn walk_qubit_init<'a>(vis: &mut impl Visitor<'a>, init: &'a QubitInit) {
}

pub fn walk_path<'a>(vis: &mut impl Visitor<'a>, path: &'a Path) {
path.namespace.iter().for_each(|n| vis.visit_ident(n));
if let Some(ref ns) = path.namespace {
vis.visit_vec_ident(ns);
}
vis.visit_ident(&path.name);
}
4 changes: 2 additions & 2 deletions compiler/qsc_circuit/src/operations/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fn compile_one_operation(code: &str) -> (Item, String) {
});
let mut namespaces = unit.package.items.values().filter_map(|i| {
if let ItemKind::Namespace(ident, _) = &i.kind {
Some(ident.name.clone())
Some(ident.clone())
} else {
None
}
Expand All @@ -44,7 +44,7 @@ fn compile_one_operation(code: &str) -> (Item, String) {
);
(
only_callable.clone(),
format!("{only_namespace}.{callable_name}"),
format!("{}.{callable_name}", only_namespace.name()),
)
}

Expand Down
1 change: 1 addition & 0 deletions compiler/qsc_data_structures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ repository.workspace = true
miette = { workspace = true }
serde = { workspace = true }
bitflags = { workspace = true }
rustc-hash = { workspace = true }

[dev-dependencies]
expect-test = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions compiler/qsc_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ pub mod functors;
pub mod index_map;
pub mod language_features;
pub mod line_column;
pub mod namespaces;
pub mod span;