mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 02:03:53 +00:00
Auto merge of #112802 - lukas-code:fancy-bool, r=Nilstrieb
use ErrorGuaranteed instead of booleans in rustc_builtin_macros implements https://github.com/rust-lang/rust/pull/112366#discussion_r1233821873 No functional changes. Best reviewed with whitespace diff disabled. r? `@Nilstrieb`
This commit is contained in:
commit
ed1ce580ec
@ -8,7 +8,7 @@ use rustc_feature::AttributeTemplate;
|
|||||||
use rustc_parse::validate_attr;
|
use rustc_parse::validate_attr;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::symbol::{sym, Ident};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::Span;
|
use rustc_span::{ErrorGuaranteed, Span};
|
||||||
|
|
||||||
pub(crate) struct Expander(pub bool);
|
pub(crate) struct Expander(pub bool);
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ impl MultiItemModifier for Expander {
|
|||||||
_: bool,
|
_: bool,
|
||||||
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
||||||
let sess = ecx.sess;
|
let sess = ecx.sess;
|
||||||
if report_bad_target(sess, &item, span) {
|
if report_bad_target(sess, &item, span).is_err() {
|
||||||
// We don't want to pass inappropriate targets to derive macros to avoid
|
// We don't want to pass inappropriate targets to derive macros to avoid
|
||||||
// follow up errors, all other errors below are recoverable.
|
// follow up errors, all other errors below are recoverable.
|
||||||
return ExpandResult::Ready(vec![item]);
|
return ExpandResult::Ready(vec![item]);
|
||||||
@ -103,7 +103,11 @@ fn dummy_annotatable() -> Annotatable {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool {
|
fn report_bad_target(
|
||||||
|
sess: &Session,
|
||||||
|
item: &Annotatable,
|
||||||
|
span: Span,
|
||||||
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let item_kind = match item {
|
let item_kind = match item {
|
||||||
Annotatable::Item(item) => Some(&item.kind),
|
Annotatable::Item(item) => Some(&item.kind),
|
||||||
Annotatable::Stmt(stmt) => match &stmt.kind {
|
Annotatable::Stmt(stmt) => match &stmt.kind {
|
||||||
@ -116,9 +120,9 @@ fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool {
|
|||||||
let bad_target =
|
let bad_target =
|
||||||
!matches!(item_kind, Some(ItemKind::Struct(..) | ItemKind::Enum(..) | ItemKind::Union(..)));
|
!matches!(item_kind, Some(ItemKind::Struct(..) | ItemKind::Enum(..) | ItemKind::Union(..)));
|
||||||
if bad_target {
|
if bad_target {
|
||||||
sess.emit_err(errors::BadDeriveTarget { span, item: item.span() });
|
return Err(sess.emit_err(errors::BadDeriveTarget { span, item: item.span() }));
|
||||||
}
|
}
|
||||||
bad_target
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_unexpected_meta_item_lit(sess: &Session, lit: &ast::MetaItemLit) {
|
fn report_unexpected_meta_item_lit(sess: &Session, lit: &ast::MetaItemLit) {
|
||||||
|
@ -8,7 +8,7 @@ use rustc_ast_pretty::pprust;
|
|||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_expand::base::*;
|
use rustc_expand::base::*;
|
||||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||||
use rustc_span::{FileNameDisplayPreference, Span};
|
use rustc_span::{ErrorGuaranteed, FileNameDisplayPreference, Span};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use thin_vec::{thin_vec, ThinVec};
|
use thin_vec::{thin_vec, ThinVec};
|
||||||
|
|
||||||
@ -128,12 +128,15 @@ pub fn expand_test_or_bench(
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// has_*_signature will report any errors in the type so compilation
|
// check_*_signature will report any errors in the type so compilation
|
||||||
// will fail. We shouldn't try to expand in this case because the errors
|
// will fail. We shouldn't try to expand in this case because the errors
|
||||||
// would be spurious.
|
// would be spurious.
|
||||||
if (!is_bench && !has_test_signature(cx, &item))
|
let check_result = if is_bench {
|
||||||
|| (is_bench && !has_bench_signature(cx, &item))
|
check_bench_signature(cx, &item, &fn_)
|
||||||
{
|
} else {
|
||||||
|
check_test_signature(cx, &item, &fn_)
|
||||||
|
};
|
||||||
|
if check_result.is_err() {
|
||||||
return if is_stmt {
|
return if is_stmt {
|
||||||
vec![Annotatable::Stmt(P(cx.stmt_item(item.span, item)))]
|
vec![Annotatable::Stmt(P(cx.stmt_item(item.span, item)))]
|
||||||
} else {
|
} else {
|
||||||
@ -523,72 +526,62 @@ fn test_type(cx: &ExtCtxt<'_>) -> TestType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
fn check_test_signature(
|
||||||
|
cx: &ExtCtxt<'_>,
|
||||||
|
i: &ast::Item,
|
||||||
|
f: &ast::Fn,
|
||||||
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic);
|
let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic);
|
||||||
let sd = &cx.sess.parse_sess.span_diagnostic;
|
let sd = &cx.sess.parse_sess.span_diagnostic;
|
||||||
match &i.kind {
|
|
||||||
ast::ItemKind::Fn(box ast::Fn { sig, generics, .. }) => {
|
|
||||||
if let ast::Unsafe::Yes(span) = sig.header.unsafety {
|
|
||||||
sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if let ast::Async::Yes { span, .. } = sig.header.asyncness {
|
|
||||||
sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "async" });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the termination trait is active, the compiler will check that the output
|
if let ast::Unsafe::Yes(span) = f.sig.header.unsafety {
|
||||||
// type implements the `Termination` trait as `libtest` enforces that.
|
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" }));
|
||||||
let has_output = match &sig.decl.output {
|
|
||||||
ast::FnRetTy::Default(..) => false,
|
|
||||||
ast::FnRetTy::Ty(t) if t.kind.is_unit() => false,
|
|
||||||
_ => true,
|
|
||||||
};
|
|
||||||
|
|
||||||
if !sig.decl.inputs.is_empty() {
|
|
||||||
sd.span_err(i.span, "functions used as tests can not have any arguments");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if has_should_panic_attr && has_output {
|
|
||||||
sd.span_err(i.span, "functions using `#[should_panic]` must return `()`");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if generics.params.iter().any(|param| !matches!(param.kind, GenericParamKind::Lifetime))
|
|
||||||
{
|
|
||||||
sd.span_err(
|
|
||||||
i.span,
|
|
||||||
"functions used as tests can not have any non-lifetime generic parameters",
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// should be unreachable because `is_test_fn_item` should catch all non-fn items
|
|
||||||
debug_assert!(false);
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
if let ast::Async::Yes { span, .. } = f.sig.header.asyncness {
|
||||||
let has_sig = match &i.kind {
|
return Err(sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "async" }));
|
||||||
// N.B., inadequate check, but we're running
|
}
|
||||||
// well before resolve, can't get too deep.
|
|
||||||
ast::ItemKind::Fn(box ast::Fn { sig, .. }) => sig.decl.inputs.len() == 1,
|
// If the termination trait is active, the compiler will check that the output
|
||||||
_ => false,
|
// type implements the `Termination` trait as `libtest` enforces that.
|
||||||
|
let has_output = match &f.sig.decl.output {
|
||||||
|
ast::FnRetTy::Default(..) => false,
|
||||||
|
ast::FnRetTy::Ty(t) if t.kind.is_unit() => false,
|
||||||
|
_ => true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !has_sig {
|
if !f.sig.decl.inputs.is_empty() {
|
||||||
cx.sess.parse_sess.span_diagnostic.span_err(
|
return Err(sd.span_err(i.span, "functions used as tests can not have any arguments"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if has_should_panic_attr && has_output {
|
||||||
|
return Err(sd.span_err(i.span, "functions using `#[should_panic]` must return `()`"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.generics.params.iter().any(|param| !matches!(param.kind, GenericParamKind::Lifetime)) {
|
||||||
|
return Err(sd.span_err(
|
||||||
|
i.span,
|
||||||
|
"functions used as tests can not have any non-lifetime generic parameters",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_bench_signature(
|
||||||
|
cx: &ExtCtxt<'_>,
|
||||||
|
i: &ast::Item,
|
||||||
|
f: &ast::Fn,
|
||||||
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
|
// N.B., inadequate check, but we're running
|
||||||
|
// well before resolve, can't get too deep.
|
||||||
|
if f.sig.decl.inputs.len() != 1 {
|
||||||
|
return Err(cx.sess.parse_sess.span_diagnostic.span_err(
|
||||||
i.span,
|
i.span,
|
||||||
"functions used as benches must have \
|
"functions used as benches must have \
|
||||||
signature `fn(&mut Bencher) -> impl Termination`",
|
signature `fn(&mut Bencher) -> impl Termination`",
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
has_sig
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user