frontend 0.4.1

rustc's frontend with no LLVM and no std: parsing through MIR, as a library
//! An immutable, owned value (except for interior mutability).
//!
//! The purpose of `Frozen` is to make a value immutable for the sake of defensive programming. For example,
//! suppose we have the following:
//!
//! ```rust
//! struct Bar { /* some data */ }
//!
//! struct Foo {
//!     /// Some computed data that should never change after construction.
//!     pub computed: Bar,
//!
//!     /* some other fields */
//! }
//!
//! impl Bar {
//!     /// Mutate the `Bar`.
//!     pub fn mutate(&mut self) { }
//! }
//! ```
//!
//! Now suppose we want to pass around a mutable `Foo` instance but, we want to make sure that
//! `computed` does not change accidentally (e.g. somebody might accidentally call
//! `foo.computed.mutate()`). This is what `Frozen` is for. We can do the following:
//!
//! ```
//! # struct Bar {}
//! use frontend::rustc_data_structures::frozen::Frozen;
//!
//! struct Foo {
//!     /// Some computed data that should never change after construction.
//!     pub computed: Frozen<Bar>,
//!
//!     /* some other fields */
//! }
//! ```
//!
//! `Frozen` impls `Deref`, so we can ergonomically call methods on `Bar`, but it doesn't `impl
//! DerefMut`. Now calling `foo.compute.mutate()` will result in a compile-time error stating that
//! `mutate` requires a mutable reference but we don't have one.
//!
//! # Caveats
//!
//! - `Frozen` doesn't try to defend against interior mutability (e.g. `Frozen<RefCell<Bar>>`).
//! - `Frozen` doesn't pin it's contents (e.g. one could still do `foo.computed =
//!    Frozen::freeze(new_bar)`).

/// An owned immutable value.
// `#![no_std]`: these arrive with the standard prelude and name no path, so a `std::`
// search cannot see them - and a `#[derive]` can use them without the name appearing
// in this file at all, which is why they are not trimmed by inspection.
use alloc::borrow::ToOwned;
use alloc::boxed::Box;
use alloc::format;
use alloc::string::{String, ToString};
use alloc::vec;
use alloc::vec::Vec;

#[derive(Debug, Clone)]
pub struct Frozen<T>(T);

impl<T> Frozen<T> {
    pub fn freeze(val: T) -> Self {
        Frozen(val)
    }
}

impl<T> core::ops::Deref for Frozen<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}