Created
August 12, 2018 04:36
-
-
Save zackmdavis/839eb750fe3bd8152b0d5ec6faad87ea to your computer and use it in GitHub Desktop.
generate structs to exercise the explicit-outlives-requirements lint
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import itertools | |
test = "" | |
signatures = set() | |
specs = [] | |
def bound_type(bound): | |
if bound.startswith("'"): | |
return "lifetime" | |
else: | |
return "trait" | |
def bound_signature(location, bounds): | |
return (location, tuple(bound_type(bound) for bound in bounds)) | |
def add_if_valid(spec): | |
has_lifetimes = False | |
for subspec in spec: | |
param_spec, bounds_spec = subspec | |
_param, position = param_spec | |
# empty where clause is illegal | |
if position == 'where' and not bounds_spec: | |
return | |
has_lifetimes |= any(bound.startswith("'") for bound in bounds_spec) | |
# We don't care about testing scenarios where none of the params have | |
# lifetimes | |
if has_lifetimes: | |
specs.append(spec) | |
for param_list in [[("T", 'inline')], | |
[("T", 'where')], | |
[("T", 'inline'), ("U", 'inline')], | |
[("T", 'inline'), ("U", 'where')], | |
[("T", 'where'), ("U", 'where')]]: | |
for lifetime_list in [[], ["'a"], ["'a", "'b"]]: | |
for trait_bound_list in [[], ["Debug"]]: | |
bounds = lifetime_list + trait_bound_list | |
if len(param_list) == 2: | |
for split in range(len(bounds)): | |
left = bounds[:split] | |
right = bounds[split:] | |
for left_order in itertools.permutations(left): | |
for right_order in itertools.permutations(right): | |
left_signature = bound_signature(param_list[0][1], | |
left_order) | |
right_signature = bound_signature(param_list[1][1], | |
right_order) | |
grand_signature = frozenset( | |
{left_signature, right_signature} | |
) | |
if grand_signature not in signatures: | |
signatures.add(grand_signature) | |
add_if_valid( | |
((param_list[0], left_order), | |
(param_list[1], right_order)) | |
) | |
else: | |
for order in itertools.permutations(bounds): | |
signature = frozenset( | |
{bound_signature(param_list[0][1], order)} | |
) | |
if signature not in signatures: | |
signatures.add(signature) | |
add_if_valid( | |
((param_list[0], order),) | |
) | |
n = 0 | |
def fab(spec): | |
lifetimes = [] | |
params = [] | |
for subspec in spec: | |
param_spec, bounds_spec = subspec | |
param, position = param_spec | |
params.append(param) | |
lifetimes.extend( | |
[bound for bound in bounds_spec if bound.startswith("'")] | |
) | |
inline_parts = lifetimes[:] | |
where_parts = [] | |
body_parts = [] | |
name = "" | |
for i, subspec in enumerate(spec): | |
param_spec, bounds_spec = subspec | |
param, position = param_spec | |
if position == 'inline': | |
if bounds_spec: | |
inline_parts.append( | |
"{}: {}".format(param, ' + '.join(bounds_spec)) | |
) | |
else: | |
inline_parts.append(param) | |
elif position == 'where': | |
inline_parts.append(param) | |
where_parts.append("{}: {}".format(param, ' + '.join(bounds_spec))) | |
name += 'Tee' if param == 'T' else 'Yoo' | |
if position == 'where': | |
name += "Where" | |
for bound in bounds_spec: | |
if bound.startswith("'"): | |
name += "Outlives" + "Ay" if bound == "'a" else "Bee" | |
else: | |
name += "IsDebug" | |
param_lts = [bound for bound in bounds_spec if bound.startswith("'")] | |
if param_lts: | |
body_parts.append( | |
"{}: {} {}".format( | |
"tee" if param == 'T' else 'yoo', | |
' '.join("&{}".format(lt) for lt in param_lts), | |
param | |
) | |
) | |
else: | |
body_parts.append( | |
"{}: {}".format( | |
"tee" if param == 'T' else 'yoo', | |
param | |
) | |
) | |
global n | |
n += 1 | |
print(inline_parts) | |
inline = ', '.join(inline_parts) | |
if where_parts: | |
where = "where " + ', '.join(where_parts) | |
else: | |
where = "" | |
err_tags = "//~^ ERROR outlives requirements can be inferred" | |
body = ',\n '.join(body_parts) | |
global test | |
test += """ | |
struct {name}<{inline}> {where} {{ | |
{err_tags} | |
{body} | |
}}""".format(**locals()) | |
print(signatures) | |
print(specs) | |
print(len(signatures)) | |
print(len(specs)) | |
for spec in specs: | |
fab(spec) | |
print(test) | |
print(n) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment