1
Fork 0

Auto merge of #93368 - eddyb:diagbld-guarantee, r=estebank

rustc_errors: let `DiagnosticBuilder::emit` return a "guarantee of emission".

That is, `DiagnosticBuilder` is now generic over the return type of `.emit()`, so we'll now have:
* `DiagnosticBuilder<ErrorReported>` for error (incl. fatal/bug) diagnostics
  * can only be created via a `const L: Level`-generic constructor, that limits allowed variants via a `where` clause, so not even `rustc_errors` can accidentally bypass this limitation
  * asserts `diagnostic.is_error()` on emission, just in case the construction restriction was bypassed (e.g. by replacing the whole `Diagnostic` inside `DiagnosticBuilder`)
  * `.emit()` returns `ErrorReported`, as a "proof" token that `.emit()` was called
    (though note that this isn't a real guarantee until after completing the work on
     #69426)
* `DiagnosticBuilder<()>` for everything else (warnings, notes, etc.)
  * can also be obtained from other `DiagnosticBuilder`s by calling `.forget_guarantee()`

This PR is a companion to other ongoing work, namely:
* #69426
  and it's ongoing implementation:
  #93222
  the API changes in this PR are needed to get statically-checked "only errors produce `ErrorReported` from `.emit()`", but doesn't itself provide any really strong guarantees without those other `ErrorReported` changes
* #93244
  would make the choices of API changes (esp. naming) in this PR fit better overall

In order to be able to let `.emit()` return anything trustable, several changes had to be made:
* `Diagnostic`'s `level` field is now private to `rustc_errors`, to disallow arbitrary "downgrade"s from "some kind of error" to "warning" (or anything else that doesn't cause compilation to fail)
  * it's still possible to replace the whole `Diagnostic` inside the `DiagnosticBuilder`, sadly, that's harder to fix, but it's unlikely enough that we can paper over it with asserts on `.emit()`
* `.cancel()` now consumes `DiagnosticBuilder`, preventing `.emit()` calls on a cancelled diagnostic
  * it's also now done internally, through `DiagnosticBuilder`-private state, instead of having a `Level::Cancelled` variant that can be read (or worse, written) by the user
  * this removes a hazard of calling `.cancel()` on an error then continuing to attach details to it, and even expect to be able to `.emit()` it
  * warnings were switched to *only* `can_emit_warnings` on emission (instead of pre-cancelling early)
  * `struct_dummy` was removed (as it relied on a pre-`Cancelled` `Diagnostic`)
* since `.emit()` doesn't consume the `DiagnosticBuilder` <sub>(I tried and gave up, it's much more work than this PR)</sub>,
  we have to make `.emit()` idempotent wrt the guarantees it returns
  * thankfully, `err.emit(); err.emit();` can return `ErrorReported` both times, as the second `.emit()` call has no side-effects *only* because the first one did do the appropriate emission
