Skip to content

Commit

Permalink
Remove small tweaks/changes unrelated to the goal of this PR
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchmindtree committed May 7, 2022
1 parent b8c3294 commit a8ce775
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 57 deletions.
2 changes: 1 addition & 1 deletion forc-pkg/src/pkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,7 @@ pub fn compile(
let bytecode = vec![];
let lib_namespace = parse_tree.namespace().clone();
let compiled = Compiled { json_abi, bytecode };
Ok((compiled, Some(lib_namespace)))
Ok((compiled, Some(lib_namespace.into())))
}

// For all other program types, we'll compile the bytecode.
Expand Down
4 changes: 2 additions & 2 deletions sway-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ pub(crate) fn compile_inner_dependency(

// Parse the file.
let parse_tree = check!(
crate::parse(input.clone(), Some(&dep_build_config)),
parse(input.clone(), Some(&dep_build_config)),
return err(warnings, errors),
warnings,
errors
Expand Down Expand Up @@ -448,7 +448,7 @@ pub fn ast_to_asm(ast_res: CompileAstResult, build_config: &BuildConfig) -> Comp
TreeType::Library { name } => CompilationResult::Library {
warnings,
name,
namespace: Box::new(parse_tree.into_namespace()),
namespace: Box::new(parse_tree.into_namespace().into()),
},
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -870,11 +870,9 @@ impl TypedExpression {
warnings,
errors
));

// put the variable and type of the enum variants inner type into a temporary namespace for
// the "then" branch, but not the else branch.
let mut then_namespace = namespace.clone();

// calculate the return type of the variable by checking the enum variant's return type

then_namespace.insert_symbol(
Expand Down Expand Up @@ -944,7 +942,6 @@ impl TypedExpression {
let r#else = check!(
TypedExpression::type_check(TypeCheckArguments {
checkee: *expr,
// TODO: Shouldn't this be an `else` namespace?
namespace,
return_type_annotation: insert_type(TypeInfo::Unknown),
help_text:
Expand Down Expand Up @@ -1711,13 +1708,6 @@ impl TypedExpression {
let mut probe_warnings = Vec::new();
let mut probe_errors = Vec::new();

// Short-hand for the `SymbolNotFound` error.
fn symbol_not_found(call_path_suffix: &Ident) -> CompileError {
CompileError::SymbolNotFound {
name: call_path_suffix.clone(),
}
}

// First, check if this could be a module. We check first so that we can check for
// ambiguity in the following enum check.
let is_module = namespace
Expand Down Expand Up @@ -1777,7 +1767,9 @@ impl TypedExpression {
let decl = match namespace.resolve_call_path(&call_path).value {
Some(decl) => decl.clone(),
None => {
errors.push(symbol_not_found(&call_path.suffix));
errors.push(CompileError::SymbolNotFound {
name: call_path.suffix.clone(),
});
return err(warnings, errors);
}
};
Expand Down Expand Up @@ -1832,7 +1824,9 @@ impl TypedExpression {

// If prefix is neither a module or enum, there's nothing to be found.
} else {
errors.push(symbol_not_found(&call_path.suffix));
errors.push(CompileError::SymbolNotFound {
name: call_path.suffix.clone(),
});
return err(warnings, errors);
};

Expand Down
45 changes: 19 additions & 26 deletions sway-core/src/semantic_analysis/namespace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ pub struct Items {
/// script/predicate/contract file or some library dependency whether introduced via `dep` or the
/// `[dependencies]` table of a `forc` manifest.
///
/// A `Module` contains a single namespace with all items that exist within the lexical scope via
/// declaration or importing, along with a map of each of its submodules.
/// A `Module` contains a set of all items that exist within the lexical scope via declaration or
/// importing, along with a map of each of its submodules.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Module {
/// Submodules of the current module represented as an ordered map from each submodule's name
Expand All @@ -65,7 +65,7 @@ pub struct Module {
///
/// Note that we *require* this map to be ordered to produce deterministic codegen results.
submodules: im::OrdMap<ModuleName, Module>,
/// The set of names in this module.
/// The set of symbols, implementations, synonyms and aliases present within this module.
items: Items,
}

Expand All @@ -76,13 +76,13 @@ pub struct Module {
/// We use a custom type for the `Root` in order to ensure that methods that only work with
/// canonical paths, or that use canonical paths internally, are *only* called from the root. This
/// normally includes methods that first lookup some canonical path via `use_synonyms` before using
/// that canonical path to look up the type declaration.
/// that canonical path to look up the symbol declaration.
#[derive(Clone, Debug, PartialEq)]
pub struct Root {
module: Module,
}

/// A wrapper around the set of namespace items passed through type checking.
/// The set of items that represent the namespace context passed throughout type checking.
#[derive(Clone, Debug, PartialEq)]
pub struct Namespace {
/// An immutable namespace that consists of the names that should always be present, no matter
Expand All @@ -106,12 +106,16 @@ pub struct Namespace {
mod_path: PathBuf,
}

/// The namespace wrapper for a submodule.
/// A namespace session type representing the type-checking of a submodule.
///
/// This acts as a session type, used briefly during `import_new_file` in order to
/// This type allows for re-using the parent's `Namespace` in order to provide access to the
/// `root` and `init` throughout type-checking of the submodule, but with an updated `mod_path` to
/// represent the submodule's path. When dropped, the `SubmoduleNamespace` reset's the
/// `Namespace`'s `mod_path` to the parent module path so that type-checking of the parent may
/// continue.
pub struct SubmoduleNamespace<'a> {
namespace: &'a mut Namespace,
original_mod_path: PathBuf,
parent_mod_path: PathBuf,
}

impl Items {
Expand Down Expand Up @@ -147,8 +151,6 @@ impl Items {
ok((), vec![], vec![])
}

// TODO: Remove in favour of `symbols`. If `symbols` isn't a good enough name, let's rename the
// `symbols` map to `symbol_declarations` or something.
pub fn get_all_declared_symbols(&self) -> impl Iterator<Item = &TypedDeclaration> {
self.symbols().values()
}
Expand Down Expand Up @@ -186,7 +188,10 @@ impl Items {
pub(crate) fn check_symbol(&self, name: &Ident) -> CompileResult<&TypedDeclaration> {
match self.symbols.get(name) {
Some(decl) => ok(decl, vec![], vec![]),
None => err(vec![], vec![symbol_not_found(name)]),
None => err(
vec![],
vec![CompileError::SymbolNotFound { name: name.clone() }],
),
}
}

Expand Down Expand Up @@ -875,7 +880,6 @@ impl Root {
let mut warnings = vec![];
let mut errors = vec![];

let mut root_methods = self.get_methods_for_type(r#type);
let local_methods = self[mod_path].get_methods_for_type(r#type);
let (method_name, method_prefix) = method_path.split_last().expect("method path is empty");

Expand Down Expand Up @@ -903,15 +907,8 @@ impl Root {
);
let mut ns_methods = self[method_prefix].get_methods_for_type(r#type);

// TODO
// Here we collect function declarations for the given type from the current module, the
// module in which the method was implemented, and the root. Perhaps we should instead have
// a root-level map that always stores all inherent methods for each type, seeing as
// inherent methods are always accessible?
let mut methods = local_methods;
methods.append(&mut ns_methods);
// TODO: Make sure we actually want this?
methods.append(&mut root_methods);

match methods
.into_iter()
Expand Down Expand Up @@ -1048,10 +1045,10 @@ impl Namespace {
.cloned()
.chain(Some(dep_name))
.collect();
let original_mod_path = std::mem::replace(&mut self.mod_path, submod_path);
let parent_mod_path = std::mem::replace(&mut self.mod_path, submod_path);
SubmoduleNamespace {
namespace: self,
original_mod_path,
parent_mod_path,
}
}
}
Expand Down Expand Up @@ -1146,7 +1143,7 @@ impl<'a> Drop for SubmoduleNamespace<'a> {
// Replace the submodule path with the original module path.
// This ensures that the namespace's module path is reset when ownership over it is
// relinquished from the SubmoduleNamespace.
self.namespace.mod_path = std::mem::take(&mut self.original_mod_path);
self.namespace.mod_path = std::mem::take(&mut self.parent_mod_path);
}
}

Expand Down Expand Up @@ -1276,7 +1273,3 @@ fn module_not_found(path: &[Ident]) -> CompileError {
.join("::"),
}
}

fn symbol_not_found(name: &Ident) -> CompileError {
CompileError::SymbolNotFound { name: name.clone() }
}
30 changes: 14 additions & 16 deletions sway-core/src/semantic_analysis/syntax_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,24 @@ pub enum TreeType {
pub enum TypedParseTree {
Script {
main_function: TypedFunctionDeclaration,
namespace: namespace::Root,
namespace: namespace::Module,
declarations: Vec<TypedDeclaration>,
all_nodes: Vec<TypedAstNode>,
},
Predicate {
main_function: TypedFunctionDeclaration,
namespace: namespace::Root,
namespace: namespace::Module,
declarations: Vec<TypedDeclaration>,
all_nodes: Vec<TypedAstNode>,
},
Contract {
abi_entries: Vec<TypedFunctionDeclaration>,
namespace: namespace::Root,
namespace: namespace::Module,
declarations: Vec<TypedDeclaration>,
all_nodes: Vec<TypedAstNode>,
},
Library {
namespace: namespace::Root,
namespace: namespace::Module,
all_nodes: Vec<TypedAstNode>,
},
}
Expand All @@ -67,7 +67,7 @@ impl TypedParseTree {
}
}

pub fn namespace(&self) -> &namespace::Root {
pub fn namespace(&self) -> &namespace::Module {
use TypedParseTree::*;
match self {
Library { namespace, .. } => namespace,
Expand All @@ -77,7 +77,7 @@ impl TypedParseTree {
}
}

pub fn into_namespace(self) -> namespace::Root {
pub fn into_namespace(self) -> namespace::Module {
use TypedParseTree::*;
match self {
Library { namespace, .. } => namespace,
Expand Down Expand Up @@ -158,7 +158,7 @@ impl TypedParseTree {
TypedParseTree::validate_typed_nodes(
typed_nodes,
parsed.span,
namespace.root().clone(),
namespace,
tree_type,
warnings,
errors,
Expand Down Expand Up @@ -201,7 +201,7 @@ impl TypedParseTree {
fn validate_typed_nodes(
typed_tree_nodes: Vec<TypedAstNode>,
span: Span,
namespace: namespace::Root,
namespace: &Namespace,
tree_type: &TreeType,
warnings: Vec<CompileWarning>,
mut errors: Vec<CompileError>,
Expand All @@ -211,8 +211,7 @@ impl TypedParseTree {

// Check that if trait B is a supertrait of trait A, and if A is implemented for type T,
// then B is also implemented for type T
// Note that we're checking supertraits from the root, so we pass an empty module path.
errors.append(&mut check_supertraits(&all_nodes, &namespace));
errors.append(&mut check_supertraits(&all_nodes, namespace));

// Extract other interesting properties from the list.
let mut mains = Vec::new();
Expand Down Expand Up @@ -244,6 +243,7 @@ impl TypedParseTree {
}

// Perform other validation based on the tree type.
let namespace = namespace.module().clone();
let typed_parse_tree = match tree_type {
TreeType::Predicate => {
// A predicate must have a main function and that function must return a boolean.
Expand Down Expand Up @@ -313,11 +313,9 @@ impl TypedParseTree {
///
fn check_supertraits(
typed_tree_nodes: &[TypedAstNode],
root: &namespace::Root,
namespace: &Namespace,
) -> Vec<CompileError> {
let mut errors = vec![];
// We check supertraits from the root, so set `&[]` as our mod_path.
let mod_path = &[];
for node in typed_tree_nodes {
if let TypedAstNodeContent::Declaration(TypedDeclaration::ImplTrait {
trait_name,
Expand All @@ -329,7 +327,7 @@ fn check_supertraits(
if let CompileResult {
value: Some(TypedDeclaration::TraitDeclaration(tr)),
..
} = root.resolve_call_path(mod_path, trait_name)
} = namespace.resolve_call_path(trait_name)
{
for supertrait in &tr.supertraits {
if !typed_tree_nodes.iter().any(|search_node| {
Expand All @@ -349,8 +347,8 @@ fn check_supertraits(
..
},
) = (
root.resolve_call_path(mod_path, search_node_trait_name),
root.resolve_call_path(mod_path, &supertrait.name),
namespace.resolve_call_path(search_node_trait_name),
namespace.resolve_call_path(&supertrait.name),
) {
return (tr1.name == tr2.name)
&& (type_implementing_for
Expand Down

0 comments on commit a8ce775

Please sign in to comment.