2019-11-27 09:18:17 -05:00
|
|
|
// TAME in Rust (TAMER)
|
|
|
|
//
|
2022-05-03 14:14:29 -04:00
|
|
|
// Copyright (C) 2014-2022 Ryan Specialty Group, LLC.
|
2020-03-06 11:05:18 -05:00
|
|
|
//
|
|
|
|
// This file is part of TAME.
|
2019-11-27 09:18:17 -05:00
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2019-12-06 15:03:29 -05:00
|
|
|
//! An incremental rewrite of TAME in Rust.
|
|
|
|
|
2021-10-02 00:50:20 -04:00
|
|
|
// Constant functions are still in their infancy as of the time of writing
|
|
|
|
// (October 2021).
|
2022-05-02 11:05:32 -04:00
|
|
|
// These this feature is used by [`sym::prefill::st_as_sym`] to provide
|
2021-10-02 00:50:20 -04:00
|
|
|
// polymorphic symbol types despite Rust's lack of support for constant
|
|
|
|
// trait methods.
|
|
|
|
// See that function for more information.
|
|
|
|
#![feature(const_transmute_copy)]
|
2022-03-17 12:20:20 -04:00
|
|
|
// This is used to unwrap const Option results rather than providing
|
|
|
|
// panicing alternatives.
|
|
|
|
#![feature(const_option)]
|
2021-10-28 14:27:33 -04:00
|
|
|
// Trait aliases are convenient for reducing verbosity in situations where
|
|
|
|
// type aliases cannot be used.
|
|
|
|
// To remove this feature if it is not stabalized,
|
|
|
|
// simply replace each alias reference with its definition,
|
|
|
|
// or possibly write a trait with a `Self` bound.
|
|
|
|
#![feature(trait_alias)]
|
2021-10-28 21:21:30 -04:00
|
|
|
// Can be replaced with `assert!(matches!(...))`,
|
|
|
|
// but at a loss of a better error message.
|
|
|
|
#![feature(assert_matches)]
|
2021-10-29 16:34:05 -04:00
|
|
|
// Simplifies creating `Option` default values.
|
|
|
|
// To remove this feature,
|
|
|
|
// this can be done more verbosely in the usual way,
|
|
|
|
// or we can write our own version.
|
|
|
|
#![feature(option_get_or_insert_default)]
|
2022-03-17 12:20:20 -04:00
|
|
|
// This allows for e.g. `parse::<N>(foo)`,
|
|
|
|
// where `fn parse<const N: T>(foo: impl Trait)`.
|
|
|
|
// Rust devs wanted more time for public testing as of the time of writing
|
|
|
|
// (March 2022).
|
|
|
|
// We _could_ do without,
|
|
|
|
// but this provides a nicer API.
|
|
|
|
#![feature(explicit_generic_args_with_impl_trait)]
|
2022-03-25 09:56:22 -04:00
|
|
|
// For `Try` and `FromResidual`,
|
|
|
|
// allowing us to write our own `?`-compatible types.
|
|
|
|
#![feature(try_trait_v2)]
|
2022-04-04 21:50:47 -04:00
|
|
|
// Used primarily for convenience,
|
|
|
|
// rather than having to create type constructors as type aliases that are
|
|
|
|
// not associated with a trait.
|
|
|
|
// However,
|
|
|
|
// this also allows for the associated type default to be overridden by
|
|
|
|
// the implementer,
|
|
|
|
// in which case this feature's only substitute is a type parameter.
|
|
|
|
#![feature(associated_type_defaults)]
|
2022-04-14 15:52:08 -04:00
|
|
|
// Convenience features that are easily replaced if not stabalized.
|
|
|
|
#![feature(nonzero_min_max)]
|
|
|
|
#![feature(nonzero_ops)]
|
2022-04-28 23:37:07 -04:00
|
|
|
#![feature(int_log)]
|
2022-06-10 16:28:15 -04:00
|
|
|
// Used for const params like `&'static str` in `crate::fmt`.
|
|
|
|
// If this is not stabalized,
|
|
|
|
// then we can do without by changing the abstraction;
|
|
|
|
// this is largely experimentation to see if it's useful.
|
|
|
|
#![allow(incomplete_features)]
|
|
|
|
#![feature(adt_const_params)]
|
2021-10-28 14:27:33 -04:00
|
|
|
// We build docs for private items.
|
2021-06-21 13:10:00 -04:00
|
|
|
#![allow(rustdoc::private_intra_doc_links)]
|
|
|
|
|
2020-01-12 22:59:16 -05:00
|
|
|
pub mod global;
|
2020-03-24 14:14:05 -04:00
|
|
|
|
2021-07-29 14:26:40 -04:00
|
|
|
#[macro_use]
|
|
|
|
extern crate static_assertions;
|
2021-09-29 23:18:23 -04:00
|
|
|
#[cfg(test)]
|
2021-08-20 10:09:55 -04:00
|
|
|
#[macro_use]
|
|
|
|
extern crate lazy_static;
|
|
|
|
|
2021-11-04 16:12:15 -04:00
|
|
|
pub mod asg;
|
2021-09-08 16:00:14 -04:00
|
|
|
pub mod convert;
|
tamer: diagnose: Introduction of diagnostic system
This is a working concept that will continue to evolve. I wanted to start
with some basic output before getting too carried away, since there's a lot
of potential here.
This is heavily influenced by Rust's helpful diagnostic messages, but will
take some time to realize a lot of the things that Rust does. The next step
will be to resolve line and column numbers, and then possibly include
snippets and underline spans, placing the labels alongside them. I need to
balance this work with everything else I have going on.
This is a large commit, but it converts the existing Error Display impls
into Diagnostic. This separation is a bit verbose, so I'll see how this
ends up evolving.
Diagnostics are tied to Error at the moment, but I imagine in the future
that any object would be able to describe itself, error or not, which would
be useful in the future both for the Summary Page and for query
functionality, to help developers understand the systems they are writing
using TAME.
Output is integrated into tameld only in this commit; I'll add tamec
next. Examples of what this outputs are available in the test cases in this
commit.
DEV-10935
2022-04-13 14:41:54 -04:00
|
|
|
pub mod diagnose;
|
2022-06-10 16:28:15 -04:00
|
|
|
pub mod fmt;
|
2020-04-06 16:13:32 -04:00
|
|
|
pub mod fs;
|
2021-10-28 14:27:33 -04:00
|
|
|
pub mod iter;
|
2019-11-27 09:18:17 -05:00
|
|
|
pub mod ld;
|
2022-05-19 10:09:49 -04:00
|
|
|
pub mod num;
|
2020-01-09 10:55:55 -05:00
|
|
|
pub mod obj;
|
2022-03-18 16:24:53 -04:00
|
|
|
pub mod parse;
|
2021-08-13 14:59:25 -04:00
|
|
|
pub mod span;
|
tamer: Global interners
This is a major change, and I apologize for it all being in one commit. I
had wanted to break it up, but doing so would have required a significant
amount of temporary work that was not worth doing while I'm the only one
working on this project at the moment.
This accomplishes a number of important things, now that I'm preparing to
write the first compiler frontend for TAMER:
1. `Symbol` has been removed; `SymbolId` is used in its place.
2. Consequently, symbols use 16 or 32 bits, rather than a 64-bit pointer.
3. Using symbols no longer requires dereferencing.
4. **Lifetimes no longer pollute the entire system! (`'i`)**
5. Two global interners are offered to produce `SymbolStr` with `'static`
lifetimes, simplfiying lifetime management and borrowing where strings
are still needed.
6. A nice API is provided for interning and lookups (e.g. "foo".intern())
which makes this look like a core feature of Rust.
Unfortunately, making this change required modifications to...virtually
everything. And that serves to emphasize why this change was needed:
_everything_ used symbols, and so there's no use in not providing globals.
I implemented this in a way that still provides for loose coupling through
Rust's trait system. Indeed, Rustc offers a global interner, and I decided
not to go that route initially because it wasn't clear to me that such a
thing was desirable. It didn't become apparent to me, in fact, until the
recent commit where I introduced `SymbolIndexSize` and saw how many things
had to be touched; the linker evolved so rapidly as I was trying to learn
Rust that I lost track of how bad it got.
Further, this shows how the design of the internment system was a bit
naive---I assumed certain requirements that never panned out. In
particular, everything using symbols stored `&'i Symbol<'i>`---that is, a
reference (usize) to an object containing an index (32-bit) and a string
slice (128-bit). So it was a reference to a pretty large value, which was
allocated in the arena alongside the interned string itself.
But, that was assuming that something would need both the symbol index _and_
a readily available string. That's not the case. In fact, it's pretty
clear that interning happens at the beginning of execution, that `SymbolId`
is all that's needed during processing (unless an error occurs; more on that
below); and it's not until _the very end_ that we need to retrieve interned
strings from the pool to write either to a file or to display to the
user. It was horribly wasteful!
So `SymbolId` solves the lifetime issue in itself for most systems, but it
still requires that an interner be available for anything that needs to
create or resolve symbols, which, as it turns out, is still a lot of
things. Therefore, I decided to implement them as thread-local static
variables, which is very similar to what Rustc does itself (Rustc's are
scoped). TAMER does not use threads, so the resulting `'static` lifetime
should be just fine for now. Eventually I'd like to implement `!Send` and
`!Sync`, though, to prevent references from escaping the thread (as noted in
the patch); I can't do that yet, since the feature has not yet been
stabalized.
In the end, this leaves us with a system that's much easier to use and
maintain; hopefully easier for newcomers to get into without having to deal
with so many complex lifetimes; and a nice API that makes it a pleasure to
work with symbols.
Admittedly, the `SymbolIndexSize` adds some complexity, and we'll see if I
end up regretting that down the line, but it exists for an important reason:
the `Span` and other structures that'll be introduced need to pack a lot of
data into 64 bits so they can be freely copied around to keep lifetimes
simple without wreaking havoc in other ways, but a 32-bit symbol size needed
by the linker is too large for that. (Actually, the linker doesn't yet need
32 bits for our systems, but it's going to in the somewhat near future
unless we optimize away a bunch of symbols...but I'd really rather not have
the linker hit a limit that requires a lot of code changes to resolve).
Rustc uses interned spans when they exceed 8 bytes, but I'd prefer to avoid
that for now. Most systems can just use on of the `PkgSymbolId` or
`ProgSymbolId` type aliases and not have to worry about it. Systems that
are actually shared between the compiler and the linker do, though, but it's
not like we don't already have a bunch of trait bounds.
Of course, as we implement link-time optimizations (LTO) in the future, it's
possible most things will need the size and I'll grow frustrated with that
and possibly revisit this. We shall see.
Anyway, this was exhausting...and...onward to the first frontend!
2021-08-02 23:54:37 -04:00
|
|
|
pub mod sym;
|
2022-06-03 14:34:08 -04:00
|
|
|
pub mod xir;
|
2020-02-13 11:50:18 -05:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
pub mod test;
|