Skip to content

Commit

Permalink
added associated type args in semantic (#6763)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomerStarkware authored Nov 28, 2024
1 parent fbd2a3b commit 334dd97
Show file tree
Hide file tree
Showing 16 changed files with 644 additions and 41 deletions.
2 changes: 1 addition & 1 deletion corelib/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "core"
version = "2.8.5"
edition = "2024_07"
experimental-features = ["coupons", "negative_impls"]
experimental-features = ["coupons", "negative_impls", "associated_item_constraints"]

# NOTE: This is non-public, unstable Scarb's field, which instructs resolver that this package does not
# depend on `core`, which is only true for this particular package. Nobody else should use it.
Expand Down
1 change: 1 addition & 0 deletions corelib/cairo_project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ edition = "2024_07"

[config.global.experimental_features]
negative_impls = true
associated_item_constraints = true
coupons = true
3 changes: 3 additions & 0 deletions crates/cairo-lang-filesystem/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ pub struct DependencySettings {
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct ExperimentalFeaturesConfig {
pub negative_impls: bool,
/// Allows using associated item constraints.
pub associated_item_constraints: bool,
/// Allows using coupon types and coupon calls.
///
/// Each function has a associated `Coupon` type, which represents paying the cost of the
Expand Down Expand Up @@ -237,6 +239,7 @@ pub fn init_dev_corelib(db: &mut (dyn FilesGroup + 'static), core_lib_dir: PathB
dependencies: Default::default(),
experimental_features: ExperimentalFeaturesConfig {
negative_impls: true,
associated_item_constraints: true,
coupons: true,
},
},
Expand Down
1 change: 1 addition & 0 deletions crates/cairo-lang-language-server/src/project/scarb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ fn scarb_package_experimental_features(

ExperimentalFeaturesConfig {
negative_impls: contains("negative_impls"),
associated_item_constraints: contains("associated_item_constraints"),
coupons: contains("coupons"),
}
}
4 changes: 4 additions & 0 deletions crates/cairo-lang-language-server/tests/e2e/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ fn cairo_projects() {
dependencies: {},
experimental_features: ExperimentalFeaturesConfig {
negative_impls: true,
associated_item_constraints: true,
coupons: true,
},
}
Expand All @@ -69,6 +70,7 @@ fn cairo_projects() {
dependencies: {},
experimental_features: ExperimentalFeaturesConfig {
negative_impls: false,
associated_item_constraints: false,
coupons: false,
},
}
Expand All @@ -83,6 +85,7 @@ fn cairo_projects() {
dependencies: {},
experimental_features: ExperimentalFeaturesConfig {
negative_impls: false,
associated_item_constraints: false,
coupons: false,
},
}
Expand All @@ -97,6 +100,7 @@ fn cairo_projects() {
dependencies: {},
experimental_features: ExperimentalFeaturesConfig {
negative_impls: false,
associated_item_constraints: false,
coupons: false,
},
}
Expand Down
6 changes: 6 additions & 0 deletions crates/cairo-lang-project/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ fn test_serde() {
dependencies: Default::default(),
experimental_features: ExperimentalFeaturesConfig {
negative_impls: true,
associated_item_constraints: false,
coupons: false,
},
cfg_set: Default::default(),
Expand All @@ -62,6 +63,7 @@ fn test_serde() {
[config.global.experimental_features]
negative_impls = false
associated_item_constraints = false
coupons = false
[config.override.crate1]
Expand All @@ -71,6 +73,7 @@ fn test_serde() {
[config.override.crate1.experimental_features]
negative_impls = false
associated_item_constraints = false
coupons = false
[config.override.crate3]
Expand All @@ -80,6 +83,7 @@ fn test_serde() {
[config.override.crate3.experimental_features]
negative_impls = true
associated_item_constraints = false
coupons = false
"# });
assert_eq!(config, toml::from_str(&serialized).unwrap());
Expand All @@ -95,6 +99,7 @@ fn test_serde_defaults() {
[config.global.experimental_features]
negative_impls = false
associated_item_constraints = false
"# };
let result = indoc! { r#"
[crate_roots]
Expand All @@ -106,6 +111,7 @@ fn test_serde_defaults() {
[config.global.experimental_features]
negative_impls = false
associated_item_constraints = false
coupons = false
[config.override]
Expand Down
28 changes: 28 additions & 0 deletions crates/cairo-lang-semantic/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::corelib::LiteralError;
use crate::db::SemanticGroup;
use crate::expr::inference::InferenceError;
use crate::items::feature_kind::FeatureMarkerDiagnostic;
use crate::items::trt::ConcreteTraitTypeId;
use crate::resolve::{ResolvedConcreteItem, ResolvedGenericItem};
use crate::types::peel_snapshots;
use crate::{ConcreteTraitId, semantic};
Expand Down Expand Up @@ -923,6 +924,25 @@ impl DiagnosticEntry for SemanticDiagnostic {
SemanticDiagnosticKind::MutableCapturedVariable => {
"Capture of mutable variables in a closure is not supported".into()
}
SemanticDiagnosticKind::NonTraitTypeConstrained { identifier, concrete_trait_id } => {
format!(
"associated type `{}` not found for `{}`",
identifier,
concrete_trait_id.full_path(db)
)
}
SemanticDiagnosticKind::DuplicateTypeConstraint {
concrete_trait_type_id: trait_type_id,
} => {
format!(
"the value of the associated type `{}` in trait `{}` is already specified",
trait_type_id.trait_type(db).name(db.upcast()),
trait_type_id.concrete_trait(db).full_path(db)
)
}
SemanticDiagnosticKind::TypeConstraintsSyntaxNotEnabled => {
"Type constraints syntax is not enabled in the current crate.".into()
}
}
}

Expand Down Expand Up @@ -1297,6 +1317,14 @@ pub enum SemanticDiagnosticKind {
},
RefClosureArgument,
MutableCapturedVariable,
NonTraitTypeConstrained {
identifier: SmolStr,
concrete_trait_id: ConcreteTraitId,
},
DuplicateTypeConstraint {
concrete_trait_type_id: ConcreteTraitTypeId,
},
TypeConstraintsSyntaxNotEnabled,
}

/// The kind of an expression with multiple possible return types.
Expand Down
14 changes: 12 additions & 2 deletions crates/cairo-lang-semantic/src/expr/compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ use crate::items::constant::{ConstValue, resolve_const_expr_and_evaluate};
use crate::items::enm::SemanticEnumEx;
use crate::items::feature_kind::extract_item_feature_config;
use crate::items::functions::function_signature_params;
use crate::items::imp::{filter_candidate_traits, infer_impl_by_self};
use crate::items::imp::{ImplLongId, filter_candidate_traits, infer_impl_by_self};
use crate::items::modifiers::compute_mutability;
use crate::items::us::get_use_path_segments;
use crate::items::visibility;
Expand All @@ -77,7 +77,7 @@ use crate::resolve::{
use crate::semantic::{self, Binding, FunctionId, LocalVariable, TypeId, TypeLongId};
use crate::substitution::SemanticRewriter;
use crate::types::{
ClosureTypeLongId, ConcreteTypeId, add_type_based_diagnostics, are_coupons_enabled,
ClosureTypeLongId, ConcreteTypeId, ImplTypeId, add_type_based_diagnostics, are_coupons_enabled,
extract_fixed_size_array_size, peel_snapshots, peel_snapshots_ex,
resolve_type_with_environment, verify_fixed_size_array_size, wrap_in_snapshots,
};
Expand Down Expand Up @@ -1051,6 +1051,16 @@ pub fn compute_root_expr(
let Ok(concrete_trait_id) = imp.concrete_trait else {
continue;
};
for (concrete_trait_type_id, ty1) in imp.type_constraints {
let trait_ty = concrete_trait_type_id.trait_type(ctx.db);
let impl_type = ImplTypeId::new(
ImplLongId::GenericParameter(*param).intern(ctx.db),
trait_ty,
ctx.db,
);
let ty0 = inference.impl_type_assignment(impl_type);
inference.conform_ty(ty0, ty1).ok();
}
let ConcreteTraitLongId { trait_id, generic_args } =
concrete_trait_id.lookup_intern(ctx.db);
if crate::corelib::fn_traits(ctx.db).contains(&trait_id) {
Expand Down
2 changes: 1 addition & 1 deletion crates/cairo-lang-semantic/src/expr/inference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,7 @@ impl<'db> Inference<'db> {
})
.map(|generic_param| {
rewriter
.rewrite(*generic_param)
.rewrite(generic_param.clone())
.and_then(|generic_param| generic_param.concrete_trait)
});
validate_no_solution_set(self, canonical_impl, lookup_context, concrete_traits)
Expand Down
18 changes: 12 additions & 6 deletions crates/cairo-lang-semantic/src/expr/inference/infers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ impl InferenceEmbeddings for Inference<'_> {
let mut substitution = GenericSubstitution::default();
for generic_param in generic_params {
let generic_param = SubstitutionRewriter { db: self.db, substitution: &substitution }
.rewrite(*generic_param)
.rewrite(generic_param.clone())
.map_err(|diag_added| self.set_error(InferenceError::Reported(diag_added)))?;
let generic_arg =
self.infer_generic_arg(&generic_param, lookup_context.clone(), stable_ptr)?;
Expand Down Expand Up @@ -374,11 +374,17 @@ impl InferenceEmbeddings for Inference<'_> {
let concrete_trait_id = param
.concrete_trait
.map_err(|diag_added| self.set_error(InferenceError::Reported(diag_added)))?;
Ok(GenericArgumentId::Impl(self.new_impl_var(
concrete_trait_id,
stable_ptr,
lookup_context,
)))
let impl_id = self.new_impl_var(concrete_trait_id, stable_ptr, lookup_context);
for (trait_ty, ty1) in param.type_constraints.iter() {
let ty0 = self.reduce_impl_ty(ImplTypeId::new(
impl_id,
trait_ty.trait_type(self.db),
self.db,
))?;
// Conforming the type will always work as the impl is a new inference variable.
self.conform_ty(ty0, *ty1).ok();
}
Ok(GenericArgumentId::Impl(impl_id))
}
GenericParam::Const(GenericParamConst { ty, .. }) => {
Ok(GenericArgumentId::Constant(self.new_const_var(stable_ptr, *ty)))
Expand Down
1 change: 1 addition & 0 deletions crates/cairo-lang-semantic/src/expr/test_data/coupon
Original file line number Diff line number Diff line change
Expand Up @@ -244,4 +244,5 @@ edition = "2023_01"

[experimental_features]
negative_impls = false
associated_item_constraints = false
coupons = false
Loading

0 comments on commit 334dd97

Please sign in to comment.