File 2591-stdlib-Fix-precedence-bug-regarding.patch of Package erlang
From 7e09b923a247b26552bb8e4f787c06d21ed60733 Mon Sep 17 00:00:00 2001
From: Hans Bolinder <hasse@erlang.org>
Date: Tue, 28 Jan 2020 15:40:10 +0100
Subject: [PATCH 1/5] stdlib: Fix precedence bug regarding '::'
A corner case: if a type `t()' is annotated as in
`N1 :: (N2 :: t())'
(where `N1' and `N2' are annotations and not type variables),
parentheses are now inserted correctly by erl_pp.
---
lib/stdlib/src/erl_parse.yrl | 4 ++--
lib/stdlib/src/erl_pp.erl | 13 +++++++------
lib/stdlib/test/erl_pp_SUITE.erl | 18 +++++++++++++++---
3 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl
index 4ad94f2507..bbd18252e5 100644
--- a/lib/stdlib/src/erl_parse.yrl
+++ b/lib/stdlib/src/erl_parse.yrl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2020. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -1584,7 +1584,7 @@ max_prec() -> 900.
-spec type_inop_prec(type_inop()) -> {prec(), prec(), prec()}.
type_inop_prec('=') -> {150,100,100};
-type_inop_prec('::') -> {160,150,150};
+type_inop_prec('::') -> {150,150,160};
type_inop_prec('|') -> {180,170,170};
type_inop_prec('..') -> {300,200,300};
type_inop_prec('+') -> {400,400,500};
diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl
index 255c0ae81f..f6a84412b7 100644
--- a/lib/stdlib/src/erl_pp.erl
+++ b/lib/stdlib/src/erl_pp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2019. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2020. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -322,9 +322,11 @@ ltype(T) ->
ltype(T, 0).
ltype({ann_type,_Line,[V,T]}, Prec) ->
- {_L,P,_R} = type_inop_prec('::'),
- E = typed(lexpr(V, options(none)), T),
- maybe_paren(P, Prec, E);
+ {L,P,R} = type_inop_prec('::'),
+ Vl = ltype(V, L),
+ Tr = ltype(T, R),
+ El = {list,[{cstep,[Vl,' ::'],Tr}]},
+ maybe_paren(P, Prec, El);
ltype({paren_type,_Line,[T]}, P) ->
%% Generated before Erlang/OTP 18.
ltype(T, P);
@@ -410,8 +412,7 @@ field_type({type,_Line,field_type,[Name,Type]}, _Prec) ->
typed(lexpr(Name, options(none)), Type).
typed(B, Type) ->
- {_L,_P,R} = type_inop_prec('::'),
- {list,[{cstep,[B,' ::'],ltype(Type, R)}]}.
+ {list,[{cstep,[B,' ::'],ltype(Type)}]}.
tuple_type([], _) ->
leaf("{}");
diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl
index c0cfd26925..e6ff141b5f 100644
--- a/lib/stdlib/test/erl_pp_SUITE.erl
+++ b/lib/stdlib/test/erl_pp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2019. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2020. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -52,7 +52,7 @@
otp_8473/1, otp_8522/1, otp_8567/1, otp_8664/1, otp_9147/1,
otp_10302/1, otp_10820/1, otp_11100/1, otp_11861/1, pr_1014/1,
otp_13662/1, otp_14285/1, otp_15592/1, otp_15751/1, otp_15755/1,
- gh_5093/1]).
+ otp_16435/1, gh_5093/1]).
%% Internal export.
-export([ehook/6]).
@@ -82,7 +83,7 @@ groups() ->
[otp_6321, otp_6911, otp_6914, otp_8150, otp_8238,
otp_8473, otp_8522, otp_8567, otp_8664, otp_9147,
otp_10302, otp_10820, otp_11100, otp_11861, pr_1014, otp_13662,
- otp_14285, otp_15592, otp_15751, otp_15755,
+ otp_14285, otp_15592, otp_15751, otp_15755, otp_16435,
gh_5093]}].
init_per_suite(Config) ->
@@ -1261,6 +1262,17 @@ otp_15755(_Config) ->
" 'sf s sdf', [], {}, {[]}}.", [])),
ok.
+otp_16435(_Config) ->
+ CheckF = fun(S) -> S = lists:flatten(parse_and_pp_forms(S, [])) end,
+ CheckF("-type t() :: A :: integer().\n"),
+ CheckF("-type t() :: A :: (B :: integer()).\n"),
+ CheckF("-type t() :: {A :: (B :: integer())}.\n"),
+ CheckF("-record(r,{f :: {A :: (B :: integer())}}).\n"),
+ CheckF("-record(r,{f = 3 :: {A :: (B :: integer())}}).\n"),
+ CheckF("-type t() :: #r{f :: A :: (B :: integer())}.\n"),
+ CheckF("-spec t(X) -> X when X :: Y :: (Z :: #r{}).\n"),
+ ok.
+
gh_5093(_Config) ->
assert_same("f() ->\n -1.\n"),
assert_same("f() ->\n +1.\n"),
--
2.16.4