# Buggy code
def match(
    self,
    segments,
    match_depth=0,
    parse_depth=0,
    verbosity=0,
    dialect=None,
    match_segment=None,
):
    # Rewrite of sequence. We should match FORWARD, this reduced duplication.
    # Sub-matchers should be greedy and so we can jsut work forward with each one.
    if isinstance(segments, BaseSegment):
        segments = tuple(segments)
    # NB: We don't use seg_idx here because the submatchers may be mutating the length
    # of the remaining segments
    matched_segments = MatchResult.from_empty()
    unmatched_segments = segments

    for idx, elem in enumerate(self._elements):
        while True:
            if len(unmatched_segments) == 0:
                # We've run our of sequence without matching everyting.
                # Do only optional elements remain.
                if all([e.is_optional() for e in self._elements[idx:]]):
                    # then it's ok, and we can return what we've got so far.
                    # No need to deal with anything left over because we're at the end.
                    return matched_segments
                else:
                    # we've got to the end of the sequence without matching all
                    # required elements.
                    return MatchResult.from_unmatched(segments)
            else:
                # We're not at the end, first detect whitespace and then try to match.
                if self.code_only and not unmatched_segments[0].is_code:
                    # We should add this one to the match and carry on
                    matched_segments += (unmatched_segments[0],)
                    unmatched_segments = unmatched_segments[1:]
                    check_still_complete(
                        segments, matched_segments.matched_segments, unmatched_segments
                    )
                    continue

                # It's not whitespace, so carry on to matching
                elem_match = elem._match(
                    unmatched_segments,
                    match_depth=match_depth + 1,
                    parse_depth=parse_depth,
                    verbosity=verbosity,
                    dialect=dialect,
                    match_segment=match_segment,
                )

                if elem_match.has_match():
                    # We're expecting mostly partial matches here, but complete
                    # matches are possible.
                    matched_segments += elem_match.matched_segments
                    unmatched_segments = elem_match.unmatched_segments
                    # Each time we do this, we do a sense check to make sure we haven't
                    # dropped anything. (Because it's happened before!).
                    check_still_complete(
                        segments, matched_segments.matched_segments, unmatched_segments
                    )

                    # Break out of the while loop and move to the next element.
                    break
                else:
                    # If we can't match an element, we should ascertain whether it's
                    # required. If so then fine, move on, but otherwise we should crash
                    # out without a match. We have not matched the sequence.
                    if elem.is_optional():
                        # This will crash us out of the while loop and move us
                        # onto the next matching element
                        break
                    else:
                        return MatchResult.from_unmatched(segments)
    else:
        # If we get to here, we've matched all of the elements (or skipped them)
        # but still have some segments left (or perhaps have precisely zero left).
        # In either case, we're golden. Return successfully, with any leftovers as
        # the unmatched elements. UNLESS they're whitespace and we should be greedy.
        if self.code_only:
            while True:
                if len(unmatched_segments) == 0:
                    break
                elif not unmatched_segments[0].is_code:
                    # We should add this one to the match and carry on
                    matched_segments += (unmatched_segments[0],)
                    unmatched_segments = unmatched_segments[1:]
                    check_still_complete(
                        segments, matched_segments.matched_segments, unmatched_segments
                    )
                    continue
                else:
                    break

        return MatchResult(matched_segments.matched_segments, unmatched_segments)


