Skip to content

Commit ee5afc0

Browse files
bors[bot]philberty
andauthored
Merge #381
381: Fix crash on empty parameters to generic data type r=philberty a=philberty When no parameters are passed to generic data types we cannot properly infer the usage of the generic block. This brings in a canonicalized check for `rustc --explain E0107` Fixes #379 Co-authored-by: Philip Herron <[email protected]>
2 parents 498758a + bb103b6 commit ee5afc0

File tree

7 files changed

+86
-54
lines changed

7 files changed

+86
-54
lines changed

gcc/rust/hir/tree/rust-hir-path.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,11 @@ struct GenericArgs
165165
GenericArgs &operator= (GenericArgs &&other) = default;
166166

167167
// Creates an empty GenericArgs (no arguments)
168-
static GenericArgs create_empty ()
168+
static GenericArgs create_empty (Location locus = Location ())
169169
{
170170
return GenericArgs (std::vector<Lifetime> (),
171171
std::vector<std::unique_ptr<Type> > (),
172-
std::vector<GenericArgsBinding> ());
172+
std::vector<GenericArgsBinding> (), locus);
173173
}
174174

175175
bool is_empty () const

gcc/rust/typecheck/rust-hir-type-check-toplevel.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,7 @@ class TypeCheckTopLevel : public TypeCheckBase
214214
auto self
215215
= TypeCheckType::Resolve (impl_block.get_type ().get (), &substitutions);
216216
if (self == nullptr || self->get_kind () == TyTy::TypeKind::ERROR)
217-
{
218-
rust_error_at (impl_block.get_locus (), "failed to resolve impl type");
219-
return;
220-
}
217+
return;
221218

222219
for (auto &impl_item : impl_block.get_impl_items ())
223220
TypeCheckTopLevelImplItem::Resolve (impl_item.get (), self,

gcc/rust/typecheck/rust-hir-type-check-type.h

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class TypeCheckResolveGenericArguments : public TypeCheckBase
7272
public:
7373
static HIR::GenericArgs resolve (HIR::TypePathSegment *segment)
7474
{
75-
TypeCheckResolveGenericArguments resolver;
75+
TypeCheckResolveGenericArguments resolver (segment->get_locus ());
7676
segment->accept_vis (resolver);
7777
return resolver.args;
7878
};
@@ -83,8 +83,8 @@ class TypeCheckResolveGenericArguments : public TypeCheckBase
8383
}
8484

8585
private:
86-
TypeCheckResolveGenericArguments ()
87-
: TypeCheckBase (), args (HIR::GenericArgs::create_empty ())
86+
TypeCheckResolveGenericArguments (Location locus)
87+
: TypeCheckBase (), args (HIR::GenericArgs::create_empty (locus))
8888
{}
8989

9090
HIR::GenericArgs args;
@@ -165,57 +165,57 @@ class TypeCheckType : public TypeCheckBase
165165
return;
166166
}
167167

