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_span::Span;
impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
pub fn dcx(&self) -> DiagCtxtHandle<'tcx> {
impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
pub fn dcx(&self) -> DiagCtxtHandle<'infcx> {
self.infcx.dcx()
}
@ -18,7 +18,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
place: &str,
borrow_place: &str,
value_place: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
self.dcx().create_err(crate::session_diagnostics::MoveBorrow {
place,
span,
@ -34,7 +34,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
desc: &str,
borrow_span: Span,
borrow_desc: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
span,
@ -54,7 +54,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
old_loan_span: Span,
old_opt_via: &str,
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 mut err = struct_span_code_err!(
self.dcx(),
@ -101,7 +101,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
desc: &str,
old_loan_span: Span,
old_load_end_span: Option<Span>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let mut err = struct_span_code_err!(
self.dcx(),
new_loan_span,
@ -134,7 +134,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
noun_old: &str,
old_opt_via: &str,
previous_end_span: Option<Span>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let mut err = struct_span_code_err!(
self.dcx(),
new_loan_span,
@ -166,7 +166,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
old_opt_via: &str,
previous_end_span: Option<Span>,
second_borrow_desc: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let mut err = struct_span_code_err!(
self.dcx(),
new_loan_span,
@ -198,7 +198,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
kind_old: &str,
msg_old: &str,
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 mut err = struct_span_code_err!(
self.dcx(),
@ -239,7 +239,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
span: Span,
borrow_span: Span,
desc: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
span,
@ -256,12 +256,12 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
span: Span,
desc: &str,
is_arg: bool,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
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)
}
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)
}
@ -269,7 +269,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self,
move_from_span: Span,
move_from_desc: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
move_from_span,
@ -287,7 +287,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
move_from_span: Span,
ty: Ty<'_>,
is_index: Option<bool>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let type_name = match (&ty.kind(), is_index) {
(&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
(&ty::Slice(_), _) => "slice",
@ -308,7 +308,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self,
move_from_span: Span,
container_ty: Ty<'_>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
move_from_span,
@ -325,7 +325,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
verb: &str,
optional_adverb_for_moved: &str,
moved_path: Option<String>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let moved_path = moved_path.map(|mp| format!(": `{mp}`")).unwrap_or_default();
struct_span_code_err!(
@ -344,7 +344,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
span: Span,
path: &str,
reason: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
span,
@ -362,7 +362,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
immutable_place: &str,
immutable_section: &str,
action: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
mutate_span,
@ -380,7 +380,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self,
span: Span,
yield_span: Span,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind;
struct_span_code_err!(
self.dcx(),
@ -391,7 +391,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
.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!(
self.dcx(),
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,)
}
@ -410,7 +410,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
return_kind: &str,
reference_desc: &str,
path_desc: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
span,
@ -433,7 +433,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
borrowed_path: &str,
capture_span: Span,
scope: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
closure_span,
@ -445,7 +445,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
.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!(
self.dcx(),
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",)
}
}

View File

@ -15,24 +15,24 @@ use std::fmt;
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
/// The results of the dataflow analyses used by the borrow checker.
pub struct BorrowckResults<'mir, 'tcx> {
pub(crate) borrows: Results<'tcx, Borrows<'mir, 'tcx>>,
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>,
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'mir, 'tcx>>,
pub struct BorrowckResults<'a, 'mir, 'tcx> {
pub(crate) borrows: Results<'tcx, Borrows<'a, 'mir, 'tcx>>,
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'mir, 'tcx>>,
}
/// The transient state of the dataflow analyses used by the borrow checker.
#[derive(Debug)]
pub struct BorrowckFlowState<'mir, 'tcx> {
pub(crate) borrows: <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) uninits: <MaybeUninitializedPlaces<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) ever_inits: <EverInitializedPlaces<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub struct BorrowckFlowState<'a, 'mir, 'tcx> {
pub(crate) borrows: <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) uninits: <MaybeUninitializedPlaces<'a, '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.
type Direction = <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction;
type FlowState = BorrowckFlowState<'mir, 'tcx>;
type Direction = <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction;
type FlowState = BorrowckFlowState<'a, 'mir, 'tcx>;
fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
BorrowckFlowState {
@ -106,11 +106,11 @@ rustc_index::newtype_index! {
/// `BorrowIndex`, and maps each such index to a `BorrowData`
/// describing the borrow. These indexes are used for representing the
/// borrows in compact bitvectors.
pub struct Borrows<'mir, 'tcx> {
pub struct Borrows<'a, 'mir, 'tcx> {
tcx: TyCtxt<'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>>,
}
@ -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(
tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>,
regioncx: &'mir RegionInferenceContext<'tcx>,
borrow_set: &'mir BorrowSet<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
borrow_set: &'a BorrowSet<'tcx>,
) -> Self {
let mut borrows_out_of_scope_at_location =
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>;
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.
/// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of
/// `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;
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 {
fn fmt_with(&self, ctxt: &Borrows<'_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
impl DebugWithContext<Borrows<'_, '_, '_>> for BorrowIndex {
fn fmt_with(&self, ctxt: &Borrows<'_, '_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", ctxt.location(*self))
}
}

View File

@ -149,13 +149,13 @@ trait TypeOpInfo<'tcx> {
fn base_universe(&self) -> ty::UniverseIndex;
fn nice_error(
fn nice_error<'infcx>(
&self,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
) -> Option<Diag<'tcx>>;
) -> Option<Diag<'infcx>>;
#[instrument(level = "debug", skip(self, mbcx))]
fn report_error(
@ -231,18 +231,25 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
self.base_universe
}
fn nice_error(
fn nice_error<'infcx>(
&self,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
) -> Option<Diag<'tcx>> {
) -> Option<Diag<'infcx>> {
let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx);
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
}
fn nice_error(
fn nice_error<'infcx>(
&self,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
) -> Option<Diag<'tcx>> {
) -> Option<Diag<'infcx>> {
let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx);
@ -288,7 +295,14 @@ where
let (param_env, value) = key.into_parts();
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
}
fn nice_error(
fn nice_error<'infcx>(
&self,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
) -> Option<Diag<'tcx>> {
) -> Option<Diag<'infcx>> {
let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx);
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()
}
fn nice_error(
fn nice_error<'infcx>(
&self,
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
_cause: ObligationCause<'tcx>,
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
) -> Option<Diag<'tcx>> {
) -> Option<Diag<'infcx>> {
try_extract_error_from_region_constraints(
mbcx.infcx,
mbcx.mir_def_id(),
@ -358,12 +379,12 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
}
#[instrument(skip(ocx), level = "debug")]
fn try_extract_error_from_fulfill_cx<'tcx>(
ocx: &ObligationCtxt<'_, 'tcx>,
fn try_extract_error_from_fulfill_cx<'a, 'tcx>(
ocx: &ObligationCtxt<'a, 'tcx>,
generic_param_scope: LocalDefId,
placeholder_region: 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
// already run, but there's no point using `span_delayed_bug`
// 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))]
fn try_extract_error_from_region_constraints<'tcx>(
infcx: &InferCtxt<'tcx>,
fn try_extract_error_from_region_constraints<'a, 'tcx>(
infcx: &'a InferCtxt<'tcx>,
generic_param_scope: LocalDefId,
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
region_constraints: &RegionConstraintData<'tcx>,
mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin,
mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex,
) -> Option<Diag<'tcx>> {
) -> Option<Diag<'a>> {
let placeholder_universe = match placeholder_region.kind() {
ty::RePlaceholder(p) => p.universe,
ty::ReVar(vid) => universe_of_region(vid),

View File

@ -73,7 +73,7 @@ enum StorageDeadOrDrop<'tcx> {
Destructor(Ty<'tcx>),
}
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
pub(crate) fn report_use_of_moved_or_uninitialized(
&mut self,
location: Location,
@ -341,7 +341,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
fn suggest_ref_or_clone(
&self,
mpi: MovePathIndex,
err: &mut Diag<'tcx>,
err: &mut Diag<'infcx>,
in_pattern: &mut bool,
move_spans: UseSpans<'tcx>,
) {
@ -517,7 +517,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
desired_action: InitializationRequiringAction,
span: Span,
use_spans: UseSpans<'tcx>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
// 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.
let inits = &self.move_data.init_path_map[mpi];
@ -1461,7 +1461,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
location: Location,
(place, _span): (Place<'tcx>, Span),
borrow: &BorrowData<'tcx>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let borrow_spans = self.retrieve_borrow_spans(borrow);
let borrow_span = borrow_spans.args_or_use();
@ -1511,7 +1511,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
(place, span): (Place<'tcx>, Span),
gen_borrow_kind: BorrowKind,
issued_borrow: &BorrowData<'tcx>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let issued_spans = self.retrieve_borrow_spans(issued_borrow);
let issued_span = issued_spans.args_or_use();
@ -1802,7 +1802,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
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 hir = tcx.hir();
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,
borrow_spans: UseSpans<'tcx>,
explanation: BorrowExplanation<'tcx>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
debug!(
"report_local_value_does_not_live_long_enough(\
{:?}, {:?}, {:?}, {:?}, {:?}\
@ -3036,7 +3036,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self,
drop_span: Span,
borrow_span: Span,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
debug!(
"report_thread_local_value_does_not_live_long_enough(\
{:?}, {:?}\
@ -3061,7 +3061,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
borrow_spans: UseSpans<'tcx>,
proper_span: Span,
explanation: BorrowExplanation<'tcx>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } =
explanation
{
@ -3226,7 +3226,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
return_span: Span,
category: ConstraintCategory<'tcx>,
opt_place_desc: Option<&String>,
) -> Result<(), Diag<'tcx>> {
) -> Result<(), Diag<'infcx>> {
let return_kind = match category {
ConstraintCategory::Return(_) => "return",
ConstraintCategory::Yield => "yield",
@ -3319,7 +3319,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
constraint_span: Span,
captured_var: &str,
scope: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let tcx = self.infcx.tcx;
let args_span = use_span.args_or_use();
@ -3431,7 +3431,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
upvar_span: Span,
upvar_name: Symbol,
escape_span: Span,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let tcx = self.infcx.tcx;
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);
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
/// is moved after being invoked.
///
@ -86,7 +86,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self,
location: Location,
place: PlaceRef<'tcx>,
diag: &mut Diag<'_>,
diag: &mut Diag<'infcx>,
) -> bool {
debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place);
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) {
let grouped_errors = self.group_move_errors();
for error in grouped_errors {
@ -291,7 +291,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
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 {
format!("static item {}", self.describe_any_place(place.as_ref()))
} else {
@ -428,7 +428,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
deref_target_place: Place<'tcx>,
span: Span,
use_spans: Option<UseSpans<'tcx>>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let tcx = self.infcx.tcx;
// Inspect the type of the content behind the
// borrow to provide feedback about why this

View File

@ -30,7 +30,7 @@ pub(crate) enum AccessKind {
Mutate,
}
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
pub(crate) fn report_mutability_error(
&mut self,
access_place: Place<'tcx>,
@ -541,7 +541,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
}
/// 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 did = adt.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.
/// When it finds it, see if it corresponds to assignment operator whose LHS
/// is an index expr.
struct SuggestIndexOperatorAlternativeVisitor<'a, 'tcx> {
struct SuggestIndexOperatorAlternativeVisitor<'a, 'infcx, 'tcx> {
assign_span: Span,
err: &'a mut Diag<'tcx>,
err: &'a mut Diag<'infcx>,
ty: Ty<'tcx>,
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>) {
hir::intravisit::walk_stmt(self, stmt);
let expr = match stmt.kind {

View File

@ -160,7 +160,7 @@ pub struct ErrorConstraintInfo<'tcx> {
pub(super) span: Span,
}
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
/// Converts a region inference variable into a `ty::Region` that
/// 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
@ -360,7 +360,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
let named_key = self.regioncx.name_regions(self.infcx.tcx, key);
let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region);
let diag = unexpected_hidden_region_diagnostic(
self.infcx.tcx,
self.infcx,
self.mir_def_id(),
span,
named_ty,
@ -589,7 +589,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self,
errci: &ErrorConstraintInfo<'tcx>,
kind: ReturnConstraint,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
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
/// ```
#[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 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`
/// ```
#[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 {
fr,
fr_is_local,

View File

@ -310,8 +310,8 @@ fn do_mir_borrowck<'tcx>(
promoted_mbcx.report_move_errors();
diags = promoted_mbcx.diags;
struct MoveVisitor<'a, 'b, 'mir, 'cx, 'tcx> {
ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'cx, 'tcx>,
struct MoveVisitor<'a, 'b, 'mir, 'infcx, 'tcx> {
ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'infcx, 'tcx>,
}
impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, '_, 'tcx> {
@ -528,8 +528,8 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {
}
}
struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> {
infcx: &'cx BorrowckInferCtxt<'tcx>,
struct MirBorrowckCtxt<'a, 'mir, 'infcx, 'tcx> {
infcx: &'infcx BorrowckInferCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
body: &'mir Body<'tcx>,
move_data: &'a MoveData<'tcx>,
@ -596,7 +596,7 @@ struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> {
/// Results of Polonius analysis.
polonius_output: Option<Rc<PoloniusOutput>>,
diags: diags::BorrowckDiags<'tcx>,
diags: diags::BorrowckDiags<'infcx, '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
// 3. assignments do not affect things loaned out as immutable
// 4. moves do not affect things loaned out in any way
impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
for MirBorrowckCtxt<'_, 'mir, '_, 'tcx>
impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
for MirBorrowckCtxt<'a, 'mir, '_, 'tcx>
{
type FlowState = Flows<'mir, 'tcx>;
type FlowState = Flows<'a, 'mir, 'tcx>;
fn visit_statement_before_primary_effect(
&mut self,
_results: &mut R,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
stmt: &'mir Statement<'tcx>,
location: Location,
) {
@ -683,7 +683,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
fn visit_terminator_before_primary_effect(
&mut self,
_results: &mut R,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
term: &'mir Terminator<'tcx>,
loc: Location,
) {
@ -794,7 +794,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
fn visit_terminator_after_primary_effect(
&mut self,
_results: &mut R,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
term: &'mir Terminator<'tcx>,
loc: Location,
) {
@ -988,7 +988,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
place_span: (Place<'tcx>, Span),
kind: (AccessDepth, ReadOrWrite),
is_local_mutation_allowed: LocalMutationIsAllowed,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
let (sd, rw) = kind;
@ -1038,7 +1038,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
place_span: (Place<'tcx>, Span),
sd: AccessDepth,
rw: ReadOrWrite,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) -> bool {
let mut error_reported = false;
let borrow_set = Rc::clone(&self.borrow_set);
@ -1179,7 +1179,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location,
place_span: (Place<'tcx>, Span),
kind: AccessDepth,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
// Write of P[i] or *P requires P init'd.
self.check_if_assigned_path_is_moved(location, place_span, flow_state);
@ -1197,7 +1197,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
&mut self,
location: Location,
(rvalue, span): (&'mir Rvalue<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
match rvalue {
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
@ -1455,7 +1455,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
&mut self,
location: Location,
(operand, span): (&'mir Operand<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
match *operand {
Operand::Copy(place) => {
@ -1579,7 +1579,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
&mut self,
location: Location,
span: Span,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
// Two-phase borrow support: For each activation that is newly
// generated at this statement, check if it interferes with
@ -1743,7 +1743,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location,
desired_action: InitializationRequiringAction,
place_span: (PlaceRef<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
let maybe_uninits = &flow_state.uninits;
@ -1848,7 +1848,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location,
desired_action: InitializationRequiringAction,
place_span: (PlaceRef<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
let maybe_uninits = &flow_state.uninits;
@ -1947,7 +1947,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
&mut self,
location: Location,
(place, span): (Place<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
debug!("check_if_assigned_path_is_moved place: {:?}", place);
@ -2013,7 +2013,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location,
base: PlaceRef<'tcx>,
span: Span,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
// rust-lang/rust#21232: Until Rust allows reads from the
// initialized parts of partially initialized structs, we
@ -2104,7 +2104,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
(place, span): (Place<'tcx>, Span),
kind: ReadOrWrite,
is_local_mutation_allowed: LocalMutationIsAllowed,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
location: Location,
) -> bool {
debug!(
@ -2220,7 +2220,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
fn is_local_ever_initialized(
&self,
local: Local,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) -> Option<InitIndex> {
let mpi = self.move_data.rev_lookup.find_local(local)?;
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
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 {
RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => {
// If the local may have been initialized, and it is now currently being
@ -2428,12 +2428,12 @@ mod diags {
use super::*;
enum BufferedDiag<'tcx> {
Error(Diag<'tcx>),
NonError(Diag<'tcx, ()>),
enum BufferedDiag<'infcx> {
Error(Diag<'infcx>),
NonError(Diag<'infcx, ()>),
}
impl<'tcx> BufferedDiag<'tcx> {
impl<'infcx> BufferedDiag<'infcx> {
fn sort_span(&self) -> Span {
match self {
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.
///
/// 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
/// 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.
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.
buffered_diags: Vec<BufferedDiag<'tcx>>,
buffered_diags: Vec<BufferedDiag<'infcx>>,
}
impl<'tcx> BorrowckDiags<'tcx> {
impl<'infcx, 'tcx> BorrowckDiags<'infcx, 'tcx> {
pub fn new() -> Self {
BorrowckDiags {
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));
}
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));
}
}
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
pub fn buffer_error(&mut self, diag: Diag<'tcx>) {
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
pub fn buffer_error(&mut self, diag: Diag<'infcx>) {
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);
}
pub fn buffer_move_error(
&mut self,
move_out_indices: Vec<MoveOutIndex>,
place_and_err: (PlaceRef<'tcx>, Diag<'tcx>),
place_and_err: (PlaceRef<'tcx>, Diag<'infcx>),
) -> bool {
if let Some((_, diag)) =
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?
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));
}
@ -2554,7 +2554,7 @@ mod diags {
pub fn has_move_error(
&self,
move_out_indices: &[MoveOutIndex],
) -> Option<&(PlaceRef<'tcx>, Diag<'tcx>)> {
) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> {
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>>,
location_table: &LocationTable,
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>,
borrow_set: &BorrowSet<'tcx>,
upvars: &[&ty::CapturedPlace<'tcx>],
@ -262,13 +262,13 @@ pub(super) fn dump_mir_results<'tcx>(
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
pub(super) fn dump_annotation<'tcx>(
infcx: &BorrowckInferCtxt<'tcx>,
pub(super) fn dump_annotation<'tcx, 'cx>(
infcx: &'cx BorrowckInferCtxt<'tcx>,
body: &Body<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
closure_region_requirements: &Option<ClosureRegionRequirements<'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 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 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);
@ -304,7 +304,7 @@ pub(super) fn dump_annotation<'tcx>(
err
} 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);
err

View File

@ -285,7 +285,7 @@ impl<'tcx> InferCtxt<'tcx> {
}
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);
}
@ -294,6 +294,10 @@ impl<'tcx> InferCtxt<'tcx> {
.remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false)
.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,
// so lets make sure that we don't accidentally misuse our current `infcx`.
match check_opaque_type_well_formed(
@ -387,10 +391,11 @@ fn check_opaque_type_well_formed<'tcx>(
/// [rustc-dev-guide chapter]:
/// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html
fn check_opaque_type_parameter_valid<'tcx>(
tcx: TyCtxt<'tcx>,
infcx: &InferCtxt<'tcx>,
opaque_type_key: OpaqueTypeKey<'tcx>,
span: Span,
) -> Result<(), ErrorGuaranteed> {
let tcx = infcx.tcx;
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id);
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)?;
return Err(tcx.dcx().emit_err(NonGenericOpaqueTypeParam {
return Err(infcx.dcx().emit_err(NonGenericOpaqueTypeParam {
ty: arg,
kind,
span,
@ -438,7 +443,7 @@ fn check_opaque_type_parameter_valid<'tcx>(
.collect();
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
return Err(tcx
return Err(infcx
.dcx()
.struct_span_err(span, "non-defining opaque type use in defining scope")
.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>,
body: &Body<'tcx>,
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>,
) {
debug!("liveness::generate");

View File

@ -43,7 +43,7 @@ pub(super) fn trace<'mir, 'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>,
body: &Body<'tcx>,
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>,
relevant_live_locals: Vec<Local>,
boring_locals: Vec<Local>,
@ -101,7 +101,7 @@ pub(super) fn trace<'mir, 'tcx>(
}
/// 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.
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
/// 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
/// dropped.
@ -131,8 +131,8 @@ struct DropData<'tcx> {
region_constraint_data: Option<&'tcx QueryRegionConstraints<'tcx>>,
}
struct LivenessResults<'me, 'typeck, 'flow, 'tcx> {
cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>,
struct LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>,
/// Set of points that define the current local.
defs: BitSet<PointIndex>,
@ -153,8 +153,8 @@ struct LivenessResults<'me, 'typeck, 'flow, 'tcx> {
stack: Vec<PointIndex>,
}
impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
fn new(cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>) -> Self {
impl<'a, 'me, 'typeck, 'flow, 'tcx> LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
fn new(cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>) -> Self {
let num_points = cx.elements.num_points();
LivenessResults {
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
/// cursor position. Callers should call one of the `seek` methods immediately before to point
/// the cursor to the desired location.

View File

@ -129,7 +129,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
location_table: &LocationTable,
borrow_set: &BorrowSet<'tcx>,
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>,
elements: &Rc<DenseLocationMap>,
upvars: &[&ty::CapturedPlace<'tcx>],

View File

@ -45,10 +45,10 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
/// MIR visitor for collecting used mutable variables.
/// 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>,
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<'_, '_, '_, '_, '_> {

View File

@ -510,7 +510,7 @@ pub struct Diag<'a, G: EmissionGuarantee = ErrorGuaranteed> {
// would be bad.
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> {
type Target = DiagInner;
@ -582,6 +582,11 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
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.
#[track_caller]
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 std::backtrace::{Backtrace, BacktraceStatus};
use std::borrow::Cow;
use std::cell::Cell;
use std::error::Report;
use std::fmt;
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.
#[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")]
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)]
pub enum SuggestionStyle {
@ -417,6 +418,9 @@ pub struct DiagCtxt {
#[derive(Copy, Clone)]
pub struct DiagCtxtHandle<'a> {
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> {
@ -752,7 +756,17 @@ impl DiagCtxt {
}
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
// diagnostic context is dropped and thus delayed bugs are emitted.
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
| Expect(_) => None,
};
@ -947,16 +963,19 @@ impl<'a> DiagCtxtHandle<'a> {
(0, _) => {
// Use `ForceWarning` rather than `Warning` to guarantee emission, e.g. with a
// configuration like `--cap-lints allow --force-warn bare_trait_objects`.
inner.emit_diagnostic(DiagInner::new(
ForceWarning(None),
DiagMessage::Str(warnings),
));
inner.emit_diagnostic(
DiagInner::new(ForceWarning(None), DiagMessage::Str(warnings)),
None,
);
}
(_, 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 {}`.",
&error_codes[0]
);
inner.emit_diagnostic(DiagInner::new(FailureNote, msg1));
inner.emit_diagnostic(DiagInner::new(FailureNote, msg2));
inner.emit_diagnostic(DiagInner::new(FailureNote, msg1), None);
inner.emit_diagnostic(DiagInner::new(FailureNote, msg2), None);
} else {
let msg = format!(
"For more information about this error, try `rustc --explain {}`.",
&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> {
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) {
@ -1080,7 +1099,7 @@ impl<'a> DiagCtxtHandle<'a> {
// 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
// id is now stable.
inner.emit_diagnostic(diag);
inner.emit_diagnostic(diag, self.tainted_with_errors);
}
}
@ -1430,13 +1449,17 @@ impl DiagCtxtInner {
continue;
}
}
guar = guar.or(self.emit_diagnostic(diag));
guar = guar.or(self.emit_diagnostic(diag, None));
}
guar
}
// 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 {
Expect(expect_id) | ForceWarning(Some(expect_id)) => {
// The `LintExpectationId` can be stable or unstable depending on when it was
@ -1609,6 +1632,9 @@ impl DiagCtxtInner {
if is_lint {
self.lint_err_guars.push(guar);
} else {
if let Some(taint) = taint {
taint.set(Some(guar));
}
self.err_guars.push(guar);
}
self.panic_if_treat_err_as_bug();
@ -1718,8 +1744,8 @@ impl DiagCtxtInner {
// `-Ztreat-err-as-bug`, which we don't want.
let note1 = "no errors encountered even though delayed bugs were created";
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, note2));
self.emit_diagnostic(DiagInner::new(Note, note1), None);
self.emit_diagnostic(DiagInner::new(Note, note2), None);
for bug in bugs {
if let Some(out) = &mut out {
@ -1752,7 +1778,7 @@ impl DiagCtxtInner {
}
bug.level = Bug;
self.emit_diagnostic(bug);
self.emit_diagnostic(bug, None);
}
// Panic with `DelayedBugPanic` to avoid "unexpected panic" messages.

View File

@ -319,7 +319,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
} else {
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 => {
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 });
}
fn report_return_mismatched_types<'a>(
fn report_return_mismatched_types<'infcx>(
&self,
cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
ty_err: TypeError<'tcx>,
fcx: &FnCtxt<'a, 'tcx>,
fcx: &'infcx FnCtxt<'_, 'tcx>,
block_or_return_id: hir::HirId,
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 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(
&self,
&'a self,
sp: Span,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) -> Result<(), Diag<'tcx>> {
) -> Result<(), Diag<'a>> {
self.demand_suptype_with_origin(&self.misc(sp), expected, actual)
}
#[instrument(skip(self), level = "debug")]
pub fn demand_suptype_with_origin(
&self,
&'a self,
cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) -> Result<(), Diag<'tcx>> {
) -> Result<(), Diag<'a>> {
self.at(cause, self.param_env)
.sup(DefineOpaqueTypes::Yes, expected, actual)
.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(
&self,
&'a self,
sp: Span,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) -> Result<(), Diag<'tcx>> {
) -> Result<(), Diag<'a>> {
self.demand_eqtype_with_origin(&self.misc(sp), expected, actual)
}
pub fn demand_eqtype_with_origin(
&self,
&'a self,
cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
) -> Result<(), Diag<'tcx>> {
) -> Result<(), Diag<'a>> {
self.at(cause, self.param_env)
.eq(DefineOpaqueTypes::Yes, expected, actual)
.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".
#[instrument(level = "debug", skip(self, expr, expected_ty_expr, allow_two_phase))]
pub fn demand_coerce_diag(
&self,
&'a self,
mut expr: &'tcx hir::Expr<'tcx>,
checked_ty: Ty<'tcx>,
expected: Ty<'tcx>,
mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
allow_two_phase: AllowTwoPhase,
) -> Result<Ty<'tcx>, Diag<'tcx>> {
) -> Result<Ty<'tcx>, Diag<'a>> {
let expected = self.resolve_vars_with_obligations(expected);
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
// by error (#114529)
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,
"illegal break with value found but no error reported",
);
@ -1716,7 +1716,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
error_happened = true;
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,
prev_span: *prev_span,
ident,
@ -1757,7 +1757,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if adt_kind == AdtKind::Union {
if hir_fields.len() != 1 {
struct_span_code_err!(
tcx.dcx(),
self.dcx(),
span,
E0784,
"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 {
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> {

View File

@ -1182,7 +1182,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
name: self.tcx.item_name(def.did()).to_ident_string(),
});
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,
impl_span: tcx.def_span(impl_def_id),
sugg,
@ -1207,7 +1207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Check the visibility of the ctor.
let vis = tcx.visibility(ctor_def_id);
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()) });
}
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))
}
_ => {
let mut err = tcx.dcx().struct_span_err(
let mut err = self.dcx().struct_span_err(
span,
"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
// our input types to err_args so we don't blow up the error messages
let guar = struct_span_code_err!(
tcx.dcx(),
self.dcx(),
call_span,
E0059,
"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)),
);
self.set_tainted_by_errors(self.report_arg_errors(
self.report_arg_errors(
compatibility_diagonal,
formal_and_expected_inputs,
provided_args,
@ -462,7 +462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn_def_id,
call_span,
call_expr,
));
);
}
}
@ -788,7 +788,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
format!("arguments to this {call_name} are incorrect"),
);
} else {
err = tcx.dcx().struct_span_err(
err = self.dcx().struct_span_err(
full_call_span,
format!(
"{call_name} takes {}{} but {} {} supplied",
@ -848,7 +848,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span_bug!(error_span, "expected errors from argument matrix");
} else {
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);
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() {
struct_span_code_err!(
tcx.dcx(),
self.dcx(),
full_call_span,
E0308,
"arguments to this {} are incorrect",
call_name,
)
} else {
tcx.dcx()
self.dcx()
.struct_span_err(
full_call_span,
format!(
@ -1424,7 +1424,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected_ty: Ty<'tcx>,
provided_ty: Ty<'tcx>,
arg: &hir::Expr<'tcx>,
err: &mut Diag<'tcx>,
err: &mut Diag<'_>,
) {
if let ty::RawPtr(_, hir::Mutability::Mut) = expected_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> {
self.infcx.dcx()
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'a> {
self.root_ctxt.infcx.dcx()
}
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
// example that triggers this would be worth minimizing and
// 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.
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)
&& 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!("target type: {to}"))
.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!(
tcx.dcx(),
self.dcx(),
span,
E0512,
"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 {
self.suggest_missing_writer(rcvr_ty, rcvr_expr)
} else {
let mut err = tcx.dcx().create_err(NoAssociatedItem {
let mut err = self.dcx().create_err(NoAssociatedItem {
span,
item_kind,
item_name,
@ -1194,7 +1194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: item_span,
..
})) => {
tcx.dcx().span_delayed_bug(
self.dcx().span_delayed_bug(
*item_span,
"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() {
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,
ty_str: ty_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 mut err = struct_span_code_err!(
tcx.dcx(),
self.dcx(),
span,
E0689,
"can't call {} `{}` on ambiguous numeric type `{}`",

View File

@ -89,7 +89,7 @@ struct PatInfo<'tcx, 'a> {
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> {
let code = ObligationCauseCode::Pattern {
span: ti.span,
@ -100,12 +100,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
}
fn demand_eqtype_pat_diag(
&self,
&'a self,
cause_span: Span,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
ti: &TopInfo<'tcx>,
) -> Result<(), Diag<'tcx>> {
) -> Result<(), Diag<'a>> {
self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)
.map_err(|mut diag| {
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 mut err = struct_span_code_err!(
self.tcx.dcx(),
self.dcx(),
ident.span,
E0596,
"cannot borrow as mutable inside an `&` pattern"
@ -1010,7 +1010,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (res, opt_ty, segments) = path_resolution;
match res {
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);
return Ty::new_error(tcx, e);
}
@ -1191,7 +1192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (res, opt_ty, segments) =
self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span);
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);
on_error(e);
return Ty::new_error(tcx, e);
@ -1207,7 +1208,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let variant = match res {
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, _) => {
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.
if adt.is_union() {
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 {
tcx.dcx().emit_err(errors::UnionPatDotDot { span: pat.span });
self.dcx().emit_err(errors::UnionPatDotDot { span: pat.span });
}
} else if !unmentioned_fields.is_empty() {
let accessible_unmentioned_fields: Vec<_> = unmentioned_fields
@ -1690,7 +1691,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat: &'tcx Pat<'tcx>,
variant: &ty::VariantDef,
args: ty::GenericArgsRef<'tcx>,
) -> Diag<'tcx> {
) -> Diag<'a> {
let tcx = self.tcx;
let (field_names, t, plural) = if let [field] = inexistent_fields {
(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 mut err = struct_span_code_err!(
tcx.dcx(),
self.dcx(),
spans,
E0026,
"{} `{}` does not have {}",
@ -1881,7 +1882,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
pat: &Pat<'_>,
fields: &'tcx [hir::PatField<'tcx>],
) -> Diag<'tcx> {
) -> Diag<'a> {
let mut err = self
.dcx()
.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)],
have_inaccessible_fields: bool,
fields: &'tcx [hir::PatField<'tcx>],
) -> Diag<'tcx> {
) -> Diag<'a> {
let inaccessible = if have_inaccessible_fields { " and inaccessible fields" } else { "" };
let field_names = if let [(_, field)] = unmentioned_fields {
format!("field `{field}`{inaccessible}")

View File

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

View File

@ -391,7 +391,7 @@ impl<'tcx> InferCtxt<'tcx> {
span: Span,
arg_data: InferenceDiagnosticsData,
error_code: TypeAnnotationNeeded,
) -> Diag<'tcx> {
) -> Diag<'_> {
let source_kind = "other";
let source_name = "";
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))]
pub fn emit_inference_failure_err(
&self,
@ -445,7 +445,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
arg: GenericArg<'tcx>,
error_code: TypeAnnotationNeeded,
should_label_span: bool,
) -> Diag<'tcx> {
) -> Diag<'a> {
let arg = self.resolve_vars_if_possible(arg);
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
// of a body, so we won't be able to get better info
// 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);
@ -465,7 +465,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
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);

View File

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

View File

@ -684,8 +684,8 @@ impl<'tcx> InferOk<'tcx, ()> {
}
impl<'tcx> InferCtxt<'tcx> {
pub fn dcx(&self) -> DiagCtxtHandle<'tcx> {
self.tcx.dcx()
pub fn dcx(&self) -> DiagCtxtHandle<'_> {
self.tcx.dcx().taintable_handle(&self.tainted_by_errors)
}
pub fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
@ -1089,19 +1089,7 @@ impl<'tcx> InferCtxt<'tcx> {
/// inference variables, regionck errors).
#[must_use = "this method does not have any side effects"]
pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
if let Some(guar) = 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
}
self.tainted_by_errors.get()
}
/// 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");
}
if value.has_infer_regions() {
let guar =
self.tcx.dcx().delayed_bug(format!("`{value:?}` is not fully resolved"));
let guar = self.dcx().delayed_bug(format!("`{value:?}` is not fully resolved"));
Ok(self.tcx.fold_regions(value, |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]
// 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),
@ -1623,9 +1610,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
sp: Span,
mk_diag: M,
actual_ty: Ty<'tcx>,
) -> Diag<'tcx>
) -> Diag<'a>
where
M: FnOnce(String) -> Diag<'tcx>,
M: FnOnce(String) -> Diag<'a>,
{
let actual_ty = self.resolve_vars_if_possible(actual_ty);
debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty);
@ -1646,7 +1633,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
expected: Ty<'tcx>,
actual: Ty<'tcx>,
err: TypeError<'tcx>,
) -> Diag<'tcx> {
) -> Diag<'a> {
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>,
actual: ty::Const<'tcx>,
err: TypeError<'tcx>,
) -> Diag<'tcx> {
) -> Diag<'a> {
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)
&& self.tcx.is_type_alias_impl_trait(b_def_id)
{
self.tcx.dcx().emit_err(OpaqueHiddenTypeDiag {
self.dcx().emit_err(OpaqueHiddenTypeDiag {
span,
hidden_type: self.tcx.def_span(b_def_id),
opaque_type: self.tcx.def_span(def_id),

View File

@ -12,15 +12,15 @@ use std::fmt;
use std::iter;
impl<'tcx> InferCtxt<'tcx> {
pub fn report_extra_impl_obligation(
&self,
pub fn report_extra_impl_obligation<'a>(
&'a self,
error_span: Span,
impl_item_def_id: LocalDefId,
trait_item_def_id: DefId,
requirement: &dyn fmt::Display,
) -> Diag<'tcx> {
) -> Diag<'a> {
let mut err = struct_span_code_err!(
self.tcx.dcx(),
self.dcx(),
error_span,
E0276,
"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
/// between this data and `MaybeUninitializedPlaces` yields the set of
/// 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>,
body: &'a Body<'tcx>,
body: &'mir Body<'tcx>,
mdpe: &'a MoveDataParamEnv<'tcx>,
skip_unreachable_unwind: bool,
}
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
pub fn new(
tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>,
mdpe: &'a MoveDataParamEnv<'tcx>,
) -> Self {
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> {
&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
/// between this data and `MaybeInitializedPlaces` yields the set of
/// 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>,
body: &'a Body<'tcx>,
body: &'mir Body<'tcx>,
mdpe: &'a MoveDataParamEnv<'tcx>,
mark_inactive_variants_as_uninit: bool,
skip_unreachable_unwind: BitSet<mir::BasicBlock>,
}
impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
impl<'a, 'mir, 'tcx> MaybeUninitializedPlaces<'a, 'mir, 'tcx> {
pub fn new(
tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>,
mdpe: &'a MoveDataParamEnv<'tcx>,
) -> Self {
MaybeUninitializedPlaces {
tcx,
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> {
&self.mdpe.move_data
}
@ -250,24 +258,24 @@ impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
/// c = S; // {a, b, c, d }
/// }
/// ```
pub struct EverInitializedPlaces<'a, 'tcx> {
body: &'a Body<'tcx>,
pub struct EverInitializedPlaces<'a, 'mir, 'tcx> {
body: &'mir Body<'tcx>,
mdpe: &'a MoveDataParamEnv<'tcx>,
}
impl<'a, 'tcx> EverInitializedPlaces<'a, 'tcx> {
pub fn new(body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
impl<'a, 'mir, 'tcx> EverInitializedPlaces<'a, 'mir, 'tcx> {
pub fn new(body: &'mir Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
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> {
&self.mdpe.move_data
}
}
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
fn update_bits(
trans: &mut impl GenKill<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(
trans: &mut impl GenKill<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.
/// We use a chunked bitset to avoid paying too high a memory footprint.
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;
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.
/// We use a chunked bitset to avoid paying too high a memory footprint.
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;
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.
/// We use a chunked bitset to avoid paying too high a memory footprint.
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;
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)]
fn compute_dead_unwinds<'mir, '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> {
// We only need to do this pass once, because unwind edges can only
// reach cleanup blocks, which can't have unwind edges themselves.
@ -118,12 +118,12 @@ fn compute_dead_unwinds<'mir, 'tcx>(
dead_unwinds
}
struct InitializationData<'mir, 'tcx> {
inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>,
struct InitializationData<'a, 'mir, 'tcx> {
inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'a, 'mir, 'tcx>>,
uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
}
impl InitializationData<'_, '_> {
impl InitializationData<'_, '_, '_> {
fn seek_before(&mut self, loc: Location) {
self.inits.seek_before_primary_effect(loc);
self.uninits.seek_before_primary_effect(loc);
@ -134,17 +134,17 @@ impl InitializationData<'_, '_> {
}
}
struct Elaborator<'a, 'b, 'tcx> {
ctxt: &'a mut ElaborateDropsCtxt<'b, 'tcx>,
struct Elaborator<'a, 'b, 'mir, '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 {
Ok(())
}
}
impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> {
impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, '_, 'tcx> {
type Path = MovePathIndex;
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>,
body: &'a Body<'tcx>,
body: &'mir Body<'tcx>,
env: &'a MoveDataParamEnv<'tcx>,
init_data: InitializationData<'a, 'tcx>,
init_data: InitializationData<'a, 'mir, 'tcx>,
drop_flags: IndexVec<MovePathIndex, Option<Local>>,
patch: MirPatch<'tcx>,
}
impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
impl<'b, 'mir, 'tcx> ElaborateDropsCtxt<'b, 'mir, 'tcx> {
fn move_data(&self) -> &'b MoveData<'tcx> {
&self.env.move_data
}

View File

@ -88,7 +88,7 @@ impl<'tcx> InferCtxt<'tcx> {
found_args: Vec<ArgKind>,
is_closure: bool,
closure_arg_span: Option<Span>,
) -> Diag<'tcx> {
) -> Diag<'_> {
let kind = if is_closure { "closure" } else { "function" };
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>)]
impl<'tcx> TypeErrCtxt<'_, 'tcx> {
#[extension(pub trait TypeErrCtxtExt<'a, 'tcx>)]
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
fn suggest_restricting_param_bound(
&self,
err: &mut Diag<'_>,
@ -1845,7 +1845,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn point_at_returns_when_relevant(
&self,
err: &mut Diag<'tcx>,
err: &mut Diag<'_>,
obligation: &PredicateObligation<'tcx>,
) {
match obligation.cause.code().peel_derives() {
@ -1884,7 +1884,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
cause: &ObligationCauseCode<'tcx>,
found_node: Option<Node<'_>>,
param_env: ty::ParamEnv<'tcx>,
) -> Diag<'tcx> {
) -> Diag<'a> {
pub(crate) fn build_fn_sig_ty<'tcx>(
infcx: &InferCtxt<'tcx>,
trait_ref: ty::TraitRef<'tcx>,
@ -2104,7 +2104,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn note_conflicting_closure_bounds(
&self,
cause: &ObligationCauseCode<'tcx>,
err: &mut Diag<'tcx>,
err: &mut Diag<'_>,
) {
// First, look for an `WhereClauseInExpr`, which means we can get
// 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>)]
impl<'tcx> TypeErrCtxt<'_, 'tcx> {
#[extension(pub trait TypeErrCtxtExt<'a, 'tcx>)]
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
fn report_fulfillment_errors(
&self,
mut errors: Vec<FulfillmentError<'tcx>>,
@ -228,7 +228,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
cause: OverflowCause<'tcx>,
span: Span,
suggest_increasing_limit: bool,
) -> Diag<'tcx> {
) -> Diag<'a> {
fn with_short_path<'tcx, T>(tcx: TyCtxt<'tcx>, value: T) -> String
where
T: fmt::Display + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
@ -1101,7 +1101,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&& let ty::FnPtr(sig) = by_ref_captures.kind()
&& !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),
kind: expected_kind.as_str(),
});
@ -1351,7 +1351,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self,
ty: Ty<'tcx>,
obligation: &PredicateObligation<'tcx>,
) -> Diag<'tcx> {
) -> Diag<'a> {
let span = obligation.cause.span;
let mut diag = match ty.kind() {
@ -1445,8 +1445,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
}
#[extension(pub(super) trait InferCtxtPrivExt<'tcx>)]
impl<'tcx> TypeErrCtxt<'_, 'tcx> {
#[extension(pub(super) trait InferCtxtPrivExt<'a, 'tcx>)]
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
fn can_match_trait(
&self,
goal: ty::TraitPredicate<'tcx>,
@ -2884,7 +2884,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
self.suggest_unsized_bound_if_applicable(err, obligation);
if let Some(span) = err.span.primary_span()
&& 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 s2) = diag.suggestions
{
@ -3379,7 +3379,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
found_kind: ty::ClosureKind,
kind: ty::ClosureKind,
trait_prefix: &'static str,
) -> Diag<'tcx> {
) -> Diag<'a> {
let closure_span = self.tcx.def_span(closure_def_id);
let mut err = ClosureKindMismatch {
@ -3422,7 +3422,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
found_trait_ref: ty::TraitRef<'tcx>,
expected_trait_ref: ty::TraitRef<'tcx>,
terr: TypeError<'tcx>,
) -> Diag<'tcx> {
) -> Diag<'a> {
let self_ty = found_trait_ref.self_ty();
let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() {
(
@ -3473,7 +3473,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
span: Span,
found_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 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));
self.report_arg_count_mismatch(
self.infcx.report_arg_count_mismatch(
span,
closure_span,
expected,
@ -3569,7 +3569,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self,
obligation: &PredicateObligation<'tcx>,
span: Span,
) -> Result<Diag<'tcx>, ErrorGuaranteed> {
) -> Result<Diag<'a>, ErrorGuaranteed> {
if !self.tcx.features().generic_const_exprs {
let guar = self
.dcx()

View File

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

View File

@ -1,5 +1,5 @@
error: invalid `sym` operand
--> $DIR/type-check-2.rs:35:24
--> $DIR/type-check-2.rs:38:24
|
LL | asm!("{}", sym x);
| ^ is a local variable
@ -7,7 +7,7 @@ LL | asm!("{}", sym x);
= help: `sym` operands must refer to either a function or a static
error: invalid `sym` operand
--> $DIR/type-check-2.rs:86:19
--> $DIR/type-check-2.rs:89:19
|
LL | global_asm!("{}", sym C);
| ^^^^^ is an `i32`
@ -15,7 +15,7 @@ LL | global_asm!("{}", sym C);
= help: `sym` operands must refer to either a function or a static
error: invalid `sym` operand
--> $DIR/type-check-2.rs:33:20
--> $DIR/type-check-2.rs:36:20
|
LL | asm!("{}", sym C);
| ^^^^^ is an `i32`
@ -23,15 +23,15 @@ LL | asm!("{}", sym C);
= help: `sym` operands must refer to either a function or a static
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));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= 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
--> $DIR/type-check-2.rs:52:28
error: cannot use value of type `{closure@$DIR/type-check-2.rs:55:28: 55:36}` for inline assembly
--> $DIR/type-check-2.rs:55:28
|
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
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]);
| ^^^^^^^
@ -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)
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));
| ^^^^^^^^^
@ -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
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]);
| ^^^^^^^^^
@ -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
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);
| ^
@ -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
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);
| ^
|
= 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() {
let x: isize = Foo::<A = usize>::bar();
//~^ 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();
| ^^^^^^^^^ 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>();
//~^ ERROR: expected associated type, found associated constant `Trait::ASSOC`
//~| ERROR: unresolved item provided when a constant was expected
//~| ERROR type annotations needed
}
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 }>();
| + +
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.
For more information about an error, try `rustc --explain E0575`.
error: aborting due to 3 previous errors
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
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>(&())];
| ^^ 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
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>(&())];
| ^^ 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
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>(&())];
| ^^ 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
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>(&())];
| ^^ 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
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>()];
| ^ 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
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>(&())];
| ^^ 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
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>(&())];
| ^^ 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
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>(&())];
| ^^ 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
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>(&())];
| ^^ 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
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>() }>;
| ^ 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
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>() }>;
| ^ 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
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>(&()) }>;
| ^^ 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
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>(&()) }>;
| ^^ 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
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>(&()) }>;
| ^^ 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
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>(&()) }>;
| ^^ 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
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>() }>;
| ^ 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
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>() }>;
| ^ 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
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>(&()) }>;
| ^^ 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
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>(&()) }>;
| ^^ 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
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>(&()) }>;
| ^^ 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
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>(&()) }>;
| ^^ 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 }>()];
| + +
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
--> $DIR/const-arg-in-const-arg.rs:18:23
--> $DIR/const-arg-in-const-arg.rs:19:23
|
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
--> $DIR/const-arg-in-const-arg.rs:21:23
--> $DIR/const-arg-in-const-arg.rs:22:23
|
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
--> $DIR/const-arg-in-const-arg.rs:35:24
--> $DIR/const-arg-in-const-arg.rs:37:24
|
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 }>() }>;
| + +
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
--> $DIR/const-arg-in-const-arg.rs:37:24
--> $DIR/const-arg-in-const-arg.rs:40:24
|
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
--> $DIR/const-arg-in-const-arg.rs:40:24
--> $DIR/const-arg-in-const-arg.rs:43:24
|
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
--> $DIR/const-arg-in-const-arg.rs:25:17
--> $DIR/const-arg-in-const-arg.rs:26:17
|
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
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>()];
| ^
@ -294,8 +318,20 @@ help: if this generic argument was intended as a const parameter, surround it wi
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
--> $DIR/const-arg-in-const-arg.rs:28:23
--> $DIR/const-arg-in-const-arg.rs:30:23
|
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
--> $DIR/const-arg-in-const-arg.rs:31:23
--> $DIR/const-arg-in-const-arg.rs:33:23
|
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
--> $DIR/const-arg-in-const-arg.rs:44:27
--> $DIR/const-arg-in-const-arg.rs:47:27
|
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 }>() }>;
| + +
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
--> $DIR/const-arg-in-const-arg.rs:46:27
--> $DIR/const-arg-in-const-arg.rs:50:27
|
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
--> $DIR/const-arg-in-const-arg.rs:49:27
--> $DIR/const-arg-in-const-arg.rs:53:27
|
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 }
| ^^
error: aborting due to 36 previous errors
error: aborting due to 40 previous errors
Some errors have detailed explanations: E0747, E0794.
For more information about an error, try `rustc --explain E0747`.
Some errors have detailed explanations: E0284, E0747, E0794.
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; bar::<N>()]; //[min]~ ERROR generic parameters may not
//[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
//[min]~^ ERROR cannot specify lifetime arguments
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; bar::<N>()]; //[min]~ ERROR generic parameters may not
//[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
//[min]~^ ERROR cannot specify lifetime arguments
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<{ bar::<N>() }>; //[min]~ ERROR generic parameters may not
//[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
//[min]~^ ERROR cannot specify lifetime arguments
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::<{ bar::<N>() }>; //[min]~ ERROR generic parameters may not
//[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
//[min]~^ ERROR cannot specify lifetime arguments
let _ = Foo::<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not

View File

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

View File

@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/opaque_type.rs:10:17
--> $DIR/opaque_type.rs:11:17
|
LL | type Foo = impl Sized;
| ---------- the found opaque type
@ -11,12 +11,20 @@ LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
found opaque type `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];
| ^^^^^^^^^^^^^^ 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.
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)]
|
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.
For more information about an error, try `rustc --explain E0747`.
error[E0284]: type annotations needed
--> $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() {
foo::<_, { [1] }>();
//[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 type provided when a constant was expected
//~| ERROR type annotations needed
}
fn c() {
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
--> $DIR/const-expression-suggest-missing-braces.rs:17:11
--> $DIR/const-expression-suggest-missing-braces.rs:18:11
|
LL | foo::<3 + 3>();
| ^^^^^
@ -21,7 +21,7 @@ LL | foo::<{ 3 + 3 }>();
| + +
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>();
| ^ expected one of `,` or `>`
@ -32,7 +32,7 @@ LL | foo::<{ BAR - 3 }>();
| + +
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>();
| ^ 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
--> $DIR/const-expression-suggest-missing-braces.rs:26:11
--> $DIR/const-expression-suggest-missing-braces.rs:27:11
|
LL | foo::<100 - BAR>();
| ^^^^^^^^^
@ -54,7 +54,7 @@ LL | foo::<{ 100 - BAR }>();
| + +
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>()>();
| ^ expected one of `,` or `>`
@ -65,7 +65,7 @@ LL | foo::<{ bar<i32>() }>();
| + +
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>()>();
| ^ expected one of `,` or `>`
@ -76,7 +76,7 @@ LL | foo::<{ bar::<i32>() }>();
| + +
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>();
| ^ expected one of `,` or `>`
@ -87,7 +87,7 @@ LL | foo::<{ bar::<i32>() + BAR }>();
| + +
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>();
| ^ expected one of `,` or `>`
@ -98,7 +98,7 @@ LL | foo::<{ bar::<i32>() - BAR }>();
| + +
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>()>();
| ^ expected one of `,` or `>`
@ -109,7 +109,7 @@ LL | foo::<{ BAR - bar::<i32>() }>();
| + +
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>()>();
| ^ expected one of `,` or `>`
@ -137,7 +137,19 @@ error[E0747]: type provided when a constant was expected
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.
For more information about an error, try `rustc --explain E0404`.
error: aborting due to 15 previous errors
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
Example::<gimme_a_const!(marker)>
//~^ ERROR: type provided when a constant was expected
//~| ERROR type annotations needed
}
fn from_marker(_: impl Marker<{
@ -35,9 +36,11 @@ fn main() {
}>;
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!()>;
//~^ ERROR unexpected end of macro invocation
//~| ERROR: type provided when a constant was expected
//~| ERROR type annotations needed
}

View File

@ -1,5 +1,5 @@
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)> {
| ----------------------
@ -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)
error: expected type, found `{`
--> $DIR/macro-fail.rs:30:27
--> $DIR/macro-fail.rs:31:27
|
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)
error: unexpected end of macro invocation
--> $DIR/macro-fail.rs:40:25
--> $DIR/macro-fail.rs:42:25
|
LL | macro_rules! gimme_a_const {
| -------------------------- when calling this macro
@ -50,7 +50,7 @@ LL | let _fail = Example::<gimme_a_const!()>;
| ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
|
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 }}
| ^^^^^^^^^^^^^
@ -75,18 +75,63 @@ error[E0747]: type provided when a constant was expected
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
--> $DIR/macro-fail.rs:37:25
--> $DIR/macro-fail.rs:38:25
|
LL | let _fail = Example::<external_macro!()>;
| ^^^^^^^^^^^^^^^^^
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!()>;
| ^^^^^^^^^^^^^^^^
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

@ -3,8 +3,10 @@
fn example<const N: usize>() {}
fn other() {
example::<[usize; 3]>();
//~^ ERROR type provided when a const
example::<[usize; 4+5]>();
//~^ ERROR type provided when a const
example::<[usize; 3]>();
//~^ ERROR type provided when a const
//~| ERROR type annotations needed
example::<[usize; 4 + 5]>();
//~^ 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
--> $DIR/suggest_const_for_array.rs:6:13
--> $DIR/suggest_const_for_array.rs:6:15
|
LL | example::<[usize; 3]>();
| ^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 3 }`
LL | example::<[usize; 3]>();
| ^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 3 }`
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]>();
| ^^^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 4+5 }`
LL | example::<[usize; 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() {
foo::<main>()
//~^ 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: 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;
fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
//~^ ERROR cannot resolve opaque type
|x| x
//~^ ERROR expected generic lifetime parameter, found `'_`
}

View File

@ -1,11 +1,19 @@
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 + '_) {
| -- this generic parameter must be used with a generic lifetime parameter
LL |
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;
fn foo() -> impl Sized {
//~^ ERROR cycle detected when computing type of
//~| WARN function cannot return without recursing
unsafe {
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
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`.

View File

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

View File

@ -10,7 +10,7 @@ LL | struct Take(Box<Take>);
| ++++ +
error[E0072]: recursive type `Foo` has infinite size
--> $DIR/infinite-struct.rs:10:1
--> $DIR/infinite-struct.rs:11:1
|
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"]`
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);
| ~~~~~~~~~~~
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;
//[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]
}

View File

@ -3,24 +3,26 @@
fn main() {}
unsafe fn _foo() {
static mut X: i32 = 1;
static mut Y: i32 = 1;
unsafe {
static mut X: i32 = 1;
static mut Y: i32 = 1;
let _y = &X;
//~^ ERROR creating a shared reference to a mutable static [E0796]
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 _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 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]
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]
foo(&X);
//~^ ERROR creating a shared reference to a mutable static [E0796]
}
}
fn foo<'a>(_x: &'a i32) {}

View File

@ -1,74 +1,74 @@
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;
| ^^ shared reference to mutable static
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-to-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);
LL | let _y = addr_of!(X);
| ~~~~~~~~~~~
error[E0796]: creating a mutable reference to a mutable static
--> $DIR/reference-to-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-to-mut-static-unsafe-fn.rs:18:21
--> $DIR/reference-to-mut-static-unsafe-fn.rs:13:22
|
LL | let (_b, _c) = (&X, &mut Y);
| ^^ shared reference to mutable static
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 (_b, _c) = (addr_of!(X), &mut Y);
| ~~~~~~~~~~~
LL | let ref _a = addr_of!(X);
| ~~~~~~~~~~~
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:16:26
|
LL | let (_b, _c) = (&X, &mut Y);
| ^^^^^^ mutable reference to mutable static
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 (_b, _c) = (&X, addr_of_mut!(Y));
| ~~~~~~~~~~~~~~~
LL | let ref mut _a = addr_of_mut!(X);
| ~~~~~~~~~~~~~~~
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:19:25
|
LL | foo(&X);
| ^^ shared reference to mutable static
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 | foo(addr_of!(X));
| ~~~~~~~~~~~
LL | let (_b, _c) = (addr_of!(X), &mut Y);
| ~~~~~~~~~~~
error[E0796]: creating a mutable reference to a mutable static
--> $DIR/reference-to-mut-static-unsafe-fn.rs:19:29
|
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-to-mut-static-unsafe-fn.rs:23: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

View File

@ -44,18 +44,6 @@ LL |
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
--> $DIR/hkl_forbidden4.rs:13:1
|
@ -68,6 +56,18 @@ note: previous use here
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
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| ()) };
//~^ 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> {
|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
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
--> $DIR/issue-53092-2.rs:10:5
--> $DIR/issue-53092-2.rs:12:5
|
LL | |x| x.into()
| ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
|
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> {
| ^^^^^^^ 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;
| +++++++++++++++++++++++
error: aborting due to 3 previous errors
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0277, E0391, E0792.
For more information about an error, try `rustc --explain E0277`.