# Traceback (TypeError)
Traceback (most recent call last):
File "/home/user/sql/.venv/bin/sqlfluff", line 11, in <module>
load_entry_point('sqlfluff==0.1.3', 'console_scripts', 'sqlfluff')()
File "/home/user/sql/.venv/lib/python3.7/site-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/home/user/sql/.venv/lib/python3.7/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/home/user/sql/.venv/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/user/sql/.venv/lib/python3.7/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/user/sql/.venv/lib/python3.7/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/cli/commands.py", line 85, in lint
result = lnt.lint_paths(paths, verbosity=verbose)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/linter.py", line 324, in lint_paths
result.add(self.lint_path(path, verbosity=verbosity, fix=fix))
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/linter.py", line 312, in lint_path
linted_path.add(self.lint_file(f, fname=fname, verbosity=verbosity, fix=fix))
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/linter.py", line 212, in lint_file
parsed, vs, time_dict = self.parse_file(f=f, fname=fname, verbosity=verbosity)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/linter.py", line 193, in parse_file
parsed = fs.parse(recurse=recurse, verbosity=verbosity, dialect=self.dialect)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/segments_base.py", line 228, in parse
verbosity=verbosity, dialect=dialect)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/segments_base.py", line 394, in expand
res = stmt.parse(recurse=recurse, parse_depth=parse_depth, verbosity=verbosity, dialect=dialect)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/segments_base.py", line 228, in parse
verbosity=verbosity, dialect=dialect)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/segments_base.py", line 394, in expand
res = stmt.parse(recurse=recurse, parse_depth=parse_depth, verbosity=verbosity, dialect=dialect)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/segments_base.py", line 228, in parse
verbosity=verbosity, dialect=dialect)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/segments_base.py", line 394, in expand
res = stmt.parse(recurse=recurse, parse_depth=parse_depth, verbosity=verbosity, dialect=dialect)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/segments_base.py", line 228, in parse
verbosity=verbosity, dialect=dialect)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/segments_base.py", line 394, in expand
res = stmt.parse(recurse=recurse, parse_depth=parse_depth, verbosity=verbosity, dialect=dialect)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/segments_base.py", line 186, in parse
dialect=dialect, match_segment=self.__class__.__name__)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/grammar.py", line 70, in _match
verbosity=verbosity, dialect=dialect, match_segment=match_segment)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/grammar.py", line 273, in match
verbosity=verbosity, dialect=dialect, match_segment=match_segment)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/grammar.py", line 70, in _match
verbosity=verbosity, dialect=dialect, match_segment=match_segment)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/grammar.py", line 485, in match
match_segment=match_segment)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/grammar.py", line 70, in _match
verbosity=verbosity, dialect=dialect, match_segment=match_segment)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/grammar.py", line 273, in match
verbosity=verbosity, dialect=dialect, match_segment=match_segment)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/grammar.py", line 70, in _match
verbosity=verbosity, dialect=dialect, match_segment=match_segment)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/grammar.py", line 236, in match
dialect=dialect, match_segment=match_segment)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/segments_base.py", line 361, in _match
verbosity=verbosity, dialect=dialect, match_segment=match_segment)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/segments_base.py", line 320, in match
dialect=dialect, match_segment=match_segment)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/grammar.py", line 70, in _match
verbosity=verbosity, dialect=dialect, match_segment=match_segment)
File "/home/user/sql/.venv/lib/python3.7/site-packages/sqlfluff/parser/grammar.py", line 586, in match
segment=segments[start_bracket_idx])
TypeError: tuple indices must be integers or slices, not NoneType

# Fixed code
def match(self, segments, parse_context):
    # Rewrite of sequence. We should match FORWARD, this reduced duplication.
    # Sub-matchers should be greedy and so we can jsut work forward with each one.
    if isinstance(segments, BaseSegment):
        segments = tuple(segments)
    # NB: We don't use seg_idx here because the submatchers may be mutating the length
    # of the remaining segments
    matched_segments = MatchResult.from_empty()
    unmatched_segments = segments

    for idx, elem in enumerate(self._elements):
        while True:
            if len(unmatched_segments) == 0:
                # We've run our of sequence without matching everyting.
                # Do only optional elements remain.
                if all([e.is_optional() for e in self._elements[idx:]]):
                    # then it's ok, and we can return what we've got so far.
                    # No need to deal with anything left over because we're at the end.
                    return matched_segments
                else:
                    # we've got to the end of the sequence without matching all
                    # required elements.
                    return MatchResult.from_unmatched(segments)
            else:
                # We're not at the end, first detect whitespace and then try to match.
                if self.code_only and not unmatched_segments[0].is_code:
                    # We should add this one to the match and carry on
                    matched_segments += (unmatched_segments[0],)
                    unmatched_segments = unmatched_segments[1:]
                    check_still_complete(
                        segments, matched_segments.matched_segments, unmatched_segments
                    )
                    continue

                # It's not whitespace, so carry on to matching
                elem_match = elem._match(
                    unmatched_segments,
                    parse_context=parse_context.copy(incr="match_depth"),
                )

                if elem_match.has_match():
                    # We're expecting mostly partial matches here, but complete
                    # matches are possible.
                    matched_segments += elem_match.matched_segments
                    unmatched_segments = elem_match.unmatched_segments
                    # Each time we do this, we do a sense check to make sure we haven't
                    # dropped anything. (Because it's happened before!).
                    check_still_complete(
                        segments, matched_segments.matched_segments, unmatched_segments
                    )

                    # Break out of the while loop and move to the next element.
                    break
                else:
                    # If we can't match an element, we should ascertain whether it's
                    # required. If so then fine, move on, but otherwise we should crash
                    # out without a match. We have not matched the sequence.
                    if elem.is_optional():
                        # This will crash us out of the while loop and move us
                        # onto the next matching element
                        break
                    else:
                        return MatchResult.from_unmatched(segments)
    else:
        # If we get to here, we've matched all of the elements (or skipped them)
        # but still have some segments left (or perhaps have precisely zero left).
        # In either case, we're golden. Return successfully, with any leftovers as
        # the unmatched elements. UNLESS they're whitespace and we should be greedy.
        if self.code_only:
            while True:
                if len(unmatched_segments) == 0:
                    break
                elif not unmatched_segments[0].is_code:
                    # We should add this one to the match and carry on
                    matched_segments += (unmatched_segments[0],)
                    unmatched_segments = unmatched_segments[1:]
                    check_still_complete(
                        segments, matched_segments.matched_segments, unmatched_segments
                    )
                    continue
                else:
                    break

        return MatchResult(matched_segments.matched_segments, unmatched_segments)