Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
42 changes: 22 additions & 20 deletions sway-core/src/concurrent_slab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,13 @@ where
}
}

impl<T> ConcurrentSlab<T>
where
T: Clone,
{
#[allow(dead_code)]
pub fn len(&self) -> usize {
let inner = self.inner.read();
inner.items.len()
}

pub fn values(&self) -> Vec<Arc<T>> {
impl<T> ConcurrentSlab<T> {
pub fn get(&self, index: usize) -> Arc<T> {
let inner = self.inner.read();
inner.items.iter().filter_map(|x| x.clone()).collect()
inner.items[index]
.as_ref()
.expect("invalid slab index for ConcurrentSlab::get")
.clone()
}

pub fn insert(&self, value: T) -> usize {
Expand All @@ -92,6 +86,22 @@ where
inner.items.len() - 1
}
}
}

impl<T> ConcurrentSlab<T>
where
T: Clone,
{
#[allow(dead_code)]
pub fn len(&self) -> usize {
let inner = self.inner.read();
inner.items.len()
}

pub fn values(&self) -> Vec<Arc<T>> {
let inner = self.inner.read();
inner.items.iter().filter_map(|x| x.clone()).collect()
}

pub fn replace(&self, index: usize, new_value: T) -> Option<T> {
let mut inner = self.inner.write();
Expand All @@ -107,14 +117,6 @@ where
Arc::into_inner(old)
}

pub fn get(&self, index: usize) -> Arc<T> {
let inner = self.inner.read();
inner.items[index]
.as_ref()
.expect("invalid slab index for ConcurrentSlab::get")
.clone()
}

/// Improve performance by avoiding `Arc::clone`.
/// The slab is kept locked while running `f`.
pub fn map<R>(&self, index: usize, f: impl FnOnce(&T) -> R) -> R {
Expand Down
6 changes: 6 additions & 0 deletions sway-core/src/engine_threading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{
decl_engine::{parsed_engine::ParsedDeclEngine, DeclEngine},
language::CallPath,
query_engine::QueryEngine,
semantic_analysis::semantic_definition::SemanticDefinitionEngine,
type_system::TypeEngine,
ObservabilityEngine,
};
Expand All @@ -21,6 +22,7 @@ pub struct Engines {
query_engine: QueryEngine,
source_engine: SourceEngine,
obs_engine: Arc<ObservabilityEngine>,
semantic_definition_engine: Arc<SemanticDefinitionEngine>,
}

impl Engines {
Expand Down Expand Up @@ -91,6 +93,10 @@ impl Engines {
engines: self,
}
}

pub(crate) fn sde(&self) -> &SemanticDefinitionEngine {
self.semantic_definition_engine.as_ref()
}
}

#[derive(Clone, Copy)]
Expand Down
30 changes: 1 addition & 29 deletions sway-core/src/language/literal.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use crate::{type_system::*, Engines};
use crate::type_system::*;
use serde::{Deserialize, Serialize};
use std::{
fmt,
hash::{Hash, Hasher},
num::{IntErrorKind, ParseIntError},
};
use sway_error::error::CompileError;
use sway_types::{integer_bits::IntegerBits, span, u256::U256};

#[derive(Debug, Clone, Eq, Serialize, Deserialize)]
Expand Down Expand Up @@ -147,32 +145,6 @@ impl fmt::Display for Literal {
}

impl Literal {
#[allow(clippy::wildcard_in_or_patterns)]
pub(crate) fn handle_parse_int_error(
engines: &Engines,
e: ParseIntError,
ty: TypeInfo,
span: sway_types::Span,
) -> CompileError {
match e.kind() {
IntErrorKind::PosOverflow => CompileError::IntegerTooLarge {
ty: engines.help_out(ty).to_string(),
span,
},
IntErrorKind::NegOverflow => CompileError::IntegerTooSmall {
ty: engines.help_out(ty).to_string(),
span,
},
IntErrorKind::InvalidDigit => CompileError::IntegerContainsInvalidDigit {
ty: engines.help_out(ty).to_string(),
span,
},
IntErrorKind::Zero | IntErrorKind::Empty | _ => {
CompileError::Internal("Called incorrect internal sway-core on literal type.", span)
}
}
}

pub(crate) fn to_typeinfo(&self) -> TypeInfo {
match self {
Literal::String(_) => TypeInfo::StringSlice,
Expand Down
45 changes: 27 additions & 18 deletions sway-core/src/language/ty/declaration/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ use crate::{
ty::*,
CallPath, Inline, Purity, Trace, Visibility,
},
semantic_analysis::TypeCheckContext,
semantic_analysis::{semantic_definition::SemanticDefinitionId, TypeCheckContext},
transform::{self, AttributeKind},
type_system::*,
types::*,
};
use ast_elements::type_parameter::ConstGenericExpr;
use either::Either;
use hashbrown::HashMap;
use monomorphization::MonomorphizeHelper;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
Expand Down Expand Up @@ -95,6 +96,9 @@ pub struct TyFunctionDecl {
/// TODO: See: https://github.com/FuelLabs/sway/issues/7371
/// !!! WARNING !!!
pub kind: TyFunctionDeclKind,

pub sdid: Option<SemanticDefinitionId>,
pub tid_map: HashMap<TypeId, TypeId>,
}

impl TyDeclParsedType for TyFunctionDecl {
Expand Down Expand Up @@ -338,6 +342,8 @@ impl DeclRefFunction {
let mut method = original.clone();

if let Some(method_implementing_for) = method.implementing_for {
engines.te().start_capturing_duplicates();

let mut type_id_type_subst_map = TypeSubstMap::new();

if let Some(TyDecl::ImplSelfOrTrait(t)) = method.implementing_type.clone() {
Expand Down Expand Up @@ -413,34 +419,33 @@ impl DeclRefFunction {
true,
));

let r = engines
method.tid_map = engines.te().end_capturing_duplicates().unwrap();

let decl_ref = engines
.de()
.insert(
method.clone(),
engines.de().get_parsed_decl_id(self.id()).as_ref(),
)
.insert(method, engines.de().get_parsed_decl_id(self.id()).as_ref())
.with_parent(decl_engine, self.id().into());

engines.obs().trace(|| {
format!(
" after get_method_safe_to_unify: {:?}; {:?}",
engines.help_out(type_id),
engines.help_out(r.id())
engines.help_out(decl_ref.id())
)
});

return r;
}

engines.obs().trace(|| {
format!(
" after get_method_safe_to_unify: {:?}; {:?}",
engines.help_out(type_id),
engines.help_out(self.id())
)
});
decl_ref
} else {
engines.obs().trace(|| {
format!(
" after get_method_safe_to_unify: {:?}; {:?}",
engines.help_out(type_id),
engines.help_out(self.id())
)
});

self.clone()
self.clone()
}
}
}

Expand Down Expand Up @@ -514,6 +519,8 @@ impl HashWithEngines for TyFunctionDecl {
is_trait_method_dummy: _,
is_type_check_finalized: _,
kind: _,
sdid: _,
tid_map: _,
} = self;
name.hash(state);
body.hash(state, engines);
Expand Down Expand Up @@ -667,6 +674,8 @@ impl TyFunctionDecl {
FunctionDeclarationKind::Test => TyFunctionDeclKind::Test,
FunctionDeclarationKind::Main => TyFunctionDeclKind::Main,
},
sdid: None,
tid_map: Default::default(),
}
}

Expand Down
19 changes: 2 additions & 17 deletions sway-core/src/language/ty/expression/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,23 +109,8 @@ impl TypeCheckAnalysis for TyExpression {
handler: &Handler,
ctx: &mut TypeCheckAnalysisContext,
) -> Result<(), ErrorEmitted> {
match &self.expression {
// Check literal "fits" into assigned typed.
TyExpressionVariant::Literal(Literal::Numeric(literal_value)) => {
let t = ctx.engines.te().get(self.return_type);
if let TypeInfo::UnsignedInteger(bits) = &*t {
if bits.would_overflow(*literal_value) {
handler.emit_err(CompileError::TypeError(TypeError::LiteralOverflow {
expected: format!("{:?}", ctx.engines.help_out(t)),
span: self.span.clone(),
}));
}
}
}
TyExpressionVariant::ArrayExplicit { .. } => {
self.as_array_unify_elements(handler, ctx.engines);
}
_ => {}
if let TyExpressionVariant::ArrayExplicit { .. } = &self.expression {
self.as_array_unify_elements(handler, ctx.engines);
}
self.expression.type_check_analyze(handler, ctx)
}
Expand Down
1 change: 1 addition & 0 deletions sway-core/src/semantic_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ pub use namespace::Namespace;
pub(crate) use type_check_analysis::*;
pub use type_check_context::TypeCheckContext;
pub(crate) use type_check_finalization::*;
pub mod semantic_definition;
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ impl ty::TyFunctionDecl {
is_in_impl_self: bool,
implementing_for: Option<TypeId>,
) -> Result<Self, ErrorEmitted> {
// If functions aren't allowed in this location, return an error.
if ctx.functions_disallowed() {
return Err(handler.emit_err(CompileError::Unimplemented {
feature: "Declaring nested functions".to_string(),
help: vec![],
span: fn_decl.span.clone(),
}));
}

let FunctionDeclaration {
name,
body: _,
Expand All @@ -103,15 +112,6 @@ impl ty::TyFunctionDecl {

let type_engine = ctx.engines.te();

// If functions aren't allowed in this location, return an error.
if ctx.functions_disallowed() {
return Err(handler.emit_err(CompileError::Unimplemented {
feature: "Declaring nested functions".to_string(),
help: vec![],
span: span.clone(),
}));
}

// Warn against non-snake case function names.
if !is_snake_case(name.as_str()) {
handler.emit_warn(CompileWarning {
Expand All @@ -120,9 +120,12 @@ impl ty::TyFunctionDecl {
})
}

let sdid = ctx.engines.sde().new_semantic_definition();

// create a namespace for the function
ctx.by_ref()
.with_const_shadowing_mode(ConstShadowingMode::Sequential)
.with_semantic_definition(sdid)
.disallow_functions()
.scoped(handler, Some(span.clone()), |ctx| {
// Type check the type parameters.
Expand Down Expand Up @@ -247,6 +250,8 @@ impl ty::TyFunctionDecl {
FunctionDeclarationKind::Test => ty::TyFunctionDeclKind::Test,
FunctionDeclarationKind::Main => ty::TyFunctionDeclKind::Main,
},
sdid: Some(sdid),
tid_map: HashMap::default(),
};

Ok(function_decl)
Expand All @@ -262,6 +267,7 @@ impl ty::TyFunctionDecl {
// create a namespace for the function
ctx.by_ref()
.with_const_shadowing_mode(ConstShadowingMode::Sequential)
.with_semantic_definition(*ty_fn_decl.sdid.as_ref().expect("missing semantic definition"))
.disallow_functions()
.scoped(handler, Some(fn_decl.span.clone()), |ctx| {
let FunctionDeclaration { body, .. } = fn_decl;
Expand Down Expand Up @@ -300,8 +306,16 @@ impl ty::TyFunctionDecl {
.with_type_annotation(return_type.type_id)
.with_function_type_annotation(return_type.type_id);

ctx.engines.te().start_capturing_duplicates();
let body = ty::TyCodeBlock::type_check(handler, ctx.by_ref(), body, true)
.unwrap_or_else(|_err| ty::TyCodeBlock::default());
let tid_map = ctx.engines.te().end_capturing_duplicates().unwrap();
assert!(tid_map.is_empty());

let sdid = ctx.get_current_semantic_definition().expect("expected semantic definition");
let sd = ctx.engines.sde().get(sdid);
let solver = sd.solver(ctx.engines, handler);
let _ = solver.solve();

ty_fn_decl.body = body;
ty_fn_decl.is_type_check_finalized = true;
Expand Down Expand Up @@ -410,6 +424,8 @@ fn test_function_selector_behavior() {
is_trait_method_dummy: false,
is_type_check_finalized: true,
kind: ty::TyFunctionDeclKind::Default,
sdid: None,
tid_map: HashMap::default(),
};

let selector_text = decl
Expand Down Expand Up @@ -461,6 +477,8 @@ fn test_function_selector_behavior() {
is_trait_method_dummy: false,
is_type_check_finalized: true,
kind: ty::TyFunctionDeclKind::Default,
sdid: None,
tid_map: HashMap::default(),
};

let selector_text = decl
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use sway_types::Spanned;

use crate::{
decl_engine::{parsed_id::ParsedDeclId, DeclId},
language::{
Expand All @@ -9,12 +7,13 @@ use crate::{
semantic_analysis::symbol_collection_context::SymbolCollectionContext,
Engines,
};
use sway_error::handler::{ErrorEmitted, Handler};

use crate::{
semantic_analysis::{AbiMode, TypeCheckContext},
type_system::*,
};
use hashbrown::HashMap;
use sway_error::handler::{ErrorEmitted, Handler};
use sway_types::Spanned;

impl ty::TyTraitFn {
pub(crate) fn collect(
Expand Down Expand Up @@ -129,6 +128,8 @@ impl ty::TyTraitFn {
is_trait_method_dummy: true,
is_type_check_finalized: true,
kind: ty::TyFunctionDeclKind::Default,
sdid: None,
tid_map: HashMap::default(),
}
}
}
Loading
Loading