1
Fork 0

Auto merge of #126996 - oli-obk:do_not_count_errors, r=nnethercote

Automatically taint InferCtxt when errors are emitted

r? `@nnethercote`

Basically `InferCtxt::dcx` now returns a `DiagCtxt` that refers back to the `Cell<Option<ErrorGuaranteed>>` of the `InferCtxt` and thus when invoking `Diag::emit`, and the diagnostic is an error, we taint the `InferCtxt` directly.

That change on its own has no effect at all, because `InferCtxt` already tracks whether errors have been emitted by recording the global error count when it gets opened, and checking at the end whether the count changed. So I removed that error count check, which had a bit of fallout that I immediately fixed by invoking `InferCtxt::dcx` instead of `TyCtxt::dcx` in a bunch of places.

The remaining new errors are because an error was reported in another query, and never bubbled up. I think they are minor enough for this to be ok, and sometimes it actually improves diagnostics, by not silencing useful diagnostics anymore.

fixes #126485 (cc `@olafes)`

There are more improvements we can do (like tainting in hir ty lowering), but I would rather do that in follow up PRs, because it requires some refactorings.
This commit is contained in:
bors 2024-07-01 06:35:58 +00:00
commit 7b21c18fe4
77 changed files with 899 additions and 829 deletions

View file

