Skip to content

Commit 9bfc436

Browse files
committed
Gather trait impls from the argument type module when handling trait operator calls.
Fixes #7330.
1 parent ab5ba9a commit 9bfc436

File tree

10 files changed

+97
-2
lines changed

10 files changed

+97
-2
lines changed

sway-core/src/language/call_path.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,13 @@ impl CallPath {
375375
.collect::<Vec<_>>()
376376
}
377377

378+
pub fn as_vec_ident(&self) -> Vec<Ident> {
379+
self.as_vec_string()
380+
.iter()
381+
.map(|s| Ident::new_no_span(s.clone()))
382+
.collect::<Vec<_>>()
383+
}
384+
378385
/// Create a full [CallPath] from a given [Ident] and the [Namespace] in which the [Ident] is
379386
/// declared.
380387
///

sway-core/src/language/ty/expression/expression_variant.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,7 @@ impl ReplaceDecls for TyExpressionVariant {
873873
method.return_type.type_id(),
874874
&arguments_types,
875875
None,
876+
false
876877
)?;
877878
method = (*decl_engine.get(&implementing_type_method_ref)).clone();
878879
}

sway-core/src/semantic_analysis/ast_node/declaration/abi.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ impl ty::TyAbiDecl {
114114
ctx.type_annotation(),
115115
&[],
116116
None,
117+
false,
117118
) {
118119
let superabi_impl_method =
119120
ctx.engines.de().get_function(&superabi_impl_method_ref);
@@ -280,6 +281,7 @@ impl ty::TyAbiDecl {
280281
ctx.type_annotation(),
281282
&[],
282283
None,
284+
false,
283285
) {
284286
let superabi_method =
285287
ctx.engines.de().get_function(&superabi_method_ref);
@@ -354,6 +356,7 @@ impl ty::TyAbiDecl {
354356
ctx.type_annotation(),
355357
&[],
356358
None,
359+
false,
357360
) {
358361
let superabi_impl_method =
359362
ctx.engines.de().get_function(&superabi_impl_method_ref);

sway-core/src/semantic_analysis/ast_node/expression/typed_expression/method_application.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,7 @@ pub(crate) fn resolve_method_name(
934934
ctx.type_annotation(),
935935
arguments_types,
936936
None,
937+
false,
937938
)?;
938939

939940
(decl_ref, type_id)
@@ -978,6 +979,7 @@ pub(crate) fn resolve_method_name(
978979
ctx.type_annotation(),
979980
arguments_types,
980981
None,
982+
true
981983
)?;
982984

983985
(decl_ref, type_id)
@@ -1001,6 +1003,7 @@ pub(crate) fn resolve_method_name(
10011003
ctx.type_annotation(),
10021004
arguments_types,
10031005
None,
1006+
false,
10041007
)?;
10051008

10061009
(decl_ref, type_id)
@@ -1025,6 +1028,7 @@ pub(crate) fn resolve_method_name(
10251028
ctx.type_annotation(),
10261029
arguments_types,
10271030
Some(*as_trait),
1031+
false,
10281032
)?;
10291033

10301034
(decl_ref, type_id)

sway-core/src/semantic_analysis/type_check_context.rs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
use std::collections::{btree_map::Entry, BTreeMap, HashSet};
33

44
use crate::{
5+
ast_elements::type_argument::GenericTypeArgument,
56
decl_engine::{DeclEngineGet, DeclRefFunction, MaterializeConstGenerics},
67
engine_threading::*,
78
language::{
@@ -11,7 +12,7 @@ use crate::{
1112
},
1213
monomorphization::{monomorphize_with_modpath, MonomorphizeHelper},
1314
namespace::{
14-
IsExtendingExistingImpl, IsImplSelf, ModulePath, ResolvedDeclaration,
15+
IsExtendingExistingImpl, IsImplSelf, Module, ModulePath, ResolvedDeclaration,
1516
ResolvedTraitImplItem, TraitMap,
1617
},
1718
semantic_analysis::{
@@ -735,6 +736,7 @@ impl<'a> TypeCheckContext<'a> {
735736
type_id: TypeId,
736737
item_prefix: &ModulePath,
737738
item_name: &Ident,
739+
from_trait: bool,
738740
) -> Result<Vec<ty::TyTraitItem>, ErrorEmitted> {
739741
let type_engine = self.engines.te();
740742

@@ -796,6 +798,19 @@ impl<'a> TypeCheckContext<'a> {
796798
&mut filter_item,
797799
);
798800

801+
// grab the items from where the argument type is declared
802+
if from_trait {
803+
let type_module = self.get_namespace_module_from_type_id(type_id);
804+
if let Ok(type_module) = type_module {
805+
TraitMap::find_items_and_trait_key_for_type(
806+
type_module,
807+
self.engines,
808+
type_id,
809+
&mut filter_item,
810+
);
811+
}
812+
}
813+
799814
if item_prefix != self.namespace().current_mod_path.as_slice() {
800815
// grab the module where the type itself is declared
801816
let type_module = self
@@ -814,6 +829,35 @@ impl<'a> TypeCheckContext<'a> {
814829
Ok(matching_item_decl_refs)
815830
}
816831

832+
fn get_namespace_module_from_type_id(&self, type_id: TypeId) -> Result<&Module, ErrorEmitted> {
833+
let type_info = self.engines().te().get(type_id);
834+
if type_info.is_alias() {
835+
if let TypeInfo::Alias { ty, .. } = &*type_info {
836+
if let Some(GenericTypeArgument { type_id, .. }) = ty.as_type_argument() {
837+
return self.get_namespace_module_from_type_id(*type_id);
838+
}
839+
}
840+
}
841+
842+
let handler = Handler::default();
843+
let call_path = match *type_info {
844+
// TypeInfo::UntypedEnum(parsed_decl_id) => Some(self.engines().pe().get_struct(&parsed_decl_id).call_path),
845+
// TypeInfo::UntypedStruct(parsed_decl_id) => todo!(),
846+
TypeInfo::Enum(decl_id) => self.engines().de().get_enum(&decl_id).call_path.clone(),
847+
TypeInfo::Struct(decl_id) => self.engines().de().get_struct(&decl_id).call_path.clone(),
848+
_ => {
849+
return Err(handler.emit_err(CompileError::Internal(
850+
"No call path for type id",
851+
Span::dummy(),
852+
)))
853+
}
854+
};
855+
856+
let call_path = call_path.rshift();
857+
self.namespace()
858+
.require_module_from_absolute_path(&handler, &call_path.as_vec_ident())
859+
}
860+
817861
#[inline]
818862
fn default_numeric_if_needed(
819863
&self,
@@ -851,11 +895,13 @@ impl<'a> TypeCheckContext<'a> {
851895
method_prefix: &ModulePath,
852896
method_name: &Ident,
853897
annotation_type: TypeId,
898+
from_trait: bool,
854899
) -> Result<Vec<ty::TyTraitItem>, ErrorEmitted> {
855900
let type_engine = self.engines.te();
856901

857902
// Start with items for the concrete type.
858-
let mut items = self.find_items_for_type(handler, type_id, method_prefix, method_name)?;
903+
let mut items =
904+
self.find_items_for_type(handler, type_id, method_prefix, method_name, from_trait)?;
859905

860906
// Consider items from supersets indicated by the annotation return type.
861907
if !matches!(&*type_engine.get(annotation_type), TypeInfo::Unknown)
@@ -873,6 +919,7 @@ impl<'a> TypeCheckContext<'a> {
873919
inner,
874920
method_prefix,
875921
method_name,
922+
from_trait,
876923
)?);
877924
}
878925
}
@@ -1258,6 +1305,7 @@ impl<'a> TypeCheckContext<'a> {
12581305
annotation_type: TypeId,
12591306
arguments_types: &[TypeId],
12601307
as_trait: Option<TypeId>,
1308+
from_trait: bool,
12611309
) -> Result<DeclRefFunction, ErrorEmitted> {
12621310
let type_engine = self.engines.te();
12631311

@@ -1269,6 +1317,7 @@ impl<'a> TypeCheckContext<'a> {
12691317
method_prefix,
12701318
method_name,
12711319
annotation_type,
1320+
from_trait,
12721321
)?;
12731322

12741323
let matching_method_decl_refs = self.items_to_method_refs(matching_items);

sway-core/src/type_system/info.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,10 @@ impl TypeInfo {
13421342
matches!(self, TypeInfo::Array(_, _))
13431343
}
13441344

1345+
pub fn is_alias(&self) -> bool {
1346+
matches!(self, TypeInfo::Alias { .. })
1347+
}
1348+
13451349
pub fn is_contract(&self) -> bool {
13461350
matches!(self, TypeInfo::Contract)
13471351
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[[package]]
2+
name = "std"
3+
source = "path+from-root-AA6134FC2B337767"
4+
5+
[[package]]
6+
name = "trait_map_use_impl_in_scope"
7+
source = "member"
8+
dependencies = ["std"]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[project]
2+
name = "trait_map_use_impl_in_scope"
3+
authors = ["Fuel Labs <contact@fuel.sh>"]
4+
entry = "main.sw"
5+
license = "Apache-2.0"
6+
7+
[dependencies]
8+
std = { path = "../../../../../../sway-lib-std" }
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
script;
2+
3+
use std::time::Time;
4+
// use std::time::*;
5+
6+
pub fn main() {
7+
let duration = Time::now().duration_since(Time::from(0)).unwrap();
8+
let _ = duration + duration;
9+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
category = "compile"
2+
expected_warnings = 0

0 commit comments

Comments
 (0)