bug fix #2108
This commit is contained in:
parent
f2df27dd87
commit
f1049a2b4e
6
TestSuite/errors/err0340_multiple_where.pas
Normal file
6
TestSuite/errors/err0340_multiple_where.pas
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
procedure p1<T1,T2>(a: T1; b: T2); where T1, T2: record;
|
||||||
|
begin end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
p1(0, '');
|
||||||
|
end.
|
||||||
7
TestSuite/errors/err0341_multiple_where.pas
Normal file
7
TestSuite/errors/err0341_multiple_where.pas
Normal 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
19
TestSuite/where10.pas
Normal 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.
|
||||||
|
|
@ -16,7 +16,7 @@ begin
|
||||||
new t1(10)
|
new t1(10)
|
||||||
));
|
));
|
||||||
|
|
||||||
Result.f0.Println; // до #1986 было AccessViolationException
|
assert(Result.f0 = 10); // до #1986 было AccessViolationException
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12356,25 +12356,28 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
List<common_type_node> used_types = new List<common_type_node>(where_list.defs.Count);
|
List<common_type_node> used_types = new List<common_type_node>(where_list.defs.Count);
|
||||||
foreach (SyntaxTree.where_definition wd in where_list.defs)
|
foreach (SyntaxTree.where_definition wd in where_list.defs)
|
||||||
{
|
{
|
||||||
bool param_not_found = true;
|
foreach (SyntaxTree.ident wd_id in wd.names.idents)
|
||||||
foreach (common_type_node param in gparams)
|
|
||||||
{
|
{
|
||||||
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 (String.Equals(param.name, wd_id.name, StringComparison.InvariantCultureIgnoreCase))
|
||||||
if (used_types.Contains(param))
|
|
||||||
{
|
{
|
||||||
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)
|
||||||
if (param_not_found)
|
{
|
||||||
{
|
AddError(new UndefinedNameReference(wd.names.idents[0].name, get_location(wd.names)));
|
||||||
AddError(new UndefinedNameReference(wd.names.idents[0].name, get_location(wd.names)));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
context.EndSkipGenericInstanceChecking();
|
context.EndSkipGenericInstanceChecking();
|
||||||
|
|
|
||||||
|
|
@ -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)
|
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;
|
int count = tparams.Count;
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
generic_parameter_eliminations gpe = gpe_list[i];
|
generic_parameter_eliminations gpe = gpe_list[i];
|
||||||
type_node tn = tparams[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);
|
return new SimpleSemanticError(null, "PARAMETER_{0}_MUST_BE_REFERENCE_TYPE", tn.PrintableName);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue