202 lines
7.8 KiB
Rust
202 lines
7.8 KiB
Rust
// TAME in Rust (TAMER)
|
|
//
|
|
// Copyright (C) 2014-2023 Ryan Specialty, LLC.
|
|
//
|
|
// This file is part of TAME.
|
|
//
|
|
// 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/>.
|
|
|
|
//! An incremental rewrite of TAME in Rust.
|
|
//!
|
|
//! There are two entry points to this system:
|
|
//!
|
|
//! - [`tamec`](../tamec), the TAME compiler; and
|
|
//! - [`tameld`](../tameld), the TAME linker.
|
|
|
|
// Constant functions are still in their infancy as of the time of writing
|
|
// (October 2021).
|
|
// These this feature is used by [`sym::prefill::st_as_sym`] to provide
|
|
// polymorphic symbol types despite Rust's lack of support for constant
|
|
// trait methods.
|
|
// See that function for more information.
|
|
#![feature(const_transmute_copy)]
|
|
// This is used to unwrap const Option results rather than providing
|
|
// panicing alternatives.
|
|
#![feature(const_option)]
|
|
// 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)]
|
|
// Can be replaced with `assert!(matches!(...))`,
|
|
// but at a loss of a better error message.
|
|
#![feature(assert_matches)]
|
|
// 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)]
|
|
// For `Try` and `FromResidual`,
|
|
// allowing us to write our own `?`-compatible types.
|
|
#![feature(try_trait_v2)]
|
|
// 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)]
|
|
// Convenience features that are easily replaced if not stabalized.
|
|
#![feature(nonzero_ops)]
|
|
// Enabled for qualified paths in `matches!`.
|
|
#![feature(more_qualified_paths)]
|
|
// Collecting interators into existing objects.
|
|
// Can be done manually in a more verbose way.
|
|
#![feature(iter_collect_into)]
|
|
// Concise and descriptive.
|
|
// Can be done manually in a more verbose way.
|
|
#![feature(str_split_remainder)]
|
|
// Concise and descriptive.
|
|
// Can be done manually in a more verbose way.
|
|
#![feature(iter_intersperse)]
|
|
// 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)]
|
|
// Used for traits returning functions,
|
|
// such as those in `crate::f`.
|
|
// Our use of this feature is fairly basic;
|
|
// should it become too complex then we should re-evaluate what we ought
|
|
// to be doing relative to the status of this feature.
|
|
#![feature(return_position_impl_trait_in_trait)]
|
|
// Added for use with `rustfmt::skip`,
|
|
// so that we can ignore formatting more precisely.
|
|
#![feature(stmt_expr_attributes)]
|
|
// Allows using `impl Trait` for associated type bounds instead of having to
|
|
// extract it into a more verbose `where` clause.
|
|
// This is not necessary,
|
|
// and may not even be desirable,
|
|
// but it's a nice option to have if `impl` would otherwise be used.
|
|
#![feature(associated_type_bounds)]
|
|
// We build docs for private items.
|
|
#![allow(rustdoc::private_intra_doc_links)]
|
|
// For sym::prefill recursive macro `static_symbols!`.
|
|
#![recursion_limit = "512"]
|
|
//
|
|
// Clippy Lints
|
|
// ============
|
|
// This section contains rationale for deviating from standard lints.
|
|
// This reasoning applies to TAMER and may not be appropriate for other
|
|
// projects,
|
|
// or even other teams.
|
|
//
|
|
// These are presented in no particular order,
|
|
// but if you do rearrange them,
|
|
// be mindful of the comments that may reference preceding lints.
|
|
//
|
|
// Choosing not to inline format args sometimes adds to the clarity of the
|
|
// format string by emphasizing structure more concisely.
|
|
// Use your judgment.
|
|
#![allow(clippy::uninlined_format_args)]
|
|
// The rationale for this lint is that it may catch accidental semicolons,
|
|
// but the type system is plenty sufficient to catch unit types that were
|
|
// unintended.
|
|
#![allow(clippy::unit_arg)]
|
|
// Use your judgment;
|
|
// a `match` may be more clear within a given context.
|
|
// Or may simply be personal preference.
|
|
#![allow(clippy::single_match)]
|
|
// Same rationale as the previous,
|
|
// but additionally this clearly scopes pattern bindings to an inner
|
|
// block,
|
|
// which is not the case with a sibling `let` binding.
|
|
// This pattern was originally taken from `rustc` itself.
|
|
#![allow(clippy::match_single_binding)]
|
|
// This lint also seems to apply when dereferencing a double reference,
|
|
// for which the use of `cloned` would be far more confusing.
|
|
#![allow(clippy::map_clone)]
|
|
// Perhaps `is_empty` does not make sense for that particular trait/impl?
|
|
// We don't need a linter to guide these abstractions;
|
|
// an `is-empty` method will be added if it is needed and actually
|
|
// utilized.
|
|
#![allow(clippy::len_without_is_empty)]
|
|
// This is another case of a linter trying to guide abstractions.
|
|
// `Default` will be implemented if it both makes sense and is needed,
|
|
// not needlessly,
|
|
// as TAMER is not a library and its uses are statically known.
|
|
// Furthermore,
|
|
// `Default` is sometimes explicitly omitted to disallow automatic
|
|
// construction in various contexts.
|
|
#![allow(clippy::new_without_default)]
|
|
// When surrounding code uses `write!`,
|
|
// switching to `writeln!` for the last line adds an inconsistency that
|
|
// can make the code less clear,
|
|
// or possibly even introduce bugs by having the reader miss the change
|
|
// in pattern.
|
|
// `writeln!` also gives the impression that it's writing a line,
|
|
// when in actuality it may simply be appending to a partially-written
|
|
// line,
|
|
// making it feel like an inappropriate abstraction.
|
|
// Choose the abstraction that's most appropriate within a given context.
|
|
#![allow(clippy::write_with_newline)]
|
|
// Calling this "obfuscation" is hyperbole.
|
|
// Furthermore,
|
|
// `if` statements are expanded by `rustfmt` into something with a
|
|
// significantly larger footprint than this form,
|
|
// so this lint does _not_ suggest a suitable replacement.
|
|
#![allow(clippy::obfuscated_if_else)]
|
|
// Sometimes being explicit about lifetimes,
|
|
// even if it's unnecessary,
|
|
// can help a human to understand what bounds are in play,
|
|
// which are hidden when they're elided.
|
|
// Sometimes doing such a thing is a bad idea and introduces complexity.
|
|
// We need to use our judgment.
|
|
// Further,
|
|
// Clippy sometimes recommends eliding named bounds which does not
|
|
// compile,
|
|
// but then accepts introducing an anonymous lifetime bound (`'_`),
|
|
// which can be inscrutable if you are not very familiar with Rust's
|
|
// borrow checker.
|
|
#![allow(clippy::needless_lifetimes)]
|
|
|
|
pub mod global;
|
|
|
|
#[macro_use]
|
|
extern crate static_assertions;
|
|
|
|
#[macro_use]
|
|
pub mod xir;
|
|
|
|
pub mod asg;
|
|
pub mod convert;
|
|
pub mod diagnose;
|
|
pub mod f;
|
|
pub mod fmt;
|
|
pub mod fs;
|
|
pub mod iter;
|
|
pub mod ld;
|
|
pub mod nir;
|
|
pub mod num;
|
|
pub mod obj;
|
|
pub mod parse;
|
|
pub mod span;
|
|
pub mod sym;
|
|
|
|
#[cfg(test)]
|
|
pub mod test;
|