168-
// reverse lookup the hir node from ast node id
169168
HirId hir_lookup;
170-
if (context->lookup_type_by_node_id (ref, &hir_lookup))
169+
if (!context->lookup_type_by_node_id (ref, &hir_lookup))
171170
{
172-
// we got an HIR node
173-
if (context->lookup_type (hir_lookup, &translated))
174-
{
175-
translated = translated->clone ();
176-
auto ref = path.get_mappings ().get_hirid ();
177-
translated->set_ref (ref);
178-
179-
HIR::TypePathSegment *final_seg = path.get_final_segment ();
180-
HIR::GenericArgs args
181-
= TypeCheckResolveGenericArguments::resolve (final_seg);
182-
183-
bool path_declared_generic_arguments = !args.is_empty ();
184-
if (path_declared_generic_arguments)
185-
{
186-
if (translated->has_subsititions_defined ())
187-
{
188-
translated
189-
= SubstMapper::Resolve (translated, path.get_locus (),
190-
&args);
191-
if (translated->get_kind () != TyTy::TypeKind::ERROR
192-
&& mappings != nullptr)
193-
{
194-
check_for_unconstrained (args.get_type_args ());
195-
}
196-
}
197-
else
198-
{
199-
rust_error_at (
200-
path.get_locus (),
201-
"TypePath %s declares generic argument's but "
202-
"the type %s does not have any",
203-
path.as_string ().c_str (),
204-
translated->as_string ().c_str ());
205-
}
206-
}
207-
else if (translated->has_subsititions_defined ())
208-
{
209-
translated
210-
= SubstMapper::InferSubst (translated, path.get_locus ());
211-
}
171+
rust_error_at (path.get_locus (), "failed to lookup HIR node");
172+
return;
173+
}
174+
175+
TyTy::BaseType *lookup = nullptr;
176+
if (!context->lookup_type (hir_lookup, &lookup))
177+
{
178+
rust_error_at (path.get_locus (), "failed to lookup HIR TyTy");
179+
return;
180+
}
181+
182+
TyTy::BaseType *path_type = lookup->clone ();
183+
path_type->set_ref (path.get_mappings ().get_hirid ());
184+
185+
HIR::TypePathSegment *final_seg = path.get_final_segment ();
186+
HIR::GenericArgs args
187+
= TypeCheckResolveGenericArguments::resolve (final_seg);
188+
189+
bool is_big_self = final_seg->is_ident_only ()
190+
&& (final_seg->as_string ().compare ("Self") == 0);
212191

192+
if (path_type->needs_generic_substitutions ())
193+
{
194+
if (is_big_self)
195+
{
196+
translated = path_type;
213197
return;
214198
}
215-
}
216199

217-
rust_error_at (path.get_locus (), "failed to type-resolve TypePath: %s",
218-
path.as_string ().c_str ());
200+
translated = SubstMapper::Resolve (path_type, path.get_locus (), &args);
201+
if (translated->get_kind () != TyTy::TypeKind::ERROR
202+
&& mappings != nullptr)
203+
{
204+
check_for_unconstrained (args.get_type_args ());
205+
}
206+
}
207+
else if (!args.is_empty ())
208+
{
209+
rust_error_at (path.get_locus (),
210+
"TypePath %s declares generic argument's but "
211+
"the type %s does not have any",
212+
path.as_string ().c_str (),
213+
translated->as_string ().c_str ());
214+
}
215+
else
216+
{
217+
translated = path_type;
218+
}
219219
}
220220

221221
void visit (HIR::ArrayType &type) override

gcc/rust/typecheck/rust-substitution-mapper.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ class SubstMapper : public TyTy::TyVisitor
5757
{
5858
TyTy::SubstitutionArgumentMappings mappings
5959
= type.get_mappings_from_generic_args (*generics);
60+
if (mappings.is_error ())
61+
return;
62+
6063
concrete = type.handle_substitions (mappings);
6164
}
6265

@@ -77,6 +80,9 @@ class SubstMapper : public TyTy::TyVisitor
7780
{
7881
TyTy::SubstitutionArgumentMappings mappings
7982
= type.get_mappings_from_generic_args (*generics);
83+
if (mappings.is_error ())
84+
return;
85+
8086
concrete = type.handle_substitions (mappings);
8187
}
8288

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
struct Foo<A>(A);
2+
3+
fn main() {
4+
let a: Foo = Foo::<i32>(123);
5+
// { dg-error "Invalid number of generic arguments to generic type" "" { target { *-*-* } } .-1 }
6+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
struct Foo<A>(A);
2+
3+
impl Foo {
4+
// { dg-error "Invalid number of generic arguments to generic type" "" { target { *-*-* } } .-1 }
5+
fn test() -> i32 {
6+
123
7+
}
8+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
struct Foo<A, B>(A, B);
2+
3+
impl<T> Foo<i32, T> {
4+
fn test(a: T) -> T { // { dg-error "duplicate definitions with name test" }
5+
a
6+
}
7+
}
8+
9+
impl Foo<i32, f32> {
10+
fn test() -> f32 { // { dg-error "duplicate definitions with name test" }
11+
123f32
12+
}
13+
}
14+
15+
fn main() {}

0 commit comments

Comments
 (0)