* `&mut Diagnostic` is now used in a lot of function signatures, which used to take `&mut DiagnosticBuilder` (in the interest of not having to make those functions generic)
  * the APIs were already mostly identical, allowing for low-effort porting to this new setup
  * only some of the suggestion methods needed some rework, to have the extra `DiagnosticBuilder` functionality on the `Diagnostic` methods themselves (that change is also present in #93259)
  * `.emit()`/`.cancel()` aren't available, but IMO calling them from an "error decorator/annotator" function isn't a good practice, and can lead to strange behavior (from the caller's perspective)
  * `.downgrade_to_delayed_bug()` was added, letting you convert any `.is_error()` diagnostic into a `delay_span_bug` one (which works because in both cases the guarantees available are the same)

This PR should ideally be reviewed commit-by-commit, since there is a lot of fallout in each.

r? `@estebank` cc `@Manishearth` `@nikomatsakis` `@mark-i-m`
This commit is contained in:
bors 2022-02-25 00:46:04 +00:00
commit d4de1f230c
134 changed files with 1497 additions and 1143 deletions

View file

@ -1,7 +1,7 @@
use std::error::Error;
use std::fmt;
use rustc_errors::{DiagnosticBuilder, ErrorReported};
use rustc_errors::Diagnostic;
use rustc_hir as hir;
use rustc_middle::mir::AssertKind;
use rustc_middle::ty::{layout::LayoutError, query::TyCtxtAt, ConstInt};
@ -94,13 +94,13 @@ impl<'tcx> ConstEvalErr<'tcx> {
&self,
tcx: TyCtxtAt<'tcx>,
message: &str,
emit: impl FnOnce(DiagnosticBuilder<'_>),
decorate: impl FnOnce(&mut Diagnostic),
) -> ErrorHandled {
self.struct_generic(tcx, message, emit, None)
self.struct_generic(tcx, message, decorate, None)
}
pub fn report_as_error(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ErrorHandled {
self.struct_error(tcx, message, |mut e| e.emit())
self.struct_error(tcx, message, |_| {})
}
pub fn report_as_lint(
@ -113,7 +113,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
self.struct_generic(
tcx,
message,
|mut lint: DiagnosticBuilder<'_>| {
|lint: &mut Diagnostic| {
// Apply the span.
if let Some(span) = span {
let primary_spans = lint.span.primary_spans().to_vec();
@ -127,7 +127,6 @@ impl<'tcx> ConstEvalErr<'tcx> {
}
}
}
lint.emit();
},
Some(lint_root),
)
@ -136,9 +135,8 @@ impl<'tcx> ConstEvalErr<'tcx> {
/// Create a diagnostic for this const eval error.
///
/// Sets the message passed in via `message` and adds span labels with detailed error
/// information before handing control back to `emit` to do any final processing.
/// It's the caller's responsibility to call emit(), stash(), etc. within the `emit`
/// function to dispose of the diagnostic properly.
/// information before handing control back to `decorate` to do any final annotations,
/// after which the diagnostic is emitted.
///
/// If `lint_root.is_some()` report it as a lint, else report it as a hard error.
/// (Except that for some errors, we ignore all that -- see `must_error` below.)
@ -146,10 +144,10 @@ impl<'tcx> ConstEvalErr<'tcx> {
&self,
tcx: TyCtxtAt<'tcx>,
message: &str,
emit: impl FnOnce(DiagnosticBuilder<'_>),
decorate: impl FnOnce(&mut Diagnostic),
lint_root: Option<hir::HirId>,
) -> ErrorHandled {
let finish = |mut err: DiagnosticBuilder<'_>, span_msg: Option<String>| {
let finish = |err: &mut Diagnostic, span_msg: Option<String>| {
trace!("reporting const eval failure at {:?}", self.span);
if let Some(span_msg) = span_msg {
err.span_label(self.span, span_msg);
@ -188,8 +186,8 @@ impl<'tcx> ConstEvalErr<'tcx> {
}
flush_last_line(last_frame, times);
}
// Let the caller finish the job.
emit(err)
// Let the caller attach any additional information it wants.
decorate(err);
};
// Special handling for certain errors
@ -206,8 +204,9 @@ impl<'tcx> ConstEvalErr<'tcx> {
// The `message` makes little sense here, this is a more serious error than the
// caller thinks anyway.
// See <https://github.com/rust-lang/rust/pull/63152>.
finish(struct_error(tcx, &self.error.to_string()), None);
return ErrorHandled::Reported(ErrorReported);
let mut err = struct_error(tcx, &self.error.to_string());
finish(&mut err, None);
return ErrorHandled::Reported(err.emit());
}
_ => {}
};
@ -223,13 +222,18 @@ impl<'tcx> ConstEvalErr<'tcx> {
rustc_session::lint::builtin::CONST_ERR,
hir_id,
tcx.span,
|lint| finish(lint.build(message), Some(err_msg)),
|lint| {
let mut lint = lint.build(message);
finish(&mut lint, Some(err_msg));
lint.emit();
},
);
ErrorHandled::Linted
} else {
// Report as hard error.
finish(struct_error(tcx, message), Some(err_msg));
ErrorHandled::Reported(ErrorReported)
let mut err = struct_error(tcx, message);
finish(&mut err, Some(err_msg));
ErrorHandled::Reported(err.emit())
}
}
}

View file

@ -361,7 +361,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
Err(err.struct_error(
ecx.tcx,
"it is undefined behavior to use this value",
|mut diag| {
|diag| {
diag.note(note_on_undefined_behavior_error());
diag.note(&format!(
"the raw bytes of the constant ({}",
@ -370,7 +370,6 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
ecx.tcx.global_alloc(alloc_id).unwrap_memory()
)
));
diag.emit();
},
))
} else {

View file

@ -1,6 +1,6 @@
//! Concrete error types for all operations which may be invalid in a certain const context.
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
@ -47,7 +47,11 @@ pub trait NonConstOp<'tcx>: std::fmt::Debug {
DiagnosticImportance::Primary
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx>;
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported>;
}
#[derive(Debug)]
@ -61,7 +65,11 @@ impl<'tcx> NonConstOp<'tcx> for FloatingPointOp {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_floating_point_arithmetic,
@ -75,7 +83,11 @@ impl<'tcx> NonConstOp<'tcx> for FloatingPointOp {
#[derive(Debug)]
pub struct FnCallIndirect;
impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
ccx.tcx.sess.struct_span_err(span, "function pointers are not allowed in const fn")
}
}
@ -91,11 +103,15 @@ pub struct FnCallNonConst<'tcx> {
}
impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
_: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let FnCallNonConst { caller, callee, substs, span, from_hir_call } = *self;
let ConstCx { tcx, param_env, .. } = *ccx;
let diag_trait = |mut err, self_ty: Ty<'_>, trait_id| {
let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
let trait_ref = TraitRef::from_method(tcx, trait_id, substs);
match self_ty.kind() {
@ -115,7 +131,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
suggest_constraining_type_param(
tcx,
generics,
&mut err,
err,
&param_ty.name.as_str(),
&constraint,
None,
@ -146,8 +162,6 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
}
_ => {}
}
err
};
let call_kind = call_kind(tcx, ccx.param_env, callee, substs, span, from_hir_call, None);
@ -162,7 +176,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
};
}
let err = match kind {
let mut err = match kind {
CallDesugaringKind::ForLoopIntoIter => {
error!("cannot convert `{}` into an iterator in {}s")
}
@ -177,7 +191,8 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
}
};
diag_trait(err, self_ty, kind.trait_def_id(tcx))
diag_trait(&mut err, self_ty, kind.trait_def_id(tcx));
err
}
CallKind::FnCall { fn_trait_id, self_ty } => {
let mut err = struct_span_err!(
@ -212,7 +227,8 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
_ => {}
}
diag_trait(err, self_ty, fn_trait_id)
diag_trait(&mut err, self_ty, fn_trait_id);
err
}
CallKind::Operator { trait_id, self_ty, .. } => {
let mut err = struct_span_err!(
@ -262,7 +278,8 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
}
}
diag_trait(err, self_ty, trait_id)
diag_trait(&mut err, self_ty, trait_id);
err
}
CallKind::DerefCoercion { deref_target, deref_target_ty, self_ty } => {
let mut err = struct_span_err!(
@ -281,7 +298,8 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
err.span_note(deref_target, "deref defined here");
}
diag_trait(err, self_ty, tcx.lang_items().deref_trait().unwrap())
diag_trait(&mut err, self_ty, tcx.lang_items().deref_trait().unwrap());
err
}
_ => struct_span_err!(
ccx.tcx.sess,
@ -310,7 +328,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
pub struct FnCallUnstable(pub DefId, pub Option<Symbol>);
impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let FnCallUnstable(def_id, feature) = *self;
let mut err = ccx.tcx.sess.struct_span_err(
@ -344,7 +366,11 @@ impl<'tcx> NonConstOp<'tcx> for FnPtrCast {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_fn_ptr_basics,
@ -365,7 +391,11 @@ impl<'tcx> NonConstOp<'tcx> for Generator {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let msg = format!("{}s are not allowed in {}s", self.0, ccx.const_kind());
if let hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) = self.0 {
feature_err(&ccx.tcx.sess.parse_sess, sym::const_async_blocks, span, &msg)
@ -378,7 +408,11 @@ impl<'tcx> NonConstOp<'tcx> for Generator {
#[derive(Debug)]
pub struct HeapAllocation;
impl<'tcx> NonConstOp<'tcx> for HeapAllocation {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let mut err = struct_span_err!(
ccx.tcx.sess,
span,
@ -402,7 +436,11 @@ impl<'tcx> NonConstOp<'tcx> for HeapAllocation {
#[derive(Debug)]
pub struct InlineAsm;
impl<'tcx> NonConstOp<'tcx> for InlineAsm {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
struct_span_err!(
ccx.tcx.sess,
span,
@ -418,7 +456,11 @@ pub struct LiveDrop {
pub dropped_at: Option<Span>,
}
impl<'tcx> NonConstOp<'tcx> for LiveDrop {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let mut err = struct_span_err!(
ccx.tcx.sess,
span,
@ -446,7 +488,11 @@ impl<'tcx> NonConstOp<'tcx> for TransientCellBorrow {
// not additionally emit a feature gate error if activating the feature gate won't work.
DiagnosticImportance::Secondary
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_refs_to_cell,
@ -462,7 +508,11 @@ impl<'tcx> NonConstOp<'tcx> for TransientCellBorrow {
/// it in the future for static items.
pub struct CellBorrow;
impl<'tcx> NonConstOp<'tcx> for CellBorrow {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let mut err = struct_span_err!(
ccx.tcx.sess,
span,
@ -509,7 +559,11 @@ impl<'tcx> NonConstOp<'tcx> for MutBorrow {
DiagnosticImportance::Secondary
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let raw = match self.0 {
hir::BorrowKind::Raw => "raw ",
hir::BorrowKind::Ref => "",
@ -548,7 +602,11 @@ impl<'tcx> NonConstOp<'tcx> for TransientMutBorrow {
Status::Unstable(sym::const_mut_refs)
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let raw = match self.0 {
hir::BorrowKind::Raw => "raw ",
hir::BorrowKind::Ref => "",
@ -575,7 +633,11 @@ impl<'tcx> NonConstOp<'tcx> for MutDeref {
DiagnosticImportance::Secondary
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_mut_refs,
@ -589,7 +651,11 @@ impl<'tcx> NonConstOp<'tcx> for MutDeref {
#[derive(Debug)]
pub struct PanicNonStr;
impl<'tcx> NonConstOp<'tcx> for PanicNonStr {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
ccx.tcx.sess.struct_span_err(
span,
"argument to `panic!()` in a const context must have type `&str`",
@ -603,7 +669,11 @@ impl<'tcx> NonConstOp<'tcx> for PanicNonStr {
#[derive(Debug)]
pub struct RawPtrComparison;
impl<'tcx> NonConstOp<'tcx> for RawPtrComparison {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let mut err = ccx
.tcx
.sess
@ -623,7 +693,11 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref {
Status::Unstable(sym::const_mut_refs)
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_mut_refs,
@ -639,7 +713,11 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref {
#[derive(Debug)]
pub struct RawPtrToIntCast;
impl<'tcx> NonConstOp<'tcx> for RawPtrToIntCast {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let mut err = ccx
.tcx
.sess
@ -664,7 +742,11 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let mut err = struct_span_err!(
ccx.tcx.sess,
span,
@ -690,7 +772,11 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess {
#[derive(Debug)]
pub struct ThreadLocalAccess;
impl<'tcx> NonConstOp<'tcx> for ThreadLocalAccess {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
struct_span_err!(
ccx.tcx.sess,
span,
@ -721,7 +807,11 @@ pub mod ty {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_mut_refs,
@ -751,7 +841,11 @@ pub mod ty {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_fn_ptr_basics,
@ -768,7 +862,11 @@ pub mod ty {
Status::Unstable(sym::const_impl_trait)
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_impl_trait,
@ -798,7 +896,11 @@ pub mod ty {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let mut err = feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_trait_bound,
@ -837,7 +939,11 @@ pub mod ty {
}
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
let mut err = feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_fn_trait_bound,
@ -864,7 +970,11 @@ pub mod ty {
Status::Unstable(sym::const_trait_bound_opt_out)
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorReported> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_trait_bound_opt_out,