Skip to content

Commit b79f368

Browse files
committed
Added better support for concrete trait by output type.
1 parent 536872b commit b79f368

File tree

3 files changed

+48
-20
lines changed

3 files changed

+48
-20
lines changed

crates/cairo-lang-semantic/src/expr/inference.rs

+24-19
Original file line numberDiff line numberDiff line change
@@ -913,29 +913,34 @@ impl<'db> Inference<'db> {
913913
let concrete_trait_id = self.rewrite(concrete_trait_id).no_err();
914914
enrich_lookup_context(self.db, concrete_trait_id, &mut lookup_context);
915915

916-
// Don't try to resolve impls if the first generic param is a variable.
917-
let generic_args = concrete_trait_id.generic_args(self.db);
918-
match generic_args.first() {
919-
Some(GenericArgumentId::Type(ty)) => {
920-
if let TypeLongId::Var(_) = ty.lookup_intern(self.db) {
921-
// Don't try to infer such impls.
922-
return Ok(SolutionSet::Ambiguous(Ambiguity::WillNotInfer(concrete_trait_id)));
916+
// If has any type assignments, we can try to resolve it, even if first generic arg is a
917+
// var.
918+
if !impl_var_trait_item_mappings
919+
.types
920+
.iter()
921+
.any(|(_, ty)| ty.is_var_free(self.db) && !ty.is_missing(self.db))
922+
{
923+
// Don't try to resolve impls if the first generic param is a variable.
924+
let dont_infer = Ok(SolutionSet::Ambiguous(Ambiguity::WillNotInfer(concrete_trait_id)));
925+
match concrete_trait_id.generic_args(self.db).first() {
926+
Some(GenericArgumentId::Type(ty))
927+
if matches!(ty.lookup_intern(self.db), TypeLongId::Var(_)) =>
928+
{
929+
return dont_infer;
923930
}
924-
}
925-
Some(GenericArgumentId::Impl(imp)) => {
926-
// Don't try to infer such impls.
927-
if let ImplLongId::ImplVar(_) = imp.lookup_intern(self.db) {
928-
return Ok(SolutionSet::Ambiguous(Ambiguity::WillNotInfer(concrete_trait_id)));
931+
Some(GenericArgumentId::Impl(imp))
932+
if matches!(imp.lookup_intern(self.db), ImplLongId::ImplVar(_)) =>
933+
{
934+
return dont_infer;
929935
}
930-
}
931-
Some(GenericArgumentId::Constant(const_value)) => {
932-
if let ConstValue::Var(_, _) = const_value.lookup_intern(self.db) {
933-
// Don't try to infer such impls.
934-
return Ok(SolutionSet::Ambiguous(Ambiguity::WillNotInfer(concrete_trait_id)));
936+
Some(GenericArgumentId::Constant(const_value))
937+
if matches!(const_value.lookup_intern(self.db), ConstValue::Var(_, _)) =>
938+
{
939+
return dont_infer;
935940
}
941+
_ => {}
936942
}
937-
_ => {}
938-
};
943+
}
939944
let (canonical_trait, canonicalizer) = CanonicalTrait::canonicalize(
940945
self.db,
941946
self.inference_id,

crates/cairo-lang-semantic/src/expr/test_data/closure

+1-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ fn baz<T, +core::ops::FnOnce<T, (u32,)>>(c: T) -> core::ops::FnOnce::<T, (u32,)>
390390
}
391391

392392
//! > expected_diagnostics
393-
error: Trait has no implementation in context: core::ops::function::Fn::<core::felt252, ()>.
393+
error: Inference cycle detected
394394
--> lib.cairo:7:19
395395
let _x: u32 = bar();
396396
^^^^^

crates/cairo-lang-semantic/src/expr/test_data/inference

+23
Original file line numberDiff line numberDiff line change
@@ -755,3 +755,26 @@ error: Type annotations needed. Failed to infer ?0.
755755
--> lib.cairo:1:13
756756
fn foo() -> Option {
757757
^^^^^^
758+
759+
//! > ==========================================================================
760+
761+
//! > Impl resolution by type.
762+
763+
//! > test_runner_name
764+
test_function_diagnostics(expect_diagnostics: false)
765+
766+
//! > function
767+
fn foo() {
768+
let _u32: u32 = 2.pow(5);
769+
const _U32: u32 = 2.pow(5);
770+
let _felt252: felt252 = 2.pow(5);
771+
const _FELT252: felt252 = 2.pow(5);
772+
}
773+
774+
//! > function_name
775+
foo
776+
777+
//! > module_code
778+
use core::num::traits::Pow;
779+
780+
//! > expected_diagnostics

0 commit comments

Comments
 (0)