@ -6,8 +6,8 @@ use rustc_middle::span_bug;
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span; use rustc_span::Span;
impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { pub fn dcx(&self) -> DiagCtxtHandle<'infcx> {
self.infcx.dcx() self.infcx.dcx()
} }
@ -18,7 +18,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
place: &str, place: &str,
borrow_place: &str, borrow_place: &str,
value_place: &str, value_place: &str,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
self.dcx().create_err(crate::session_diagnostics::MoveBorrow { self.dcx().create_err(crate::session_diagnostics::MoveBorrow {
place, place,
span, span,
@ -34,7 +34,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
desc: &str, desc: &str,
borrow_span: Span, borrow_span: Span,
borrow_desc: &str, borrow_desc: &str,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
struct_span_code_err!( struct_span_code_err!(
self.dcx(), self.dcx(),
span, span,
@ -54,7 +54,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
old_loan_span: Span, old_loan_span: Span,
old_opt_via: &str, old_opt_via: &str,
old_load_end_span: Option<Span>, old_load_end_span: Option<Span>,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") };
let mut err = struct_span_code_err!( let mut err = struct_span_code_err!(
self.dcx(), self.dcx(),
@ -101,7 +101,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
desc: &str, desc: &str,
old_loan_span: Span, old_loan_span: Span,
old_load_end_span: Option<Span>, old_load_end_span: Option<Span>,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let mut err = struct_span_code_err!( let mut err = struct_span_code_err!(
self.dcx(), self.dcx(),
new_loan_span, new_loan_span,
@ -134,7 +134,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
noun_old: &str, noun_old: &str,
old_opt_via: &str, old_opt_via: &str,
previous_end_span: Option<Span>, previous_end_span: Option<Span>,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let mut err = struct_span_code_err!( let mut err = struct_span_code_err!(
self.dcx(), self.dcx(),
new_loan_span, new_loan_span,
@ -166,7 +166,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
old_opt_via: &str, old_opt_via: &str,
previous_end_span: Option<Span>, previous_end_span: Option<Span>,
second_borrow_desc: &str, second_borrow_desc: &str,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let mut err = struct_span_code_err!( let mut err = struct_span_code_err!(
self.dcx(), self.dcx(),
new_loan_span, new_loan_span,
@ -198,7 +198,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
kind_old: &str, kind_old: &str,
msg_old: &str, msg_old: &str,
old_load_end_span: Option<Span>, old_load_end_span: Option<Span>,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") };
let mut err = struct_span_code_err!( let mut err = struct_span_code_err!(
self.dcx(), self.dcx(),
@ -239,7 +239,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
span: Span, span: Span,
borrow_span: Span, borrow_span: Span,
desc: &str, desc: &str,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
struct_span_code_err!( struct_span_code_err!(
self.dcx(), self.dcx(),
span, span,
@ -256,12 +256,12 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
span: Span, span: Span,
desc: &str, desc: &str,
is_arg: bool, is_arg: bool,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" }; let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" };
struct_span_code_err!(self.dcx(), span, E0384, "cannot assign {} {}", msg, desc) struct_span_code_err!(self.dcx(), span, E0384, "cannot assign {} {}", msg, desc)
} }
pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'tcx> { pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'infcx> {
struct_span_code_err!(self.dcx(), span, E0594, "cannot assign to {}", desc) struct_span_code_err!(self.dcx(), span, E0594, "cannot assign to {}", desc)
} }
@ -269,7 +269,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self, &self,
move_from_span: Span, move_from_span: Span,
move_from_desc: &str, move_from_desc: &str,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
struct_span_code_err!( struct_span_code_err!(
self.dcx(), self.dcx(),
move_from_span, move_from_span,
@ -287,7 +287,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
move_from_span: Span, move_from_span: Span,
ty: Ty<'_>, ty: Ty<'_>,
is_index: Option<bool>, is_index: Option<bool>,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let type_name = match (&ty.kind(), is_index) { let type_name = match (&ty.kind(), is_index) {
(&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array", (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
(&ty::Slice(_), _) => "slice", (&ty::Slice(_), _) => "slice",
@ -308,7 +308,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self, &self,
move_from_span: Span, move_from_span: Span,
container_ty: Ty<'_>, container_ty: Ty<'_>,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
struct_span_code_err!( struct_span_code_err!(
self.dcx(), self.dcx(),
move_from_span, move_from_span,
@ -325,7 +325,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
verb: &str, verb: &str,
optional_adverb_for_moved: &str, optional_adverb_for_moved: &str,
moved_path: Option<String>, moved_path: Option<String>,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let moved_path = moved_path.map(|mp| format!(": `{mp}`")).unwrap_or_default(); let moved_path = moved_path.map(|mp| format!(": `{mp}`")).unwrap_or_default();
struct_span_code_err!( struct_span_code_err!(
@ -344,7 +344,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
span: Span, span: Span,
path: &str, path: &str,
reason: &str, reason: &str,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
struct_span_code_err!( struct_span_code_err!(
self.dcx(), self.dcx(),
span, span,
@ -362,7 +362,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
immutable_place: &str, immutable_place: &str,
immutable_section: &str, immutable_section: &str,
action: &str, action: &str,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
struct_span_code_err!( struct_span_code_err!(
self.dcx(), self.dcx(),
mutate_span, mutate_span,
@ -380,7 +380,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self, &self,
span: Span, span: Span,
yield_span: Span, yield_span: Span,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind; let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind;
struct_span_code_err!( struct_span_code_err!(
self.dcx(), self.dcx(),
@ -391,7 +391,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
.with_span_label(yield_span, "possible yield occurs here") .with_span_label(yield_span, "possible yield occurs here")
} }
pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'tcx> { pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'infcx> {
struct_span_code_err!( struct_span_code_err!(
self.dcx(), self.dcx(),
borrow_span, borrow_span,
@ -400,7 +400,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
) )
} }
pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'tcx> { pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'infcx> {
struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path,) struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path,)
} }
@ -410,7 +410,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
return_kind: &str, return_kind: &str,
reference_desc: &str, reference_desc: &str,
path_desc: &str, path_desc: &str,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
struct_span_code_err!( struct_span_code_err!(
self.dcx(), self.dcx(),
span, span,
@ -433,7 +433,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
borrowed_path: &str, borrowed_path: &str,
capture_span: Span, capture_span: Span,
scope: &str, scope: &str,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
struct_span_code_err!( struct_span_code_err!(
self.dcx(), self.dcx(),
closure_span, closure_span,
@ -445,7 +445,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
.with_span_label(closure_span, format!("may outlive borrowed value {borrowed_path}")) .with_span_label(closure_span, format!("may outlive borrowed value {borrowed_path}"))
} }
pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'tcx> { pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'infcx> {
struct_span_code_err!( struct_span_code_err!(
self.dcx(), self.dcx(),
span, span,
@ -454,7 +454,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
) )
} }
pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'tcx> { pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'infcx> {
struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed",) struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed",)
} }
} }

View file

@ -15,24 +15,24 @@ use std::fmt;
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext}; use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
/// The results of the dataflow analyses used by the borrow checker. /// The results of the dataflow analyses used by the borrow checker.
pub struct BorrowckResults<'mir, 'tcx> { pub struct BorrowckResults<'a, 'mir, 'tcx> {
pub(crate) borrows: Results<'tcx, Borrows<'mir, 'tcx>>, pub(crate) borrows: Results<'tcx, Borrows<'a, 'mir, 'tcx>>,
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>, pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'mir, 'tcx>>, pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'mir, 'tcx>>,
} }
/// The transient state of the dataflow analyses used by the borrow checker. /// The transient state of the dataflow analyses used by the borrow checker.
#[derive(Debug)] #[derive(Debug)]
pub struct BorrowckFlowState<'mir, 'tcx> { pub struct BorrowckFlowState<'a, 'mir, 'tcx> {
pub(crate) borrows: <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain, pub(crate) borrows: <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) uninits: <MaybeUninitializedPlaces<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain, pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) ever_inits: <EverInitializedPlaces<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain, pub(crate) ever_inits: <EverInitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
} }
impl<'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'mir, 'tcx> { impl<'a, 'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'mir, 'tcx> {
// All three analyses are forward, but we have to use just one here. // All three analyses are forward, but we have to use just one here.
type Direction = <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction; type Direction = <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction;
type FlowState = BorrowckFlowState<'mir, 'tcx>; type FlowState = BorrowckFlowState<'a, 'mir, 'tcx>;
fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState { fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
BorrowckFlowState { BorrowckFlowState {
@ -106,11 +106,11 @@ rustc_index::newtype_index! {
/// `BorrowIndex`, and maps each such index to a `BorrowData` /// `BorrowIndex`, and maps each such index to a `BorrowData`
/// describing the borrow. These indexes are used for representing the /// describing the borrow. These indexes are used for representing the
/// borrows in compact bitvectors. /// borrows in compact bitvectors.
pub struct Borrows<'mir, 'tcx> { pub struct Borrows<'a, 'mir, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>, body: &'mir Body<'tcx>,
borrow_set: &'mir BorrowSet<'tcx>, borrow_set: &'a BorrowSet<'tcx>,
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>, borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
} }
@ -389,12 +389,12 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
} }
} }
impl<'mir, 'tcx> Borrows<'mir, 'tcx> { impl<'a, 'mir, 'tcx> Borrows<'a, 'mir, 'tcx> {
pub fn new( pub fn new(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>, body: &'mir Body<'tcx>,
regioncx: &'mir RegionInferenceContext<'tcx>, regioncx: &RegionInferenceContext<'tcx>,
borrow_set: &'mir BorrowSet<'tcx>, borrow_set: &'a BorrowSet<'tcx>,
) -> Self { ) -> Self {
let mut borrows_out_of_scope_at_location = let mut borrows_out_of_scope_at_location =
calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set); calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set);
@ -494,7 +494,7 @@ impl<'mir, 'tcx> Borrows<'mir, 'tcx> {
} }
} }
impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> { impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, '_, 'tcx> {
type Domain = BitSet<BorrowIndex>; type Domain = BitSet<BorrowIndex>;
const NAME: &'static str = "borrows"; const NAME: &'static str = "borrows";
@ -517,7 +517,7 @@ impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> {
/// region stops containing the CFG points reachable from the issuing location. /// region stops containing the CFG points reachable from the issuing location.
/// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of /// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of
/// `a.b.c` when `a` is overwritten. /// `a.b.c` when `a` is overwritten.
impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, '_, 'tcx> {
type Idx = BorrowIndex; type Idx = BorrowIndex;
fn domain_size(&self, _: &mir::Body<'tcx>) -> usize { fn domain_size(&self, _: &mir::Body<'tcx>) -> usize {
@ -617,8 +617,8 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
} }
} }
impl DebugWithContext<Borrows<'_, '_>> for BorrowIndex { impl DebugWithContext<Borrows<'_, '_, '_>> for BorrowIndex {
fn fmt_with(&self, ctxt: &Borrows<'_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt_with(&self, ctxt: &Borrows<'_, '_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", ctxt.location(*self)) write!(f, "{:?}", ctxt.location(*self))
} }
} }

View file

@ -149,13 +149,13 @@ trait TypeOpInfo<'tcx> {
fn base_universe(&self) -> ty::UniverseIndex; fn base_universe(&self) -> ty::UniverseIndex;
fn nice_error( fn nice_error<'infcx>(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<Diag<'tcx>>; ) -> Option<Diag<'infcx>>;
#[instrument(level = "debug", skip(self, mbcx))] #[instrument(level = "debug", skip(self, mbcx))]
fn report_error( fn report_error(
@ -231,18 +231,25 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
self.base_universe self.base_universe
} }
fn nice_error( fn nice_error<'infcx>(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<Diag<'tcx>> { ) -> Option<Diag<'infcx>> {
let (infcx, key, _) = let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
type_op_prove_predicate_with_cause(&ocx, key, cause); type_op_prove_predicate_with_cause(&ocx, key, cause);
try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) let diag = try_extract_error_from_fulfill_cx(
&ocx,
mbcx.mir_def_id(),
placeholder_region,
error_region,
)?
.with_dcx(mbcx.dcx());
Some(diag)
} }
} }
@ -268,13 +275,13 @@ where
self.base_universe self.base_universe
} }
fn nice_error( fn nice_error<'infcx>(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<Diag<'tcx>> { ) -> Option<Diag<'infcx>> {
let (infcx, key, _) = let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
@ -288,7 +295,14 @@ where
let (param_env, value) = key.into_parts(); let (param_env, value) = key.into_parts();
let _ = ocx.normalize(&cause, param_env, value.value); let _ = ocx.normalize(&cause, param_env, value.value);
try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) let diag = try_extract_error_from_fulfill_cx(
&ocx,
mbcx.mir_def_id(),
placeholder_region,
error_region,
)?
.with_dcx(mbcx.dcx());
Some(diag)
} }
} }
@ -308,18 +322,25 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
self.base_universe self.base_universe
} }
fn nice_error( fn nice_error<'infcx>(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<Diag<'tcx>> { ) -> Option<Diag<'infcx>> {
let (infcx, key, _) = let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?; type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?;
try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) let diag = try_extract_error_from_fulfill_cx(
&ocx,
mbcx.mir_def_id(),
placeholder_region,
error_region,
)?
.with_dcx(mbcx.dcx());
Some(diag)
} }
} }
@ -334,13 +355,13 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
self.base_universe.unwrap() self.base_universe.unwrap()
} }
fn nice_error( fn nice_error<'infcx>(
&self, &self,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
_cause: ObligationCause<'tcx>, _cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<Diag<'tcx>> { ) -> Option<Diag<'infcx>> {
try_extract_error_from_region_constraints( try_extract_error_from_region_constraints(
mbcx.infcx, mbcx.infcx,
mbcx.mir_def_id(), mbcx.mir_def_id(),
@ -358,12 +379,12 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
} }
#[instrument(skip(ocx), level = "debug")] #[instrument(skip(ocx), level = "debug")]
fn try_extract_error_from_fulfill_cx<'tcx>( fn try_extract_error_from_fulfill_cx<'a, 'tcx>(
ocx: &ObligationCtxt<'_, 'tcx>, ocx: &ObligationCtxt<'a, 'tcx>,
generic_param_scope: LocalDefId, generic_param_scope: LocalDefId,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
) -> Option<Diag<'tcx>> { ) -> Option<Diag<'a>> {
// We generally shouldn't have errors here because the query was // We generally shouldn't have errors here because the query was
// already run, but there's no point using `span_delayed_bug` // already run, but there's no point using `span_delayed_bug`
// when we're going to emit an error here anyway. // when we're going to emit an error here anyway.
@ -381,15 +402,15 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
} }
#[instrument(level = "debug", skip(infcx, region_var_origin, universe_of_region))] #[instrument(level = "debug", skip(infcx, region_var_origin, universe_of_region))]
fn try_extract_error_from_region_constraints<'tcx>( fn try_extract_error_from_region_constraints<'a, 'tcx>(
infcx: &InferCtxt<'tcx>, infcx: &'a InferCtxt<'tcx>,
generic_param_scope: LocalDefId, generic_param_scope: LocalDefId,
placeholder_region: ty::Region<'tcx>, placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>, error_region: Option<ty::Region<'tcx>>,
region_constraints: &RegionConstraintData<'tcx>, region_constraints: &RegionConstraintData<'tcx>,
mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin, mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin,
mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex, mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex,
) -> Option<Diag<'tcx>> { ) -> Option<Diag<'a>> {
let placeholder_universe = match placeholder_region.kind() { let placeholder_universe = match placeholder_region.kind() {
ty::RePlaceholder(p) => p.universe, ty::RePlaceholder(p) => p.universe,
ty::ReVar(vid) => universe_of_region(vid), ty::ReVar(vid) => universe_of_region(vid),

View file

@ -73,7 +73,7 @@ enum StorageDeadOrDrop<'tcx> {
Destructor(Ty<'tcx>), Destructor(Ty<'tcx>),
} }
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
pub(crate) fn report_use_of_moved_or_uninitialized( pub(crate) fn report_use_of_moved_or_uninitialized(
&mut self, &mut self,
location: Location, location: Location,
@ -341,7 +341,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
fn suggest_ref_or_clone( fn suggest_ref_or_clone(
&self, &self,
mpi: MovePathIndex, mpi: MovePathIndex,
err: &mut Diag<'tcx>, err: &mut Diag<'infcx>,
in_pattern: &mut bool, in_pattern: &mut bool,
move_spans: UseSpans<'tcx>, move_spans: UseSpans<'tcx>,
) { ) {
@ -517,7 +517,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
desired_action: InitializationRequiringAction, desired_action: InitializationRequiringAction,
span: Span, span: Span,
use_spans: UseSpans<'tcx>, use_spans: UseSpans<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
// We need all statements in the body where the binding was assigned to later find all // We need all statements in the body where the binding was assigned to later find all
// the branching code paths where the binding *wasn't* assigned to. // the branching code paths where the binding *wasn't* assigned to.
let inits = &self.move_data.init_path_map[mpi]; let inits = &self.move_data.init_path_map[mpi];
@ -1461,7 +1461,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
location: Location, location: Location,
(place, _span): (Place<'tcx>, Span), (place, _span): (Place<'tcx>, Span),
borrow: &BorrowData<'tcx>, borrow: &BorrowData<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let borrow_spans = self.retrieve_borrow_spans(borrow); let borrow_spans = self.retrieve_borrow_spans(borrow);
let borrow_span = borrow_spans.args_or_use(); let borrow_span = borrow_spans.args_or_use();
@ -1511,7 +1511,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
(place, span): (Place<'tcx>, Span), (place, span): (Place<'tcx>, Span),
gen_borrow_kind: BorrowKind, gen_borrow_kind: BorrowKind,
issued_borrow: &BorrowData<'tcx>, issued_borrow: &BorrowData<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let issued_spans = self.retrieve_borrow_spans(issued_borrow); let issued_spans = self.retrieve_borrow_spans(issued_borrow);
let issued_span = issued_spans.args_or_use(); let issued_span = issued_spans.args_or_use();
@ -1802,7 +1802,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
err err
} }
fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'tcx>, place: Place<'tcx>) { fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'infcx>, place: Place<'tcx>) {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let hir = tcx.hir(); let hir = tcx.hir();
let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return };
@ -2861,7 +2861,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
drop_span: Span, drop_span: Span,
borrow_spans: UseSpans<'tcx>, borrow_spans: UseSpans<'tcx>,
explanation: BorrowExplanation<'tcx>, explanation: BorrowExplanation<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
debug!( debug!(
"report_local_value_does_not_live_long_enough(\ "report_local_value_does_not_live_long_enough(\
{:?}, {:?}, {:?}, {:?}, {:?}\ {:?}, {:?}, {:?}, {:?}, {:?}\
@ -3036,7 +3036,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self, &self,
drop_span: Span, drop_span: Span,
borrow_span: Span, borrow_span: Span,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
debug!( debug!(
"report_thread_local_value_does_not_live_long_enough(\ "report_thread_local_value_does_not_live_long_enough(\
{:?}, {:?}\ {:?}, {:?}\
@ -3061,7 +3061,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
borrow_spans: UseSpans<'tcx>, borrow_spans: UseSpans<'tcx>,
proper_span: Span, proper_span: Span,
explanation: BorrowExplanation<'tcx>, explanation: BorrowExplanation<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } = if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } =
explanation explanation
{ {
@ -3226,7 +3226,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
return_span: Span, return_span: Span,
category: ConstraintCategory<'tcx>, category: ConstraintCategory<'tcx>,
opt_place_desc: Option<&String>, opt_place_desc: Option<&String>,
) -> Result<(), Diag<'tcx>> { ) -> Result<(), Diag<'infcx>> {
let return_kind = match category { let return_kind = match category {
ConstraintCategory::Return(_) => "return", ConstraintCategory::Return(_) => "return",
ConstraintCategory::Yield => "yield", ConstraintCategory::Yield => "yield",
@ -3319,7 +3319,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
constraint_span: Span, constraint_span: Span,
captured_var: &str, captured_var: &str,
scope: &str, scope: &str,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let args_span = use_span.args_or_use(); let args_span = use_span.args_or_use();
@ -3431,7 +3431,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
upvar_span: Span, upvar_span: Span,
upvar_name: Symbol, upvar_name: Symbol,
escape_span: Span, escape_span: Span,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let escapes_from = tcx.def_descr(self.mir_def_id().to_def_id()); let escapes_from = tcx.def_descr(self.mir_def_id().to_def_id());

View file

@ -69,7 +69,7 @@ pub(super) struct DescribePlaceOpt {
pub(super) struct IncludingTupleField(pub(super) bool); pub(super) struct IncludingTupleField(pub(super) bool);
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
/// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure
/// is moved after being invoked. /// is moved after being invoked.
/// ///
@ -86,7 +86,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self, &self,
location: Location, location: Location,
place: PlaceRef<'tcx>, place: PlaceRef<'tcx>,
diag: &mut Diag<'_>, diag: &mut Diag<'infcx>,
) -> bool { ) -> bool {
debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place); debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place);
let mut target = place.local_or_deref_local(); let mut target = place.local_or_deref_local();

View file

@ -93,7 +93,7 @@ enum GroupedMoveError<'tcx> {
}, },
} }
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
pub(crate) fn report_move_errors(&mut self) { pub(crate) fn report_move_errors(&mut self) {
let grouped_errors = self.group_move_errors(); let grouped_errors = self.group_move_errors();
for error in grouped_errors { for error in grouped_errors {
@ -291,7 +291,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
self.buffer_error(err); self.buffer_error(err);
} }
fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'tcx> { fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'infcx> {
let description = if place.projection.len() == 1 { let description = if place.projection.len() == 1 {
format!("static item {}", self.describe_any_place(place.as_ref())) format!("static item {}", self.describe_any_place(place.as_ref()))
} else { } else {
@ -428,7 +428,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
deref_target_place: Place<'tcx>, deref_target_place: Place<'tcx>,
span: Span, span: Span,
use_spans: Option<UseSpans<'tcx>>, use_spans: Option<UseSpans<'tcx>>,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
// Inspect the type of the content behind the // Inspect the type of the content behind the
// borrow to provide feedback about why this // borrow to provide feedback about why this

View file

@ -30,7 +30,7 @@ pub(crate) enum AccessKind {
Mutate, Mutate,
} }
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
pub(crate) fn report_mutability_error( pub(crate) fn report_mutability_error(
&mut self, &mut self,
access_place: Place<'tcx>, access_place: Place<'tcx>,
@ -541,7 +541,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
} }
/// Suggest `map[k] = v` => `map.insert(k, v)` and the like. /// Suggest `map[k] = v` => `map.insert(k, v)` and the like.
fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diag<'tcx>, span: Span) { fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diag<'infcx>, span: Span) {
let Some(adt) = ty.ty_adt_def() else { return }; let Some(adt) = ty.ty_adt_def() else { return };
let did = adt.did(); let did = adt.did();
if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did) if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did)
@ -550,13 +550,13 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
/// Walks through the HIR, looking for the corresponding span for this error. /// Walks through the HIR, looking for the corresponding span for this error.
/// When it finds it, see if it corresponds to assignment operator whose LHS /// When it finds it, see if it corresponds to assignment operator whose LHS
/// is an index expr. /// is an index expr.
struct SuggestIndexOperatorAlternativeVisitor<'a, 'tcx> { struct SuggestIndexOperatorAlternativeVisitor<'a, 'infcx, 'tcx> {
assign_span: Span, assign_span: Span,
err: &'a mut Diag<'tcx>, err: &'a mut Diag<'infcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
suggested: bool, suggested: bool,
} }
impl<'a, 'tcx> Visitor<'tcx> for SuggestIndexOperatorAlternativeVisitor<'a, 'tcx> { impl<'a, 'cx, 'tcx> Visitor<'tcx> for SuggestIndexOperatorAlternativeVisitor<'a, 'cx, 'tcx> {
fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) { fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) {
hir::intravisit::walk_stmt(self, stmt); hir::intravisit::walk_stmt(self, stmt);
let expr = match stmt.kind { let expr = match stmt.kind {

View file

@ -160,7 +160,7 @@ pub struct ErrorConstraintInfo<'tcx> {
pub(super) span: Span, pub(super) span: Span,
} }
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
/// Converts a region inference variable into a `ty::Region` that /// Converts a region inference variable into a `ty::Region` that
/// we can use for error reporting. If `r` is universally bound, /// we can use for error reporting. If `r` is universally bound,
/// then we use the name that we have on record for it. If `r` is /// then we use the name that we have on record for it. If `r` is
@ -360,7 +360,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
let named_key = self.regioncx.name_regions(self.infcx.tcx, key); let named_key = self.regioncx.name_regions(self.infcx.tcx, key);
let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region); let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region);
let diag = unexpected_hidden_region_diagnostic( let diag = unexpected_hidden_region_diagnostic(
self.infcx.tcx, self.infcx,
self.mir_def_id(), self.mir_def_id(),
span, span,
named_ty, named_ty,
@ -589,7 +589,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self, &self,
errci: &ErrorConstraintInfo<'tcx>, errci: &ErrorConstraintInfo<'tcx>,
kind: ReturnConstraint, kind: ReturnConstraint,
) -> Diag<'tcx> { ) -> Diag<'infcx> {
let ErrorConstraintInfo { outlived_fr, span, .. } = errci; let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
@ -658,7 +658,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
/// | ^^^^^^^^^^ `x` escapes the function body here /// | ^^^^^^^^^^ `x` escapes the function body here
/// ``` /// ```
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'tcx> { fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'infcx> {
let ErrorConstraintInfo { span, category, .. } = errci; let ErrorConstraintInfo { span, category, .. } = errci;
let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region(
@ -767,7 +767,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
/// | is returning data with lifetime `'b` /// | is returning data with lifetime `'b`
/// ``` /// ```
#[allow(rustc::diagnostic_outside_of_impl)] // FIXME #[allow(rustc::diagnostic_outside_of_impl)] // FIXME
fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'tcx> { fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'infcx> {
let ErrorConstraintInfo { let ErrorConstraintInfo {
fr, fr,
fr_is_local, fr_is_local,

View file

@ -310,8 +310,8 @@ fn do_mir_borrowck<'tcx>(
promoted_mbcx.report_move_errors(); promoted_mbcx.report_move_errors();
diags = promoted_mbcx.diags; diags = promoted_mbcx.diags;
struct MoveVisitor<'a, 'b, 'mir, 'cx, 'tcx> { struct MoveVisitor<'a, 'b, 'mir, 'infcx, 'tcx> {
ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'cx, 'tcx>, ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'infcx, 'tcx>,
} }
impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, '_, 'tcx> { impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, '_, 'tcx> {
@ -528,8 +528,8 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {
} }
} }
struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> { struct MirBorrowckCtxt<'a, 'mir, 'infcx, 'tcx> {
infcx: &'cx BorrowckInferCtxt<'tcx>, infcx: &'infcx BorrowckInferCtxt<'tcx>,
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
body: &'mir Body<'tcx>, body: &'mir Body<'tcx>,
move_data: &'a MoveData<'tcx>, move_data: &'a MoveData<'tcx>,
@ -596,7 +596,7 @@ struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> {
/// Results of Polonius analysis. /// Results of Polonius analysis.
polonius_output: Option<Rc<PoloniusOutput>>, polonius_output: Option<Rc<PoloniusOutput>>,
diags: diags::BorrowckDiags<'tcx>, diags: diags::BorrowckDiags<'infcx, 'tcx>,
move_errors: Vec<MoveError<'tcx>>, move_errors: Vec<MoveError<'tcx>>,
} }
@ -605,15 +605,15 @@ struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> {
// 2. loans made in overlapping scopes do not conflict // 2. loans made in overlapping scopes do not conflict
// 3. assignments do not affect things loaned out as immutable // 3. assignments do not affect things loaned out as immutable
// 4. moves do not affect things loaned out in any way // 4. moves do not affect things loaned out in any way
impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
for MirBorrowckCtxt<'_, 'mir, '_, 'tcx> for MirBorrowckCtxt<'a, 'mir, '_, 'tcx>
{ {
type FlowState = Flows<'mir, 'tcx>; type FlowState = Flows<'a, 'mir, 'tcx>;
fn visit_statement_before_primary_effect( fn visit_statement_before_primary_effect(
&mut self, &mut self,
_results: &mut R, _results: &mut R,
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
stmt: &'mir Statement<'tcx>, stmt: &'mir Statement<'tcx>,
location: Location, location: Location,
) { ) {
@ -683,7 +683,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
fn visit_terminator_before_primary_effect( fn visit_terminator_before_primary_effect(
&mut self, &mut self,
_results: &mut R, _results: &mut R,
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
term: &'mir Terminator<'tcx>, term: &'mir Terminator<'tcx>,
loc: Location, loc: Location,
) { ) {
@ -794,7 +794,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
fn visit_terminator_after_primary_effect( fn visit_terminator_after_primary_effect(
&mut self, &mut self,
_results: &mut R, _results: &mut R,
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
term: &'mir Terminator<'tcx>, term: &'mir Terminator<'tcx>,
loc: Location, loc: Location,
) { ) {
@ -988,7 +988,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
place_span: (Place<'tcx>, Span), place_span: (Place<'tcx>, Span),
kind: (AccessDepth, ReadOrWrite), kind: (AccessDepth, ReadOrWrite),
is_local_mutation_allowed: LocalMutationIsAllowed, is_local_mutation_allowed: LocalMutationIsAllowed,
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
) { ) {
let (sd, rw) = kind; let (sd, rw) = kind;
@ -1038,7 +1038,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
place_span: (Place<'tcx>, Span), place_span: (Place<'tcx>, Span),
sd: AccessDepth, sd: AccessDepth,
rw: ReadOrWrite, rw: ReadOrWrite,
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
) -> bool { ) -> bool {
let mut error_reported = false; let mut error_reported = false;
let borrow_set = Rc::clone(&self.borrow_set); let borrow_set = Rc::clone(&self.borrow_set);
@ -1179,7 +1179,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location, location: Location,
place_span: (Place<'tcx>, Span), place_span: (Place<'tcx>, Span),
kind: AccessDepth, kind: AccessDepth,
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
) { ) {
// Write of P[i] or *P requires P init'd. // Write of P[i] or *P requires P init'd.
self.check_if_assigned_path_is_moved(location, place_span, flow_state); self.check_if_assigned_path_is_moved(location, place_span, flow_state);
@ -1197,7 +1197,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
&mut self, &mut self,
location: Location, location: Location,
(rvalue, span): (&'mir Rvalue<'tcx>, Span), (rvalue, span): (&'mir Rvalue<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
) { ) {
match rvalue { match rvalue {
&Rvalue::Ref(_ /*rgn*/, bk, place) => { &Rvalue::Ref(_ /*rgn*/, bk, place) => {
@ -1455,7 +1455,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
&mut self, &mut self,
location: Location, location: Location,
(operand, span): (&'mir Operand<'tcx>, Span), (operand, span): (&'mir Operand<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
) { ) {
match *operand { match *operand {
Operand::Copy(place) => { Operand::Copy(place) => {
@ -1579,7 +1579,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
&mut self, &mut self,
location: Location, location: Location,
span: Span, span: Span,
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
) { ) {
// Two-phase borrow support: For each activation that is newly // Two-phase borrow support: For each activation that is newly
// generated at this statement, check if it interferes with // generated at this statement, check if it interferes with
@ -1743,7 +1743,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location, location: Location,
desired_action: InitializationRequiringAction, desired_action: InitializationRequiringAction,
place_span: (PlaceRef<'tcx>, Span), place_span: (PlaceRef<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
) { ) {
let maybe_uninits = &flow_state.uninits; let maybe_uninits = &flow_state.uninits;
@ -1848,7 +1848,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location, location: Location,
desired_action: InitializationRequiringAction, desired_action: InitializationRequiringAction,
place_span: (PlaceRef<'tcx>, Span), place_span: (PlaceRef<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
) { ) {
let maybe_uninits = &flow_state.uninits; let maybe_uninits = &flow_state.uninits;
@ -1947,7 +1947,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
&mut self, &mut self,
location: Location, location: Location,
(place, span): (Place<'tcx>, Span), (place, span): (Place<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
) { ) {
debug!("check_if_assigned_path_is_moved place: {:?}", place); debug!("check_if_assigned_path_is_moved place: {:?}", place);
@ -2013,7 +2013,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location, location: Location,
base: PlaceRef<'tcx>, base: PlaceRef<'tcx>,
span: Span, span: Span,
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
) { ) {
// rust-lang/rust#21232: Until Rust allows reads from the // rust-lang/rust#21232: Until Rust allows reads from the
// initialized parts of partially initialized structs, we // initialized parts of partially initialized structs, we
@ -2104,7 +2104,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
(place, span): (Place<'tcx>, Span), (place, span): (Place<'tcx>, Span),
kind: ReadOrWrite, kind: ReadOrWrite,
is_local_mutation_allowed: LocalMutationIsAllowed, is_local_mutation_allowed: LocalMutationIsAllowed,
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
location: Location, location: Location,
) -> bool { ) -> bool {
debug!( debug!(
@ -2220,7 +2220,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
fn is_local_ever_initialized( fn is_local_ever_initialized(
&self, &self,
local: Local, local: Local,
flow_state: &Flows<'mir, 'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>,
) -> Option<InitIndex> { ) -> Option<InitIndex> {
let mpi = self.move_data.rev_lookup.find_local(local)?; let mpi = self.move_data.rev_lookup.find_local(local)?;
let ii = &self.move_data.init_path_map[mpi]; let ii = &self.move_data.init_path_map[mpi];
@ -2228,7 +2228,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
} }
/// Adds the place into the used mutable variables set /// Adds the place into the used mutable variables set
fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'mir, 'tcx>) { fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>) {
match root_place { match root_place {
RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => { RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => {
// If the local may have been initialized, and it is now currently being // If the local may have been initialized, and it is now currently being
@ -2428,12 +2428,12 @@ mod diags {
use super::*; use super::*;
enum BufferedDiag<'tcx> { enum BufferedDiag<'infcx> {
Error(Diag<'tcx>), Error(Diag<'infcx>),
NonError(Diag<'tcx, ()>), NonError(Diag<'infcx, ()>),
} }
impl<'tcx> BufferedDiag<'tcx> { impl<'infcx> BufferedDiag<'infcx> {
fn sort_span(&self) -> Span { fn sort_span(&self) -> Span {
match self { match self {
BufferedDiag::Error(diag) => diag.sort_span, BufferedDiag::Error(diag) => diag.sort_span,
@ -2442,7 +2442,7 @@ mod diags {
} }
} }
pub struct BorrowckDiags<'tcx> { pub struct BorrowckDiags<'infcx, 'tcx> {
/// This field keeps track of move errors that are to be reported for given move indices. /// This field keeps track of move errors that are to be reported for given move indices.
/// ///
/// There are situations where many errors can be reported for a single move out (see /// There are situations where many errors can be reported for a single move out (see
@ -2457,15 +2457,15 @@ mod diags {
/// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary
/// when errors in the map are being re-added to the error buffer so that errors with the /// when errors in the map are being re-added to the error buffer so that errors with the
/// same primary span come out in a consistent order. /// same primary span come out in a consistent order.
buffered_move_errors: BTreeMap<Vec<MoveOutIndex>, (PlaceRef<'tcx>, Diag<'tcx>)>, buffered_move_errors: BTreeMap<Vec<MoveOutIndex>, (PlaceRef<'tcx>, Diag<'infcx>)>,
buffered_mut_errors: FxIndexMap<Span, (Diag<'tcx>, usize)>, buffered_mut_errors: FxIndexMap<Span, (Diag<'infcx>, usize)>,
/// Buffer of diagnostics to be reported. A mixture of error and non-error diagnostics. /// Buffer of diagnostics to be reported. A mixture of error and non-error diagnostics.
buffered_diags: Vec<BufferedDiag<'tcx>>, buffered_diags: Vec<BufferedDiag<'infcx>>,
} }
impl<'tcx> BorrowckDiags<'tcx> { impl<'infcx, 'tcx> BorrowckDiags<'infcx, 'tcx> {
pub fn new() -> Self { pub fn new() -> Self {
BorrowckDiags { BorrowckDiags {
buffered_move_errors: BTreeMap::new(), buffered_move_errors: BTreeMap::new(),
@ -2474,28 +2474,28 @@ mod diags {
} }
} }
pub fn buffer_error(&mut self, diag: Diag<'tcx>) { pub fn buffer_error(&mut self, diag: Diag<'infcx>) {
self.buffered_diags.push(BufferedDiag::Error(diag)); self.buffered_diags.push(BufferedDiag::Error(diag));
} }
pub fn buffer_non_error(&mut self, diag: Diag<'tcx, ()>) { pub fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
self.buffered_diags.push(BufferedDiag::NonError(diag)); self.buffered_diags.push(BufferedDiag::NonError(diag));
} }
} }
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
pub fn buffer_error(&mut self, diag: Diag<'tcx>) { pub fn buffer_error(&mut self, diag: Diag<'infcx>) {
self.diags.buffer_error(diag); self.diags.buffer_error(diag);
} }
pub fn buffer_non_error(&mut self, diag: Diag<'tcx, ()>) { pub fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
self.diags.buffer_non_error(diag); self.diags.buffer_non_error(diag);
} }
pub fn buffer_move_error( pub fn buffer_move_error(
&mut self, &mut self,
move_out_indices: Vec<MoveOutIndex>, move_out_indices: Vec<MoveOutIndex>,
place_and_err: (PlaceRef<'tcx>, Diag<'tcx>), place_and_err: (PlaceRef<'tcx>, Diag<'infcx>),
) -> bool { ) -> bool {
if let Some((_, diag)) = if let Some((_, diag)) =
self.diags.buffered_move_errors.insert(move_out_indices, place_and_err) self.diags.buffered_move_errors.insert(move_out_indices, place_and_err)
@ -2508,12 +2508,12 @@ mod diags {
} }
} }
pub fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'tcx>, usize)> { pub fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'infcx>, usize)> {
// FIXME(#120456) - is `swap_remove` correct? // FIXME(#120456) - is `swap_remove` correct?
self.diags.buffered_mut_errors.swap_remove(&span) self.diags.buffered_mut_errors.swap_remove(&span)
} }
pub fn buffer_mut_error(&mut self, span: Span, diag: Diag<'tcx>, count: usize) { pub fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) {
self.diags.buffered_mut_errors.insert(span, (diag, count)); self.diags.buffered_mut_errors.insert(span, (diag, count));
} }
@ -2554,7 +2554,7 @@ mod diags {
pub fn has_move_error( pub fn has_move_error(
&self, &self,
move_out_indices: &[MoveOutIndex], move_out_indices: &[MoveOutIndex],
) -> Option<&(PlaceRef<'tcx>, Diag<'tcx>)> { ) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> {
self.diags.buffered_move_errors.get(move_out_indices) self.diags.buffered_move_errors.get(move_out_indices)
} }
} }

View file

@ -81,7 +81,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
promoted: &IndexSlice<Promoted, Body<'tcx>>, promoted: &IndexSlice<Promoted, Body<'tcx>>,
location_table: &LocationTable, location_table: &LocationTable,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'cx, 'tcx>>, flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'_, 'cx, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
upvars: &[&ty::CapturedPlace<'tcx>], upvars: &[&ty::CapturedPlace<'tcx>],
@ -262,13 +262,13 @@ pub(super) fn dump_mir_results<'tcx>(
#[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
pub(super) fn dump_annotation<'tcx>( pub(super) fn dump_annotation<'tcx, 'cx>(
infcx: &BorrowckInferCtxt<'tcx>, infcx: &'cx BorrowckInferCtxt<'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
regioncx: &RegionInferenceContext<'tcx>, regioncx: &RegionInferenceContext<'tcx>,
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>, closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
opaque_type_values: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>, opaque_type_values: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
diags: &mut crate::diags::BorrowckDiags<'tcx>, diags: &mut crate::diags::BorrowckDiags<'cx, 'tcx>,
) { ) {
let tcx = infcx.tcx; let tcx = infcx.tcx;
let base_def_id = tcx.typeck_root_def_id(body.source.def_id()); let base_def_id = tcx.typeck_root_def_id(body.source.def_id());
@ -285,7 +285,7 @@ pub(super) fn dump_annotation<'tcx>(
let def_span = tcx.def_span(body.source.def_id()); let def_span = tcx.def_span(body.source.def_id());
let mut err = if let Some(closure_region_requirements) = closure_region_requirements { let mut err = if let Some(closure_region_requirements) = closure_region_requirements {
let mut err = tcx.dcx().struct_span_note(def_span, "external requirements"); let mut err = infcx.dcx().struct_span_note(def_span, "external requirements");
regioncx.annotate(tcx, &mut err); regioncx.annotate(tcx, &mut err);
@ -304,7 +304,7 @@ pub(super) fn dump_annotation<'tcx>(
err err
} else { } else {
let mut err = tcx.dcx().struct_span_note(def_span, "no external requirements"); let mut err = infcx.dcx().struct_span_note(def_span, "no external requirements");
regioncx.annotate(tcx, &mut err); regioncx.annotate(tcx, &mut err);
err err

View file

@ -285,7 +285,7 @@ impl<'tcx> InferCtxt<'tcx> {
} }
if let Err(guar) = if let Err(guar) =
check_opaque_type_parameter_valid(self.tcx, opaque_type_key, instantiated_ty.span) check_opaque_type_parameter_valid(self, opaque_type_key, instantiated_ty.span)
{ {
return Ty::new_error(self.tcx, guar); return Ty::new_error(self.tcx, guar);
} }
@ -294,6 +294,10 @@ impl<'tcx> InferCtxt<'tcx> {
.remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false) .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false)
.ty; .ty;
if let Err(e) = definition_ty.error_reported() {
return Ty::new_error(self.tcx, e);
}
// `definition_ty` does not live in of the current inference context, // `definition_ty` does not live in of the current inference context,
// so lets make sure that we don't accidentally misuse our current `infcx`. // so lets make sure that we don't accidentally misuse our current `infcx`.
match check_opaque_type_well_formed( match check_opaque_type_well_formed(
@ -387,10 +391,11 @@ fn check_opaque_type_well_formed<'tcx>(
/// [rustc-dev-guide chapter]: /// [rustc-dev-guide chapter]:
/// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html /// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html
fn check_opaque_type_parameter_valid<'tcx>( fn check_opaque_type_parameter_valid<'tcx>(
tcx: TyCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
opaque_type_key: OpaqueTypeKey<'tcx>, opaque_type_key: OpaqueTypeKey<'tcx>,
span: Span, span: Span,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let tcx = infcx.tcx;
let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id); let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id);
let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
@ -420,7 +425,7 @@ fn check_opaque_type_parameter_valid<'tcx>(
opaque_env.param_is_error(i)?; opaque_env.param_is_error(i)?;
return Err(tcx.dcx().emit_err(NonGenericOpaqueTypeParam { return Err(infcx.dcx().emit_err(NonGenericOpaqueTypeParam {
ty: arg, ty: arg,
kind, kind,
span, span,
@ -438,7 +443,7 @@ fn check_opaque_type_parameter_valid<'tcx>(
.collect(); .collect();
#[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
return Err(tcx return Err(infcx
.dcx() .dcx()
.struct_span_err(span, "non-defining opaque type use in defining scope") .struct_span_err(span, "non-defining opaque type use in defining scope")
.with_span_note(spans, format!("{descr} used multiple times")) .with_span_note(spans, format!("{descr} used multiple times"))

View file

@ -34,7 +34,7 @@ pub(super) fn generate<'mir, 'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>, typeck: &mut TypeChecker<'_, 'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
elements: &Rc<DenseLocationMap>, elements: &Rc<DenseLocationMap>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
) { ) {
debug!("liveness::generate"); debug!("liveness::generate");

View file

@ -43,7 +43,7 @@ pub(super) fn trace<'mir, 'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>, typeck: &mut TypeChecker<'_, 'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
elements: &Rc<DenseLocationMap>, elements: &Rc<DenseLocationMap>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
relevant_live_locals: Vec<Local>, relevant_live_locals: Vec<Local>,
boring_locals: Vec<Local>, boring_locals: Vec<Local>,
@ -101,7 +101,7 @@ pub(super) fn trace<'mir, 'tcx>(
} }
/// Contextual state for the type-liveness coroutine. /// Contextual state for the type-liveness coroutine.
struct LivenessContext<'me, 'typeck, 'flow, 'tcx> { struct LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx> {
/// Current type-checker, giving us our inference context etc. /// Current type-checker, giving us our inference context etc.
typeck: &'me mut TypeChecker<'typeck, 'tcx>, typeck: &'me mut TypeChecker<'typeck, 'tcx>,
@ -119,7 +119,7 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> {
/// Results of dataflow tracking which variables (and paths) have been /// Results of dataflow tracking which variables (and paths) have been
/// initialized. /// initialized.
flow_inits: &'me mut ResultsCursor<'flow, 'tcx, MaybeInitializedPlaces<'flow, 'tcx>>, flow_inits: &'me mut ResultsCursor<'flow, 'tcx, MaybeInitializedPlaces<'a, 'flow, 'tcx>>,
/// Index indicating where each variable is assigned, used, or /// Index indicating where each variable is assigned, used, or
/// dropped. /// dropped.
@ -131,8 +131,8 @@ struct DropData<'tcx> {
region_constraint_data: Option<&'tcx QueryRegionConstraints<'tcx>>, region_constraint_data: Option<&'tcx QueryRegionConstraints<'tcx>>,
} }
struct LivenessResults<'me, 'typeck, 'flow, 'tcx> { struct LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>, cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>,
/// Set of points that define the current local. /// Set of points that define the current local.
defs: BitSet<PointIndex>, defs: BitSet<PointIndex>,
@ -153,8 +153,8 @@ struct LivenessResults<'me, 'typeck, 'flow, 'tcx> {
stack: Vec<PointIndex>, stack: Vec<PointIndex>,
} }
impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> { impl<'a, 'me, 'typeck, 'flow, 'tcx> LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
fn new(cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>) -> Self { fn new(cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>) -> Self {
let num_points = cx.elements.num_points(); let num_points = cx.elements.num_points();
LivenessResults { LivenessResults {
cx, cx,
@ -507,7 +507,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
} }
} }
impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { impl<'tcx> LivenessContext<'_, '_, '_, '_, 'tcx> {
/// Returns `true` if the local variable (or some part of it) is initialized at the current /// Returns `true` if the local variable (or some part of it) is initialized at the current
/// cursor position. Callers should call one of the `seek` methods immediately before to point /// cursor position. Callers should call one of the `seek` methods immediately before to point
/// the cursor to the desired location. /// the cursor to the desired location.

View file

@ -129,7 +129,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
location_table: &LocationTable, location_table: &LocationTable,
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
all_facts: &mut Option<AllFacts>, all_facts: &mut Option<AllFacts>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
elements: &Rc<DenseLocationMap>, elements: &Rc<DenseLocationMap>,
upvars: &[&ty::CapturedPlace<'tcx>], upvars: &[&ty::CapturedPlace<'tcx>],

View file

@ -45,10 +45,10 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
/// MIR visitor for collecting used mutable variables. /// MIR visitor for collecting used mutable variables.
/// The 'visit lifetime represents the duration of the MIR walk. /// The 'visit lifetime represents the duration of the MIR walk.
struct GatherUsedMutsVisitor<'visit, 'a, 'mir, 'cx, 'tcx> { struct GatherUsedMutsVisitor<'visit, 'a, 'mir, 'infcx, 'tcx> {
temporary_used_locals: FxIndexSet<Local>, temporary_used_locals: FxIndexSet<Local>,
never_initialized_mut_locals: &'visit mut FxIndexSet<Local>, never_initialized_mut_locals: &'visit mut FxIndexSet<Local>,
mbcx: &'visit mut MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx>, mbcx: &'visit mut MirBorrowckCtxt<'a, 'mir, 'infcx, 'tcx>,
} }
impl GatherUsedMutsVisitor<'_, '_, '_, '_, '_> { impl GatherUsedMutsVisitor<'_, '_, '_, '_, '_> {

View file

@ -510,7 +510,7 @@ pub struct Diag<'a, G: EmissionGuarantee = ErrorGuaranteed> {
// would be bad. // would be bad.
impl<G> !Clone for Diag<'_, G> {} impl<G> !Clone for Diag<'_, G> {}
rustc_data_structures::static_assert_size!(Diag<'_, ()>, 2 * std::mem::size_of::<usize>()); rustc_data_structures::static_assert_size!(Diag<'_, ()>, 3 * std::mem::size_of::<usize>());
impl<G: EmissionGuarantee> Deref for Diag<'_, G> { impl<G: EmissionGuarantee> Deref for Diag<'_, G> {
type Target = DiagInner; type Target = DiagInner;
@ -582,6 +582,11 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
Self::new_diagnostic(dcx, DiagInner::new(level, message)) Self::new_diagnostic(dcx, DiagInner::new(level, message))
} }
/// Allow moving diagnostics between different error tainting contexts
pub fn with_dcx(mut self, dcx: DiagCtxtHandle<'_>) -> Diag<'_, G> {
Diag { dcx, diag: self.diag.take(), _marker: PhantomData }
}
/// Creates a new `Diag` with an already constructed diagnostic. /// Creates a new `Diag` with an already constructed diagnostic.
#[track_caller] #[track_caller]
pub(crate) fn new_diagnostic(dcx: DiagCtxtHandle<'a>, diag: DiagInner) -> Self { pub(crate) fn new_diagnostic(dcx: DiagCtxtHandle<'a>, diag: DiagInner) -> Self {

View file

@ -63,6 +63,7 @@ use rustc_span::source_map::SourceMap;
use rustc_span::{Loc, Span, DUMMY_SP}; use rustc_span::{Loc, Span, DUMMY_SP};
use std::backtrace::{Backtrace, BacktraceStatus}; use std::backtrace::{Backtrace, BacktraceStatus};
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::Cell;
use std::error::Report; use std::error::Report;
use std::fmt; use std::fmt;
use std::hash::Hash; use std::hash::Hash;
@ -98,9 +99,9 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger. // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
rustc_data_structures::static_assert_size!(PResult<'_, ()>, 16); rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24);
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
rustc_data_structures::static_assert_size!(PResult<'_, bool>, 16); rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24);
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)] #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)]
pub enum SuggestionStyle { pub enum SuggestionStyle {
@ -417,6 +418,9 @@ pub struct DiagCtxt {
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct DiagCtxtHandle<'a> { pub struct DiagCtxtHandle<'a> {
dcx: &'a DiagCtxt, dcx: &'a DiagCtxt,
/// Some contexts create `DiagCtxtHandle` with this field set, and thus all
/// errors emitted with it will automatically taint when emitting errors.
tainted_with_errors: Option<&'a Cell<Option<ErrorGuaranteed>>>,
} }
impl<'a> std::ops::Deref for DiagCtxtHandle<'a> { impl<'a> std::ops::Deref for DiagCtxtHandle<'a> {
@ -752,7 +756,17 @@ impl DiagCtxt {
} }
pub fn handle<'a>(&'a self) -> DiagCtxtHandle<'a> { pub fn handle<'a>(&'a self) -> DiagCtxtHandle<'a> {
DiagCtxtHandle { dcx: self } DiagCtxtHandle { dcx: self, tainted_with_errors: None }
}
/// Link this to a taintable context so that emitting errors will automatically set
/// the `Option<ErrorGuaranteed>` instead of having to do that manually at every error
/// emission site.
pub fn taintable_handle<'a>(
&'a self,
tainted_with_errors: &'a Cell<Option<ErrorGuaranteed>>,
) -> DiagCtxtHandle<'a> {
DiagCtxtHandle { dcx: self, tainted_with_errors: Some(tainted_with_errors) }
} }
} }
@ -795,7 +809,9 @@ impl<'a> DiagCtxtHandle<'a> {
// can be used to create a backtrace at the stashing site insted of whenever the // can be used to create a backtrace at the stashing site insted of whenever the
// diagnostic context is dropped and thus delayed bugs are emitted. // diagnostic context is dropped and thus delayed bugs are emitted.
Error => Some(self.span_delayed_bug(span, format!("stashing {key:?}"))), Error => Some(self.span_delayed_bug(span, format!("stashing {key:?}"))),
DelayedBug => return self.inner.borrow_mut().emit_diagnostic(diag), DelayedBug => {
return self.inner.borrow_mut().emit_diagnostic(diag, self.tainted_with_errors);
}
ForceWarning(_) | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow ForceWarning(_) | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow
| Expect(_) => None, | Expect(_) => None,
}; };
@ -947,16 +963,19 @@ impl<'a> DiagCtxtHandle<'a> {
(0, _) => { (0, _) => {
// Use `ForceWarning` rather than `Warning` to guarantee emission, e.g. with a // Use `ForceWarning` rather than `Warning` to guarantee emission, e.g. with a
// configuration like `--cap-lints allow --force-warn bare_trait_objects`. // configuration like `--cap-lints allow --force-warn bare_trait_objects`.
inner.emit_diagnostic(DiagInner::new( inner.emit_diagnostic(
ForceWarning(None), DiagInner::new(ForceWarning(None), DiagMessage::Str(warnings)),
DiagMessage::Str(warnings), None,
)); );
} }
(_, 0) => { (_, 0) => {
inner.emit_diagnostic(DiagInner::new(Error, errors)); inner.emit_diagnostic(DiagInner::new(Error, errors), self.tainted_with_errors);
} }
(_, _) => { (_, _) => {
inner.emit_diagnostic(DiagInner::new(Error, format!("{errors}; {warnings}"))); inner.emit_diagnostic(
DiagInner::new(Error, format!("{errors}; {warnings}")),
self.tainted_with_errors,
);
} }
} }
@ -987,14 +1006,14 @@ impl<'a> DiagCtxtHandle<'a> {
"For more information about an error, try `rustc --explain {}`.", "For more information about an error, try `rustc --explain {}`.",
&error_codes[0] &error_codes[0]
); );
inner.emit_diagnostic(DiagInner::new(FailureNote, msg1)); inner.emit_diagnostic(DiagInner::new(FailureNote, msg1), None);
inner.emit_diagnostic(DiagInner::new(FailureNote, msg2)); inner.emit_diagnostic(DiagInner::new(FailureNote, msg2), None);
} else { } else {
let msg = format!( let msg = format!(
"For more information about this error, try `rustc --explain {}`.", "For more information about this error, try `rustc --explain {}`.",
&error_codes[0] &error_codes[0]
); );
inner.emit_diagnostic(DiagInner::new(FailureNote, msg)); inner.emit_diagnostic(DiagInner::new(FailureNote, msg), None);
} }
} }
} }
@ -1020,7 +1039,7 @@ impl<'a> DiagCtxtHandle<'a> {
} }
pub fn emit_diagnostic(&self, diagnostic: DiagInner) -> Option<ErrorGuaranteed> { pub fn emit_diagnostic(&self, diagnostic: DiagInner) -> Option<ErrorGuaranteed> {
self.inner.borrow_mut().emit_diagnostic(diagnostic) self.inner.borrow_mut().emit_diagnostic(diagnostic, self.tainted_with_errors)
} }
pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
@ -1080,7 +1099,7 @@ impl<'a> DiagCtxtHandle<'a> {
// Here the diagnostic is given back to `emit_diagnostic` where it was first // Here the diagnostic is given back to `emit_diagnostic` where it was first
// intercepted. Now it should be processed as usual, since the unstable expectation // intercepted. Now it should be processed as usual, since the unstable expectation
// id is now stable. // id is now stable.
inner.emit_diagnostic(diag); inner.emit_diagnostic(diag, self.tainted_with_errors);
} }
} }
@ -1430,13 +1449,17 @@ impl DiagCtxtInner {
continue; continue;
} }
} }
guar = guar.or(self.emit_diagnostic(diag)); guar = guar.or(self.emit_diagnostic(diag, None));
} }
guar guar
} }
// Return value is only `Some` if the level is `Error` or `DelayedBug`. // Return value is only `Some` if the level is `Error` or `DelayedBug`.
fn emit_diagnostic(&mut self, mut diagnostic: DiagInner) -> Option<ErrorGuaranteed> { fn emit_diagnostic(
&mut self,
mut diagnostic: DiagInner,
taint: Option<&Cell<Option<ErrorGuaranteed>>>,
) -> Option<ErrorGuaranteed> {
match diagnostic.level { match diagnostic.level {
Expect(expect_id) | ForceWarning(Some(expect_id)) => { Expect(expect_id) | ForceWarning(Some(expect_id)) => {
// The `LintExpectationId` can be stable or unstable depending on when it was // The `LintExpectationId` can be stable or unstable depending on when it was
@ -1609,6 +1632,9 @@ impl DiagCtxtInner {
if is_lint { if is_lint {
self.lint_err_guars.push(guar); self.lint_err_guars.push(guar);
} else { } else {
if let Some(taint) = taint {
taint.set(Some(guar));
}
self.err_guars.push(guar); self.err_guars.push(guar);
} }
self.panic_if_treat_err_as_bug(); self.panic_if_treat_err_as_bug();
@ -1718,8 +1744,8 @@ impl DiagCtxtInner {
// `-Ztreat-err-as-bug`, which we don't want. // `-Ztreat-err-as-bug`, which we don't want.
let note1 = "no errors encountered even though delayed bugs were created"; let note1 = "no errors encountered even though delayed bugs were created";
let note2 = "those delayed bugs will now be shown as internal compiler errors"; let note2 = "those delayed bugs will now be shown as internal compiler errors";
self.emit_diagnostic(DiagInner::new(Note, note1)); self.emit_diagnostic(DiagInner::new(Note, note1), None);
self.emit_diagnostic(DiagInner::new(Note, note2)); self.emit_diagnostic(DiagInner::new(Note, note2), None);
for bug in bugs { for bug in bugs {
if let Some(out) = &mut out { if let Some(out) = &mut out {
@ -1752,7 +1778,7 @@ impl DiagCtxtInner {
} }
bug.level = Bug; bug.level = Bug;
self.emit_diagnostic(bug); self.emit_diagnostic(bug, None);
} }
// Panic with `DelayedBugPanic` to avoid "unexpected panic" messages. // Panic with `DelayedBugPanic` to avoid "unexpected panic" messages.

View file

@ -319,7 +319,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
} else { } else {
errors::CannotCastToBoolHelp::Unsupported(self.span) errors::CannotCastToBoolHelp::Unsupported(self.span)
}; };
fcx.tcx.dcx().emit_err(errors::CannotCastToBool { span: self.span, expr_ty, help }); fcx.dcx().emit_err(errors::CannotCastToBool { span: self.span, expr_ty, help });
} }
CastError::CastToChar => { CastError::CastToChar => {
let mut err = type_error_struct!( let mut err = type_error_struct!(

View file

@ -1797,16 +1797,16 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
err.subdiagnostic(SuggestBoxingForReturnImplTrait::BoxReturnExpr { starts, ends }); err.subdiagnostic(SuggestBoxingForReturnImplTrait::BoxReturnExpr { starts, ends });
} }
fn report_return_mismatched_types<'a>( fn report_return_mismatched_types<'infcx>(
&self, &self,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
ty_err: TypeError<'tcx>, ty_err: TypeError<'tcx>,
fcx: &FnCtxt<'a, 'tcx>, fcx: &'infcx FnCtxt<'_, 'tcx>,
block_or_return_id: hir::HirId, block_or_return_id: hir::HirId,
expression: Option<&'tcx hir::Expr<'tcx>>, expression: Option<&'tcx hir::Expr<'tcx>>,
) -> Diag<'a> { ) -> Diag<'infcx> {
let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err); let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err);
let due_to_block = matches!(fcx.tcx.hir_node(block_or_return_id), hir::Node::Block(..)); let due_to_block = matches!(fcx.tcx.hir_node(block_or_return_id), hir::Node::Block(..));

View file

@ -172,21 +172,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
pub fn demand_suptype_diag( pub fn demand_suptype_diag(
&self, &'a self,
sp: Span, sp: Span,
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
) -> Result<(), Diag<'tcx>> { ) -> Result<(), Diag<'a>> {
self.demand_suptype_with_origin(&self.misc(sp), expected, actual) self.demand_suptype_with_origin(&self.misc(sp), expected, actual)
} }
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
pub fn demand_suptype_with_origin( pub fn demand_suptype_with_origin(
&self, &'a self,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
) -> Result<(), Diag<'tcx>> { ) -> Result<(), Diag<'a>> {
self.at(cause, self.param_env) self.at(cause, self.param_env)
.sup(DefineOpaqueTypes::Yes, expected, actual) .sup(DefineOpaqueTypes::Yes, expected, actual)
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
@ -200,20 +200,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
pub fn demand_eqtype_diag( pub fn demand_eqtype_diag(
&self, &'a self,
sp: Span, sp: Span,
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
) -> Result<(), Diag<'tcx>> { ) -> Result<(), Diag<'a>> {
self.demand_eqtype_with_origin(&self.misc(sp), expected, actual) self.demand_eqtype_with_origin(&self.misc(sp), expected, actual)
} }
pub fn demand_eqtype_with_origin( pub fn demand_eqtype_with_origin(
&self, &'a self,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
) -> Result<(), Diag<'tcx>> { ) -> Result<(), Diag<'a>> {
self.at(cause, self.param_env) self.at(cause, self.param_env)
.eq(DefineOpaqueTypes::Yes, expected, actual) .eq(DefineOpaqueTypes::Yes, expected, actual)
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
@ -247,13 +247,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// will be permitted if the diverges flag is currently "always". /// will be permitted if the diverges flag is currently "always".
#[instrument(level = "debug", skip(self, expr, expected_ty_expr, allow_two_phase))] #[instrument(level = "debug", skip(self, expr, expected_ty_expr, allow_two_phase))]
pub fn demand_coerce_diag( pub fn demand_coerce_diag(
&self, &'a self,
mut expr: &'tcx hir::Expr<'tcx>, mut expr: &'tcx hir::Expr<'tcx>,
checked_ty: Ty<'tcx>, checked_ty: Ty<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
allow_two_phase: AllowTwoPhase, allow_two_phase: AllowTwoPhase,
) -> Result<Ty<'tcx>, Diag<'tcx>> { ) -> Result<Ty<'tcx>, Diag<'a>> {
let expected = self.resolve_vars_with_obligations(expected); let expected = self.resolve_vars_with_obligations(expected);
let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) { let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) {

View file

@ -638,7 +638,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Set expectation to error in that case and set tainted // Set expectation to error in that case and set tainted
// by error (#114529) // by error (#114529)
let coerce_to = opt_coerce_to.unwrap_or_else(|| { let coerce_to = opt_coerce_to.unwrap_or_else(|| {
let guar = tcx.dcx().span_delayed_bug( let guar = self.dcx().span_delayed_bug(
expr.span, expr.span,
"illegal break with value found but no error reported", "illegal break with value found but no error reported",
); );
@ -1716,7 +1716,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else { } else {
error_happened = true; error_happened = true;
let guar = if let Some(prev_span) = seen_fields.get(&ident) { let guar = if let Some(prev_span) = seen_fields.get(&ident) {
tcx.dcx().emit_err(FieldMultiplySpecifiedInInitializer { self.dcx().emit_err(FieldMultiplySpecifiedInInitializer {
span: field.ident.span, span: field.ident.span,
prev_span: *prev_span, prev_span: *prev_span,
ident, ident,
@ -1757,7 +1757,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if adt_kind == AdtKind::Union { if adt_kind == AdtKind::Union {
if hir_fields.len() != 1 { if hir_fields.len() != 1 {
struct_span_code_err!( struct_span_code_err!(
tcx.dcx(), self.dcx(),
span, span,
E0784, E0784,
"union expressions should have exactly one field", "union expressions should have exactly one field",

View file

@ -170,7 +170,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> {
} }
fn report_error(&self, span: Span, msg: impl ToString) -> Self::Error { fn report_error(&self, span: Span, msg: impl ToString) -> Self::Error {
self.tcx.dcx().span_delayed_bug(span, msg.to_string()) self.dcx().span_delayed_bug(span, msg.to_string())
} }
fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error> { fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error> {

View file

@ -1182,7 +1182,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
name: self.tcx.item_name(def.did()).to_ident_string(), name: self.tcx.item_name(def.did()).to_ident_string(),
}); });
if ty.raw.has_param() { if ty.raw.has_param() {
let guar = self.tcx.dcx().emit_err(errors::SelfCtorFromOuterItem { let guar = self.dcx().emit_err(errors::SelfCtorFromOuterItem {
span: path_span, span: path_span,
impl_span: tcx.def_span(impl_def_id), impl_span: tcx.def_span(impl_def_id),
sugg, sugg,
@ -1207,7 +1207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Check the visibility of the ctor. // Check the visibility of the ctor.
let vis = tcx.visibility(ctor_def_id); let vis = tcx.visibility(ctor_def_id);
if !vis.is_accessible_from(tcx.parent_module(hir_id).to_def_id(), tcx) { if !vis.is_accessible_from(tcx.parent_module(hir_id).to_def_id(), tcx) {
tcx.dcx() self.dcx()
.emit_err(CtorIsPrivate { span, def: tcx.def_path_str(adt_def.did()) }); .emit_err(CtorIsPrivate { span, def: tcx.def_path_str(adt_def.did()) });
} }
let new_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id); let new_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
@ -1216,7 +1216,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(new_res, Some(user_args.args)) (new_res, Some(user_args.args))
} }
_ => { _ => {
let mut err = tcx.dcx().struct_span_err( let mut err = self.dcx().struct_span_err(
span, span,
"the `Self` constructor can only be used with tuple or unit structs", "the `Self` constructor can only be used with tuple or unit structs",
); );

View file

@ -238,7 +238,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Otherwise, there's a mismatch, so clear out what we're expecting, and set // Otherwise, there's a mismatch, so clear out what we're expecting, and set
// our input types to err_args so we don't blow up the error messages // our input types to err_args so we don't blow up the error messages
let guar = struct_span_code_err!( let guar = struct_span_code_err!(
tcx.dcx(), self.dcx(),
call_span, call_span,
E0059, E0059,
"cannot use call notation; the first type parameter \ "cannot use call notation; the first type parameter \
@ -453,7 +453,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.map(|vars| self.resolve_vars_if_possible(vars)), .map(|vars| self.resolve_vars_if_possible(vars)),
); );
self.set_tainted_by_errors(self.report_arg_errors( self.report_arg_errors(
compatibility_diagonal, compatibility_diagonal,
formal_and_expected_inputs, formal_and_expected_inputs,
provided_args, provided_args,
@ -462,7 +462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn_def_id, fn_def_id,
call_span, call_span,
call_expr, call_expr,
)); );
} }
} }
@ -788,7 +788,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
format!("arguments to this {call_name} are incorrect"), format!("arguments to this {call_name} are incorrect"),
); );
} else { } else {
err = tcx.dcx().struct_span_err( err = self.dcx().struct_span_err(
full_call_span, full_call_span,
format!( format!(
"{call_name} takes {}{} but {} {} supplied", "{call_name} takes {}{} but {} {} supplied",
@ -848,7 +848,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span_bug!(error_span, "expected errors from argument matrix"); span_bug!(error_span, "expected errors from argument matrix");
} else { } else {
let mut err = let mut err =
tcx.dcx().create_err(errors::ArgMismatchIndeterminate { span: error_span }); self.dcx().create_err(errors::ArgMismatchIndeterminate { span: error_span });
suggest_confusable(&mut err); suggest_confusable(&mut err);
return err.emit(); return err.emit();
} }
@ -953,14 +953,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut err = if formal_and_expected_inputs.len() == provided_args.len() { let mut err = if formal_and_expected_inputs.len() == provided_args.len() {
struct_span_code_err!( struct_span_code_err!(
tcx.dcx(), self.dcx(),
full_call_span, full_call_span,
E0308, E0308,
"arguments to this {} are incorrect", "arguments to this {} are incorrect",
call_name, call_name,
) )
} else { } else {
tcx.dcx() self.dcx()
.struct_span_err( .struct_span_err(
full_call_span, full_call_span,
format!( format!(
@ -1424,7 +1424,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
provided_ty: Ty<'tcx>, provided_ty: Ty<'tcx>,
arg: &hir::Expr<'tcx>, arg: &hir::Expr<'tcx>,
err: &mut Diag<'tcx>, err: &mut Diag<'_>,
) { ) {
if let ty::RawPtr(_, hir::Mutability::Mut) = expected_ty.kind() if let ty::RawPtr(_, hir::Mutability::Mut) = expected_ty.kind()
&& let ty::RawPtr(_, hir::Mutability::Not) = provided_ty.kind() && let ty::RawPtr(_, hir::Mutability::Not) = provided_ty.kind()

View file

@ -144,8 +144,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'tcx> { pub(crate) fn dcx(&self) -> DiagCtxtHandle<'a> {
self.infcx.dcx() self.root_ctxt.infcx.dcx()
} }
pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> { pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> {

View file

@ -52,7 +52,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Note: this path is currently not reached in any test, so any // Note: this path is currently not reached in any test, so any
// example that triggers this would be worth minimizing and // example that triggers this would be worth minimizing and
// converting into a test. // converting into a test.
tcx.dcx().span_bug(span, "argument to transmute has inference variables"); self.dcx().span_bug(span, "argument to transmute has inference variables");
} }
// Transmutes that are only changing lifetimes are always ok. // Transmutes that are only changing lifetimes are always ok.
if from == to { if from == to {
@ -76,7 +76,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let (&ty::FnDef(..), SizeSkeleton::Known(size_to, _)) = (from.kind(), sk_to) if let (&ty::FnDef(..), SizeSkeleton::Known(size_to, _)) = (from.kind(), sk_to)
&& size_to == Pointer(dl.instruction_address_space).size(&tcx) && size_to == Pointer(dl.instruction_address_space).size(&tcx)
{ {
struct_span_code_err!(tcx.dcx(), span, E0591, "can't transmute zero-sized type") struct_span_code_err!(self.dcx(), span, E0591, "can't transmute zero-sized type")
.with_note(format!("source type: {from}")) .with_note(format!("source type: {from}"))
.with_note(format!("target type: {to}")) .with_note(format!("target type: {to}"))
.with_help("cast with `as` to a pointer instead") .with_help("cast with `as` to a pointer instead")
@ -116,7 +116,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}; };
let mut err = struct_span_code_err!( let mut err = struct_span_code_err!(
tcx.dcx(), self.dcx(),
span, span,
E0512, E0512,
"cannot transmute between types of different sizes, \ "cannot transmute between types of different sizes, \

View file

@ -705,7 +705,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source { let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source {
self.suggest_missing_writer(rcvr_ty, rcvr_expr) self.suggest_missing_writer(rcvr_ty, rcvr_expr)
} else { } else {
let mut err = tcx.dcx().create_err(NoAssociatedItem { let mut err = self.dcx().create_err(NoAssociatedItem {
span, span,
item_kind, item_kind,
item_name, item_name,
@ -1194,7 +1194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: item_span, span: item_span,
.. ..
})) => { })) => {
tcx.dcx().span_delayed_bug( self.dcx().span_delayed_bug(
*item_span, *item_span,
"auto trait is invoked with no method error, but no error reported?", "auto trait is invoked with no method error, but no error reported?",
); );
@ -2361,7 +2361,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
); );
if pick.is_ok() { if pick.is_ok() {
let range_span = parent_expr.span.with_hi(expr.span.hi()); let range_span = parent_expr.span.with_hi(expr.span.hi());
return Err(tcx.dcx().emit_err(errors::MissingParenthesesInRange { return Err(self.dcx().emit_err(errors::MissingParenthesesInRange {
span, span,
ty_str: ty_str.to_string(), ty_str: ty_str.to_string(),
method_name: item_name.as_str().to_string(), method_name: item_name.as_str().to_string(),
@ -2420,7 +2420,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let SelfSource::MethodCall(expr) = source && let SelfSource::MethodCall(expr) = source
{ {
let mut err = struct_span_code_err!( let mut err = struct_span_code_err!(
tcx.dcx(), self.dcx(),
span, span,
E0689, E0689,
"can't call {} `{}` on ambiguous numeric type `{}`", "can't call {} `{}` on ambiguous numeric type `{}`",

View file

@ -89,7 +89,7 @@ struct PatInfo<'tcx, 'a> {
current_depth: u32, current_depth: u32,
} }
impl<'tcx> FnCtxt<'_, 'tcx> { impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn pattern_cause(&self, ti: &TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> { fn pattern_cause(&self, ti: &TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> {
let code = ObligationCauseCode::Pattern { let code = ObligationCauseCode::Pattern {
span: ti.span, span: ti.span,
@ -100,12 +100,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
} }
fn demand_eqtype_pat_diag( fn demand_eqtype_pat_diag(
&self, &'a self,
cause_span: Span, cause_span: Span,
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
ti: &TopInfo<'tcx>, ti: &TopInfo<'tcx>,
) -> Result<(), Diag<'tcx>> { ) -> Result<(), Diag<'a>> {
self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual) self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)
.map_err(|mut diag| { .map_err(|mut diag| {
if let Some(expr) = ti.origin_expr { if let Some(expr) = ti.origin_expr {
@ -698,7 +698,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let MutblCap::WeaklyNot(and_pat_span) = pat_info.max_ref_mutbl && let MutblCap::WeaklyNot(and_pat_span) = pat_info.max_ref_mutbl
{ {
let mut err = struct_span_code_err!( let mut err = struct_span_code_err!(
self.tcx.dcx(), self.dcx(),
ident.span, ident.span,
E0596, E0596,
"cannot borrow as mutable inside an `&` pattern" "cannot borrow as mutable inside an `&` pattern"
@ -1010,7 +1010,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (res, opt_ty, segments) = path_resolution; let (res, opt_ty, segments) = path_resolution;
match res { match res {
Res::Err => { Res::Err => {
let e = tcx.dcx().span_delayed_bug(qpath.span(), "`Res::Err` but no error emitted"); let e =
self.dcx().span_delayed_bug(qpath.span(), "`Res::Err` but no error emitted");
self.set_tainted_by_errors(e); self.set_tainted_by_errors(e);
return Ty::new_error(tcx, e); return Ty::new_error(tcx, e);
} }
@ -1191,7 +1192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (res, opt_ty, segments) = let (res, opt_ty, segments) =
self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span); self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span);
if res == Res::Err { if res == Res::Err {
let e = tcx.dcx().span_delayed_bug(pat.span, "`Res::Err` but no error emitted"); let e = self.dcx().span_delayed_bug(pat.span, "`Res::Err` but no error emitted");
self.set_tainted_by_errors(e); self.set_tainted_by_errors(e);
on_error(e); on_error(e);
return Ty::new_error(tcx, e); return Ty::new_error(tcx, e);
@ -1207,7 +1208,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let variant = match res { let variant = match res {
Res::Err => { Res::Err => {
tcx.dcx().span_bug(pat.span, "`Res::Err` but no error emitted"); self.dcx().span_bug(pat.span, "`Res::Err` but no error emitted");
} }
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => { Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => {
let e = report_unexpected_res(res); let e = report_unexpected_res(res);
@ -1549,10 +1550,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Report an error if an incorrect number of fields was specified. // Report an error if an incorrect number of fields was specified.
if adt.is_union() { if adt.is_union() {
if fields.len() != 1 { if fields.len() != 1 {
tcx.dcx().emit_err(errors::UnionPatMultipleFields { span: pat.span }); self.dcx().emit_err(errors::UnionPatMultipleFields { span: pat.span });
} }
if has_rest_pat { if has_rest_pat {
tcx.dcx().emit_err(errors::UnionPatDotDot { span: pat.span }); self.dcx().emit_err(errors::UnionPatDotDot { span: pat.span });
} }
} else if !unmentioned_fields.is_empty() { } else if !unmentioned_fields.is_empty() {
let accessible_unmentioned_fields: Vec<_> = unmentioned_fields let accessible_unmentioned_fields: Vec<_> = unmentioned_fields
@ -1690,7 +1691,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat: &'tcx Pat<'tcx>, pat: &'tcx Pat<'tcx>,
variant: &ty::VariantDef, variant: &ty::VariantDef,
args: ty::GenericArgsRef<'tcx>, args: ty::GenericArgsRef<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'a> {
let tcx = self.tcx; let tcx = self.tcx;
let (field_names, t, plural) = if let [field] = inexistent_fields { let (field_names, t, plural) = if let [field] = inexistent_fields {
(format!("a field named `{}`", field.ident), "this", "") (format!("a field named `{}`", field.ident), "this", "")
@ -1710,7 +1711,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}; };
let spans = inexistent_fields.iter().map(|field| field.ident.span).collect::<Vec<_>>(); let spans = inexistent_fields.iter().map(|field| field.ident.span).collect::<Vec<_>>();
let mut err = struct_span_code_err!( let mut err = struct_span_code_err!(
tcx.dcx(), self.dcx(),
spans, spans,
E0026, E0026,
"{} `{}` does not have {}", "{} `{}` does not have {}",
@ -1881,7 +1882,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self, &self,
pat: &Pat<'_>, pat: &Pat<'_>,
fields: &'tcx [hir::PatField<'tcx>], fields: &'tcx [hir::PatField<'tcx>],
) -> Diag<'tcx> { ) -> Diag<'a> {
let mut err = self let mut err = self
.dcx() .dcx()
.struct_span_err(pat.span, "pattern requires `..` due to inaccessible fields"); .struct_span_err(pat.span, "pattern requires `..` due to inaccessible fields");
@ -1973,7 +1974,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
unmentioned_fields: &[(&ty::FieldDef, Ident)], unmentioned_fields: &[(&ty::FieldDef, Ident)],
have_inaccessible_fields: bool, have_inaccessible_fields: bool,
fields: &'tcx [hir::PatField<'tcx>], fields: &'tcx [hir::PatField<'tcx>],
) -> Diag<'tcx> { ) -> Diag<'a> {
let inaccessible = if have_inaccessible_fields { " and inaccessible fields" } else { "" }; let inaccessible = if have_inaccessible_fields { " and inaccessible fields" } else { "" };
let field_names = if let [(_, field)] = unmentioned_fields { let field_names = if let [(_, field)] = unmentioned_fields {
format!("field `{field}`{inaccessible}") format!("field `{field}`{inaccessible}")

View file

@ -139,7 +139,7 @@ pub struct TypeErrCtxt<'a, 'tcx> {
} }
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { pub fn dcx(&self) -> DiagCtxtHandle<'a> {
self.infcx.dcx() self.infcx.dcx()
} }
@ -305,16 +305,17 @@ fn label_msg_span(
} }
} }
#[instrument(level = "trace", skip(tcx))] #[instrument(level = "trace", skip(infcx))]
pub fn unexpected_hidden_region_diagnostic<'tcx>( pub fn unexpected_hidden_region_diagnostic<'a, 'tcx>(
tcx: TyCtxt<'tcx>, infcx: &'a InferCtxt<'tcx>,
generic_param_scope: LocalDefId, generic_param_scope: LocalDefId,
span: Span, span: Span,
hidden_ty: Ty<'tcx>, hidden_ty: Ty<'tcx>,
hidden_region: ty::Region<'tcx>, hidden_region: ty::Region<'tcx>,
opaque_ty_key: ty::OpaqueTypeKey<'tcx>, opaque_ty_key: ty::OpaqueTypeKey<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'a> {
let mut err = tcx.dcx().create_err(errors::OpaqueCapturesLifetime { let tcx = infcx.tcx;
let mut err = infcx.dcx().create_err(errors::OpaqueCapturesLifetime {
span, span,
opaque_ty: Ty::new_opaque(tcx, opaque_ty_key.def_id.to_def_id(), opaque_ty_key.args), opaque_ty: Ty::new_opaque(tcx, opaque_ty_key.def_id.to_def_id(), opaque_ty_key.args),
opaque_ty_span: tcx.def_span(opaque_ty_key.def_id), opaque_ty_span: tcx.def_span(opaque_ty_key.def_id),
@ -436,7 +437,7 @@ impl<'tcx> InferCtxt<'tcx> {
} }
} }
impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
pub fn report_region_errors( pub fn report_region_errors(
&self, &self,
generic_param_scope: LocalDefId, generic_param_scope: LocalDefId,
@ -2206,7 +2207,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self, &self,
trace: TypeTrace<'tcx>, trace: TypeTrace<'tcx>,
terr: TypeError<'tcx>, terr: TypeError<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'a> {
debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr); debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr);
let span = trace.cause.span(); let span = trace.cause.span();
@ -2215,7 +2216,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
span, span,
self.type_error_additional_suggestions(&trace, terr), self.type_error_additional_suggestions(&trace, terr),
); );
let mut diag = self.tcx.dcx().create_err(failure_code); let mut diag = self.dcx().create_err(failure_code);
self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr, false, false); self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr, false, false);
diag diag
} }
@ -2357,14 +2358,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
origin: Option<SubregionOrigin<'tcx>>, origin: Option<SubregionOrigin<'tcx>>,
bound_kind: GenericKind<'tcx>, bound_kind: GenericKind<'tcx>,
sub: Region<'tcx>, sub: Region<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'a> {
if let Some(SubregionOrigin::CompareImplItemObligation { if let Some(SubregionOrigin::CompareImplItemObligation {
span, span,
impl_item_def_id, impl_item_def_id,
trait_item_def_id, trait_item_def_id,
}) = origin }) = origin
{ {
return self.report_extra_impl_obligation( return self.infcx.report_extra_impl_obligation(
span, span,
impl_item_def_id, impl_item_def_id,
trait_item_def_id, trait_item_def_id,
@ -2790,7 +2791,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for SameTypeModuloInfer<'_, 'tcx> {
} }
impl<'tcx> InferCtxt<'tcx> { impl<'tcx> InferCtxt<'tcx> {
fn report_inference_failure(&self, var_origin: RegionVariableOrigin) -> Diag<'tcx> { fn report_inference_failure(&self, var_origin: RegionVariableOrigin) -> Diag<'_> {
let br_string = |br: ty::BoundRegionKind| { let br_string = |br: ty::BoundRegionKind| {
let mut s = match br { let mut s = match br {
ty::BrNamed(_, name) => name.to_string(), ty::BrNamed(_, name) => name.to_string(),
@ -2829,7 +2830,7 @@ impl<'tcx> InferCtxt<'tcx> {
}; };
struct_span_code_err!( struct_span_code_err!(
self.tcx.dcx(), self.dcx(),
var_origin.span(), var_origin.span(),
E0495, E0495,
"cannot infer an appropriate lifetime{} due to conflicting requirements", "cannot infer an appropriate lifetime{} due to conflicting requirements",

View file

@ -391,7 +391,7 @@ impl<'tcx> InferCtxt<'tcx> {
span: Span, span: Span,
arg_data: InferenceDiagnosticsData, arg_data: InferenceDiagnosticsData,
error_code: TypeAnnotationNeeded, error_code: TypeAnnotationNeeded,
) -> Diag<'tcx> { ) -> Diag<'_> {
let source_kind = "other"; let source_kind = "other";
let source_name = ""; let source_name = "";
let failure_span = None; let failure_span = None;
@ -436,7 +436,7 @@ impl<'tcx> InferCtxt<'tcx> {
} }
} }
impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
#[instrument(level = "debug", skip(self, error_code))] #[instrument(level = "debug", skip(self, error_code))]
pub fn emit_inference_failure_err( pub fn emit_inference_failure_err(
&self, &self,
@ -445,7 +445,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
arg: GenericArg<'tcx>, arg: GenericArg<'tcx>,
error_code: TypeAnnotationNeeded, error_code: TypeAnnotationNeeded,
should_label_span: bool, should_label_span: bool,
) -> Diag<'tcx> { ) -> Diag<'a> {
let arg = self.resolve_vars_if_possible(arg); let arg = self.resolve_vars_if_possible(arg);
let arg_data = self.extract_inference_diagnostics_data(arg, None); let arg_data = self.extract_inference_diagnostics_data(arg, None);
@ -453,7 +453,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// If we don't have any typeck results we're outside // If we don't have any typeck results we're outside
// of a body, so we won't be able to get better info // of a body, so we won't be able to get better info
// here. // here.
return self.bad_inference_failure_err(failure_span, arg_data, error_code); return self.infcx.bad_inference_failure_err(failure_span, arg_data, error_code);
}; };
let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, arg); let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, arg);
@ -465,7 +465,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
let Some(InferSource { span, kind }) = local_visitor.infer_source else { let Some(InferSource { span, kind }) = local_visitor.infer_source else {
return self.bad_inference_failure_err(failure_span, arg_data, error_code); return self.infcx.bad_inference_failure_err(failure_span, arg_data, error_code);
}; };
let (source_kind, name, path) = kind.ty_localized_msg(self); let (source_kind, name, path) = kind.ty_localized_msg(self);

View file

@ -14,7 +14,7 @@ use rustc_span::symbol::kw;
use super::ObligationCauseAsDiagArg; use super::ObligationCauseAsDiagArg;
impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) { pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) {
match *origin { match *origin {
infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
@ -79,7 +79,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
origin: SubregionOrigin<'tcx>, origin: SubregionOrigin<'tcx>,
sub: Region<'tcx>, sub: Region<'tcx>,
sup: Region<'tcx>, sup: Region<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'a> {
let mut err = match origin { let mut err = match origin {
infer::Subtype(box trace) => { infer::Subtype(box trace) => {
let terr = TypeError::RegionsDoesNotOutlive(sup, sub); let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
@ -245,7 +245,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}) })
} }
infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => { infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => {
let mut err = self.report_extra_impl_obligation( let mut err = self.infcx.report_extra_impl_obligation(
span, span,
impl_item_def_id, impl_item_def_id,
trait_item_def_id, trait_item_def_id,
@ -378,7 +378,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
placeholder_origin: SubregionOrigin<'tcx>, placeholder_origin: SubregionOrigin<'tcx>,
sub: Region<'tcx>, sub: Region<'tcx>,
sup: Region<'tcx>, sup: Region<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'a> {
// I can't think how to do better than this right now. -nikomatsakis // I can't think how to do better than this right now. -nikomatsakis
debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure"); debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure");
match placeholder_origin { match placeholder_origin {

View file

@ -684,8 +684,8 @@ impl<'tcx> InferOk<'tcx, ()> {
} }
impl<'tcx> InferCtxt<'tcx> { impl<'tcx> InferCtxt<'tcx> {
pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { pub fn dcx(&self) -> DiagCtxtHandle<'_> {
self.tcx.dcx() self.tcx.dcx().taintable_handle(&self.tainted_by_errors)
} }
pub fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> { pub fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
@ -1089,19 +1089,7 @@ impl<'tcx> InferCtxt<'tcx> {
/// inference variables, regionck errors). /// inference variables, regionck errors).
#[must_use = "this method does not have any side effects"] #[must_use = "this method does not have any side effects"]
pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> { pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
if let Some(guar) = self.tainted_by_errors.get() { self.tainted_by_errors.get()
Some(guar)
} else if self.dcx().err_count_excluding_lint_errs() > self.err_count_on_creation {
// Errors reported since this infcx was made. Lint errors are
// excluded to avoid some being swallowed in the presence of
// non-lint errors. (It's arguable whether or not this exclusion is
// important.)
let guar = self.dcx().has_errors().unwrap();
self.set_tainted_by_errors(guar);
Some(guar)
} else {
None
}
} }
/// Set the "tainted by errors" flag to true. We call this when we /// Set the "tainted by errors" flag to true. We call this when we
@ -1328,8 +1316,7 @@ impl<'tcx> InferCtxt<'tcx> {
bug!("`{value:?}` is not fully resolved"); bug!("`{value:?}` is not fully resolved");
} }
if value.has_infer_regions() { if value.has_infer_regions() {
let guar = let guar = self.dcx().delayed_bug(format!("`{value:?}` is not fully resolved"));
self.tcx.dcx().delayed_bug(format!("`{value:?}` is not fully resolved"));
Ok(self.tcx.fold_regions(value, |re, _| { Ok(self.tcx.fold_regions(value, |re, _| {
if re.is_var() { ty::Region::new_error(self.tcx, guar) } else { re } if re.is_var() { ty::Region::new_error(self.tcx, guar) } else { re }
})) }))
@ -1607,7 +1594,7 @@ impl<'tcx> InferCtxt<'tcx> {
} }
} }
impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
// [Note-Type-error-reporting] // [Note-Type-error-reporting]
// An invariant is that anytime the expected or actual type is Error (the special // An invariant is that anytime the expected or actual type is Error (the special
// error type, meaning that an error occurred when typechecking this expression), // error type, meaning that an error occurred when typechecking this expression),
@ -1623,9 +1610,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
sp: Span, sp: Span,
mk_diag: M, mk_diag: M,
actual_ty: Ty<'tcx>, actual_ty: Ty<'tcx>,
) -> Diag<'tcx> ) -> Diag<'a>
where where
M: FnOnce(String) -> Diag<'tcx>, M: FnOnce(String) -> Diag<'a>,
{ {
let actual_ty = self.resolve_vars_if_possible(actual_ty); let actual_ty = self.resolve_vars_if_possible(actual_ty);
debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty); debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty);
@ -1646,7 +1633,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
err: TypeError<'tcx>, err: TypeError<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'a> {
self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err) self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err)
} }
@ -1656,7 +1643,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
expected: ty::Const<'tcx>, expected: ty::Const<'tcx>,
actual: ty::Const<'tcx>, actual: ty::Const<'tcx>,
err: TypeError<'tcx>, err: TypeError<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'a> {
self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err) self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err)
} }
} }

View file

@ -156,7 +156,7 @@ impl<'tcx> InferCtxt<'tcx> {
if self.can_define_opaque_ty(b_def_id) if self.can_define_opaque_ty(b_def_id)
&& self.tcx.is_type_alias_impl_trait(b_def_id) && self.tcx.is_type_alias_impl_trait(b_def_id)
{ {
self.tcx.dcx().emit_err(OpaqueHiddenTypeDiag { self.dcx().emit_err(OpaqueHiddenTypeDiag {
span, span,
hidden_type: self.tcx.def_span(b_def_id), hidden_type: self.tcx.def_span(b_def_id),
opaque_type: self.tcx.def_span(def_id), opaque_type: self.tcx.def_span(def_id),

View file

@ -12,15 +12,15 @@ use std::fmt;
use std::iter; use std::iter;
impl<'tcx> InferCtxt<'tcx> { impl<'tcx> InferCtxt<'tcx> {
pub fn report_extra_impl_obligation( pub fn report_extra_impl_obligation<'a>(
&self, &'a self,
error_span: Span, error_span: Span,
impl_item_def_id: LocalDefId, impl_item_def_id: LocalDefId,
trait_item_def_id: DefId, trait_item_def_id: DefId,
requirement: &dyn fmt::Display, requirement: &dyn fmt::Display,
) -> Diag<'tcx> { ) -> Diag<'a> {
let mut err = struct_span_code_err!( let mut err = struct_span_code_err!(
self.tcx.dcx(), self.dcx(),
error_span, error_span,
E0276, E0276,
"impl has stricter requirements than trait" "impl has stricter requirements than trait"

View file

@ -50,15 +50,19 @@ use crate::{lattice, AnalysisDomain, GenKill, GenKillAnalysis, MaybeReachable};
/// Similarly, at a given `drop` statement, the set-intersection /// Similarly, at a given `drop` statement, the set-intersection
/// between this data and `MaybeUninitializedPlaces` yields the set of /// between this data and `MaybeUninitializedPlaces` yields the set of
/// places that would require a dynamic drop-flag at that statement. /// places that would require a dynamic drop-flag at that statement.
pub struct MaybeInitializedPlaces<'a, 'tcx> { pub struct MaybeInitializedPlaces<'a, 'mir, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
body: &'a Body<'tcx>, body: &'mir Body<'tcx>,
mdpe: &'a MoveDataParamEnv<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>,
skip_unreachable_unwind: bool, skip_unreachable_unwind: bool,
} }
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { pub fn new(
tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>,
mdpe: &'a MoveDataParamEnv<'tcx>,
) -> Self {
MaybeInitializedPlaces { tcx, body, mdpe, skip_unreachable_unwind: false } MaybeInitializedPlaces { tcx, body, mdpe, skip_unreachable_unwind: false }
} }
@ -84,7 +88,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> { impl<'a, 'mir, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'mir, 'tcx> {
fn move_data(&self) -> &MoveData<'tcx> { fn move_data(&self) -> &MoveData<'tcx> {
&self.mdpe.move_data &self.mdpe.move_data
} }
@ -125,17 +129,21 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
/// Similarly, at a given `drop` statement, the set-intersection /// Similarly, at a given `drop` statement, the set-intersection
/// between this data and `MaybeInitializedPlaces` yields the set of /// between this data and `MaybeInitializedPlaces` yields the set of
/// places that would require a dynamic drop-flag at that statement. /// places that would require a dynamic drop-flag at that statement.
pub struct MaybeUninitializedPlaces<'a, 'tcx> { pub struct MaybeUninitializedPlaces<'a, 'mir, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
body: &'a Body<'tcx>, body: &'mir Body<'tcx>,
mdpe: &'a MoveDataParamEnv<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>,
mark_inactive_variants_as_uninit: bool, mark_inactive_variants_as_uninit: bool,
skip_unreachable_unwind: BitSet<mir::BasicBlock>, skip_unreachable_unwind: BitSet<mir::BasicBlock>,
} }
impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> { impl<'a, 'mir, 'tcx> MaybeUninitializedPlaces<'a, 'mir, 'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { pub fn new(
tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>,
mdpe: &'a MoveDataParamEnv<'tcx>,
) -> Self {
MaybeUninitializedPlaces { MaybeUninitializedPlaces {
tcx, tcx,
body, body,
@ -164,7 +172,7 @@ impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> { impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, '_, 'tcx> {
fn move_data(&self) -> &MoveData<'tcx> { fn move_data(&self) -> &MoveData<'tcx> {
&self.mdpe.move_data &self.mdpe.move_data
} }
@ -250,24 +258,24 @@ impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
/// c = S; // {a, b, c, d } /// c = S; // {a, b, c, d }
/// } /// }
/// ``` /// ```
pub struct EverInitializedPlaces<'a, 'tcx> { pub struct EverInitializedPlaces<'a, 'mir, 'tcx> {
body: &'a Body<'tcx>, body: &'mir Body<'tcx>,
mdpe: &'a MoveDataParamEnv<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>,
} }
impl<'a, 'tcx> EverInitializedPlaces<'a, 'tcx> { impl<'a, 'mir, 'tcx> EverInitializedPlaces<'a, 'mir, 'tcx> {
pub fn new(body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { pub fn new(body: &'mir Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
EverInitializedPlaces { body, mdpe } EverInitializedPlaces { body, mdpe }
} }
} }
impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, 'tcx> { impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, '_, 'tcx> {
fn move_data(&self) -> &MoveData<'tcx> { fn move_data(&self) -> &MoveData<'tcx> {
&self.mdpe.move_data &self.mdpe.move_data
} }
} }
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
fn update_bits( fn update_bits(
trans: &mut impl GenKill<MovePathIndex>, trans: &mut impl GenKill<MovePathIndex>,
path: MovePathIndex, path: MovePathIndex,
@ -280,7 +288,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> { impl<'a, 'tcx> MaybeUninitializedPlaces<'a, '_, 'tcx> {
fn update_bits( fn update_bits(
trans: &mut impl GenKill<MovePathIndex>, trans: &mut impl GenKill<MovePathIndex>,
path: MovePathIndex, path: MovePathIndex,
@ -306,7 +314,7 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
} }
} }
impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> {
/// There can be many more `MovePathIndex` than there are locals in a MIR body. /// There can be many more `MovePathIndex` than there are locals in a MIR body.
/// We use a chunked bitset to avoid paying too high a memory footprint. /// We use a chunked bitset to avoid paying too high a memory footprint.
type Domain = MaybeReachable<ChunkedBitSet<MovePathIndex>>; type Domain = MaybeReachable<ChunkedBitSet<MovePathIndex>>;
@ -328,7 +336,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
} }
} }
impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> {
type Idx = MovePathIndex; type Idx = MovePathIndex;
fn domain_size(&self, _: &Body<'tcx>) -> usize { fn domain_size(&self, _: &Body<'tcx>) -> usize {
@ -441,7 +449,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
} }
} }
impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> {
/// There can be many more `MovePathIndex` than there are locals in a MIR body. /// There can be many more `MovePathIndex` than there are locals in a MIR body.
/// We use a chunked bitset to avoid paying too high a memory footprint. /// We use a chunked bitset to avoid paying too high a memory footprint.
type Domain = ChunkedBitSet<MovePathIndex>; type Domain = ChunkedBitSet<MovePathIndex>;
@ -465,7 +473,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
} }
} }
impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> {
type Idx = MovePathIndex; type Idx = MovePathIndex;
fn domain_size(&self, _: &Body<'tcx>) -> usize { fn domain_size(&self, _: &Body<'tcx>) -> usize {
@ -642,7 +650,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
} }
} }
impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> { impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> {
/// There can be many more `InitIndex` than there are locals in a MIR body. /// There can be many more `InitIndex` than there are locals in a MIR body.
/// We use a chunked bitset to avoid paying too high a memory footprint. /// We use a chunked bitset to avoid paying too high a memory footprint.
type Domain = ChunkedBitSet<InitIndex>; type Domain = ChunkedBitSet<InitIndex>;
@ -661,7 +669,7 @@ impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> {
} }
} }
impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> {
type Idx = InitIndex; type Idx = InitIndex;
fn domain_size(&self, _: &Body<'tcx>) -> usize { fn domain_size(&self, _: &Body<'tcx>) -> usize {

View file

@ -97,7 +97,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
#[instrument(level = "trace", skip(body, flow_inits), ret)] #[instrument(level = "trace", skip(body, flow_inits), ret)]
fn compute_dead_unwinds<'mir, 'tcx>( fn compute_dead_unwinds<'mir, 'tcx>(
body: &'mir Body<'tcx>, body: &'mir Body<'tcx>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>,
) -> BitSet<BasicBlock> { ) -> BitSet<BasicBlock> {
// We only need to do this pass once, because unwind edges can only // We only need to do this pass once, because unwind edges can only
// reach cleanup blocks, which can't have unwind edges themselves. // reach cleanup blocks, which can't have unwind edges themselves.
@ -118,12 +118,12 @@ fn compute_dead_unwinds<'mir, 'tcx>(
dead_unwinds dead_unwinds
} }
struct InitializationData<'mir, 'tcx> { struct InitializationData<'a, 'mir, 'tcx> {
inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'a, 'mir, 'tcx>>,
uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>, uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
} }
impl InitializationData<'_, '_> { impl InitializationData<'_, '_, '_> {
fn seek_before(&mut self, loc: Location) { fn seek_before(&mut self, loc: Location) {
self.inits.seek_before_primary_effect(loc); self.inits.seek_before_primary_effect(loc);
self.uninits.seek_before_primary_effect(loc); self.uninits.seek_before_primary_effect(loc);
@ -134,17 +134,17 @@ impl InitializationData<'_, '_> {
} }
} }
struct Elaborator<'a, 'b, 'tcx> { struct Elaborator<'a, 'b, 'mir, 'tcx> {
ctxt: &'a mut ElaborateDropsCtxt<'b, 'tcx>, ctxt: &'a mut ElaborateDropsCtxt<'b, 'mir, 'tcx>,
} }
impl fmt::Debug for Elaborator<'_, '_, '_> { impl fmt::Debug for Elaborator<'_, '_, '_, '_> {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
Ok(()) Ok(())
} }
} }
impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> { impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, '_, 'tcx> {
type Path = MovePathIndex; type Path = MovePathIndex;
fn patch(&mut self) -> &mut MirPatch<'tcx> { fn patch(&mut self) -> &mut MirPatch<'tcx> {
@ -238,16 +238,16 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> {
} }
} }
struct ElaborateDropsCtxt<'a, 'tcx> { struct ElaborateDropsCtxt<'a, 'mir, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
body: &'a Body<'tcx>, body: &'mir Body<'tcx>,
env: &'a MoveDataParamEnv<'tcx>, env: &'a MoveDataParamEnv<'tcx>,
init_data: InitializationData<'a, 'tcx>, init_data: InitializationData<'a, 'mir, 'tcx>,
drop_flags: IndexVec<MovePathIndex, Option<Local>>, drop_flags: IndexVec<MovePathIndex, Option<Local>>,
patch: MirPatch<'tcx>, patch: MirPatch<'tcx>,
} }
impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { impl<'b, 'mir, 'tcx> ElaborateDropsCtxt<'b, 'mir, 'tcx> {
fn move_data(&self) -> &'b MoveData<'tcx> { fn move_data(&self) -> &'b MoveData<'tcx> {
&self.env.move_data &self.env.move_data
} }

View file

@ -88,7 +88,7 @@ impl<'tcx> InferCtxt<'tcx> {
found_args: Vec<ArgKind>, found_args: Vec<ArgKind>,
is_closure: bool, is_closure: bool,
closure_arg_span: Option<Span>, closure_arg_span: Option<Span>,
) -> Diag<'tcx> { ) -> Diag<'_> {
let kind = if is_closure { "closure" } else { "function" }; let kind = if is_closure { "closure" } else { "function" };
let args_str = |arguments: &[ArgKind], other: &[ArgKind]| { let args_str = |arguments: &[ArgKind], other: &[ArgKind]| {

View file

@ -241,8 +241,8 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
} }
} }
#[extension(pub trait TypeErrCtxtExt<'tcx>)] #[extension(pub trait TypeErrCtxtExt<'a, 'tcx>)]
impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
fn suggest_restricting_param_bound( fn suggest_restricting_param_bound(
&self, &self,
err: &mut Diag<'_>, err: &mut Diag<'_>,
@ -1845,7 +1845,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn point_at_returns_when_relevant( fn point_at_returns_when_relevant(
&self, &self,
err: &mut Diag<'tcx>, err: &mut Diag<'_>,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
) { ) {
match obligation.cause.code().peel_derives() { match obligation.cause.code().peel_derives() {
@ -1884,7 +1884,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
cause: &ObligationCauseCode<'tcx>, cause: &ObligationCauseCode<'tcx>,
found_node: Option<Node<'_>>, found_node: Option<Node<'_>>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'a> {
pub(crate) fn build_fn_sig_ty<'tcx>( pub(crate) fn build_fn_sig_ty<'tcx>(
infcx: &InferCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
trait_ref: ty::TraitRef<'tcx>, trait_ref: ty::TraitRef<'tcx>,
@ -2104,7 +2104,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn note_conflicting_closure_bounds( fn note_conflicting_closure_bounds(
&self, &self,
cause: &ObligationCauseCode<'tcx>, cause: &ObligationCauseCode<'tcx>,
err: &mut Diag<'tcx>, err: &mut Diag<'_>,
) { ) {
// First, look for an `WhereClauseInExpr`, which means we can get // First, look for an `WhereClauseInExpr`, which means we can get
// the uninstantiated predicate list of the called function. And check // the uninstantiated predicate list of the called function. And check

View file

@ -82,8 +82,8 @@ pub fn suggest_new_overflow_limit<'tcx, G: EmissionGuarantee>(
)); ));
} }
#[extension(pub trait TypeErrCtxtExt<'tcx>)] #[extension(pub trait TypeErrCtxtExt<'a, 'tcx>)]
impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
fn report_fulfillment_errors( fn report_fulfillment_errors(
&self, &self,
mut errors: Vec<FulfillmentError<'tcx>>, mut errors: Vec<FulfillmentError<'tcx>>,
@ -228,7 +228,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
cause: OverflowCause<'tcx>, cause: OverflowCause<'tcx>,
span: Span, span: Span,
suggest_increasing_limit: bool, suggest_increasing_limit: bool,
) -> Diag<'tcx> { ) -> Diag<'a> {
fn with_short_path<'tcx, T>(tcx: TyCtxt<'tcx>, value: T) -> String fn with_short_path<'tcx, T>(tcx: TyCtxt<'tcx>, value: T) -> String
where where
T: fmt::Display + Print<'tcx, FmtPrinter<'tcx, 'tcx>>, T: fmt::Display + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
@ -1101,7 +1101,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&& let ty::FnPtr(sig) = by_ref_captures.kind() && let ty::FnPtr(sig) = by_ref_captures.kind()
&& !sig.skip_binder().output().is_unit() && !sig.skip_binder().output().is_unit()
{ {
let mut err = self.tcx.dcx().create_err(AsyncClosureNotFn { let mut err = self.dcx().create_err(AsyncClosureNotFn {
span: self.tcx.def_span(closure_def_id), span: self.tcx.def_span(closure_def_id),
kind: expected_kind.as_str(), kind: expected_kind.as_str(),
}); });
@ -1351,7 +1351,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self, &self,
ty: Ty<'tcx>, ty: Ty<'tcx>,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'a> {
let span = obligation.cause.span; let span = obligation.cause.span;
let mut diag = match ty.kind() { let mut diag = match ty.kind() {
@ -1445,8 +1445,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
} }
#[extension(pub(super) trait InferCtxtPrivExt<'tcx>)] #[extension(pub(super) trait InferCtxtPrivExt<'a, 'tcx>)]
impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
fn can_match_trait( fn can_match_trait(
&self, &self,
goal: ty::TraitPredicate<'tcx>, goal: ty::TraitPredicate<'tcx>,
@ -2884,7 +2884,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
self.suggest_unsized_bound_if_applicable(err, obligation); self.suggest_unsized_bound_if_applicable(err, obligation);
if let Some(span) = err.span.primary_span() if let Some(span) = err.span.primary_span()
&& let Some(mut diag) = && let Some(mut diag) =
self.tcx.dcx().steal_non_err(span, StashKey::AssociatedTypeSuggestion) self.dcx().steal_non_err(span, StashKey::AssociatedTypeSuggestion)
&& let Ok(ref mut s1) = err.suggestions && let Ok(ref mut s1) = err.suggestions
&& let Ok(ref mut s2) = diag.suggestions && let Ok(ref mut s2) = diag.suggestions
{ {
@ -3379,7 +3379,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
found_kind: ty::ClosureKind, found_kind: ty::ClosureKind,
kind: ty::ClosureKind, kind: ty::ClosureKind,
trait_prefix: &'static str, trait_prefix: &'static str,
) -> Diag<'tcx> { ) -> Diag<'a> {
let closure_span = self.tcx.def_span(closure_def_id); let closure_span = self.tcx.def_span(closure_def_id);
let mut err = ClosureKindMismatch { let mut err = ClosureKindMismatch {
@ -3422,7 +3422,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
found_trait_ref: ty::TraitRef<'tcx>, found_trait_ref: ty::TraitRef<'tcx>,
expected_trait_ref: ty::TraitRef<'tcx>, expected_trait_ref: ty::TraitRef<'tcx>,
terr: TypeError<'tcx>, terr: TypeError<'tcx>,
) -> Diag<'tcx> { ) -> Diag<'a> {
let self_ty = found_trait_ref.self_ty(); let self_ty = found_trait_ref.self_ty();
let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() { let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() {
( (
@ -3473,7 +3473,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
span: Span, span: Span,
found_trait_ref: ty::TraitRef<'tcx>, found_trait_ref: ty::TraitRef<'tcx>,
expected_trait_ref: ty::TraitRef<'tcx>, expected_trait_ref: ty::TraitRef<'tcx>,
) -> Result<Diag<'tcx>, ErrorGuaranteed> { ) -> Result<Diag<'a>, ErrorGuaranteed> {
let found_trait_ref = self.resolve_vars_if_possible(found_trait_ref); let found_trait_ref = self.resolve_vars_if_possible(found_trait_ref);
let expected_trait_ref = self.resolve_vars_if_possible(expected_trait_ref); let expected_trait_ref = self.resolve_vars_if_possible(expected_trait_ref);
@ -3553,7 +3553,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}) })
.unwrap_or((found_span, None, found)); .unwrap_or((found_span, None, found));
self.report_arg_count_mismatch( self.infcx.report_arg_count_mismatch(
span, span,
closure_span, closure_span,
expected, expected,
@ -3569,7 +3569,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
span: Span, span: Span,
) -> Result<Diag<'tcx>, ErrorGuaranteed> { ) -> Result<Diag<'a>, ErrorGuaranteed> {
if !self.tcx.features().generic_const_exprs { if !self.tcx.features().generic_const_exprs {
let guar = self let guar = self
.dcx() .dcx()

View file

@ -13,13 +13,16 @@ fn main() {
let x: u64; let x: u64;
asm!("{}", in(reg) x); asm!("{}", in(reg) x);
//~^ ERROR isn't initialized
let mut y: u64; let mut y: u64;
asm!("{}", inout(reg) y); asm!("{}", inout(reg) y);
//~^ ERROR isn't initialized
let _ = y; let _ = y;
// Outputs require mutable places // Outputs require mutable places
let v: Vec<u64> = vec![0, 1, 2]; let v: Vec<u64> = vec![0, 1, 2];
//~^ ERROR is not declared as mutable
asm!("{}", in(reg) v[0]); asm!("{}", in(reg) v[0]);
asm!("{}", out(reg) v[0]); asm!("{}", out(reg) v[0]);
asm!("{}", inout(reg) v[0]); asm!("{}", inout(reg) v[0]);

View file

@ -1,5 +1,5 @@
error: invalid `sym` operand error: invalid `sym` operand
--> $DIR/type-check-2.rs:35:24 --> $DIR/type-check-2.rs:38:24
| |
LL | asm!("{}", sym x); LL | asm!("{}", sym x);
| ^ is a local variable | ^ is a local variable
@ -7,7 +7,7 @@ LL | asm!("{}", sym x);
= help: `sym` operands must refer to either a function or a static = help: `sym` operands must refer to either a function or a static
error: invalid `sym` operand error: invalid `sym` operand
--> $DIR/type-check-2.rs:86:19 --> $DIR/type-check-2.rs:89:19
| |
LL | global_asm!("{}", sym C); LL | global_asm!("{}", sym C);
| ^^^^^ is an `i32` | ^^^^^ is an `i32`
@ -15,7 +15,7 @@ LL | global_asm!("{}", sym C);
= help: `sym` operands must refer to either a function or a static = help: `sym` operands must refer to either a function or a static
error: invalid `sym` operand error: invalid `sym` operand
--> $DIR/type-check-2.rs:33:20 --> $DIR/type-check-2.rs:36:20
| |
LL | asm!("{}", sym C); LL | asm!("{}", sym C);
| ^^^^^ is an `i32` | ^^^^^ is an `i32`
@ -23,15 +23,15 @@ LL | asm!("{}", sym C);
= help: `sym` operands must refer to either a function or a static = help: `sym` operands must refer to either a function or a static
error: arguments for inline assembly must be copyable error: arguments for inline assembly must be copyable
--> $DIR/type-check-2.rs:40:32 --> $DIR/type-check-2.rs:43:32
| |
LL | asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0)); LL | asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= note: `SimdNonCopy` does not implement the Copy trait = note: `SimdNonCopy` does not implement the Copy trait
error: cannot use value of type `{closure@$DIR/type-check-2.rs:52:28: 52:36}` for inline assembly error: cannot use value of type `{closure@$DIR/type-check-2.rs:55:28: 55:36}` for inline assembly
--> $DIR/type-check-2.rs:52:28 --> $DIR/type-check-2.rs:55:28
| |
LL | asm!("{}", in(reg) |x: i32| x); LL | asm!("{}", in(reg) |x: i32| x);
| ^^^^^^^^^^ | ^^^^^^^^^^
@ -39,7 +39,7 @@ LL | asm!("{}", in(reg) |x: i32| x);
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
error: cannot use value of type `Vec<i32>` for inline assembly error: cannot use value of type `Vec<i32>` for inline assembly
--> $DIR/type-check-2.rs:54:28 --> $DIR/type-check-2.rs:57:28
| |
LL | asm!("{}", in(reg) vec![0]); LL | asm!("{}", in(reg) vec![0]);
| ^^^^^^^ | ^^^^^^^
@ -48,7 +48,7 @@ LL | asm!("{}", in(reg) vec![0]);
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot use value of type `(i32, i32, i32)` for inline assembly error: cannot use value of type `(i32, i32, i32)` for inline assembly
--> $DIR/type-check-2.rs:56:28 --> $DIR/type-check-2.rs:59:28
| |
LL | asm!("{}", in(reg) (1, 2, 3)); LL | asm!("{}", in(reg) (1, 2, 3));
| ^^^^^^^^^ | ^^^^^^^^^
@ -56,7 +56,7 @@ LL | asm!("{}", in(reg) (1, 2, 3));
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
error: cannot use value of type `[i32; 3]` for inline assembly error: cannot use value of type `[i32; 3]` for inline assembly
--> $DIR/type-check-2.rs:58:28 --> $DIR/type-check-2.rs:61:28
| |
LL | asm!("{}", in(reg) [1, 2, 3]); LL | asm!("{}", in(reg) [1, 2, 3]);
| ^^^^^^^^^ | ^^^^^^^^^
@ -64,7 +64,7 @@ LL | asm!("{}", in(reg) [1, 2, 3]);
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
error: cannot use value of type `fn() {main}` for inline assembly error: cannot use value of type `fn() {main}` for inline assembly
--> $DIR/type-check-2.rs:66:31 --> $DIR/type-check-2.rs:69:31
| |
LL | asm!("{}", inout(reg) f); LL | asm!("{}", inout(reg) f);
| ^ | ^
@ -72,12 +72,56 @@ LL | asm!("{}", inout(reg) f);
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
error: cannot use value of type `&mut i32` for inline assembly error: cannot use value of type `&mut i32` for inline assembly
--> $DIR/type-check-2.rs:69:31 --> $DIR/type-check-2.rs:72:31
| |
LL | asm!("{}", inout(reg) r); LL | asm!("{}", inout(reg) r);
| ^ | ^
| |
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
error: aborting due to 10 previous errors error[E0381]: used binding `x` isn't initialized
--> $DIR/type-check-2.rs:15:28
|
LL | let x: u64;
| - binding declared here but left uninitialized
LL | asm!("{}", in(reg) x);
| ^ `x` used here but it isn't initialized
|
help: consider assigning a value
|
LL | let x: u64 = 42;
| ++++
error[E0381]: used binding `y` isn't initialized
--> $DIR/type-check-2.rs:18:9
|
LL | let mut y: u64;
| ----- binding declared here but left uninitialized
LL | asm!("{}", inout(reg) y);
| ^^^^^^^^^^^^^^^^^^^^^^^^ `y` used here but it isn't initialized
|
help: consider assigning a value
|
LL | let mut y: u64 = 42;
| ++++
error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
--> $DIR/type-check-2.rs:24:13
|
LL | let v: Vec<u64> = vec![0, 1, 2];
| ^ not mutable
...
LL | asm!("{}", out(reg) v[0]);
| - cannot borrow as mutable
LL | asm!("{}", inout(reg) v[0]);
| - cannot borrow as mutable
|
help: consider changing this to be mutable
|
LL | let mut v: Vec<u64> = vec![0, 1, 2];
| +++
error: aborting due to 13 previous errors
Some errors have detailed explanations: E0381, E0596.
For more information about an error, try `rustc --explain E0381`.

View file

@ -13,4 +13,5 @@ impl Foo for isize {
pub fn main() { pub fn main() {
let x: isize = Foo::<A = usize>::bar(); let x: isize = Foo::<A = usize>::bar();
//~^ ERROR associated item constraints are not allowed here //~^ ERROR associated item constraints are not allowed here
//~| ERROR cannot call
} }

View file

@ -4,6 +4,22 @@ error[E0229]: associated item constraints are not allowed here
LL | let x: isize = Foo::<A = usize>::bar(); LL | let x: isize = Foo::<A = usize>::bar();
| ^^^^^^^^^ associated item constraint not allowed here | ^^^^^^^^^ associated item constraint not allowed here
error: aborting due to 1 previous error error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
--> $DIR/associated-types-eq-expr-path.rs:14:20
|
LL | fn bar() -> isize;
| ------------------ `Foo::bar` defined here
...
LL | let x: isize = Foo::<A = usize>::bar();
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
|
help: use the fully-qualified path to the only available implementation
|
LL - let x: isize = Foo::<A = usize>::bar();
LL + let x: isize = <isize as Foo<A = usize>>::bar();
|
For more information about this error, try `rustc --explain E0229`. error: aborting due to 2 previous errors
Some errors have detailed explanations: E0229, E0790.
For more information about an error, try `rustc --explain E0229`.

View file

@ -8,6 +8,7 @@ fn foo<T: Trait>() {
bar::<<T as Trait>::ASSOC>(); bar::<<T as Trait>::ASSOC>();
//~^ ERROR: expected associated type, found associated constant `Trait::ASSOC` //~^ ERROR: expected associated type, found associated constant `Trait::ASSOC`
//~| ERROR: unresolved item provided when a constant was expected //~| ERROR: unresolved item provided when a constant was expected
//~| ERROR type annotations needed
} }
fn main() {} fn main() {}

View file

@ -15,7 +15,19 @@ help: if this generic argument was intended as a const parameter, surround it wi
LL | bar::<{ <T as Trait>::ASSOC }>(); LL | bar::<{ <T as Trait>::ASSOC }>();
| + + | + +
error: aborting due to 2 previous errors error[E0284]: type annotations needed
--> $DIR/assoc_const_as_type_argument.rs:8:5
|
LL | bar::<<T as Trait>::ASSOC>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar`
|
note: required by a const generic parameter in `bar`
--> $DIR/assoc_const_as_type_argument.rs:5:8
|
LL | fn bar<const N: usize>() {}
| ^^^^^^^^^^^^^^ required by this const generic parameter in `bar`
Some errors have detailed explanations: E0575, E0747. error: aborting due to 3 previous errors
For more information about an error, try `rustc --explain E0575`.
Some errors have detailed explanations: E0284, E0575, E0747.
For more information about an error, try `rustc --explain E0284`.

View file

@ -17,7 +17,7 @@ LL | let _: [u8; bar::<N>()];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:18:23 --> $DIR/const-arg-in-const-arg.rs:19:23
| |
LL | let _: [u8; faz::<'a>(&())]; LL | let _: [u8; faz::<'a>(&())];
| ^^ cannot perform const operation using `'a` | ^^ cannot perform const operation using `'a`
@ -26,7 +26,7 @@ LL | let _: [u8; faz::<'a>(&())];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:20:23 --> $DIR/const-arg-in-const-arg.rs:21:23
| |
LL | let _: [u8; baz::<'a>(&())]; LL | let _: [u8; baz::<'a>(&())];
| ^^ cannot perform const operation using `'a` | ^^ cannot perform const operation using `'a`
@ -35,7 +35,7 @@ LL | let _: [u8; baz::<'a>(&())];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:21:23 --> $DIR/const-arg-in-const-arg.rs:22:23
| |
LL | let _: [u8; faz::<'b>(&())]; LL | let _: [u8; faz::<'b>(&())];
| ^^ cannot perform const operation using `'b` | ^^ cannot perform const operation using `'b`
@ -44,7 +44,7 @@ LL | let _: [u8; faz::<'b>(&())];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:23:23 --> $DIR/const-arg-in-const-arg.rs:24:23
| |
LL | let _: [u8; baz::<'b>(&())]; LL | let _: [u8; baz::<'b>(&())];
| ^^ cannot perform const operation using `'b` | ^^ cannot perform const operation using `'b`
@ -53,7 +53,7 @@ LL | let _: [u8; baz::<'b>(&())];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:26:23 --> $DIR/const-arg-in-const-arg.rs:27:23
| |
LL | let _ = [0; bar::<N>()]; LL | let _ = [0; bar::<N>()];
| ^ cannot perform const operation using `N` | ^ cannot perform const operation using `N`
@ -62,7 +62,7 @@ LL | let _ = [0; bar::<N>()];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:28:23 --> $DIR/const-arg-in-const-arg.rs:30:23
| |
LL | let _ = [0; faz::<'a>(&())]; LL | let _ = [0; faz::<'a>(&())];
| ^^ cannot perform const operation using `'a` | ^^ cannot perform const operation using `'a`
@ -71,7 +71,7 @@ LL | let _ = [0; faz::<'a>(&())];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:30:23 --> $DIR/const-arg-in-const-arg.rs:32:23
| |
LL | let _ = [0; baz::<'a>(&())]; LL | let _ = [0; baz::<'a>(&())];
| ^^ cannot perform const operation using `'a` | ^^ cannot perform const operation using `'a`
@ -80,7 +80,7 @@ LL | let _ = [0; baz::<'a>(&())];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:31:23 --> $DIR/const-arg-in-const-arg.rs:33:23
| |
LL | let _ = [0; faz::<'b>(&())]; LL | let _ = [0; faz::<'b>(&())];
| ^^ cannot perform const operation using `'b` | ^^ cannot perform const operation using `'b`
@ -89,7 +89,7 @@ LL | let _ = [0; faz::<'b>(&())];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:33:23 --> $DIR/const-arg-in-const-arg.rs:35:23
| |
LL | let _ = [0; baz::<'b>(&())]; LL | let _ = [0; baz::<'b>(&())];
| ^^ cannot perform const operation using `'b` | ^^ cannot perform const operation using `'b`
@ -98,7 +98,7 @@ LL | let _ = [0; baz::<'b>(&())];
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:34:24 --> $DIR/const-arg-in-const-arg.rs:36:24
| |
LL | let _: Foo<{ foo::<T>() }>; LL | let _: Foo<{ foo::<T>() }>;
| ^ cannot perform const operation using `T` | ^ cannot perform const operation using `T`
@ -107,7 +107,7 @@ LL | let _: Foo<{ foo::<T>() }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:35:24 --> $DIR/const-arg-in-const-arg.rs:37:24
| |
LL | let _: Foo<{ bar::<N>() }>; LL | let _: Foo<{ bar::<N>() }>;
| ^ cannot perform const operation using `N` | ^ cannot perform const operation using `N`
@ -116,7 +116,7 @@ LL | let _: Foo<{ bar::<N>() }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:37:24 --> $DIR/const-arg-in-const-arg.rs:40:24
| |
LL | let _: Foo<{ faz::<'a>(&()) }>; LL | let _: Foo<{ faz::<'a>(&()) }>;
| ^^ cannot perform const operation using `'a` | ^^ cannot perform const operation using `'a`
@ -125,7 +125,7 @@ LL | let _: Foo<{ faz::<'a>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:39:24 --> $DIR/const-arg-in-const-arg.rs:42:24
| |
LL | let _: Foo<{ baz::<'a>(&()) }>; LL | let _: Foo<{ baz::<'a>(&()) }>;
| ^^ cannot perform const operation using `'a` | ^^ cannot perform const operation using `'a`
@ -134,7 +134,7 @@ LL | let _: Foo<{ baz::<'a>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:40:24 --> $DIR/const-arg-in-const-arg.rs:43:24
| |
LL | let _: Foo<{ faz::<'b>(&()) }>; LL | let _: Foo<{ faz::<'b>(&()) }>;
| ^^ cannot perform const operation using `'b` | ^^ cannot perform const operation using `'b`
@ -143,7 +143,7 @@ LL | let _: Foo<{ faz::<'b>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:42:24 --> $DIR/const-arg-in-const-arg.rs:45:24
| |
LL | let _: Foo<{ baz::<'b>(&()) }>; LL | let _: Foo<{ baz::<'b>(&()) }>;
| ^^ cannot perform const operation using `'b` | ^^ cannot perform const operation using `'b`
@ -152,7 +152,7 @@ LL | let _: Foo<{ baz::<'b>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:43:27 --> $DIR/const-arg-in-const-arg.rs:46:27
| |
LL | let _ = Foo::<{ foo::<T>() }>; LL | let _ = Foo::<{ foo::<T>() }>;
| ^ cannot perform const operation using `T` | ^ cannot perform const operation using `T`
@ -161,7 +161,7 @@ LL | let _ = Foo::<{ foo::<T>() }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:44:27 --> $DIR/const-arg-in-const-arg.rs:47:27
| |
LL | let _ = Foo::<{ bar::<N>() }>; LL | let _ = Foo::<{ bar::<N>() }>;
| ^ cannot perform const operation using `N` | ^ cannot perform const operation using `N`
@ -170,7 +170,7 @@ LL | let _ = Foo::<{ bar::<N>() }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:46:27 --> $DIR/const-arg-in-const-arg.rs:50:27
| |
LL | let _ = Foo::<{ faz::<'a>(&()) }>; LL | let _ = Foo::<{ faz::<'a>(&()) }>;
| ^^ cannot perform const operation using `'a` | ^^ cannot perform const operation using `'a`
@ -179,7 +179,7 @@ LL | let _ = Foo::<{ faz::<'a>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:48:27 --> $DIR/const-arg-in-const-arg.rs:52:27
| |
LL | let _ = Foo::<{ baz::<'a>(&()) }>; LL | let _ = Foo::<{ baz::<'a>(&()) }>;
| ^^ cannot perform const operation using `'a` | ^^ cannot perform const operation using `'a`
@ -188,7 +188,7 @@ LL | let _ = Foo::<{ baz::<'a>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:49:27 --> $DIR/const-arg-in-const-arg.rs:53:27
| |
LL | let _ = Foo::<{ faz::<'b>(&()) }>; LL | let _ = Foo::<{ faz::<'b>(&()) }>;
| ^^ cannot perform const operation using `'b` | ^^ cannot perform const operation using `'b`
@ -197,7 +197,7 @@ LL | let _ = Foo::<{ faz::<'b>(&()) }>;
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error: generic parameters may not be used in const operations error: generic parameters may not be used in const operations
--> $DIR/const-arg-in-const-arg.rs:51:27 --> $DIR/const-arg-in-const-arg.rs:55:27
| |
LL | let _ = Foo::<{ baz::<'b>(&()) }>; LL | let _ = Foo::<{ baz::<'b>(&()) }>;
| ^^ cannot perform const operation using `'b` | ^^ cannot perform const operation using `'b`
@ -216,8 +216,20 @@ help: if this generic argument was intended as a const parameter, surround it wi
LL | let _: [u8; bar::<{ N }>()]; LL | let _: [u8; bar::<{ N }>()];
| + + | + +
error[E0284]: type annotations needed
--> $DIR/const-arg-in-const-arg.rs:16:17
|
LL | let _: [u8; bar::<N>()];
| ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar`
|
note: required by a const generic parameter in `bar`
--> $DIR/const-arg-in-const-arg.rs:9:14
|
LL | const fn bar<const N: usize>() -> usize { N }
| ^^^^^^^^^^^^^^ required by this const generic parameter in `bar`
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:18:23 --> $DIR/const-arg-in-const-arg.rs:19:23
| |
LL | let _: [u8; faz::<'a>(&())]; LL | let _: [u8; faz::<'a>(&())];
| ^^ | ^^
@ -229,7 +241,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^ | ^^
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:21:23 --> $DIR/const-arg-in-const-arg.rs:22:23
| |
LL | let _: [u8; faz::<'b>(&())]; LL | let _: [u8; faz::<'b>(&())];
| ^^ | ^^
@ -241,7 +253,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^ | ^^
error[E0747]: unresolved item provided when a constant was expected error[E0747]: unresolved item provided when a constant was expected
--> $DIR/const-arg-in-const-arg.rs:35:24 --> $DIR/const-arg-in-const-arg.rs:37:24
| |
LL | let _: Foo<{ bar::<N>() }>; LL | let _: Foo<{ bar::<N>() }>;
| ^ | ^
@ -251,8 +263,20 @@ help: if this generic argument was intended as a const parameter, surround it wi
LL | let _: Foo<{ bar::<{ N }>() }>; LL | let _: Foo<{ bar::<{ N }>() }>;
| + + | + +
error[E0284]: type annotations needed
--> $DIR/const-arg-in-const-arg.rs:37:18
|
LL | let _: Foo<{ bar::<N>() }>;
| ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar`
|
note: required by a const generic parameter in `bar`
--> $DIR/const-arg-in-const-arg.rs:9:14
|
LL | const fn bar<const N: usize>() -> usize { N }
| ^^^^^^^^^^^^^^ required by this const generic parameter in `bar`
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:37:24 --> $DIR/const-arg-in-const-arg.rs:40:24
| |
LL | let _: Foo<{ faz::<'a>(&()) }>; LL | let _: Foo<{ faz::<'a>(&()) }>;
| ^^ | ^^
@ -264,7 +288,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^ | ^^
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:40:24 --> $DIR/const-arg-in-const-arg.rs:43:24
| |
LL | let _: Foo<{ faz::<'b>(&()) }>; LL | let _: Foo<{ faz::<'b>(&()) }>;
| ^^ | ^^
@ -276,7 +300,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^ | ^^
error: constant expression depends on a generic parameter error: constant expression depends on a generic parameter
--> $DIR/const-arg-in-const-arg.rs:25:17 --> $DIR/const-arg-in-const-arg.rs:26:17
| |
LL | let _ = [0; foo::<T>()]; LL | let _ = [0; foo::<T>()];
| ^^^^^^^^^^ | ^^^^^^^^^^
@ -284,7 +308,7 @@ LL | let _ = [0; foo::<T>()];
= note: this may fail depending on what value the parameter takes = note: this may fail depending on what value the parameter takes
error[E0747]: unresolved item provided when a constant was expected error[E0747]: unresolved item provided when a constant was expected
--> $DIR/const-arg-in-const-arg.rs:26:23 --> $DIR/const-arg-in-const-arg.rs:27:23
| |
LL | let _ = [0; bar::<N>()]; LL | let _ = [0; bar::<N>()];
| ^ | ^
@ -294,8 +318,20 @@ help: if this generic argument was intended as a const parameter, surround it wi
LL | let _ = [0; bar::<{ N }>()]; LL | let _ = [0; bar::<{ N }>()];
| + + | + +
error[E0284]: type annotations needed
--> $DIR/const-arg-in-const-arg.rs:27:17
|
LL | let _ = [0; bar::<N>()];
| ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar`
|
note: required by a const generic parameter in `bar`
--> $DIR/const-arg-in-const-arg.rs:9:14
|
LL | const fn bar<const N: usize>() -> usize { N }
| ^^^^^^^^^^^^^^ required by this const generic parameter in `bar`
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:28:23 --> $DIR/const-arg-in-const-arg.rs:30:23
| |
LL | let _ = [0; faz::<'a>(&())]; LL | let _ = [0; faz::<'a>(&())];
| ^^ | ^^
@ -307,7 +343,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^ | ^^
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:31:23 --> $DIR/const-arg-in-const-arg.rs:33:23
| |
LL | let _ = [0; faz::<'b>(&())]; LL | let _ = [0; faz::<'b>(&())];
| ^^ | ^^
@ -319,7 +355,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^ | ^^
error[E0747]: unresolved item provided when a constant was expected error[E0747]: unresolved item provided when a constant was expected
--> $DIR/const-arg-in-const-arg.rs:44:27 --> $DIR/const-arg-in-const-arg.rs:47:27
| |
LL | let _ = Foo::<{ bar::<N>() }>; LL | let _ = Foo::<{ bar::<N>() }>;
| ^ | ^
@ -329,8 +365,20 @@ help: if this generic argument was intended as a const parameter, surround it wi
LL | let _ = Foo::<{ bar::<{ N }>() }>; LL | let _ = Foo::<{ bar::<{ N }>() }>;
| + + | + +
error[E0284]: type annotations needed
--> $DIR/const-arg-in-const-arg.rs:47:21
|
LL | let _ = Foo::<{ bar::<N>() }>;
| ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar`
|
note: required by a const generic parameter in `bar`
--> $DIR/const-arg-in-const-arg.rs:9:14
|
LL | const fn bar<const N: usize>() -> usize { N }
| ^^^^^^^^^^^^^^ required by this const generic parameter in `bar`
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:46:27 --> $DIR/const-arg-in-const-arg.rs:50:27
| |
LL | let _ = Foo::<{ faz::<'a>(&()) }>; LL | let _ = Foo::<{ faz::<'a>(&()) }>;
| ^^ | ^^
@ -342,7 +390,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^ | ^^
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> $DIR/const-arg-in-const-arg.rs:49:27 --> $DIR/const-arg-in-const-arg.rs:53:27
| |
LL | let _ = Foo::<{ faz::<'b>(&()) }>; LL | let _ = Foo::<{ faz::<'b>(&()) }>;
| ^^ | ^^
@ -353,7 +401,7 @@ note: the late bound lifetime parameter is introduced here
LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } LL | const fn faz<'a>(_: &'a ()) -> usize { 13 }
| ^^ | ^^
error: aborting due to 36 previous errors error: aborting due to 40 previous errors
Some errors have detailed explanations: E0747, E0794. Some errors have detailed explanations: E0284, E0747, E0794.
For more information about an error, try `rustc --explain E0747`. For more information about an error, try `rustc --explain E0284`.

View file

@ -15,6 +15,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized {
let _: [u8; foo::<T>()]; //[min]~ ERROR generic parameters may not let _: [u8; foo::<T>()]; //[min]~ ERROR generic parameters may not
let _: [u8; bar::<N>()]; //[min]~ ERROR generic parameters may not let _: [u8; bar::<N>()]; //[min]~ ERROR generic parameters may not
//[min]~^ ERROR unresolved item provided when a constant was expected //[min]~^ ERROR unresolved item provided when a constant was expected
//[min]~| ERROR type annotations needed
let _: [u8; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not let _: [u8; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not
//[min]~^ ERROR cannot specify lifetime arguments //[min]~^ ERROR cannot specify lifetime arguments
let _: [u8; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not let _: [u8; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not
@ -25,6 +26,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized {
let _ = [0; foo::<T>()]; //[min]~ ERROR constant expression depends on a generic parameter let _ = [0; foo::<T>()]; //[min]~ ERROR constant expression depends on a generic parameter
let _ = [0; bar::<N>()]; //[min]~ ERROR generic parameters may not let _ = [0; bar::<N>()]; //[min]~ ERROR generic parameters may not
//[min]~^ ERROR unresolved item provided when a constant was expected //[min]~^ ERROR unresolved item provided when a constant was expected
//[min]~| ERROR type annotations needed
let _ = [0; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not let _ = [0; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not
//[min]~^ ERROR cannot specify lifetime arguments //[min]~^ ERROR cannot specify lifetime arguments
let _ = [0; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not let _ = [0; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not
@ -34,6 +36,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized {
let _: Foo<{ foo::<T>() }>; //[min]~ ERROR generic parameters may not let _: Foo<{ foo::<T>() }>; //[min]~ ERROR generic parameters may not
let _: Foo<{ bar::<N>() }>; //[min]~ ERROR generic parameters may not let _: Foo<{ bar::<N>() }>; //[min]~ ERROR generic parameters may not
//[min]~^ ERROR unresolved item provided when a constant was expected //[min]~^ ERROR unresolved item provided when a constant was expected
//[min]~| ERROR type annotations needed
let _: Foo<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not let _: Foo<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not
//[min]~^ ERROR cannot specify lifetime arguments //[min]~^ ERROR cannot specify lifetime arguments
let _: Foo<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not let _: Foo<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not
@ -43,6 +46,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized {
let _ = Foo::<{ foo::<T>() }>; //[min]~ ERROR generic parameters may not let _ = Foo::<{ foo::<T>() }>; //[min]~ ERROR generic parameters may not
let _ = Foo::<{ bar::<N>() }>; //[min]~ ERROR generic parameters may not let _ = Foo::<{ bar::<N>() }>; //[min]~ ERROR generic parameters may not
//[min]~^ ERROR unresolved item provided when a constant was expected //[min]~^ ERROR unresolved item provided when a constant was expected
//[min]~| ERROR type annotations needed
let _ = Foo::<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not let _ = Foo::<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not
//[min]~^ ERROR cannot specify lifetime arguments //[min]~^ ERROR cannot specify lifetime arguments
let _ = Foo::<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not let _ = Foo::<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not

View file

@ -2,6 +2,7 @@
#![allow(incomplete_features)] #![allow(incomplete_features)]
type Foo = impl Sized; type Foo = impl Sized;
//~^ ERROR: unconstrained opaque type
fn with_bound<const N: usize>() -> Foo fn with_bound<const N: usize>() -> Foo
where where

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/opaque_type.rs:10:17 --> $DIR/opaque_type.rs:11:17
| |
LL | type Foo = impl Sized; LL | type Foo = impl Sized;
| ---------- the found opaque type | ---------- the found opaque type
@ -11,12 +11,20 @@ LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
found opaque type `Foo` found opaque type `Foo`
error[E0605]: non-primitive cast: `usize` as `Foo` error[E0605]: non-primitive cast: `usize` as `Foo`
--> $DIR/opaque_type.rs:10:17 --> $DIR/opaque_type.rs:11:17
| |
LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
| ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object | ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
error: aborting due to 2 previous errors error: unconstrained opaque type
--> $DIR/opaque_type.rs:4:12
|
LL | type Foo = impl Sized;
| ^^^^^^^^^^
|
= note: `Foo` must be used in combination with a concrete type within the same module
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0308, E0605. Some errors have detailed explanations: E0308, E0605.
For more information about an error, try `rustc --explain E0308`. For more information about an error, try `rustc --explain E0308`.

View file

@ -30,7 +30,31 @@ help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
LL + #![feature(generic_arg_infer)] LL + #![feature(generic_arg_infer)]
| |
error: aborting due to 3 previous errors error[E0284]: type annotations needed
--> $DIR/issue-62878.rs:10:5
|
LL | foo::<_, { [1] }>();
| ^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `foo`
|
note: required by a const generic parameter in `foo`
--> $DIR/issue-62878.rs:5:8
|
LL | fn foo<const N: usize, const A: [u8; N]>() {}
| ^^^^^^^^^^^^^^ required by this const generic parameter in `foo`
Some errors have detailed explanations: E0747, E0770. error[E0284]: type annotations needed
For more information about an error, try `rustc --explain E0747`. --> $DIR/issue-62878.rs:10:5
|
LL | foo::<_, { [1] }>();
| ^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `A` declared on the function `foo`
|
note: required by a const generic parameter in `foo`
--> $DIR/issue-62878.rs:5:24
|
LL | fn foo<const N: usize, const A: [u8; N]>() {}
| ^^^^^^^^^^^^^^^^ required by this const generic parameter in `foo`
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0284, E0747, E0770.
For more information about an error, try `rustc --explain E0284`.

View file

@ -9,4 +9,6 @@ fn foo<const N: usize, const A: [u8; N]>() {}
fn main() { fn main() {
foo::<_, { [1] }>(); foo::<_, { [1] }>();
//[min]~^ ERROR: type provided when a constant was expected //[min]~^ ERROR: type provided when a constant was expected
//[min]~| ERROR type annotations needed
//[min]~| ERROR type annotations needed
} }

View file

@ -12,6 +12,7 @@ fn b() {
//~^ ERROR expected trait, found constant `BAR` //~^ ERROR expected trait, found constant `BAR`
//~| ERROR expected trait, found constant `BAR` //~| ERROR expected trait, found constant `BAR`
//~| ERROR type provided when a constant was expected //~| ERROR type provided when a constant was expected
//~| ERROR type annotations needed
} }
fn c() { fn c() {
foo::<3 + 3>(); //~ ERROR expressions must be enclosed in braces foo::<3 + 3>(); //~ ERROR expressions must be enclosed in braces

View file

@ -10,7 +10,7 @@ LL | foo::<{ BAR + 3 }>();
| + + | + +
error: expressions must be enclosed in braces to be used as const generic arguments error: expressions must be enclosed in braces to be used as const generic arguments
--> $DIR/const-expression-suggest-missing-braces.rs:17:11 --> $DIR/const-expression-suggest-missing-braces.rs:18:11
| |
LL | foo::<3 + 3>(); LL | foo::<3 + 3>();
| ^^^^^ | ^^^^^
@ -21,7 +21,7 @@ LL | foo::<{ 3 + 3 }>();
| + + | + +
error: expected one of `,` or `>`, found `-` error: expected one of `,` or `>`, found `-`
--> $DIR/const-expression-suggest-missing-braces.rs:20:15 --> $DIR/const-expression-suggest-missing-braces.rs:21:15
| |
LL | foo::<BAR - 3>(); LL | foo::<BAR - 3>();
| ^ expected one of `,` or `>` | ^ expected one of `,` or `>`
@ -32,7 +32,7 @@ LL | foo::<{ BAR - 3 }>();
| + + | + +
error: expected one of `,` or `>`, found `-` error: expected one of `,` or `>`, found `-`
--> $DIR/const-expression-suggest-missing-braces.rs:23:15 --> $DIR/const-expression-suggest-missing-braces.rs:24:15
| |
LL | foo::<BAR - BAR>(); LL | foo::<BAR - BAR>();
| ^ expected one of `,` or `>` | ^ expected one of `,` or `>`
@ -43,7 +43,7 @@ LL | foo::<{ BAR - BAR }>();
| + + | + +
error: expressions must be enclosed in braces to be used as const generic arguments error: expressions must be enclosed in braces to be used as const generic arguments
--> $DIR/const-expression-suggest-missing-braces.rs:26:11 --> $DIR/const-expression-suggest-missing-braces.rs:27:11
| |
LL | foo::<100 - BAR>(); LL | foo::<100 - BAR>();
| ^^^^^^^^^ | ^^^^^^^^^
@ -54,7 +54,7 @@ LL | foo::<{ 100 - BAR }>();
| + + | + +
error: expected one of `,` or `>`, found `(` error: expected one of `,` or `>`, found `(`
--> $DIR/const-expression-suggest-missing-braces.rs:29:19 --> $DIR/const-expression-suggest-missing-braces.rs:30:19
| |
LL | foo::<bar<i32>()>(); LL | foo::<bar<i32>()>();
| ^ expected one of `,` or `>` | ^ expected one of `,` or `>`
@ -65,7 +65,7 @@ LL | foo::<{ bar<i32>() }>();
| + + | + +
error: expected one of `,` or `>`, found `(` error: expected one of `,` or `>`, found `(`
--> $DIR/const-expression-suggest-missing-braces.rs:32:21 --> $DIR/const-expression-suggest-missing-braces.rs:33:21
| |
LL | foo::<bar::<i32>()>(); LL | foo::<bar::<i32>()>();
| ^ expected one of `,` or `>` | ^ expected one of `,` or `>`
@ -76,7 +76,7 @@ LL | foo::<{ bar::<i32>() }>();
| + + | + +
error: expected one of `,` or `>`, found `(` error: expected one of `,` or `>`, found `(`
--> $DIR/const-expression-suggest-missing-braces.rs:35:21 --> $DIR/const-expression-suggest-missing-braces.rs:36:21
| |
LL | foo::<bar::<i32>() + BAR>(); LL | foo::<bar::<i32>() + BAR>();
| ^ expected one of `,` or `>` | ^ expected one of `,` or `>`
@ -87,7 +87,7 @@ LL | foo::<{ bar::<i32>() + BAR }>();
| + + | + +
error: expected one of `,` or `>`, found `(` error: expected one of `,` or `>`, found `(`
--> $DIR/const-expression-suggest-missing-braces.rs:38:21 --> $DIR/const-expression-suggest-missing-braces.rs:39:21
| |
LL | foo::<bar::<i32>() - BAR>(); LL | foo::<bar::<i32>() - BAR>();
| ^ expected one of `,` or `>` | ^ expected one of `,` or `>`
@ -98,7 +98,7 @@ LL | foo::<{ bar::<i32>() - BAR }>();
| + + | + +
error: expected one of `,` or `>`, found `-` error: expected one of `,` or `>`, found `-`
--> $DIR/const-expression-suggest-missing-braces.rs:41:15 --> $DIR/const-expression-suggest-missing-braces.rs:42:15
| |
LL | foo::<BAR - bar::<i32>()>(); LL | foo::<BAR - bar::<i32>()>();
| ^ expected one of `,` or `>` | ^ expected one of `,` or `>`
@ -109,7 +109,7 @@ LL | foo::<{ BAR - bar::<i32>() }>();
| + + | + +
error: expected one of `,` or `>`, found `-` error: expected one of `,` or `>`, found `-`
--> $DIR/const-expression-suggest-missing-braces.rs:44:15 --> $DIR/const-expression-suggest-missing-braces.rs:45:15
| |
LL | foo::<BAR - bar::<i32>()>(); LL | foo::<BAR - bar::<i32>()>();
| ^ expected one of `,` or `>` | ^ expected one of `,` or `>`
@ -137,7 +137,19 @@ error[E0747]: type provided when a constant was expected
LL | foo::<BAR + BAR>(); LL | foo::<BAR + BAR>();
| ^^^^^^^^^ | ^^^^^^^^^
error: aborting due to 14 previous errors error[E0284]: type annotations needed
--> $DIR/const-expression-suggest-missing-braces.rs:11:5
|
LL | foo::<BAR + BAR>();
| ^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the function `foo`
|
note: required by a const generic parameter in `foo`
--> $DIR/const-expression-suggest-missing-braces.rs:1:8
|
LL | fn foo<const C: usize>() {}
| ^^^^^^^^^^^^^^ required by this const generic parameter in `foo`
Some errors have detailed explanations: E0404, E0747. error: aborting due to 15 previous errors
For more information about an error, try `rustc --explain E0404`.
Some errors have detailed explanations: E0284, E0404, E0747.
For more information about an error, try `rustc --explain E0284`.

View file

@ -16,6 +16,7 @@ fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
//~| ERROR: type provided when a constant was expected //~| ERROR: type provided when a constant was expected
Example::<gimme_a_const!(marker)> Example::<gimme_a_const!(marker)>
//~^ ERROR: type provided when a constant was expected //~^ ERROR: type provided when a constant was expected
//~| ERROR type annotations needed
} }
fn from_marker(_: impl Marker<{ fn from_marker(_: impl Marker<{
@ -35,9 +36,11 @@ fn main() {
}>; }>;
let _fail = Example::<external_macro!()>; let _fail = Example::<external_macro!()>;
//~^ ERROR: type provided when a constant was expected //~^ ERROR: type provided when a constant
//~| ERROR type annotations needed
let _fail = Example::<gimme_a_const!()>; let _fail = Example::<gimme_a_const!()>;
//~^ ERROR unexpected end of macro invocation //~^ ERROR unexpected end of macro invocation
//~| ERROR: type provided when a constant was expected //~| ERROR: type provided when a constant was expected
//~| ERROR type annotations needed
} }

View file

@ -1,5 +1,5 @@
error: expected type, found `{` error: expected type, found `{`
--> $DIR/macro-fail.rs:30:27 --> $DIR/macro-fail.rs:31:27
| |
LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> { LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
| ---------------------- | ----------------------
@ -13,7 +13,7 @@ LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
= note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
error: expected type, found `{` error: expected type, found `{`
--> $DIR/macro-fail.rs:30:27 --> $DIR/macro-fail.rs:31:27
| |
LL | Example::<gimme_a_const!(marker)> LL | Example::<gimme_a_const!(marker)>
| ---------------------- | ----------------------
@ -41,7 +41,7 @@ LL | let _fail = Example::<external_macro!()>;
= note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error: unexpected end of macro invocation error: unexpected end of macro invocation
--> $DIR/macro-fail.rs:40:25 --> $DIR/macro-fail.rs:42:25
| |
LL | macro_rules! gimme_a_const { LL | macro_rules! gimme_a_const {
| -------------------------- when calling this macro | -------------------------- when calling this macro
@ -50,7 +50,7 @@ LL | let _fail = Example::<gimme_a_const!()>;
| ^^^^^^^^^^^^^^^^ missing tokens in macro arguments | ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
| |
note: while trying to match meta-variable `$rusty:ident` note: while trying to match meta-variable `$rusty:ident`
--> $DIR/macro-fail.rs:30:8 --> $DIR/macro-fail.rs:31:8
| |
LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -75,18 +75,63 @@ error[E0747]: type provided when a constant was expected
LL | Example::<gimme_a_const!(marker)> LL | Example::<gimme_a_const!(marker)>
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0284]: type annotations needed
--> $DIR/macro-fail.rs:17:3
|
LL | Example::<gimme_a_const!(marker)>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the struct `Example`
|
note: required by a const generic parameter in `Example`
--> $DIR/macro-fail.rs:1:16
|
LL | struct Example<const N: usize>;
| ^^^^^^^^^^^^^^ required by this const generic parameter in `Example`
error[E0747]: type provided when a constant was expected error[E0747]: type provided when a constant was expected
--> $DIR/macro-fail.rs:37:25 --> $DIR/macro-fail.rs:38:25
| |
LL | let _fail = Example::<external_macro!()>; LL | let _fail = Example::<external_macro!()>;
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error[E0747]: type provided when a constant was expected error[E0747]: type provided when a constant was expected
--> $DIR/macro-fail.rs:40:25 --> $DIR/macro-fail.rs:42:25
| |
LL | let _fail = Example::<gimme_a_const!()>; LL | let _fail = Example::<gimme_a_const!()>;
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: aborting due to 9 previous errors error[E0284]: type annotations needed for `Example<_>`
--> $DIR/macro-fail.rs:38:7
|
LL | let _fail = Example::<external_macro!()>;
| ^^^^^ ---------------------------- type must be known at this point
|
note: required by a const generic parameter in `Example`
--> $DIR/macro-fail.rs:1:16
|
LL | struct Example<const N: usize>;
| ^^^^^^^^^^^^^^ required by this const generic parameter in `Example`
help: consider giving `_fail` an explicit type, where the value of const parameter `N` is specified
|
LL | let _fail: Example<N> = Example::<external_macro!()>;
| ++++++++++++
For more information about this error, try `rustc --explain E0747`. error[E0284]: type annotations needed for `Example<_>`
--> $DIR/macro-fail.rs:42:7
|
LL | let _fail = Example::<gimme_a_const!()>;
| ^^^^^ --------------------------- type must be known at this point
|
note: required by a const generic parameter in `Example`
--> $DIR/macro-fail.rs:1:16
|
LL | struct Example<const N: usize>;
| ^^^^^^^^^^^^^^ required by this const generic parameter in `Example`
help: consider giving `_fail` an explicit type, where the value of const parameter `N` is specified
|
LL | let _fail: Example<N> = Example::<gimme_a_const!()>;
| ++++++++++++
error: aborting due to 12 previous errors
Some errors have detailed explanations: E0284, E0747.
For more information about an error, try `rustc --explain E0284`.

View file

@ -5,6 +5,8 @@ fn example<const N: usize>() {}
fn other() { fn other() {
example::<[usize; 3]>(); example::<[usize; 3]>();
//~^ ERROR type provided when a const //~^ ERROR type provided when a const
example::<[usize; 4+5]>(); //~| ERROR type annotations needed
example::<[usize; 4 + 5]>();
//~^ ERROR type provided when a const //~^ ERROR type provided when a const
//~| ERROR type annotations needed
} }

View file

@ -1,15 +1,40 @@
error[E0747]: type provided when a constant was expected error[E0747]: type provided when a constant was expected
--> $DIR/suggest_const_for_array.rs:6:13 --> $DIR/suggest_const_for_array.rs:6:15
| |
LL | example::<[usize; 3]>(); LL | example::<[usize; 3]>();
| ^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 3 }` | ^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 3 }`
error[E0747]: type provided when a constant was expected error[E0747]: type provided when a constant was expected
--> $DIR/suggest_const_for_array.rs:8:13 --> $DIR/suggest_const_for_array.rs:9:15
| |
LL | example::<[usize; 4+5]>(); LL | example::<[usize; 4 + 5]>();
| ^^^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 4+5 }` | ^^^^^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 4 + 5 }`
error: aborting due to 2 previous errors error[E0284]: type annotations needed
--> $DIR/suggest_const_for_array.rs:6:5
|
LL | example::<[usize; 3]>();
| ^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `example`
|
note: required by a const generic parameter in `example`
--> $DIR/suggest_const_for_array.rs:3:12
|
LL | fn example<const N: usize>() {}
| ^^^^^^^^^^^^^^ required by this const generic parameter in `example`
For more information about this error, try `rustc --explain E0747`. error[E0284]: type annotations needed
--> $DIR/suggest_const_for_array.rs:9:5
|
LL | example::<[usize; 4 + 5]>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `example`
|
note: required by a const generic parameter in `example`
--> $DIR/suggest_const_for_array.rs:3:12
|
LL | fn example<const N: usize>() {}
| ^^^^^^^^^^^^^^ required by this const generic parameter in `example`
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0284, E0747.
For more information about an error, try `rustc --explain E0284`.

View file

@ -3,4 +3,5 @@ fn foo<U>() {}
fn main() { fn main() {
foo::<main>() foo::<main>()
//~^ ERROR constant provided when a type was expected //~^ ERROR constant provided when a type was expected
//~| ERROR type annotations needed
} }

View file

@ -7,6 +7,13 @@ LL | foo::<main>()
= help: `main` is a function item, not a type = help: `main` is a function item, not a type
= help: function item types cannot be named directly = help: function item types cannot be named directly
error: aborting due to 1 previous error error[E0282]: type annotations needed
--> $DIR/generic-function-item-where-type.rs:4:5
|
LL | foo::<main>()
| ^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `foo`
For more information about this error, try `rustc --explain E0747`. error: aborting due to 2 previous errors
Some errors have detailed explanations: E0282, E0747.
For more information about an error, try `rustc --explain E0282`.

View file

@ -2,6 +2,7 @@
use std::fmt::Debug; use std::fmt::Debug;
fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
//~^ ERROR cannot resolve opaque type
|x| x |x| x
//~^ ERROR expected generic lifetime parameter, found `'_` //~^ ERROR expected generic lifetime parameter, found `'_`
} }

View file

@ -1,11 +1,19 @@
error[E0792]: expected generic lifetime parameter, found `'_` error[E0792]: expected generic lifetime parameter, found `'_`
--> $DIR/impl-fn-predefined-lifetimes.rs:5:9 --> $DIR/impl-fn-predefined-lifetimes.rs:6:9
| |
LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
| -- this generic parameter must be used with a generic lifetime parameter | -- this generic parameter must be used with a generic lifetime parameter
LL |
LL | |x| x LL | |x| x
| ^ | ^
error: aborting due to 1 previous error error[E0720]: cannot resolve opaque type
--> $DIR/impl-fn-predefined-lifetimes.rs:4:35
|
LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
| ^^^^^^^^^^^^^^^ cannot resolve opaque type
For more information about this error, try `rustc --explain E0792`. error: aborting due to 2 previous errors
Some errors have detailed explanations: E0720, E0792.
For more information about an error, try `rustc --explain E0720`.

View file

@ -5,6 +5,7 @@
use std::mem::transmute; use std::mem::transmute;
fn foo() -> impl Sized { fn foo() -> impl Sized {
//~^ ERROR cycle detected when computing type of //~^ ERROR cycle detected when computing type of
//~| WARN function cannot return without recursing
unsafe { unsafe {
transmute::<_, u8>(foo()); transmute::<_, u8>(foo());
} }

View file

@ -24,6 +24,18 @@ LL | fn foo() -> impl Sized {
| ^^^^^^^^^^ | ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error: aborting due to 1 previous error warning: function cannot return without recursing
--> $DIR/in-defining-scope.rs:6:1
|
LL | fn foo() -> impl Sized {
| ^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
...
LL | transmute::<_, u8>(foo());
| ----- recursive call site
|
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default
error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0391`. For more information about this error, try `rustc --explain E0391`.

View file

@ -1,5 +1,6 @@
struct Take(Take); struct Take(Take);
//~^ ERROR has infinite size //~^ ERROR has infinite size
//~| ERROR cycle
// check that we don't hang trying to find the tail of a recursive struct (#79437) // check that we don't hang trying to find the tail of a recursive struct (#79437)
fn foo() -> Take { fn foo() -> Take {

View file

@ -10,7 +10,7 @@ LL | struct Take(Box<Take>);
| ++++ + | ++++ +
error[E0072]: recursive type `Foo` has infinite size error[E0072]: recursive type `Foo` has infinite size
--> $DIR/infinite-struct.rs:10:1 --> $DIR/infinite-struct.rs:11:1
| |
LL | struct Foo { LL | struct Foo {
| ^^^^^^^^^^ | ^^^^^^^^^^
@ -26,6 +26,17 @@ error: reached the recursion limit finding the struct tail for `Take`
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
error: aborting due to 3 previous errors error[E0391]: cycle detected when computing when `Take` needs drop
--> $DIR/infinite-struct.rs:1:1
|
LL | struct Take(Take);
| ^^^^^^^^^^^
|
= note: ...which immediately requires computing when `Take` needs drop again
= note: cycle used when computing whether `Take` needs drop
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
For more information about this error, try `rustc --explain E0072`. error: aborting due to 4 previous errors
Some errors have detailed explanations: E0072, E0391.
For more information about an error, try `rustc --explain E0072`.

View file

@ -1,26 +0,0 @@
//@ compile-flags: --edition 2024 -Z unstable-options
fn main() {}
unsafe fn _foo() {
static mut X: i32 = 1;
static mut Y: i32 = 1;
let _y = &X;
//~^ ERROR creating a shared reference to a mutable static [E0796]
let ref _a = X;
//~^ ERROR creating a shared reference to a mutable static [E0796]
let ref mut _a = X;
//~^ ERROR creating a mutable reference to a mutable static [E0796]
let (_b, _c) = (&X, &mut Y);
//~^ ERROR creating a shared reference to a mutable static [E0796]
//~^^ ERROR creating a mutable reference to a mutable static [E0796]
foo(&X);
//~^ ERROR creating a shared reference to a mutable static [E0796]
}
fn foo<'a>(_x: &'a i32) {}

View file

@ -1,75 +0,0 @@
error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-of-mut-static-unsafe-fn.rs:9:14
|
LL | let _y = &X;
| ^^ shared reference to mutable static
|
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let _y = addr_of!(X);
| ~~~~~~~~~~~
error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-of-mut-static-unsafe-fn.rs:12:18
|
LL | let ref _a = X;
| ^ shared reference to mutable static
|
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let ref _a = addr_of!(X);
| ~~~~~~~~~~~
error[E0796]: creating a mutable reference to a mutable static
--> $DIR/reference-of-mut-static-unsafe-fn.rs:15:22
|
LL | let ref mut _a = X;
| ^ mutable reference to mutable static
|
= note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
help: use `addr_of_mut!` instead to create a raw pointer
|
LL | let ref mut _a = addr_of_mut!(X);
| ~~~~~~~~~~~~~~~
error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-of-mut-static-unsafe-fn.rs:18:21
|
LL | let (_b, _c) = (&X, &mut Y);
| ^^ shared reference to mutable static
|
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let (_b, _c) = (addr_of!(X), &mut Y);
| ~~~~~~~~~~~
error[E0796]: creating a mutable reference to a mutable static
--> $DIR/reference-of-mut-static-unsafe-fn.rs:18:25
|
LL | let (_b, _c) = (&X, &mut Y);
| ^^^^^^ mutable reference to mutable static
|
= note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
help: use `addr_of_mut!` instead to create a raw pointer
|
LL | let (_b, _c) = (&X, addr_of_mut!(Y));
| ~~~~~~~~~~~~~~~
error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-of-mut-static-unsafe-fn.rs:22:9
|
LL | foo(&X);
| ^^ shared reference to mutable static
|
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | foo(addr_of!(X));
| ~~~~~~~~~~~
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0796`.

View file

@ -1,91 +0,0 @@
error: creating a shared reference to mutable static is discouraged
--> $DIR/reference-of-mut-static.rs:16:18
|
LL | let _y = &X;
| ^^ shared reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
note: the lint level is defined here
--> $DIR/reference-of-mut-static.rs:6:9
|
LL | #![deny(static_mut_refs)]
| ^^^^^^^^^^^^^^^
help: use `addr_of!` instead to create a raw pointer
|
LL | let _y = addr_of!(X);
| ~~~~~~~~~~~
error: creating a mutable reference to mutable static is discouraged
--> $DIR/reference-of-mut-static.rs:20:18
|
LL | let _y = &mut X;
| ^^^^^^ mutable reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
help: use `addr_of_mut!` instead to create a raw pointer
|
LL | let _y = addr_of_mut!(X);
| ~~~~~~~~~~~~~~~
error: creating a shared reference to mutable static is discouraged
--> $DIR/reference-of-mut-static.rs:28:22
|
LL | let ref _a = X;
| ^ shared reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let ref _a = addr_of!(X);
| ~~~~~~~~~~~
error: creating a shared reference to mutable static is discouraged
--> $DIR/reference-of-mut-static.rs:32:25
|
LL | let (_b, _c) = (&X, &Y);
| ^^ shared reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let (_b, _c) = (addr_of!(X), &Y);
| ~~~~~~~~~~~
error: creating a shared reference to mutable static is discouraged
--> $DIR/reference-of-mut-static.rs:32:29
|
LL | let (_b, _c) = (&X, &Y);
| ^^ shared reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let (_b, _c) = (&X, addr_of!(Y));
| ~~~~~~~~~~~
error: creating a shared reference to mutable static is discouraged
--> $DIR/reference-of-mut-static.rs:38:13
|
LL | foo(&X);
| ^^ shared reference to mutable static
|
= note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
= note: this will be a hard error in the 2024 edition
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | foo(addr_of!(X));
| ~~~~~~~~~~~
error: aborting due to 6 previous errors

View file

@ -1,75 +0,0 @@
error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-of-mut-static.rs:16:18
|
LL | let _y = &X;
| ^^ shared reference to mutable static
|
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let _y = addr_of!(X);
| ~~~~~~~~~~~
error[E0796]: creating a mutable reference to a mutable static
--> $DIR/reference-of-mut-static.rs:20:18
|
LL | let _y = &mut X;
| ^^^^^^ mutable reference to mutable static
|
= note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
help: use `addr_of_mut!` instead to create a raw pointer
|
LL | let _y = addr_of_mut!(X);
| ~~~~~~~~~~~~~~~
error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-of-mut-static.rs:28:22
|
LL | let ref _a = X;
| ^ shared reference to mutable static
|
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let ref _a = addr_of!(X);
| ~~~~~~~~~~~
error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-of-mut-static.rs:32:25
|
LL | let (_b, _c) = (&X, &Y);
| ^^ shared reference to mutable static
|
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let (_b, _c) = (addr_of!(X), &Y);
| ~~~~~~~~~~~
error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-of-mut-static.rs:32:29
|
LL | let (_b, _c) = (&X, &Y);
| ^^ shared reference to mutable static
|
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | let (_b, _c) = (&X, addr_of!(Y));
| ~~~~~~~~~~~
error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-of-mut-static.rs:38:13
|
LL | foo(&X);
| ^^ shared reference to mutable static
|
= note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
help: use `addr_of!` instead to create a raw pointer
|
LL | foo(addr_of!(X));
| ~~~~~~~~~~~
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0796`.

View file

@ -1,50 +0,0 @@
//@ revisions: e2021 e2024
//@ [e2021] edition:2021
//@ [e2024] compile-flags: --edition 2024 -Z unstable-options
#![deny(static_mut_refs)]
use std::ptr::{addr_of, addr_of_mut};
fn main() {
static mut X: i32 = 1;
static mut Y: i32 = 1;
unsafe {
let _y = &X;
//[e2024]~^ ERROR creating a shared reference to a mutable static [E0796]
//[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
let _y = &mut X;
//[e2024]~^ ERROR creating a mutable reference to a mutable static [E0796]
//[e2021]~^^ ERROR mutable reference to mutable static is discouraged [static_mut_refs]
let _z = addr_of_mut!(X);
let _p = addr_of!(X);
let ref _a = X;
//[e2024]~^ ERROR creating a shared reference to a mutable static [E0796]
//[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
let (_b, _c) = (&X, &Y);
//[e2024]~^ ERROR creating a shared reference to a mutable static [E0796]
//[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
//[e2024]~^^^ ERROR creating a shared reference to a mutable static [E0796]
//[e2021]~^^^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
foo(&X);
//[e2024]~^ ERROR creating a shared reference to a mutable static [E0796]
//[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
static mut Z: &[i32; 3] = &[0, 1, 2];
let _ = Z.len();
let _ = Z[0];
let _ = format!("{:?}", Z);
}
}
fn foo<'a>(_x: &'a i32) {}

View file

@ -10,6 +10,15 @@ help: use `addr_of!` instead to create a raw pointer
LL | let _x = addr_of!(X); LL | let _x = addr_of!(X);
| ~~~~~~~~~~~ | ~~~~~~~~~~~
error: aborting due to 1 previous error error[E0133]: use of mutable static is unsafe and requires unsafe block
--> $DIR/reference-to-mut-static-safe.rs:9:15
|
LL | let _x = &X;
| ^ use of mutable static
|
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
For more information about this error, try `rustc --explain E0796`. error: aborting due to 2 previous errors
Some errors have detailed explanations: E0133, E0796.
For more information about an error, try `rustc --explain E0133`.

View file

@ -8,6 +8,6 @@ fn main() {
let _x = &X; let _x = &X;
//[e2024]~^ creating a shared reference to a mutable static [E0796] //[e2024]~^ creating a shared reference to a mutable static [E0796]
//[e2021]~^^ use of mutable static is unsafe and requires unsafe function or block [E0133] //~^^ use of mutable static is unsafe and requires unsafe
//[e2021]~^^^ shared reference to mutable static is discouraged [static_mut_refs] //[e2021]~^^^ shared reference to mutable static is discouraged [static_mut_refs]
} }

View file

@ -3,6 +3,7 @@
fn main() {} fn main() {}
unsafe fn _foo() { unsafe fn _foo() {
unsafe {
static mut X: i32 = 1; static mut X: i32 = 1;
static mut Y: i32 = 1; static mut Y: i32 = 1;
@ -21,6 +22,7 @@ unsafe fn _foo() {
foo(&X); foo(&X);
//~^ ERROR creating a shared reference to a mutable static [E0796] //~^ ERROR creating a shared reference to a mutable static [E0796]
}
} }
fn foo<'a>(_x: &'a i32) {} fn foo<'a>(_x: &'a i32) {}

View file

@ -1,5 +1,5 @@
error[E0796]: creating a shared reference to a mutable static error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:9:14 --> $DIR/reference-to-mut-static-unsafe-fn.rs:10:18
| |
LL | let _y = &X; LL | let _y = &X;
| ^^ shared reference to mutable static | ^^ shared reference to mutable static
@ -11,7 +11,7 @@ LL | let _y = addr_of!(X);
| ~~~~~~~~~~~ | ~~~~~~~~~~~
error[E0796]: creating a shared reference to a mutable static error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:12:18 --> $DIR/reference-to-mut-static-unsafe-fn.rs:13:22
| |
LL | let ref _a = X; LL | let ref _a = X;
| ^ shared reference to mutable static | ^ shared reference to mutable static
@ -23,7 +23,7 @@ LL | let ref _a = addr_of!(X);
| ~~~~~~~~~~~ | ~~~~~~~~~~~
error[E0796]: creating a mutable reference to a mutable static error[E0796]: creating a mutable reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:15:22 --> $DIR/reference-to-mut-static-unsafe-fn.rs:16:26
| |
LL | let ref mut _a = X; LL | let ref mut _a = X;
| ^ mutable reference to mutable static | ^ mutable reference to mutable static
@ -35,7 +35,7 @@ LL | let ref mut _a = addr_of_mut!(X);
| ~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~
error[E0796]: creating a shared reference to a mutable static error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:18:21 --> $DIR/reference-to-mut-static-unsafe-fn.rs:19:25
| |
LL | let (_b, _c) = (&X, &mut Y); LL | let (_b, _c) = (&X, &mut Y);
| ^^ shared reference to mutable static | ^^ shared reference to mutable static
@ -47,7 +47,7 @@ LL | let (_b, _c) = (addr_of!(X), &mut Y);
| ~~~~~~~~~~~ | ~~~~~~~~~~~
error[E0796]: creating a mutable reference to a mutable static error[E0796]: creating a mutable reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:18:25 --> $DIR/reference-to-mut-static-unsafe-fn.rs:19:29
| |
LL | let (_b, _c) = (&X, &mut Y); LL | let (_b, _c) = (&X, &mut Y);
| ^^^^^^ mutable reference to mutable static | ^^^^^^ mutable reference to mutable static
@ -59,7 +59,7 @@ LL | let (_b, _c) = (&X, addr_of_mut!(Y));
| ~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~
error[E0796]: creating a shared reference to a mutable static error[E0796]: creating a shared reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:22:9 --> $DIR/reference-to-mut-static-unsafe-fn.rs:23:13
| |
LL | foo(&X); LL | foo(&X);
| ^^ shared reference to mutable static | ^^ shared reference to mutable static

View file

@ -44,18 +44,6 @@ LL |
LL | call(operation).await LL | call(operation).await
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error[E0792]: expected generic lifetime parameter, found `'any`
--> $DIR/hkl_forbidden4.rs:23:1
|
LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
| -- this generic parameter must be used with a generic lifetime parameter
...
LL | / {
LL | |
LL | |
LL | | }
| |_^
error: concrete type differs from previous defining opaque type use error: concrete type differs from previous defining opaque type use
--> $DIR/hkl_forbidden4.rs:13:1 --> $DIR/hkl_forbidden4.rs:13:1
| |
@ -68,6 +56,18 @@ note: previous use here
LL | call(operation).await LL | call(operation).await
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error[E0792]: expected generic lifetime parameter, found `'any`
--> $DIR/hkl_forbidden4.rs:23:1
|
LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
| -- this generic parameter must be used with a generic lifetime parameter
...
LL | / {
LL | |
LL | |
LL | | }
| |_^
error: aborting due to 6 previous errors error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0792`. For more information about this error, try `rustc --explain E0792`.

View file

@ -5,6 +5,8 @@ type Bug<T, U> = impl Fn(T) -> U + Copy; //~ ERROR cycle detected
const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) }; const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
//~^ ERROR: non-defining opaque type use //~^ ERROR: non-defining opaque type use
//~| ERROR: item does not constrain
//~| ERROR: item does not constrain
fn make_bug<T, U: From<T>>() -> Bug<T, U> { fn make_bug<T, U: From<T>>() -> Bug<T, U> {
|x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied |x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied

View file

@ -36,14 +36,40 @@ LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error: item does not constrain `Bug::{opaque#0}`, but has it in its signature
--> $DIR/issue-53092-2.rs:6:7
|
LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
| ^^^^^^^^^
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
note: this opaque type is in the signature
--> $DIR/issue-53092-2.rs:4:18
|
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
| ^^^^^^^^^^^^^^^^^^^^^^
error: item does not constrain `Bug::{opaque#0}`, but has it in its signature
--> $DIR/issue-53092-2.rs:6:61
|
LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
| ^^^^^^^
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
note: this opaque type is in the signature
--> $DIR/issue-53092-2.rs:4:18
|
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `U: From<T>` is not satisfied error[E0277]: the trait bound `U: From<T>` is not satisfied
--> $DIR/issue-53092-2.rs:10:5 --> $DIR/issue-53092-2.rs:12:5
| |
LL | |x| x.into() LL | |x| x.into()
| ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U` | ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
| |
note: required by a bound in `make_bug` note: required by a bound in `make_bug`
--> $DIR/issue-53092-2.rs:9:19 --> $DIR/issue-53092-2.rs:11:19
| |
LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> { LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
| ^^^^^^^ required by this bound in `make_bug` | ^^^^^^^ required by this bound in `make_bug`
@ -52,7 +78,7 @@ help: consider restricting type parameter `U`
LL | type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy; LL | type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy;
| +++++++++++++++++++++++ | +++++++++++++++++++++++
error: aborting due to 3 previous errors error: aborting due to 5 previous errors
Some errors have detailed explanations: E0277, E0391, E0792. Some errors have detailed explanations: E0277, E0391, E0792.
For more information about an error, try `rustc --explain E0277`. For more information about an error, try `rustc --explain E0277`.