Skip to content

Commit 8610000

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

File tree

7 files changed

+80
-1
lines changed

7 files changed

+80
-1
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/semantic_analysis/type_check_context.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
use std::collections::{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::{
@@ -796,6 +797,19 @@ impl<'a> TypeCheckContext<'a> {
796797
&mut filter_item,
797798
);
798799

800+
// grab the items from where the argument type is declared
801+
if let Some(MethodName::FromTrait { .. }) = method_name {
802+
let type_module = self.get_namespace_module_from_type_id(type_id);
803+
if let Ok(type_module) = type_module {
804+
TraitMap::find_items_and_trait_key_for_type(
805+
type_module,
806+
self.engines,
807+
type_id,
808+
&mut filter_item,
809+
);
810+
}
811+
}
812+
799813
if item_prefix != self.namespace().current_mod_path.as_slice() {
800814
// grab the module where the type itself is declared
801815
let type_module = self
@@ -814,6 +828,33 @@ impl<'a> TypeCheckContext<'a> {
814828
Ok(matching_item_decl_refs)
815829
}
816830

831+
fn get_namespace_module_from_type_id(&self, type_id: TypeId) -> Result<&Module, ErrorEmitted> {
832+
let type_info = self.engines().te().get(type_id);
833+
if type_info.is_alias() {
834+
if let TypeInfo::Alias { ty, .. } = &*type_info {
835+
if let Some(GenericTypeArgument { type_id, .. }) = ty.as_type_argument() {
836+
return self.get_namespace_module_from_type_id(*type_id);
837+
}
838+
}
839+
}
840+
841+
let handler = Handler::default();
842+
let call_path = match *type_info {
843+
TypeInfo::Enum(decl_id) => self.engines().de().get_enum(&decl_id).call_path.clone(),
844+
TypeInfo::Struct(decl_id) => self.engines().de().get_struct(&decl_id).call_path.clone(),
845+
_ => {
846+
return Err(handler.emit_err(CompileError::Internal(
847+
"No call path for type id",
848+
Span::dummy(),
849+
)))
850+
}
851+
};
852+
853+
let call_path = call_path.rshift();
854+
self.namespace()
855+
.require_module_from_absolute_path(&handler, &call_path.as_vec_ident())
856+
}
857+
817858
#[inline]
818859
fn default_numeric_if_needed(
819860
&self,

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 <[email protected]>"]
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)