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)
|
||||
));
|
||||
|
||||
Result.f0.Println; // до #1986 было AccessViolationException
|
||||
assert(Result.f0 = 10); // до #1986 было AccessViolationException
|
||||
|
||||
end;
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue