This commit is contained in:
Бондарев Иван 2019-10-04 13:37:47 +02:00
parent f2df27dd87
commit f1049a2b4e
6 changed files with 53 additions and 16 deletions

View file

@ -0,0 +1,6 @@
procedure p1<T1,T2>(a: T1; b: T2); where T1, T2: record;
begin end;
begin
p1(0, '');
end.

View file

@ -0,0 +1,7 @@
procedure p2<T1,T2,T3>(a: T1; b: T2; c: T3); where T1, T2: record; where T3: class;
begin
end;
begin
p2(2, 4, 6);
end.

19
TestSuite/where10.pas Normal file
View file

@ -0,0 +1,19 @@
procedure p1<T1,T2>(a: T1; b: T2); where T1, T2: record;
begin
end;
procedure p2<T1,T2,T3>(a: T1; b: T2; c: T3); where T1, T2: record; where T3: record;
begin
end;
procedure p3<T1>(a: T1); where T1: record;
begin
end;
type Digits = (one, two);
begin
p1(0, 2);
p2(2, 4, 6);
p3(one);
end.

View file

@ -16,7 +16,7 @@ begin
new t1(10)
));
Result.f0.Println; // до #1986 было AccessViolationException
assert(Result.f0 = 10); // до #1986 было AccessViolationException
end;

View file

@ -12356,25 +12356,28 @@ namespace PascalABCCompiler.TreeConverter
List<common_type_node> used_types = new List<common_type_node>(where_list.defs.Count);
foreach (SyntaxTree.where_definition wd in where_list.defs)
{
bool param_not_found = true;
foreach (common_type_node param in gparams)
foreach (SyntaxTree.ident wd_id in wd.names.idents)
{
if (String.Equals(param.name, wd.names.idents[0].name, StringComparison.InvariantCultureIgnoreCase))
bool param_not_found = true;
foreach (common_type_node param in gparams)
{
//Нашли нужный шаблонный параметр
if (used_types.Contains(param))
if (String.Equals(param.name, wd_id.name, StringComparison.InvariantCultureIgnoreCase))
{
AddError(get_location(wd.names), "SPECIFICATORS_FOR_{0}_ALREADY_EXIST", wd.names.idents[0].name);
//Нашли нужный шаблонный параметр
if (used_types.Contains(param))
{
AddError(get_location(wd.names), "SPECIFICATORS_FOR_{0}_ALREADY_EXIST", wd_id.name);
}
add_generic_eliminations(param, wd.types.defs);
used_types.Add(param);
param_not_found = false;
break;
}
add_generic_eliminations(param, wd.types.defs);
used_types.Add(param);
param_not_found = false;
break;
}
}
if (param_not_found)
{
AddError(new UndefinedNameReference(wd.names.idents[0].name, get_location(wd.names)));
if (param_not_found)
{
AddError(new UndefinedNameReference(wd.names.idents[0].name, get_location(wd.names)));
}
}
}
context.EndSkipGenericInstanceChecking();

View file

@ -141,11 +141,13 @@ namespace PascalABCCompiler.TreeRealization
public static CompilationErrorWithLocation check_type_list(List<type_node> tparams, List<generic_parameter_eliminations> gpe_list, bool method_param_types, out int i)
{
int count = tparams.Count;
for (i = 0; i < count; i++)
{
generic_parameter_eliminations gpe = gpe_list[i];
type_node tn = tparams[i];
if (gpe.is_class && !tn.is_class && !(tn.base_type != null && tn.base_type.is_class))
if (gpe.is_class && !tn.is_class && !(tn.is_generic_parameter && tn.base_type != null && tn.base_type.is_class))
{
return new SimpleSemanticError(null, "PARAMETER_{0}_MUST_BE_REFERENCE_TYPE", tn.PrintableName);
}