about summary refs log tree commit diff
path: root/compiler/rustc_builtin_macros/src
diff options
context:
space:
mode:
authorCaio <c410.f3r@gmail.com>2022-06-02 09:00:04 -0300
committerCaio <c410.f3r@gmail.com>2022-06-02 09:00:04 -0300
commitaa115eba12d6a12bfa4c51e3b6c187f28c42a889 (patch)
treea9587640c8c7eea3b3d940335d9b432d5ee68e60 /compiler/rustc_builtin_macros/src
parent5e6bb83268518dcd74c96b5504f485b71e604e4c (diff)
downloadrust-aa115eba12d6a12bfa4c51e3b6c187f28c42a889.tar.gz
rust-aa115eba12d6a12bfa4c51e3b6c187f28c42a889.zip
Basic compiler infra
Diffstat (limited to 'compiler/rustc_builtin_macros/src')
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs70
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs44
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs5
3 files changed, 95 insertions, 24 deletions
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index a984980dea9..0c75187193c 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -1,11 +1,13 @@
+mod context;
+
 use crate::edition_panic::use_panic_2021;
 use rustc_ast::ptr::P;
 use rustc_ast::token;
 use rustc_ast::tokenstream::{DelimSpan, TokenStream};
-use rustc_ast::{self as ast, *};
+use rustc_ast::{Expr, ExprKind, MacArgs, MacCall, MacDelimiter, Path, PathSegment, UnOp};
 use rustc_ast_pretty::pprust;
 use rustc_errors::{Applicability, PResult};
-use rustc_expand::base::*;
+use rustc_expand::base::{DummyResult, ExtCtxt, MacEager, MacResult};
 use rustc_parse::parser::Parser;
 use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
@@ -25,13 +27,13 @@ pub fn expand_assert<'cx>(
 
     // `core::panic` and `std::panic` are different macros, so we use call-site
     // context to pick up whichever is currently in scope.
-    let sp = cx.with_call_site_ctxt(span);
+    let call_site_span = cx.with_call_site_ctxt(span);
 
-    let panic_call = if let Some(tokens) = custom_message {
-        let path = if use_panic_2021(span) {
+    let panic_path = || {
+        if use_panic_2021(span) {
             // On edition 2021, we always call `$crate::panic::panic_2021!()`.
             Path {
-                span: sp,
+                span: call_site_span,
                 segments: cx
                     .std_path(&[sym::panic, sym::panic_2021])
                     .into_iter()
@@ -42,27 +44,40 @@ pub fn expand_assert<'cx>(
         } else {
             // Before edition 2021, we call `panic!()` unqualified,
             // such that it calls either `std::panic!()` or `core::panic!()`.
-            Path::from_ident(Ident::new(sym::panic, sp))
-        };
-        // Pass the custom message to panic!().
-        cx.expr(
-            sp,
+            Path::from_ident(Ident::new(sym::panic, call_site_span))
+        }
+    };
+
+    // Simply uses the user provided message instead of generating custom outputs
+    let expr = if let Some(tokens) = custom_message {
+        let then = cx.expr(
+            call_site_span,
             ExprKind::MacCall(MacCall {
-                path,
+                path: panic_path(),
                 args: P(MacArgs::Delimited(
-                    DelimSpan::from_single(sp),
+                    DelimSpan::from_single(call_site_span),
                     MacDelimiter::Parenthesis,
                     tokens,
                 )),
                 prior_type_ascription: None,
             }),
-        )
-    } else {
+        );
+        expr_if_not(cx, call_site_span, cond_expr, then, None)
+    }
+    // If `generic_assert` is enabled, generates rich captured outputs
+    //
+    // FIXME(c410-f3r) See https://github.com/rust-lang/rust/issues/96949
+    else if let Some(features) = cx.ecfg.features && features.generic_assert {
+        context::Context::new(cx, call_site_span).build(cond_expr, panic_path())
+    }
+    // If `generic_assert` is not enabled, only outputs a literal "assertion failed: ..."
+    // string
+    else {
         // Pass our own message directly to $crate::panicking::panic(),
         // because it might contain `{` and `}` that should always be
         // passed literally.
-        cx.expr_call_global(
-            sp,
+        let then = cx.expr_call_global(
+            call_site_span,
             cx.std_path(&[sym::panicking, sym::panic]),
             vec![cx.expr_str(
                 DUMMY_SP,
@@ -71,18 +86,29 @@ pub fn expand_assert<'cx>(
                     pprust::expr_to_string(&cond_expr).escape_debug()
                 )),
             )],
-        )
+        );
+        expr_if_not(cx, call_site_span, cond_expr, then, None)
     };
-    let if_expr =
-        cx.expr_if(sp, cx.expr(sp, ExprKind::Unary(UnOp::Not, cond_expr)), panic_call, None);
-    MacEager::expr(if_expr)
+
+    MacEager::expr(expr)
 }
 
 struct Assert {
-    cond_expr: P<ast::Expr>,
+    cond_expr: P<Expr>,
     custom_message: Option<TokenStream>,
 }
 
+// if !{ ... } { ... } else { ... }
+fn expr_if_not(
+    cx: &ExtCtxt<'_>,
+    span: Span,
+    cond: P<Expr>,
+    then: P<Expr>,
+    els: Option<P<Expr>>,
+) -> P<Expr> {
+    cx.expr_if(span, cx.expr(span, ExprKind::Unary(UnOp::Not, cond)), then, els)
+}
+
 fn parse_assert<'a>(cx: &mut ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PResult<'a, Assert> {
     let mut parser = cx.new_parser_from_tts(stream);
 
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
new file mode 100644
index 00000000000..8d187a4be8a
--- /dev/null
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -0,0 +1,44 @@
+use rustc_ast::{ptr::P, Expr, Path};
+use rustc_expand::base::ExtCtxt;
+use rustc_span::Span;
+
+pub(super) struct Context<'cx, 'a> {
+    cx: &'cx ExtCtxt<'a>,
+    span: Span,
+}
+
+impl<'cx, 'a> Context<'cx, 'a> {
+    pub(super) fn new(cx: &'cx ExtCtxt<'a>, span: Span) -> Self {
+        Self { cx, span }
+    }
+
+    /// Builds the whole `assert!` expression.
+    ///
+    /// {
+    ///    use ::core::asserting::{ ... };
+    ///
+    ///    let mut __capture0 = Capture::new();
+    ///    ...
+    ///    ...
+    ///    ...
+    ///
+    ///    if !{
+    ///       ...
+    ///       ...
+    ///       ...
+    ///    } {
+    ///        panic!(
+    ///            "Assertion failed: ... \n With expansion: ...",
+    ///            __capture0,
+    ///            ...
+    ///            ...
+    ///            ...
+    ///        );
+    ///    }
+    /// }
+    pub(super) fn build(self, _cond_expr: P<Expr>, _panic_path: Path) -> P<Expr> {
+        let Self { cx, span, .. } = self;
+        let stmts = Vec::new();
+        cx.expr_block(cx.block(span, stmts))
+    }
+}
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 0c9e3c22bcf..48b1470ced5 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -1,17 +1,18 @@
 //! This crate contains implementations of built-in macros and other code generating facilities
 //! injecting code into the crate before it is lowered to HIR.
 
+#![allow(rustc::potential_query_instability)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(array_windows)]
 #![feature(box_patterns)]
 #![feature(decl_macro)]
 #![feature(is_sorted)]
-#![feature(nll)]
+#![feature(let_chains)]
 #![feature(let_else)]
+#![feature(nll)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
 #![recursion_limit = "256"]
-#![allow(rustc::potential_query_instability)]
 
 extern crate proc_macro;