Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Mapping::find_match to return error when multiple replacements are possible. #5540

Open
esdrubal opened this issue Feb 2, 2024 · 2 comments · May be fixed by #5610
Open

Improve Mapping::find_match to return error when multiple replacements are possible. #5540

esdrubal opened this issue Feb 2, 2024 · 2 comments · May be fixed by #5610
Labels
compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen

Comments

@esdrubal
Copy link
Contributor

esdrubal commented Feb 2, 2024

The following code should return an error when multiple replacements can be done.

pub(crate) fn find_match(&self, decl_ref: SourceDecl) -> Option<DestinationDecl> {
for (source_decl_ref, dest_decl_ref) in self.mapping.iter() {
if *source_decl_ref == decl_ref {
return Some(dest_decl_ref.clone());
}
}
None
}

@esdrubal esdrubal added the compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen label Feb 2, 2024
@AbhinavMir
Copy link

AbhinavMir commented Feb 11, 2024

Hi @esdrubal ! Started some light work on this, how can I quickly test if I'm in the right direction? Thanks!

@esdrubal
Copy link
Contributor Author

Hi @AbhinavMir, the current Mapping::find_match looks a bit different now:

pub(crate) fn find_match(
&self,
_handler: &Handler,
engines: &Engines,
decl_ref: AssociatedItemDeclId,
typeid: Option<TypeId>,
self_typeid: Option<TypeId>,
) -> Result<Option<DestinationDecl>, ErrorEmitted> {
let mut dest_decl_refs = HashSet::<DestinationDecl>::new();
if let Some(mut typeid) = typeid {
if engines.te().get(typeid).is_self_type() && self_typeid.is_some() {
// If typeid is `Self`, then we use the self_typeid instead.
typeid = self_typeid.unwrap();
}
for (source_decl_ref, dest_decl_ref) in self.mapping.iter() {
let unify_check = UnifyCheck::non_dynamic_equality(engines);
if source_decl_ref.0 == decl_ref && unify_check.check(source_decl_ref.1, typeid) {
dest_decl_refs.insert(dest_decl_ref.clone());
}
}
}
// At most one replacement should be found for decl_ref.
/* TODO uncomment this and close issue #5540
if dest_decl_refs.len() > 1 {
handler.emit_err(CompileError::InternalOwned(
format!(
"Multiple replacements for decl {} implemented in {}",
engines.help_out(decl_ref),
engines.help_out(typeid),
),
dest_decl_refs.iter().last().unwrap().span(engines),
));
}*/
Ok(dest_decl_refs.iter().next().cloned())
}

If you do cargo run --bin test --release -- there will be some errors after you uncomment the code above. When those errors are fixed it should be good to go. When I looked at it there was an issue related to repeated TraitConstraints adding multiple times the same bindings, it will require some printing around the code and debugging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants