The big change here is to enable libc++'s debug mode outside of `opt`
builds on Linux where it seems to work well with the Homebrew installed
toolchain. I'm restricting it to Linux as the system libc++ install on
x86 macOS doesn't seem to work. This is based on and subsumes #811.
This also tidies up how `-NDEBUG` is set to include non-codegen compile
actions, and consolidates some optimization flags in a single location.
This part has no functionality change, but would likely invalidate
caches so bundled here where both a) I noticed and b) we already had
a cache invalidation.
Only the special nullability attributes (`_Nonnull`) work correctly
through type aliases like we're using with `Ptr`. But they aren't
strictly UB and so have to be specially enabled in our sanitizer config
in order to usefully catch nullness errors early. Turn on those
sanitizers as well.
Also, now that we are using fully remote build output caching for our
CI and not trying to squeeze under an arbitrary size limit, re-enable
the nice error messages for all the UBSan checks.
Note that this will have a (very) slow CI run as it will have to
recompile ~everything and upload fresh artifacts. But those should then
be effective cache hits going forward.
The advantage is a C++ pointer is special, and this approach eliminates the Ptr class type that was causing problems in conversions. Attribute suggestion was courtesy of chandlerc. We're sticking with the Ptr name because it's shorter than Nonnull, and we're likely to keep this in lots of places.
There's a small update to update_checks.py to handle the recursive directories. Also, I'm only using one level of nesting in this PR but really no reason we can't do more. I'm just not sure what clustering is best right now.
As a pattern, I'm trying to name all failing tests `fail_*.carbon`.
I'm seeing if I can upstream thundergolfer/bazel-mypy-integration#43, but we can also point at my fork for the time being.
This should resolve conflicts with mypy treating imports as non-hermetic, creating inconsistent behavior if packages are/aren't installed locally.
With this, only main.cpp instantiates an arena. Maybe we'll want to split that up more later (e.g., so that the runtime interpreter uses its own arena), but given the intent to have type-checking update the AST, I thought this was a reasonable approach for now in order to avoid ownership complexities.
Fixes#769
* Debugging quality-of-life improvements
- Use std::abort for `CHECK`/`FATAL` failures, which acts as a debugger breakpoint as well as automatically printing a stack trace.
- Re-enable printing continuations in `--trace` mode.
- Log the source location of each step in `--trace` mode.
Co-authored-by: Jon Meow <46229924+jonmeow@users.noreply.github.com>
These aren't really statements (because they're not executed at run time), and it's debatable whether they're declarations, since their primary purpose isn't to introduce a name. On Discord, "directive" seemed to be the consensus choice for an alternate term.
Also apply it to the list of tokens. This way there's no need for "sort order" comments.
This was a side-effect of me trying to merge in api/impl/library/package, and thinking "why am I doing this manually?"
Co-authored-by: Geoff Romer <gromer@google.com>
Doesn't add much logic, only takes advantage of parser structure for the ordering enforcement.
Note import_nonexistent tests should probably fail, but writing import tests needs a chain of functionality, and I figured I'd just start adding some to validate the syntax (not adding existent imports because that'd require multi-file structure).
This is based on discussion on #732: that we should probably parse the invalid whitespace, then reject it as part of string validation, rather than having different parses. I worry the question of "how is this parsed" may lead to subtly unexpected results if we aren't consistent, so I'm switching the logic from the lexer to the unescape library (and also adjusting the list of rejected whitespace).
Along with #789 this addresses most of #769 although global_arena is still a TODO (that's widespread and overlaps with other changes so I wanted to do it after these are in).
Related to discussion on #738, but also trying to standardize handling of everything and make placement of token spellings (`AND "and"`) consistently in lexer.lpp.
I could have gone the other direction, removing the list of things in lexer.lpp, but this feels like it does more to use the compiler to detect skew between lexer.lpp and parser.ypp.
Note this makes a few cases where the Statement was optional explicit (Block, If, Sequence). I do add a few CHECKs around where statements were optional and assumed but unverified.
I switch TypeCheckStmt to not take an optional Statement because I think it makes the call sites clearer in behavior. It's also a smaller change than the converse, because taking an optional Statement means the returned statement would also need to be optional. Arguably a wrapper for optional statements could be added, but this still seems cleaner to me, and there aren't that many cases of an optional statement.
Co-authored-by: Geoff Romer <gromer@google.com>
This supports both struct type literals, `{.x: i32, .y: i32}`, and struct
value literals, `{.x = 3, .y = 4}`. The degenerate case of `{}` is
treated as a struct value literal, with the expectation that an empty
struct value has the same type/value duality as an empty tuple value.
I've modified the text from the proposal slightly, focusing the overview more on a design setup, but mostly kept the details. One important thing here is I noticed that raw tab characters are disallowed -- this was a little buried before, and I've now updated the list of characters allowed in a string to exclude tabs. Additionally, I've noted `\0D` in the list of escapes as explicitly invalid.
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Recent experience indicates that the system of thumbs-up doesn't seem to
work consistently. Replace it with more broad encouragement to use PR
reactions to surface sentiment and a judgement call by the leads on when
a proposal is ready to merge.
An explicit goal here is that leads can make this judgement call
reflecting the nature of the proposal. Many of these are low-risk.
Either they are easily fixed-forward or minimally disruptive. This can
be because they are merely beginning to fill out a largely open area, or
because they are minor changes.
Also try to clarify that it is expected for the leads to sometimes miss
things or make mistakes, and encourage a revert or fix-forward mentality
rather than slowing down progress to reduce the rate of mistakes.
Sorry about the big change, this is hard to split. ParenContents is used by both, templated, and expects the same pointer type. While I could duplicate ParenContents with some ExpressionParenContents or PatternParenContents, that seems a little kludgy versus a single large change handling both. The worst of it is that Expression is already pretty sweeping, Pattern is really just incrementally adding.
That said, I believe this includes a couple fixes I found with incorrect use of dyn_cast in typecheck.cpp (checked nullptr at the wrong step in 2 code locations). There's also a missing `*` in member.cpp this caught. I adjust passing of expressions for Return due to nullness (I felt adding another constructor was the best solution).
I add a `.Release()` to BisonWrap due to things like `$3.first` needing some way to work through BIsonWrap. I felt this was better than `operator->`, but feel free to comment if you prefer the other path (`.Release()` conveniently lets me do pair unwrapping, so it felt a better solution).
I do add a TODO to think about better Ptr-to-Ptr cast<> support too, though, as that doesn't work cleanly with LLVM's infra. But so far it seems to only come up in one spot, so I'm not prioritizing it.