diff options
7 files changed, 86 insertions, 54 deletions
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h index d6f9fc0..262a04a 100644 --- a/gcc/rust/hir/tree/rust-hir-path.h +++ b/gcc/rust/hir/tree/rust-hir-path.h @@ -165,11 +165,11 @@ public: GenericArgs &operator= (GenericArgs &&other) = default; // Creates an empty GenericArgs (no arguments) - static GenericArgs create_empty () + static GenericArgs create_empty (Location locus = Location ()) { return GenericArgs (std::vector<Lifetime> (), std::vector<std::unique_ptr<Type> > (), - std::vector<GenericArgsBinding> ()); + std::vector<GenericArgsBinding> (), locus); } bool is_empty () const diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h index 356faa6..8b23920 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h +++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h @@ -214,10 +214,7 @@ public: auto self = TypeCheckType::Resolve (impl_block.get_type ().get (), &substitutions); if (self == nullptr || self->get_kind () == TyTy::TypeKind::ERROR) - { - rust_error_at (impl_block.get_locus (), "failed to resolve impl type"); - return; - } + return; for (auto &impl_item : impl_block.get_impl_items ()) TypeCheckTopLevelImplItem::Resolve (impl_item.get (), self, diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h index 6556947..5c21d5a 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.h +++ b/gcc/rust/typecheck/rust-hir-type-check-type.h @@ -72,7 +72,7 @@ class TypeCheckResolveGenericArguments : public TypeCheckBase public: static HIR::GenericArgs resolve (HIR::TypePathSegment *segment) { - TypeCheckResolveGenericArguments resolver; + TypeCheckResolveGenericArguments resolver (segment->get_locus ()); segment->accept_vis (resolver); return resolver.args; }; @@ -83,8 +83,8 @@ public: } private: - TypeCheckResolveGenericArguments () - : TypeCheckBase (), args (HIR::GenericArgs::create_empty ()) + TypeCheckResolveGenericArguments (Location locus) + : TypeCheckBase (), args (HIR::GenericArgs::create_empty (locus)) {} HIR::GenericArgs args; @@ -165,57 +165,57 @@ public: return; } - // reverse lookup the hir node from ast node id HirId hir_lookup; - if (context->lookup_type_by_node_id (ref, &hir_lookup)) + if (!context->lookup_type_by_node_id (ref, &hir_lookup)) { - // we got an HIR node - if (context->lookup_type (hir_lookup, &translated)) - { - translated = translated->clone (); - auto ref = path.get_mappings ().get_hirid (); - translated->set_ref (ref); - - HIR::TypePathSegment *final_seg = path.get_final_segment (); - HIR::GenericArgs args - = TypeCheckResolveGenericArguments::resolve (final_seg); - - bool path_declared_generic_arguments = !args.is_empty (); - if (path_declared_generic_arguments) - { - if (translated->has_subsititions_defined ()) - { - translated - = SubstMapper::Resolve (translated, path.get_locus (), - &args); - if (translated->get_kind () != TyTy::TypeKind::ERROR - && mappings != nullptr) - { - check_for_unconstrained (args.get_type_args ()); - } - } - else - { - rust_error_at ( - path.get_locus (), - "TypePath %s declares generic argument's but " - "the type %s does not have any", - path.as_string ().c_str (), - translated->as_string ().c_str ()); - } - } - else if (translated->has_subsititions_defined ()) - { - translated - = SubstMapper::InferSubst (translated, path.get_locus ()); - } + rust_error_at (path.get_locus (), "failed to lookup HIR node"); + return; + } + + TyTy::BaseType *lookup = nullptr; + if (!context->lookup_type (hir_lookup, &lookup)) + { + rust_error_at (path.get_locus (), "failed to lookup HIR TyTy"); + return; + } + + TyTy::BaseType *path_type = lookup->clone (); + path_type->set_ref (path.get_mappings ().get_hirid ()); + + HIR::TypePathSegment *final_seg = path.get_final_segment (); + HIR::GenericArgs args + = TypeCheckResolveGenericArguments::resolve (final_seg); + + bool is_big_self = final_seg->is_ident_only () + && (final_seg->as_string ().compare ("Self") == 0); + if (path_type->needs_generic_substitutions ()) + { + if (is_big_self) + { + translated = path_type; return; } - } - rust_error_at (path.get_locus (), "failed to type-resolve TypePath: %s", - path.as_string ().c_str ()); + translated = SubstMapper::Resolve (path_type, path.get_locus (), &args); + if (translated->get_kind () != TyTy::TypeKind::ERROR + && mappings != nullptr) + { + check_for_unconstrained (args.get_type_args ()); + } + } + else if (!args.is_empty ()) + { + rust_error_at (path.get_locus (), + "TypePath %s declares generic argument's but " + "the type %s does not have any", + path.as_string ().c_str (), + translated->as_string ().c_str ()); + } + else + { + translated = path_type; + } } void visit (HIR::ArrayType &type) override diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h index bc20e4b..cd04b0e 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.h +++ b/gcc/rust/typecheck/rust-substitution-mapper.h @@ -57,6 +57,9 @@ public: { TyTy::SubstitutionArgumentMappings mappings = type.get_mappings_from_generic_args (*generics); + if (mappings.is_error ()) + return; + concrete = type.handle_substitions (mappings); } @@ -77,6 +80,9 @@ public: { TyTy::SubstitutionArgumentMappings mappings = type.get_mappings_from_generic_args (*generics); + if (mappings.is_error ()) + return; + concrete = type.handle_substitions (mappings); } diff --git a/gcc/testsuite/rust.test/xfail_compile/expected_type_args2.rs b/gcc/testsuite/rust.test/xfail_compile/expected_type_args2.rs new file mode 100644 index 0000000..b92c48f --- /dev/null +++ b/gcc/testsuite/rust.test/xfail_compile/expected_type_args2.rs @@ -0,0 +1,6 @@ +struct Foo<A>(A); + +fn main() { + let a: Foo = Foo::<i32>(123); + // { dg-error "Invalid number of generic arguments to generic type" "" { target { *-*-* } } .-1 } +} diff --git a/gcc/testsuite/rust.test/xfail_compile/expected_type_args3.rs b/gcc/testsuite/rust.test/xfail_compile/expected_type_args3.rs new file mode 100644 index 0000000..4c164ff --- /dev/null +++ b/gcc/testsuite/rust.test/xfail_compile/expected_type_args3.rs @@ -0,0 +1,8 @@ +struct Foo<A>(A); + +impl Foo { + // { dg-error "Invalid number of generic arguments to generic type" "" { target { *-*-* } } .-1 } + fn test() -> i32 { + 123 + } +} diff --git a/gcc/testsuite/rust.test/xfail_compile/generics8.rs b/gcc/testsuite/rust.test/xfail_compile/generics8.rs new file mode 100644 index 0000000..70bad1a --- /dev/null +++ b/gcc/testsuite/rust.test/xfail_compile/generics8.rs @@ -0,0 +1,15 @@ +struct Foo<A, B>(A, B); + +impl<T> Foo<i32, T> { + fn test(a: T) -> T { // { dg-error "duplicate definitions with name test" } + a + } +} + +impl Foo<i32, f32> { + fn test() -> f32 { // { dg-error "duplicate definitions with name test" } + 123f32 + } +} + +fn main() {} |