Skip to content

Commit

Permalink
Changes TypeInfo::Custom to have call paths. (FuelLabs#4026)
Browse files Browse the repository at this point in the history
  • Loading branch information
esdrubal authored Feb 12, 2023
1 parent ed60928 commit dda0f8b
Show file tree
Hide file tree
Showing 42 changed files with 416 additions and 81 deletions.
2 changes: 1 addition & 1 deletion sway-core/src/abi_generation/evm_json_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub fn json_abi_str(type_info: &TypeInfo, type_engine: &TypeEngine) -> String {
}
.into(),
Boolean => "bool".into(),
Custom { name, .. } => name.to_string(),
Custom { call_path, .. } => call_path.suffix.to_string(),
Tuple(fields) => {
let field_strs = fields
.iter()
Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/abi_generation/fuel_json_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ impl TypeInfo {
}
.into(),
Boolean => "bool".into(),
Custom { name, .. } => name.to_string(),
Custom { call_path, .. } => call_path.suffix.to_string(),
Tuple(fields) => {
let field_strs = fields
.iter()
Expand Down
4 changes: 2 additions & 2 deletions sway-core/src/language/parsed/expression/scrutinee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl Scrutinee {
..
} => {
let name = vec![TypeInfo::Custom {
name: struct_name.clone().suffix,
call_path: struct_name.clone(),
type_arguments: None,
}];
let fields = fields
Expand All @@ -151,7 +151,7 @@ impl Scrutinee {
} => {
let enum_name = call_path.prefixes.last().unwrap_or(&call_path.suffix);
let name = vec![TypeInfo::Custom {
name: enum_name.clone(),
call_path: enum_name.clone().into(),
type_arguments: None,
}];
let value = value.gather_approximate_typeinfo_dependencies();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ impl ty::TyImplTrait {
let trait_name = CallPath {
prefixes: vec![],
suffix: match &type_implementing_for {
TypeInfo::Custom { name, .. } => name.clone(),
TypeInfo::Custom { call_path, .. } => call_path.suffix.clone(),
_ => Ident::new_with_override("r#Self", type_implementing_for_span.clone()),
},
is_absolute: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,13 @@ fn type_check_enum(

let decl_engine = ctx.decl_engine;

let enum_name = match call_path.prefixes.last() {
Some(enum_name) => enum_name,
let mut prefixes = call_path.prefixes.clone();
let enum_callpath = match prefixes.pop() {
Some(enum_name) => CallPath {
suffix: enum_name,
prefixes,
is_absolute: call_path.is_absolute,
},
None => {
errors.push(CompileError::EnumNotFound {
name: call_path.suffix.clone(),
Expand All @@ -235,13 +240,13 @@ fn type_check_enum(

// find the enum definition from the name
let unknown_decl = check!(
ctx.namespace.resolve_symbol(enum_name).cloned(),
ctx.namespace.resolve_call_path(&enum_callpath).cloned(),
return err(warnings, errors),
warnings,
errors
);
let mut enum_decl = check!(
unknown_decl.expect_enum(decl_engine, &enum_name.span()),
unknown_decl.expect_enum(decl_engine, &enum_callpath.span()),
return err(warnings, errors),
warnings,
errors
Expand All @@ -253,7 +258,7 @@ fn type_check_enum(
&mut enum_decl,
&mut [],
EnforceTypeArguments::No,
&enum_name.span()
&enum_callpath.span()
),
return err(warnings, errors),
warnings,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ impl ty::TyExpression {
let before_span = before.span();
let type_name = before.inner;
let type_info = type_name_to_type_info_opt(&type_name).unwrap_or(TypeInfo::Custom {
name: type_name.clone(),
call_path: type_name.clone().into(),
type_arguments: None,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ pub(crate) fn type_check_method_application(
} => {
let mut prefixes = call_path_binding.inner.prefixes;
prefixes.push(match &call_path_binding.inner.suffix {
(TypeInfo::Custom { name, .. }, ..) => name.clone(),
(TypeInfo::Custom { call_path, .. }, ..) => call_path.clone().suffix,
(_, ident) => ident.clone(),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ pub(crate) fn struct_instantiation(
return err(warnings, errors);
}
(_, true) => TypeInfo::Custom {
name: suffix,
call_path: suffix.into(),
type_arguments: None,
},
(_, false) => TypeInfo::Custom {
name: suffix,
call_path: suffix.into(),
type_arguments: Some(type_arguments),
},
};
Expand Down
53 changes: 51 additions & 2 deletions sway-core/src/semantic_analysis/namespace/root.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use sway_error::error::CompileError;
use sway_types::Spanned;

use crate::{
language::{ty, CallPath},
CompileResult, Ident,
error::*,
language::{ty, CallPath, Visibility},
CompileResult, Engines, Ident,
};

use super::{module::Module, namespace::Namespace, Path};
Expand Down Expand Up @@ -36,6 +40,51 @@ impl Root {
self.resolve_symbol(&symbol_path, &call_path.suffix)
}

/// Resolve a symbol that is potentially prefixed with some path, e.g. `foo::bar::symbol`.
///
/// This is short-hand for concatenating the `mod_path` with the `call_path`'s prefixes and
/// then calling `resolve_symbol` with the resulting path and call_path's suffix.
///
/// When `call_path` contains prefixes and the resolved declaration visibility is not public
/// an error is thrown.
pub(crate) fn resolve_call_path_with_visibility_check(
&self,
engines: Engines<'_>,
mod_path: &Path,
call_path: &CallPath,
) -> CompileResult<&ty::TyDeclaration> {
let mut warnings = vec![];
let mut errors = vec![];

let result = self.resolve_call_path(mod_path, call_path);

// In case there are no prefixes we don't need to check visibility
if call_path.prefixes.is_empty() {
return result;
}

if let CompileResult {
value: Some(decl), ..
} = result
{
let visibility = check!(
decl.visibility(engines.de()),
return err(warnings, errors),
warnings,
errors
);
if visibility != Visibility::Public {
errors.push(CompileError::ImportPrivateSymbol {
name: call_path.suffix.clone(),
span: call_path.suffix.span(),
});
return err(warnings, errors);
}
}

result
}

/// Given a path to a module and the identifier of a symbol within that module, resolve its
/// declaration.
///
Expand Down
14 changes: 7 additions & 7 deletions sway-core/src/semantic_analysis/namespace/trait_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl TraitMap {
let trait_type_id = type_engine.insert(
decl_engine,
TypeInfo::Custom {
name: trait_name.suffix.clone(),
call_path: trait_name.suffix.clone().into(),
type_arguments: if trait_type_args.is_empty() {
None
} else {
Expand Down Expand Up @@ -146,7 +146,7 @@ impl TraitMap {
let map_trait_type_id = type_engine.insert(
decl_engine,
TypeInfo::Custom {
name: map_trait_name_suffix.clone(),
call_path: map_trait_name_suffix.clone().into(),
type_arguments: if map_trait_type_args.is_empty() {
None
} else {
Expand Down Expand Up @@ -706,7 +706,7 @@ impl TraitMap {
let map_trait_type_id = type_engine.insert(
decl_engine,
TypeInfo::Custom {
name: suffix.name.clone(),
call_path: suffix.name.clone().into(),
type_arguments: if suffix.args.is_empty() {
None
} else {
Expand All @@ -732,7 +732,7 @@ impl TraitMap {
let constraint_type_id = type_engine.insert(
decl_engine,
TypeInfo::Custom {
name: constraint_trait_name.suffix.clone(),
call_path: constraint_trait_name.suffix.clone().into(),
type_arguments: if constraint_type_arguments.is_empty() {
None
} else {
Expand Down Expand Up @@ -823,15 +823,15 @@ pub(crate) fn are_equal_minus_dynamic_types(
// these cases may contain dynamic types
(
TypeInfo::Custom {
name: l_name,
call_path: l_name,
type_arguments: l_type_args,
},
TypeInfo::Custom {
name: r_name,
call_path: r_name,
type_arguments: r_type_args,
},
) => {
l_name == r_name
l_name.suffix == r_name.suffix
&& l_type_args
.unwrap_or_default()
.iter()
Expand Down
9 changes: 6 additions & 3 deletions sway-core/src/semantic_analysis/node_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,10 +650,11 @@ impl Dependencies {
..
} => self.gather_from_call_path(abi_name, false, false),
TypeInfo::Custom {
name,
call_path: name,
type_arguments,
} => {
self.deps.insert(DependentSymbol::Symbol(name.clone()));
self.deps
.insert(DependentSymbol::Symbol(name.clone().suffix));
match type_arguments {
Some(type_arguments) => {
self.gather_from_type_arguments(type_engine, type_arguments)
Expand Down Expand Up @@ -807,7 +808,9 @@ fn type_info_name(type_info: &TypeInfo) -> String {
IntegerBits::SixtyFour => "uint64",
},
TypeInfo::Boolean => "bool",
TypeInfo::Custom { name, .. } => name.as_str(),
TypeInfo::Custom {
call_path: name, ..
} => name.suffix.as_str(),
TypeInfo::Tuple(fields) if fields.is_empty() => "unit",
TypeInfo::Tuple(..) => "tuple",
TypeInfo::SelfType => "self",
Expand Down
34 changes: 17 additions & 17 deletions sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ fn item_struct_to_struct_declaration(
.collect::<Result<Vec<_>, _>>()?;

if fields.iter().any(
|field| matches!(&field.type_info, TypeInfo::Custom { name, ..} if name == &item_struct.name),
|field| matches!(&field.type_info, TypeInfo::Custom { call_path, ..} if call_path.suffix == item_struct.name),
) {
errors.push(ConvertParseTreeError::RecursiveType { span: span.clone() });
}
Expand Down Expand Up @@ -380,7 +380,7 @@ fn item_enum_to_enum_declaration(
.collect::<Result<Vec<_>, _>>()?;

if variants.iter().any(|variant| {
matches!(&variant.type_info, TypeInfo::Custom { name, ..} if name == &item_enum.name)
matches!(&variant.type_info, TypeInfo::Custom { call_path, ..} if call_path.suffix == item_enum.name)
}) {
errors.push(ConvertParseTreeError::RecursiveType { span: span.clone() });
}
Expand Down Expand Up @@ -892,7 +892,7 @@ fn generic_params_opt_to_type_parameters(
let custom_type = type_engine.insert(
decl_engine,
TypeInfo::Custom {
name: ident.clone(),
call_path: ident.clone().into(),
type_arguments: None,
},
);
Expand Down Expand Up @@ -3278,7 +3278,7 @@ fn ty_to_type_parameter(
let custom_type = type_engine.insert(
decl_engine,
TypeInfo::Custom {
name: name_ident.clone(),
call_path: name_ident.clone().into(),
type_arguments: None,
},
);
Expand Down Expand Up @@ -3520,15 +3520,14 @@ fn path_type_to_type_info(
root_opt,
prefix: PathTypeSegment { name, generics_opt },
suffix,
} = path_type;

if root_opt.is_some() || !suffix.is_empty() {
let error = ConvertParseTreeError::FullySpecifiedTypesNotSupported { span };
return Err(handler.emit_err(error.into()));
}
} = path_type.clone();

let type_info = match type_name_to_type_info_opt(&name) {
Some(type_info) => {
if root_opt.is_some() || !suffix.is_empty() {
let error = ConvertParseTreeError::FullySpecifiedTypesNotSupported { span };
return Err(handler.emit_err(error.into()));
}
if let Some((_, generic_args)) = generics_opt {
let error = ConvertParseTreeError::GenericsNotSupportedHere {
span: generic_args.span(),
Expand All @@ -3539,6 +3538,10 @@ fn path_type_to_type_info(
}
None => {
if name.as_str() == "ContractCaller" {
if root_opt.is_some() || !suffix.is_empty() {
let error = ConvertParseTreeError::FullySpecifiedTypesNotSupported { span };
return Err(handler.emit_err(error.into()));
}
let generic_ty = match {
generics_opt.and_then(|(_, generic_args)| {
iter_to_array(generic_args.parameters.into_inner())
Expand Down Expand Up @@ -3567,14 +3570,11 @@ fn path_type_to_type_info(
address: None,
}
} else {
let type_arguments = match generics_opt {
Some((_double_colon_token, generic_args)) => {
generic_args_to_type_arguments(context, handler, engines, generic_args)?
}
None => Vec::new(),
};
let (call_path, type_arguments) = path_type_to_call_path_and_type_arguments(
context, handler, engines, path_type,
)?;
TypeInfo::Custom {
name,
call_path,
type_arguments: Some(type_arguments),
}
}
Expand Down
16 changes: 10 additions & 6 deletions sway-core/src/type_system/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,19 +402,21 @@ impl TypeEngine {
let module_path = type_info_prefix.unwrap_or(mod_path);
let type_id = match self.get(type_id) {
TypeInfo::Custom {
name,
call_path,
type_arguments,
} => {
match namespace
.root()
.resolve_symbol(module_path, &name)
.resolve_call_path_with_visibility_check(engines, module_path, &call_path)
.ok(&mut warnings, &mut errors)
.cloned()
{
Some(ty::TyDeclaration::StructDeclaration(original_id)) => {
// get the copy from the declaration engine
let mut new_copy = check!(
CompileResult::from(decl_engine.get_struct(original_id, &name.span())),
CompileResult::from(
decl_engine.get_struct(original_id, &call_path.span())
),
return err(warnings, errors),
warnings,
errors
Expand Down Expand Up @@ -448,7 +450,9 @@ impl TypeEngine {
Some(ty::TyDeclaration::EnumDeclaration(original_id)) => {
// get the copy from the declaration engine
let mut new_copy = check!(
CompileResult::from(decl_engine.get_enum(original_id, &name.span())),
CompileResult::from(
decl_engine.get_enum(original_id, &call_path.span())
),
return err(warnings, errors),
warnings,
errors
Expand Down Expand Up @@ -482,8 +486,8 @@ impl TypeEngine {
Some(ty::TyDeclaration::GenericTypeForFunctionScope { type_id, .. }) => type_id,
_ => {
errors.push(CompileError::UnknownTypeName {
name: name.to_string(),
span: name.span(),
name: call_path.to_string(),
span: call_path.span(),
});
self.insert(decl_engine, TypeInfo::ErrorRecovery)
}
Expand Down
Loading

0 comments on commit dda0f8b

Please sign in to comment.