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

Fix issue with name clash on auto implementation of AbiEncode and AbiDecode #6044

Merged
merged 18 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions forc-pkg/src/pkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1595,7 +1595,6 @@ pub fn dependency_namespace(
};

root_module.write(engines, |root_module| {
root_module.is_external = true;
root_module.name.clone_from(&name);
root_module.visibility = Visibility::Public;
});
Expand All @@ -1606,7 +1605,7 @@ pub fn dependency_namespace(
let dep_node = edge.target();
let dep_name = kebab_to_snake_case(&edge.weight().name);
let dep_edge = edge.weight();
let dep_namespace = match dep_edge.kind {
let mut dep_namespace = match dep_edge.kind {
DepKind::Library => lib_namespace_map
.get(&dep_node)
.cloned()
Expand All @@ -1628,12 +1627,12 @@ pub fn dependency_namespace(
contract_id_value,
experimental,
)?;
module.is_external = true;
module.name = name;
module.visibility = Visibility::Public;
module
}
};
dep_namespace.is_external = true;
root_module.insert_submodule(dep_name, dep_namespace);
let dep = &graph[dep_node];
if dep.name == CORE {
Expand Down
21 changes: 20 additions & 1 deletion sway-core/src/language/call_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,23 @@ impl CallPath {
.collect::<Vec<_>>()
}

/// Create a full [CallPath] from aiven an [Ident] and the [Namespace] in which the [Ident] is
jjcnn marked this conversation as resolved.
Show resolved Hide resolved
/// declared.
///
/// This function is intended to be used while typechecking the identifier declaration, i.e.,
/// before the identifier is added to the environment.
pub fn ident_to_fullpath(suffix: Ident, namespace: &Namespace) -> CallPath {
let mut res: Self = suffix.clone().into();
if let Some(ref pkg_name) = namespace.root_module().name {
res.prefixes.push(pkg_name.clone())
};
for mod_path in namespace.mod_path() {
res.prefixes.push(mod_path.clone())
}
res.is_absolute = true;
res
}

/// Convert a given [CallPath] to a symbol to a full [CallPath] from the root of the project
/// in which the symbol is declared. For example, given a path `pkga::SOME_CONST` where `pkga`
/// is an _internal_ library of a package named `my_project`, the corresponding call path is
Expand All @@ -350,7 +367,9 @@ impl CallPath {
let mut is_absolute = false;

if let Some(mod_path) = namespace.program_id(engines).read(engines, |m| {
if let Some((_, path, _)) = m
if m.current_items().symbols().contains_key(&self.suffix) {
None
} else if let Some((_, path, _)) = m
.current_items()
.use_item_synonyms
.get(&self.suffix)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ impl ty::TyAbiDecl {
// from the same ABI later, during method application typechecking.
let _ = ctx.insert_trait_implementation(
&Handler::default(),
CallPath::from(self.name.clone()),
CallPath::ident_to_fullpath(self.name.clone(), ctx.namespace()),
vec![],
type_id,
&all_items,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ impl ty::TyEnumDecl {
);
}

let mut call_path: CallPath = name.into();
call_path = call_path.to_fullpath(ctx.engines(), ctx.namespace());
let call_path = CallPath::ident_to_fullpath(name, ctx.namespace());

// create the enum decl
let decl = ty::TyEnumDecl {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,17 +305,14 @@ impl TyImplTrait {
let self_type_id = self_type_param.type_id;

// create the trait name
let trait_name = CallPath {
prefixes: vec![],
suffix: match &&*type_engine.get(implementing_for.type_id) {
TypeInfo::Custom {
qualified_call_path: call_path,
..
} => call_path.call_path.suffix.clone(),
_ => Ident::new_with_override("r#Self".into(), implementing_for.span()),
},
is_absolute: false,
let suffix = match &&*type_engine.get(implementing_for.type_id) {
TypeInfo::Custom {
qualified_call_path: call_path,
..
} => call_path.call_path.suffix.clone(),
_ => Ident::new_with_override("r#Self".into(), implementing_for.span()),
};
let trait_name = CallPath::ident_to_fullpath(suffix, ctx.namespace());

// Type check the type parameters.
let new_impl_type_parameters = TypeParameter::type_check_type_params(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ impl ty::TyStructDecl {
new_fields.push(ty::TyStructField::type_check(handler, ctx.by_ref(), field)?);
}

let mut path: CallPath = name.into();
path = path.to_fullpath(ctx.engines(), ctx.namespace());
let path = CallPath::ident_to_fullpath(name, ctx.namespace());

// create the struct decl
let decl = ty::TyStructDecl {
Expand Down
12 changes: 2 additions & 10 deletions sway-core/src/semantic_analysis/ast_node/declaration/trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,7 @@ impl TyTraitDecl {
// to allow methods to use those functions
ctx.insert_trait_implementation(
handler,
CallPath {
prefixes: vec![],
suffix: name.clone(),
is_absolute: false,
},
CallPath::ident_to_fullpath(name.clone(), ctx.namespace),
new_type_parameters.iter().map(|x| x.into()).collect(),
self_type,
&dummy_interface_surface,
Expand Down Expand Up @@ -180,11 +176,7 @@ impl TyTraitDecl {
// to allow methods to use those functions
ctx.insert_trait_implementation(
handler,
CallPath {
prefixes: vec![],
suffix: name.clone(),
is_absolute: false,
},
CallPath::ident_to_fullpath(name.clone(), ctx.namespace()),
new_type_parameters.iter().map(|x| x.into()).collect(),
self_type,
&dummy_interface_surface,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ fn default_with_contract_id_inner(
let mut ns = Namespace::init_root(root);
// This is pretty hacky but that's okay because of this code is being removed pretty soon
ns.root.module.name = ns_name;
ns.root.module.is_external = true;
ns.root.module.visibility = Visibility::Public;
let type_check_ctx = TypeCheckContext::from_namespace(&mut ns, engines, experimental);
let typed_node = TyAstNode::type_check(handler, type_check_ctx, &ast_node).unwrap();
Expand Down
44 changes: 40 additions & 4 deletions sway-core/src/semantic_analysis/namespace/namespace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ use super::{
root::{ResolvedDeclaration, Root},
submodule_namespace::SubmoduleNamespace,
trait_map::ResolvedTraitImplItem,
ModulePath, ModulePathBuf,
ModuleName, ModulePath, ModulePathBuf,
};

use rustc_hash::FxHasher;
use std::hash::BuildHasherDefault;
use sway_error::handler::{ErrorEmitted, Handler};
use sway_types::span::Span;

Expand Down Expand Up @@ -55,11 +57,44 @@ impl Namespace {
}

/// Initialise the namespace at its root from the given initial namespace.
/// If the root module contains submodules these are now considered external.
pub fn init_root(root: Root) -> Self {
assert!(
!root.module.is_external,
"The root module must not be external during compilation"
);
let mod_path = vec![];

// A copy of the root module is used to initialize every new submodule in the program.
//
// Every submodule that has been added before calling init_root is now considered
// external, which we have to enforce at this point.
fn clone_with_submodules_external(module: &Module) -> Module {
let mut new_submods =
im::HashMap::<ModuleName, Module, BuildHasherDefault<FxHasher>>::default();
for (name, submod) in module.submodules.iter() {
let new_submod = clone_with_submodules_external(submod);
new_submods.insert(name.clone(), new_submod);
}
Module {
submodules: new_submods,
lexical_scopes: module.lexical_scopes.clone(),
current_lexical_scope_id: module.current_lexical_scope_id,
name: module.name.clone(),
visibility: module.visibility,
span: module.span.clone(),
is_external: true,
mod_path: module.mod_path.clone(),
}
}

let mut init = clone_with_submodules_external(&root.module);
// The init module itself is not external
init.is_external = false;

Self {
init: root.module.clone(),
root,
init: init.clone(),
root: Root { module: init },
mod_path,
}
}
Expand Down Expand Up @@ -268,6 +303,7 @@ impl Namespace {
module_span: Span,
) -> SubmoduleNamespace {
let init = self.init.clone();
let is_external = self.module(engines).is_external;
self.module_mut(engines)
.submodules
.entry(mod_name.to_string())
Expand All @@ -284,7 +320,7 @@ impl Namespace {
new_module.name = Some(mod_name);
new_module.span = Some(module_span);
new_module.visibility = visibility;
new_module.is_external = false;
new_module.is_external = is_external;
new_module.mod_path = submod_path;
SubmoduleNamespace {
namespace: self,
Expand Down
1 change: 0 additions & 1 deletion sway-core/src/semantic_analysis/namespace/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ impl Root {
self.check_module_privacy(handler, engines, src)?;

let src_mod = self.module.lookup_submodule(handler, engines, src)?;

let implemented_traits = src_mod.current_items().implemented_traits.clone();
let mut symbols_and_decls = vec![];
for (symbol, decl) in src_mod.current_items().symbols.iter() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[[package]]
name = "callpath_local_shadowing"
source = "member"
dependencies = ["std"]

[[package]]
name = "core"
source = "path+from-root-779BB769D43AD4B7"

[[package]]
name = "std"
source = "path+from-root-779BB769D43AD4B7"
dependencies = ["core"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
license = "Apache-2.0"
name = "callpath_local_shadowing"
entry = "main.sw"
implicit-std = false

[dependencies]
std = { path = "../../../../../../../sway-lib-std" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"configurables": [],
"encoding": "1",
"functions": [
{
"attributes": null,
"inputs": [],
"name": "main",
"output": {
"name": "",
"type": 0,
"typeArguments": null
}
}
],
"loggedTypes": [],
"messagesTypes": [],
"types": [
{
"components": [],
"type": "()",
"typeId": 0,
"typeParameters": null
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"configurables": [],
"encoding": "1",
"functions": [
{
"attributes": null,
"inputs": [],
"name": "main",
"output": {
"name": "",
"type": 0,
"typeArguments": null
}
}
],
"loggedTypes": [],
"messagesTypes": [],
"types": [
{
"components": [],
"type": "()",
"typeId": 0,
"typeParameters": null
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
library;

pub struct TestStruct {
pub a: u64,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
script;

mod lib;

use lib::*;

struct TestStruct {
pub x: u64,
pub y: u64,
}

fn main() {
let ts = TestStruct { x: 0, y: 0 };
poke(ts.x);
}

fn poke<T>(_x: T) { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
category = "compile"
validate_abi = true
expected_warnings = 2
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
category = "disabled"
category = "compile"
expected_warnings = 27
Loading