return resolver.lookup_path (path);
}
+HIR::Trait *
+TraitResolver::ResolveHirItem (const HIR::TypePath &path)
+{
+ TraitResolver resolver;
+
+ HIR::Trait *lookup = nullptr;
+ bool ok = resolver.resolve_path_to_trait (path, &lookup);
+ return ok ? lookup : nullptr;
+}
+
TraitResolver::TraitResolver () : TypeCheckBase () {}
bool
static TraitReference *Lookup (HIR::TypePath &path);
+ static HIR::Trait *ResolveHirItem (const HIR::TypePath &path);
+
private:
TraitResolver ();
// is it an impl_type?
if (auto impl_block_by_type = mappings.lookup_impl_block_type (reference))
{
- *result
- = TypeCheckItem::ResolveImplBlockSelf (*impl_block_by_type.value ());
+ // found an impl item
+ HIR::ImplBlock *impl = impl_block_by_type.value ();
+ rust_debug_loc (impl->get_locus (), "resolved impl block type {%u} to",
+ reference);
+ *result = TypeCheckItem::ResolveImplBlockSelf (*impl);
context->query_completed (reference);
return true;
}
#include "rust-hir-type-bounds.h"
#include "rust-hir-trait-resolve.h"
#include "rust-substitution-mapper.h"
+#include "rust-hir-trait-resolve.h"
#include "rust-type-util.h"
namespace Rust {
if (!impl->has_trait_ref ())
return true;
+ // can be recursive trait resolution
+ HIR::Trait *t = TraitResolver::ResolveHirItem (impl->get_trait_ref ());
+ if (t == nullptr)
+ return true;
+ DefId trait_id = t->get_mappings ().get_defid ();
+ if (context->trait_query_in_progress (trait_id))
+ return true;
+
HirId impl_ty_id = impl->get_type ().get_mappings ().get_hirid ();
TyTy::BaseType *impl_type = nullptr;
if (!query_type (impl_ty_id, &impl_type))
if (identifier.compare (other.identifier) != 0)
return false;
- if (discriminant != other.discriminant)
- return false;
-
if (fields.size () != other.fields.size ())
return false;
--- /dev/null
+/* { dg-output "child\r*\n" }*/
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+struct Foo {
+ my_int: u32,
+ // { dg-warning "field is never read: .my_int." "" { target *-*-* } .-1 }
+}
+
+trait Parent<T> {
+ fn parent(&self) -> T;
+}
+
+trait Child: Parent<u32> {
+ fn child(&self);
+}
+
+impl Parent<u32> for Foo {
+ fn parent(&self) -> u32 {
+ unsafe {
+ let parent = "parent %i\n\0";
+ let msg = parent as *const str;
+ printf(msg as *const i8, self.my_int);
+ return self.my_int;
+ }
+ }
+}
+
+impl Child for Foo {
+ fn child(&self) {
+ let _ = self;
+ unsafe {
+ let child = "child\n\0";
+ let msg = child as *const str;
+ printf(msg as *const i8);
+ }
+ }
+}
+
+pub fn main() -> i32 {
+ let a = Foo { my_int: 0xf00dfeed };
+ let b: &dyn Child = &a;
+
+ // b.parent();
+ b.child();
+
+ 0
+}