diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index c94c04a..a5bfbea 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -22,9 +22,9 @@ jobs: toolchain: nightly default: true - name: Install LLVM and Clang - uses: KyleMayes/install-llvm-action@v1 + uses: KyleMayes/install-llvm-action@v2 with: - version: "18.0" + version: "18.1.3" - name: Build compiler run: cargo build --verbose - name: Run tests diff --git a/src/ir/to_ir.rs b/src/ir/to_ir.rs index aa990bf..bdc896a 100644 --- a/src/ir/to_ir.rs +++ b/src/ir/to_ir.rs @@ -516,8 +516,15 @@ impl<'llvm, 'm> ToIR<'llvm, FunctionContext<'llvm, 'm, '_>> for Call { debug_assert!( self.function.read().unwrap().mangled_name.is_some() || self.function.read().unwrap().is_definition(), - "Generic function {} has no definition, inside this call: {}", + "Generic function {} {} has no definition, inside this call: {}", self.function.read().unwrap(), + self.function + .read() + .unwrap() + .tr + .as_ref() + .map(|tr| format!("from trait {}", tr.name())) + .unwrap_or_default(), self ); self.function.read().unwrap().to_ir(context) diff --git a/src/semantics/link_impls.rs b/src/semantics/link_impls.rs new file mode 100644 index 0000000..e855ae6 --- /dev/null +++ b/src/semantics/link_impls.rs @@ -0,0 +1,37 @@ +use derive_visitor::VisitorMut; +use log::debug; + +use crate::hir::{Call, Generic, Type}; + +use super::Context; + +#[derive(VisitorMut)] +#[visitor(Call(exit))] +pub struct TraitFunctionsLinker<'ctx, C: Context> { + context: &'ctx mut C, +} + +impl<'ctx, C: Context> TraitFunctionsLinker<'ctx, C> { + pub fn new(context: &'ctx mut C) -> Self { + Self { context } + } + + fn exit_call(&mut self, call: &mut Call) { + let f = call.function.read().unwrap(); + // FIXME: definition may be overrided + if f.is_generic() || !f.is_from_trait() || f.is_definition() { + return; + } + + debug!(target: "linking-trait-fn-from", "{f}"); + // Unknown type here is ok, because we don't have selfs any more + let real_impl = self + .context + .find_implementation(&f, &Type::Unknown) + .unwrap(); + drop(f); + + call.function = real_impl; + debug!(target: "linking-trait-fn-to", "{}", call.function); + } +} diff --git a/src/semantics/mod.rs b/src/semantics/mod.rs index a23e255..8749b8b 100644 --- a/src/semantics/mod.rs +++ b/src/semantics/mod.rs @@ -40,3 +40,6 @@ pub use unnamed::*; mod replace_self; pub use replace_self::*; + +mod link_impls; +pub use link_impls::*; diff --git a/src/semantics/to_hir.rs b/src/semantics/to_hir.rs index 7266ea3..b023587 100644 --- a/src/semantics/to_hir.rs +++ b/src/semantics/to_hir.rs @@ -15,7 +15,9 @@ use crate::hir::{ use crate::mutability::{Mutability, Mutable}; use crate::named::Named; use crate::semantics::clone::Clonner; -use crate::semantics::{InsertDestructors, ParameterNamer, TemporariesInserter}; +use crate::semantics::{ + InsertDestructors, ParameterNamer, TemporariesInserter, TraitFunctionsLinker, +}; use crate::syntax::{Identifier, Keyword, Ranged}; use crate::{AddSourceLocation, ErrVec, SourceLocation, WithSourceLocation}; @@ -975,6 +977,7 @@ impl ToHIR for ast::Module { debug!(target: &format!("{name}-hir"), "\n{:#}", module); trace!(target: "steps", "Running passes on `{}`", module.source_file.path().display()); module.drive_mut(&mut ParameterNamer::new()); + module.drive_mut(&mut TraitFunctionsLinker::new(context)); module.drive_mut(&mut Clonner::new(context)); module.drive_mut(&mut TemporariesInserter::new()); module.insert_destructors(context);