diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 31a184fe921e..3a4c95b250c3 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -92,9 +92,6 @@ ast_passes_fn_body_extern = incorrect function inside `extern` block ast_passes_fn_param_c_var_args_not_last = `...` must be the last argument of a C-variadic function -ast_passes_fn_param_c_var_args_only = - C-variadic function must be declared with at least one named argument - ast_passes_fn_param_doc_comment = documentation comments cannot be applied to function parameters .label = doc comments are not allowed here diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index c57be3cdf353..598a3ec2d3c3 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -364,7 +364,7 @@ impl<'a> AstValidator<'a> { fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) { self.check_decl_num_args(fn_decl); - self.check_decl_cvaradic_pos(fn_decl); + self.check_decl_cvariadic_pos(fn_decl); self.check_decl_attrs(fn_decl); self.check_decl_self_param(fn_decl, self_semantic); } @@ -379,13 +379,11 @@ impl<'a> AstValidator<'a> { } } - fn check_decl_cvaradic_pos(&self, fn_decl: &FnDecl) { + /// Emits an error if a function declaration has a variadic parameter in the + /// beginning or middle of parameter list. + /// Example: `fn foo(..., x: i32)` will emit an error. + fn check_decl_cvariadic_pos(&self, fn_decl: &FnDecl) { match &*fn_decl.inputs { - [Param { ty, span, .. }] => { - if let TyKind::CVarArgs = ty.kind { - self.dcx().emit_err(errors::FnParamCVarArgsOnly { span: *span }); - } - } [ps @ .., _] => { for Param { ty, span, .. } in ps { if let TyKind::CVarArgs = ty.kind { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index a95a7bdaf6da..c07fbe5b0166 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -92,13 +92,6 @@ pub struct FnParamTooMany { pub max_num_args: usize, } -#[derive(Diagnostic)] -#[diag(ast_passes_fn_param_c_var_args_only)] -pub struct FnParamCVarArgsOnly { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(ast_passes_fn_param_c_var_args_not_last)] pub struct FnParamCVarArgsNotLast { diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 9b8b7e8ddda6..5e10f14f31b5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -1,4 +1,5 @@ use rustc_errors::Diag; +use rustc_hir::def_id::LocalDefId; use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError; use rustc_infer::infer::region_constraints::Constraint; @@ -241,7 +242,7 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { 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, placeholder_region, error_region) + try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) } } @@ -287,7 +288,7 @@ where let (param_env, value) = key.into_parts(); let _ = ocx.normalize(&cause, param_env, value.value); - try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region) + try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) } } @@ -318,7 +319,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { 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, placeholder_region, error_region) + try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) } } @@ -342,6 +343,7 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { ) -> Option> { try_extract_error_from_region_constraints( mbcx.infcx, + mbcx.mir_def_id(), placeholder_region, error_region, self.region_constraints.as_ref().unwrap(), @@ -358,6 +360,7 @@ 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>, + generic_param_scope: LocalDefId, placeholder_region: ty::Region<'tcx>, error_region: Option>, ) -> Option> { @@ -368,6 +371,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>( let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone()); try_extract_error_from_region_constraints( ocx.infcx, + generic_param_scope, placeholder_region, error_region, ®ion_constraints, @@ -379,6 +383,7 @@ 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>, + generic_param_scope: LocalDefId, placeholder_region: ty::Region<'tcx>, error_region: Option>, region_constraints: &RegionConstraintData<'tcx>, @@ -452,15 +457,18 @@ fn try_extract_error_from_region_constraints<'tcx>( RegionResolutionError::ConcreteFailure(cause.clone(), sub_region, placeholder_region) } }; - NiceRegionError::new(&infcx.err_ctxt(), error).try_report_from_nll().or_else(|| { - if let SubregionOrigin::Subtype(trace) = cause { - Some( - infcx - .err_ctxt() - .report_and_explain_type_error(*trace, TypeError::RegionsPlaceholderMismatch), - ) - } else { - None - } - }) + NiceRegionError::new(&infcx.err_ctxt(), generic_param_scope, error) + .try_report_from_nll() + .or_else(|| { + if let SubregionOrigin::Subtype(trace) = cause { + Some( + infcx.err_ctxt().report_and_explain_type_error( + *trace, + TypeError::RegionsPlaceholderMismatch, + ), + ) + } else { + None + } + }) } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 8112fb7b89c6..e11e4a7247c2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -361,6 +361,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region); let diag = unexpected_hidden_region_diagnostic( self.infcx.tcx, + self.mir_def_id(), span, named_ty, named_region, @@ -453,7 +454,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // Check if we can use one of the "nice region errors". if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { let infer_err = self.infcx.err_ctxt(); - let nice = NiceRegionError::new_from_span(&infer_err, cause.span, o, f); + let nice = + NiceRegionError::new_from_span(&infer_err, self.mir_def_id(), cause.span, o, f); if let Some(diag) = nice.try_report_from_nll() { self.buffer_error(diag); return; @@ -843,14 +845,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if *outlived_f != ty::ReStatic { return; } - let suitable_region = self.infcx.tcx.is_suitable_region(f); + let suitable_region = self.infcx.tcx.is_suitable_region(self.mir_def_id(), f); let Some(suitable_region) = suitable_region else { return; }; let fn_returns = self.infcx.tcx.return_type_impl_or_dyn_traits(suitable_region.def_id); - let param = if let Some(param) = find_param_with_region(self.infcx.tcx, f, outlived_f) { + let param = if let Some(param) = + find_param_with_region(self.infcx.tcx, self.mir_def_id(), f, outlived_f) + { param } else { return; @@ -959,7 +963,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { return; }; - let param = match find_param_with_region(tcx, f, o) { + let param = match find_param_with_region(tcx, self.mir_def_id(), f, o) { Some(param) => param, None => return, }; @@ -1022,25 +1026,30 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { return; }; - let Some((ty_sub, _)) = self - .infcx - .tcx - .is_suitable_region(sub) - .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sub, &anon_reg.bound_region)) + let Some((ty_sub, _)) = + self.infcx.tcx.is_suitable_region(self.mir_def_id(), sub).and_then(|anon_reg| { + find_anon_type(self.infcx.tcx, self.mir_def_id(), sub, &anon_reg.bound_region) + }) else { return; }; - let Some((ty_sup, _)) = self - .infcx - .tcx - .is_suitable_region(sup) - .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sup, &anon_reg.bound_region)) + let Some((ty_sup, _)) = + self.infcx.tcx.is_suitable_region(self.mir_def_id(), sup).and_then(|anon_reg| { + find_anon_type(self.infcx.tcx, self.mir_def_id(), sup, &anon_reg.bound_region) + }) else { return; }; - suggest_adding_lifetime_params(self.infcx.tcx, sub, ty_sup, ty_sub, diag); + suggest_adding_lifetime_params( + self.infcx.tcx, + diag, + self.mir_def_id(), + sub, + ty_sup, + ty_sub, + ); } #[allow(rustc::diagnostic_outside_of_impl)] diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 46011c1f43ec..c2db64e77025 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -289,7 +289,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { debug!("give_region_a_name: error_region = {:?}", error_region); match *error_region { ty::ReEarlyParam(ebr) => ebr.has_name().then(|| { - let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP); + let def_id = tcx.generics_of(self.mir_def_id()).region_param(ebr, tcx).def_id; + let span = tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP); RegionName { name: ebr.name, source: RegionNameSource::NamedEarlyParamRegion(span) } }), @@ -912,7 +913,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { }; let tcx = self.infcx.tcx; - let region_parent = tcx.parent(region.def_id); + let region_def = tcx.generics_of(self.mir_def_id()).region_param(region, tcx).def_id; + let region_parent = tcx.parent(region_def); let DefKind::Impl { .. } = tcx.def_kind(region_parent) else { return None; }; @@ -925,7 +927,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { Some(RegionName { name: self.synthesize_region_name(), source: RegionNameSource::AnonRegionFromImplSignature( - tcx.def_span(region.def_id), + tcx.def_span(region_def), // FIXME(compiler-errors): Does this ever actually show up // anywhere other than the self type? I couldn't create an // example of a `'_` in the impl's trait being referenceable. diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 9bf055b17394..5d7257b15c42 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -327,6 +327,18 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } else { codegen_fn_attrs.linkage = linkage; } + if tcx.is_mutable_static(did.into()) { + let mut diag = tcx.dcx().struct_span_err( + attr.span, + "mutable statics are not allowed with `#[linkage]`", + ); + diag.note( + "making the static mutable would allow changing which symbol the \ + static references rather than make the target of the symbol \ + mutable", + ); + diag.emit(); + } } } sym::link_section => { @@ -564,8 +576,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, - "`no_sanitize` will have no effect after inlining", |lint| { + lint.primary_message("`no_sanitize` will have no effect after inlining"); lint.span_note(inline_span, "inlining requested here"); }, ) diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 8406e0f48762..90b622cae656 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -309,7 +309,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { } if let ConstContext::Static(_) = ccx.const_kind() { - err.note("consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell"); + err.note("consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`"); } err diff --git a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs index 530a05a1ed88..62979af8a601 100644 --- a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs @@ -44,8 +44,8 @@ impl HasStaticRootDefId for DummyMachine { } } -impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine { - interpret::compile_time_machine!(<'mir, 'tcx>); +impl<'tcx> interpret::Machine<'tcx> for DummyMachine { + interpret::compile_time_machine!(<'tcx>); type MemoryKind = !; const PANIC_ON_ALLOC_FAIL: bool = true; @@ -53,11 +53,11 @@ impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine { const ALL_CONSTS_ARE_PRECHECKED: bool = false; #[inline(always)] - fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { + fn enforce_alignment(_ecx: &InterpCx<'tcx, Self>) -> bool { false // no reason to enforce alignment } - fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>, _layout: TyAndLayout<'tcx>) -> bool { + fn enforce_validity(_ecx: &InterpCx<'tcx, Self>, _layout: TyAndLayout<'tcx>) -> bool { false } @@ -83,26 +83,26 @@ impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine { } fn find_mir_or_eval_fn( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'tcx, Self>, _instance: ty::Instance<'tcx>, _abi: rustc_target::spec::abi::Abi, _args: &[interpret::FnArg<'tcx, Self::Provenance>], _destination: &interpret::MPlaceTy<'tcx, Self::Provenance>, _target: Option, _unwind: UnwindAction, - ) -> interpret::InterpResult<'tcx, Option<(&'mir Body<'tcx>, ty::Instance<'tcx>)>> { + ) -> interpret::InterpResult<'tcx, Option<(&'tcx Body<'tcx>, ty::Instance<'tcx>)>> { unimplemented!() } fn panic_nounwind( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'tcx, Self>, _msg: &str, ) -> interpret::InterpResult<'tcx> { unimplemented!() } fn call_intrinsic( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'tcx, Self>, _instance: ty::Instance<'tcx>, _args: &[interpret::OpTy<'tcx, Self::Provenance>], _destination: &interpret::MPlaceTy<'tcx, Self::Provenance>, @@ -113,7 +113,7 @@ impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine { } fn assert_panic( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'tcx, Self>, _msg: &rustc_middle::mir::AssertMessage<'tcx>, _unwind: UnwindAction, ) -> interpret::InterpResult<'tcx> { @@ -121,7 +121,7 @@ impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine { } fn binary_ptr_op( - ecx: &InterpCx<'mir, 'tcx, Self>, + ecx: &InterpCx<'tcx, Self>, bin_op: BinOp, left: &interpret::ImmTy<'tcx, Self::Provenance>, right: &interpret::ImmTy<'tcx, Self::Provenance>, @@ -168,32 +168,30 @@ impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine { } fn expose_ptr( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'tcx, Self>, _ptr: interpret::Pointer, ) -> interpret::InterpResult<'tcx> { unimplemented!() } fn init_frame_extra( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, - _frame: interpret::Frame<'mir, 'tcx, Self::Provenance>, - ) -> interpret::InterpResult< - 'tcx, - interpret::Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>, - > { + _ecx: &mut InterpCx<'tcx, Self>, + _frame: interpret::Frame<'tcx, Self::Provenance>, + ) -> interpret::InterpResult<'tcx, interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>> + { unimplemented!() } fn stack<'a>( - _ecx: &'a InterpCx<'mir, 'tcx, Self>, - ) -> &'a [interpret::Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>] { + _ecx: &'a InterpCx<'tcx, Self>, + ) -> &'a [interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>] { // Return an empty stack instead of panicking, as `cur_span` uses it to evaluate constants. &[] } fn stack_mut<'a>( - _ecx: &'a mut InterpCx<'mir, 'tcx, Self>, - ) -> &'a mut Vec> { + _ecx: &'a mut InterpCx<'tcx, Self>, + ) -> &'a mut Vec> { unimplemented!() } } diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 650669ac690b..923b9ddf9afb 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -58,13 +58,10 @@ impl<'tcx> Into> for ConstEvalErrKind { } } -pub fn get_span_and_frames<'tcx, 'mir>( +pub fn get_span_and_frames<'tcx>( tcx: TyCtxtAt<'tcx>, - stack: &[Frame<'mir, 'tcx, impl Provenance, impl Sized>], -) -> (Span, Vec) -where - 'tcx: 'mir, -{ + stack: &[Frame<'tcx, impl Provenance, impl Sized>], +) -> (Span, Vec) { let mut stacktrace = Frame::generate_stacktrace_from_stack(stack); // Filter out `requires_caller_location` frames. stacktrace.retain(|frame| !frame.instance.def.requires_caller_location(*tcx)); @@ -161,9 +158,9 @@ where /// Emit a lint from a const-eval situation. // Even if this is unused, please don't remove it -- chances are we will need to emit a lint during const-eval again in the future! -pub(super) fn lint<'tcx, 'mir, L>( +pub(super) fn lint<'tcx, L>( tcx: TyCtxtAt<'tcx>, - machine: &CompileTimeInterpreter<'mir, 'tcx>, + machine: &CompileTimeInterpreter<'tcx>, lint: &'static rustc_session::lint::Lint, decorator: impl FnOnce(Vec) -> L, ) where diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 966951e7d9a4..36f468d3308a 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -31,10 +31,10 @@ use crate::CTRL_C_RECEIVED; // Returns a pointer to where the result lives #[instrument(level = "trace", skip(ecx, body))] -fn eval_body_using_ecx<'mir, 'tcx, R: InterpretationResult<'tcx>>( - ecx: &mut CompileTimeEvalContext<'mir, 'tcx>, +fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>( + ecx: &mut CompileTimeEvalContext<'tcx>, cid: GlobalId<'tcx>, - body: &'mir mir::Body<'tcx>, + body: &'tcx mir::Body<'tcx>, ) -> InterpResult<'tcx, R> { trace!(?ecx.param_env); let tcx = *ecx.tcx; @@ -134,12 +134,12 @@ fn eval_body_using_ecx<'mir, 'tcx, R: InterpretationResult<'tcx>>( /// that inform us about the generic bounds of the constant. E.g., using an associated constant /// of a function's generic parameter will require knowledge about the bounds on the generic /// parameter. These bounds are passed to `mk_eval_cx` via the `ParamEnv` argument. -pub(crate) fn mk_eval_cx_to_read_const_val<'mir, 'tcx>( +pub(crate) fn mk_eval_cx_to_read_const_val<'tcx>( tcx: TyCtxt<'tcx>, root_span: Span, param_env: ty::ParamEnv<'tcx>, can_access_mut_global: CanAccessMutGlobal, -) -> CompileTimeEvalContext<'mir, 'tcx> { +) -> CompileTimeEvalContext<'tcx> { debug!("mk_eval_cx: {:?}", param_env); InterpCx::new( tcx, @@ -151,12 +151,12 @@ pub(crate) fn mk_eval_cx_to_read_const_val<'mir, 'tcx>( /// Create an interpreter context to inspect the given `ConstValue`. /// Returns both the context and an `OpTy` that represents the constant. -pub fn mk_eval_cx_for_const_val<'mir, 'tcx>( +pub fn mk_eval_cx_for_const_val<'tcx>( tcx: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>, val: mir::ConstValue<'tcx>, ty: Ty<'tcx>, -) -> Option<(CompileTimeEvalContext<'mir, 'tcx>, OpTy<'tcx>)> { +) -> Option<(CompileTimeEvalContext<'tcx>, OpTy<'tcx>)> { let ecx = mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, param_env, CanAccessMutGlobal::No); let op = ecx.const_val_to_op(val, ty, None).ok()?; Some((ecx, op)) @@ -170,7 +170,7 @@ pub fn mk_eval_cx_for_const_val<'mir, 'tcx>( /// encounter an `Indirect` they cannot handle. #[instrument(skip(ecx), level = "debug")] pub(super) fn op_to_const<'tcx>( - ecx: &CompileTimeEvalContext<'_, 'tcx>, + ecx: &CompileTimeEvalContext<'tcx>, op: &OpTy<'tcx>, for_diagnostics: bool, ) -> ConstValue<'tcx> { @@ -326,16 +326,16 @@ pub trait InterpretationResult<'tcx> { /// This function takes the place where the result of the evaluation is stored /// and prepares it for returning it in the appropriate format needed by the specific /// evaluation query. - fn make_result<'mir>( + fn make_result( mplace: MPlaceTy<'tcx>, - ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, + ecx: &mut InterpCx<'tcx, CompileTimeInterpreter<'tcx>>, ) -> Self; } impl<'tcx> InterpretationResult<'tcx> for ConstAlloc<'tcx> { - fn make_result<'mir>( + fn make_result( mplace: MPlaceTy<'tcx>, - _ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, + _ecx: &mut InterpCx<'tcx, CompileTimeInterpreter<'tcx>>, ) -> Self { ConstAlloc { alloc_id: mplace.ptr().provenance.unwrap().alloc_id(), ty: mplace.layout.ty } } @@ -416,8 +416,8 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>( } #[inline(always)] -fn const_validate_mplace<'mir, 'tcx>( - ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, +fn const_validate_mplace<'tcx>( + ecx: &InterpCx<'tcx, CompileTimeInterpreter<'tcx>>, mplace: &MPlaceTy<'tcx>, cid: GlobalId<'tcx>, ) -> Result<(), ErrorHandled> { @@ -446,8 +446,8 @@ fn const_validate_mplace<'mir, 'tcx>( } #[inline(always)] -fn report_validation_error<'mir, 'tcx>( - ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, +fn report_validation_error<'tcx>( + ecx: &InterpCx<'tcx, CompileTimeInterpreter<'tcx>>, error: InterpErrorInfo<'tcx>, alloc_id: AllocId, ) -> ErrorHandled { diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index b8b4426c2ec6..950e7c12da2e 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -45,7 +45,7 @@ const TINY_LINT_TERMINATOR_LIMIT: usize = 20; const PROGRESS_INDICATOR_START: usize = 4_000_000; /// Extra machine state for CTFE, and the Machine instance -pub struct CompileTimeInterpreter<'mir, 'tcx> { +pub struct CompileTimeInterpreter<'tcx> { /// The number of terminators that have been evaluated. /// /// This is used to produce lints informing the user that the compiler is not stuck. @@ -53,7 +53,7 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> { pub(super) num_evaluated_steps: usize, /// The virtual call stack. - pub(super) stack: Vec>, + pub(super) stack: Vec>, /// Pattern matching on consts with references would be unsound if those references /// could point to anything mutable. Therefore, when evaluating consts and when constructing valtrees, @@ -90,7 +90,7 @@ impl From for CanAccessMutGlobal { } } -impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> { +impl<'tcx> CompileTimeInterpreter<'tcx> { pub(crate) fn new( can_access_mut_global: CanAccessMutGlobal, check_alignment: CheckAlignment, @@ -164,8 +164,7 @@ impl interpret::AllocMap for FxIndexMap { } } -pub(crate) type CompileTimeEvalContext<'mir, 'tcx> = - InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>; +pub(crate) type CompileTimeEvalContext<'tcx> = InterpCx<'tcx, CompileTimeInterpreter<'tcx>>; #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum MemoryKind { @@ -197,7 +196,7 @@ impl interpret::MayLeak for ! { } } -impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> { +impl<'tcx> CompileTimeEvalContext<'tcx> { fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) { let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo()); @@ -371,25 +370,25 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> { } } -impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, 'tcx> { - compile_time_machine!(<'mir, 'tcx>); +impl<'tcx> interpret::Machine<'tcx> for CompileTimeInterpreter<'tcx> { + compile_time_machine!(<'tcx>); type MemoryKind = MemoryKind; const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error #[inline(always)] - fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { + fn enforce_alignment(ecx: &InterpCx<'tcx, Self>) -> bool { matches!(ecx.machine.check_alignment, CheckAlignment::Error) } #[inline(always)] - fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool { + fn enforce_validity(ecx: &InterpCx<'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool { ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks || layout.abi.is_uninhabited() } fn load_mir( - ecx: &InterpCx<'mir, 'tcx, Self>, + ecx: &InterpCx<'tcx, Self>, instance: ty::InstanceDef<'tcx>, ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> { match instance { @@ -410,14 +409,14 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } fn find_mir_or_eval_fn( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, orig_instance: ty::Instance<'tcx>, _abi: CallAbi, args: &[FnArg<'tcx>], dest: &MPlaceTy<'tcx>, ret: Option, _unwind: mir::UnwindAction, // unwinding is not supported in consts - ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> { + ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> { debug!("find_mir_or_eval_fn: {:?}", orig_instance); // Replace some functions. @@ -448,7 +447,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, Ok(Some((ecx.load_mir(instance.def, None)?, orig_instance))) } - fn panic_nounwind(ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx> { + fn panic_nounwind(ecx: &mut InterpCx<'tcx, Self>, msg: &str) -> InterpResult<'tcx> { let msg = Symbol::intern(msg); let span = ecx.find_closest_untracked_caller_location(); let (file, line, col) = ecx.location_triple_for_span(span); @@ -456,7 +455,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } fn call_intrinsic( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx, Self::Provenance>, @@ -555,7 +554,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } fn assert_panic( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, msg: &AssertMessage<'tcx>, _unwind: mir::UnwindAction, ) -> InterpResult<'tcx> { @@ -586,7 +585,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } fn binary_ptr_op( - _ecx: &InterpCx<'mir, 'tcx, Self>, + _ecx: &InterpCx<'tcx, Self>, _bin_op: mir::BinOp, _left: &ImmTy<'tcx>, _right: &ImmTy<'tcx>, @@ -594,7 +593,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, throw_unsup_format!("pointer arithmetic or comparison is not supported at compile-time"); } - fn increment_const_eval_counter(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { + fn increment_const_eval_counter(ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> { // The step limit has already been hit in a previous call to `increment_const_eval_counter`. if let Some(new_steps) = ecx.machine.num_evaluated_steps.checked_add(1) { @@ -650,16 +649,16 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } #[inline(always)] - fn expose_ptr(_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ptr: Pointer) -> InterpResult<'tcx> { + fn expose_ptr(_ecx: &mut InterpCx<'tcx, Self>, _ptr: Pointer) -> InterpResult<'tcx> { // This is only reachable with -Zunleash-the-miri-inside-of-you. throw_unsup_format!("exposing pointers is not possible at compile-time") } #[inline(always)] fn init_frame_extra( - ecx: &mut InterpCx<'mir, 'tcx, Self>, - frame: Frame<'mir, 'tcx>, - ) -> InterpResult<'tcx, Frame<'mir, 'tcx>> { + ecx: &mut InterpCx<'tcx, Self>, + frame: Frame<'tcx>, + ) -> InterpResult<'tcx, Frame<'tcx>> { // Enforce stack size limit. Add 1 because this is run before the new frame is pushed. if !ecx.recursion_limit.value_within_limit(ecx.stack().len() + 1) { throw_exhaust!(StackFrameLimitReached) @@ -670,15 +669,15 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, #[inline(always)] fn stack<'a>( - ecx: &'a InterpCx<'mir, 'tcx, Self>, - ) -> &'a [Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>] { + ecx: &'a InterpCx<'tcx, Self>, + ) -> &'a [Frame<'tcx, Self::Provenance, Self::FrameExtra>] { &ecx.machine.stack } #[inline(always)] fn stack_mut<'a>( - ecx: &'a mut InterpCx<'mir, 'tcx, Self>, - ) -> &'a mut Vec> { + ecx: &'a mut InterpCx<'tcx, Self>, + ) -> &'a mut Vec> { &mut ecx.machine.stack } @@ -715,7 +714,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } fn retag_ptr_value( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, _kind: mir::RetagKind, val: &ImmTy<'tcx, CtfeProvenance>, ) -> InterpResult<'tcx, ImmTy<'tcx, CtfeProvenance>> { @@ -756,10 +755,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, Ok(()) } - fn before_alloc_read( - ecx: &InterpCx<'mir, 'tcx, Self>, - alloc_id: AllocId, - ) -> InterpResult<'tcx> { + fn before_alloc_read(ecx: &InterpCx<'tcx, Self>, alloc_id: AllocId) -> InterpResult<'tcx> { // Check if this is the currently evaluated static. if Some(alloc_id) == ecx.machine.static_root_ids.map(|(id, _)| id) { return Err(ConstEvalErrKind::RecursiveStatic.into()); diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index b906bfa775f8..5312f1f946f5 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -21,7 +21,7 @@ use crate::interpret::{ #[instrument(skip(ecx), level = "debug")] fn branches<'tcx>( - ecx: &CompileTimeEvalContext<'tcx, 'tcx>, + ecx: &CompileTimeEvalContext<'tcx>, place: &MPlaceTy<'tcx>, n: usize, variant: Option, @@ -59,7 +59,7 @@ fn branches<'tcx>( #[instrument(skip(ecx), level = "debug")] fn slice_branches<'tcx>( - ecx: &CompileTimeEvalContext<'tcx, 'tcx>, + ecx: &CompileTimeEvalContext<'tcx>, place: &MPlaceTy<'tcx>, num_nodes: &mut usize, ) -> ValTreeCreationResult<'tcx> { @@ -77,7 +77,7 @@ fn slice_branches<'tcx>( #[instrument(skip(ecx), level = "debug")] fn const_to_valtree_inner<'tcx>( - ecx: &CompileTimeEvalContext<'tcx, 'tcx>, + ecx: &CompileTimeEvalContext<'tcx>, place: &MPlaceTy<'tcx>, num_nodes: &mut usize, ) -> ValTreeCreationResult<'tcx> { @@ -219,7 +219,7 @@ fn reconstruct_place_meta<'tcx>( #[instrument(skip(ecx), level = "debug", ret)] fn create_valtree_place<'tcx>( - ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>, + ecx: &mut CompileTimeEvalContext<'tcx>, layout: TyAndLayout<'tcx>, valtree: ty::ValTree<'tcx>, ) -> MPlaceTy<'tcx> { @@ -364,7 +364,7 @@ pub fn valtree_to_const_value<'tcx>( /// Put a valtree into memory and return a reference to that. fn valtree_to_ref<'tcx>( - ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>, + ecx: &mut CompileTimeEvalContext<'tcx>, valtree: ty::ValTree<'tcx>, pointee_ty: Ty<'tcx>, ) -> Immediate { @@ -380,7 +380,7 @@ fn valtree_to_ref<'tcx>( #[instrument(skip(ecx), level = "debug")] fn valtree_into_mplace<'tcx>( - ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>, + ecx: &mut CompileTimeEvalContext<'tcx>, place: &MPlaceTy<'tcx>, valtree: ty::ValTree<'tcx>, ) { @@ -457,6 +457,6 @@ fn valtree_into_mplace<'tcx>( } } -fn dump_place<'tcx>(ecx: &CompileTimeEvalContext<'tcx, 'tcx>, place: &MPlaceTy<'tcx>) { +fn dump_place<'tcx>(ecx: &CompileTimeEvalContext<'tcx>, place: &MPlaceTy<'tcx>) { trace!("{:?}", ecx.dump_place(&PlaceTy::from(place.clone()))); } diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index ecfb25e32cda..737a70f335d0 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -19,7 +19,7 @@ use super::{ use crate::fluent_generated as fluent; -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { pub fn cast( &mut self, src: &OpTy<'tcx, M::Provenance>, @@ -324,13 +324,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { use rustc_type_ir::TyKind::*; fn adjust_nan< - 'mir, - 'tcx: 'mir, - M: Machine<'mir, 'tcx>, + 'tcx, + M: Machine<'tcx>, F1: rustc_apfloat::Float + FloatConvert, F2: rustc_apfloat::Float, >( - ecx: &InterpCx<'mir, 'tcx, M>, + ecx: &InterpCx<'tcx, M>, f1: F1, f2: F2, ) -> F2 { diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index 0790f06e6e1d..224d17dbf52b 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -12,7 +12,7 @@ use super::{ err_ub, throw_ub, ImmTy, InterpCx, InterpResult, Machine, Readable, Scalar, Writeable, }; -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Writes the discriminant of the given variant. /// /// If the variant is uninhabited, this is UB. diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index d82623fa0094..5cd50a928704 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -34,7 +34,7 @@ use crate::errors; use crate::util; use crate::{fluent_generated as fluent, ReportErrorExt}; -pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { +pub struct InterpCx<'tcx, M: Machine<'tcx>> { /// Stores the `Machine` instance. /// /// Note: the stack is provided by the machine. @@ -49,7 +49,7 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { pub(crate) param_env: ty::ParamEnv<'tcx>, /// The virtual memory system. - pub memory: Memory<'mir, 'tcx, M>, + pub memory: Memory<'tcx, M>, /// The recursion limit (cached from `tcx.recursion_limit(())`) pub recursion_limit: Limit, @@ -90,12 +90,12 @@ impl Drop for SpanGuard { } /// A stack frame. -pub struct Frame<'mir, 'tcx, Prov: Provenance = CtfeProvenance, Extra = ()> { +pub struct Frame<'tcx, Prov: Provenance = CtfeProvenance, Extra = ()> { //////////////////////////////////////////////////////////////////////////////// // Function and callsite information //////////////////////////////////////////////////////////////////////////////// /// The MIR for the function called on this frame. - pub body: &'mir mir::Body<'tcx>, + pub body: &'tcx mir::Body<'tcx>, /// The def_id and args of the current function. pub instance: ty::Instance<'tcx>, @@ -232,8 +232,8 @@ impl<'tcx, Prov: Provenance> LocalState<'tcx, Prov> { } } -impl<'mir, 'tcx, Prov: Provenance> Frame<'mir, 'tcx, Prov> { - pub fn with_extra(self, extra: Extra) -> Frame<'mir, 'tcx, Prov, Extra> { +impl<'tcx, Prov: Provenance> Frame<'tcx, Prov> { + pub fn with_extra(self, extra: Extra) -> Frame<'tcx, Prov, Extra> { Frame { body: self.body, instance: self.instance, @@ -247,7 +247,7 @@ impl<'mir, 'tcx, Prov: Provenance> Frame<'mir, 'tcx, Prov> { } } -impl<'mir, 'tcx, Prov: Provenance, Extra> Frame<'mir, 'tcx, Prov, Extra> { +impl<'tcx, Prov: Provenance, Extra> Frame<'tcx, Prov, Extra> { /// Get the current location within the Frame. /// /// If this is `Left`, we are not currently executing any particular statement in @@ -345,16 +345,16 @@ impl<'tcx> FrameInfo<'tcx> { } } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> HasDataLayout for InterpCx<'tcx, M> { #[inline] fn data_layout(&self) -> &TargetDataLayout { &self.tcx.data_layout } } -impl<'mir, 'tcx, M> layout::HasTyCtxt<'tcx> for InterpCx<'mir, 'tcx, M> +impl<'tcx, M> layout::HasTyCtxt<'tcx> for InterpCx<'tcx, M> where - M: Machine<'mir, 'tcx>, + M: Machine<'tcx>, { #[inline] fn tcx(&self) -> TyCtxt<'tcx> { @@ -362,16 +362,16 @@ where } } -impl<'mir, 'tcx, M> layout::HasParamEnv<'tcx> for InterpCx<'mir, 'tcx, M> +impl<'tcx, M> layout::HasParamEnv<'tcx> for InterpCx<'tcx, M> where - M: Machine<'mir, 'tcx>, + M: Machine<'tcx>, { fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } } -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'tcx, M> { type LayoutOfResult = InterpResult<'tcx, TyAndLayout<'tcx>>; #[inline] @@ -391,7 +391,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> LayoutOfHelpers<'tcx> for InterpC } } -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> { type FnAbiOfResult = InterpResult<'tcx, &'tcx FnAbi<'tcx, Ty<'tcx>>>; fn handle_fn_abi_err( @@ -484,7 +484,7 @@ pub fn format_interp_error<'tcx>(dcx: &DiagCtxt, e: InterpErrorInfo<'tcx>) -> St s } -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { pub fn new( tcx: TyCtxt<'tcx>, root_span: Span, @@ -517,14 +517,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } #[inline(always)] - pub(crate) fn stack(&self) -> &[Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>] { + pub(crate) fn stack(&self) -> &[Frame<'tcx, M::Provenance, M::FrameExtra>] { M::stack(self) } #[inline(always)] - pub(crate) fn stack_mut( - &mut self, - ) -> &mut Vec> { + pub(crate) fn stack_mut(&mut self) -> &mut Vec> { M::stack_mut(self) } @@ -536,17 +534,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } #[inline(always)] - pub fn frame(&self) -> &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra> { + pub fn frame(&self) -> &Frame<'tcx, M::Provenance, M::FrameExtra> { self.stack().last().expect("no call frames exist") } #[inline(always)] - pub fn frame_mut(&mut self) -> &mut Frame<'mir, 'tcx, M::Provenance, M::FrameExtra> { + pub fn frame_mut(&mut self) -> &mut Frame<'tcx, M::Provenance, M::FrameExtra> { self.stack_mut().last_mut().expect("no call frames exist") } #[inline(always)] - pub fn body(&self) -> &'mir mir::Body<'tcx> { + pub fn body(&self) -> &'tcx mir::Body<'tcx> { self.frame().body } @@ -602,7 +600,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { T: TypeFoldable>, >( &self, - frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>, + frame: &Frame<'tcx, M::Provenance, M::FrameExtra>, value: T, ) -> Result { frame @@ -680,7 +678,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline(always)] pub(super) fn layout_of_local( &self, - frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>, + frame: &Frame<'tcx, M::Provenance, M::FrameExtra>, local: mir::Local, layout: Option>, ) -> InterpResult<'tcx, TyAndLayout<'tcx>> { @@ -803,7 +801,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn push_stack_frame( &mut self, instance: ty::Instance<'tcx>, - body: &'mir mir::Body<'tcx>, + body: &'tcx mir::Body<'tcx>, return_place: &MPlaceTy<'tcx, M::Provenance>, return_to_block: StackPopCleanup, ) -> InterpResult<'tcx> { @@ -1205,10 +1203,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } #[must_use] - pub fn dump_place( - &self, - place: &PlaceTy<'tcx, M::Provenance>, - ) -> PlacePrinter<'_, 'mir, 'tcx, M> { + pub fn dump_place(&self, place: &PlaceTy<'tcx, M::Provenance>) -> PlacePrinter<'_, 'tcx, M> { PlacePrinter { ecx: self, place: *place.place() } } @@ -1220,14 +1215,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[doc(hidden)] /// Helper struct for the `dump_place` function. -pub struct PlacePrinter<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> { - ecx: &'a InterpCx<'mir, 'tcx, M>, +pub struct PlacePrinter<'a, 'tcx, M: Machine<'tcx>> { + ecx: &'a InterpCx<'tcx, M>, place: Place, } -impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> std::fmt::Debug - for PlacePrinter<'a, 'mir, 'tcx, M> -{ +impl<'a, 'tcx, M: Machine<'tcx>> std::fmt::Debug for PlacePrinter<'a, 'tcx, M> { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self.place { Place::Local { local, offset, locals_addr } => { diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index c34b658fb373..8d0b267e1a9c 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -29,8 +29,7 @@ use super::{err_ub, AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind use crate::const_eval; use crate::errors::NestedStaticInThreadLocal; -pub trait CompileTimeMachine<'mir, 'tcx: 'mir, T> = Machine< - 'mir, +pub trait CompileTimeMachine<'tcx, T> = Machine< 'tcx, MemoryKind = T, Provenance = CtfeProvenance, @@ -46,7 +45,7 @@ pub trait HasStaticRootDefId { fn static_def_id(&self) -> Option; } -impl HasStaticRootDefId for const_eval::CompileTimeInterpreter<'_, '_> { +impl HasStaticRootDefId for const_eval::CompileTimeInterpreter<'_> { fn static_def_id(&self) -> Option { Some(self.static_root_ids?.1) } @@ -59,8 +58,8 @@ impl HasStaticRootDefId for const_eval::CompileTimeInterpreter<'_, '_> { /// already mutable (as a sanity check). /// /// Returns an iterator over all relocations referred to by this allocation. -fn intern_shallow<'rt, 'mir, 'tcx, T, M: CompileTimeMachine<'mir, 'tcx, T>>( - ecx: &'rt mut InterpCx<'mir, 'tcx, M>, +fn intern_shallow<'rt, 'tcx, T, M: CompileTimeMachine<'tcx, T>>( + ecx: &'rt mut InterpCx<'tcx, M>, alloc_id: AllocId, mutability: Mutability, ) -> Result + 'tcx, ()> { @@ -146,12 +145,8 @@ pub enum InternResult { /// /// For `InternKind::Static` the root allocation will not be interned, but must be handled by the caller. #[instrument(level = "debug", skip(ecx))] -pub fn intern_const_alloc_recursive< - 'mir, - 'tcx: 'mir, - M: CompileTimeMachine<'mir, 'tcx, const_eval::MemoryKind>, ->( - ecx: &mut InterpCx<'mir, 'tcx, M>, +pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval::MemoryKind>>( + ecx: &mut InterpCx<'tcx, M>, intern_kind: InternKind, ret: &MPlaceTy<'tcx>, ) -> Result<(), InternResult> { @@ -290,13 +285,8 @@ pub fn intern_const_alloc_recursive< /// Intern `ret`. This function assumes that `ret` references no other allocation. #[instrument(level = "debug", skip(ecx))] -pub fn intern_const_alloc_for_constprop< - 'mir, - 'tcx: 'mir, - T, - M: CompileTimeMachine<'mir, 'tcx, T>, ->( - ecx: &mut InterpCx<'mir, 'tcx, M>, +pub fn intern_const_alloc_for_constprop<'tcx, T, M: CompileTimeMachine<'tcx, T>>( + ecx: &mut InterpCx<'tcx, M>, alloc_id: AllocId, ) -> InterpResult<'tcx, ()> { if ecx.tcx.try_get_global_alloc(alloc_id).is_some() { @@ -315,19 +305,14 @@ pub fn intern_const_alloc_for_constprop< Ok(()) } -impl<'mir, 'tcx: 'mir, M: super::intern::CompileTimeMachine<'mir, 'tcx, !>> - InterpCx<'mir, 'tcx, M> -{ +impl<'tcx, M: super::intern::CompileTimeMachine<'tcx, !>> InterpCx<'tcx, M> { /// A helper function that allocates memory for the layout given and gives you access to mutate /// it. Once your own mutation code is done, the backing `Allocation` is removed from the /// current `Memory` and interned as read-only into the global memory. pub fn intern_with_temp_alloc( &mut self, layout: TyAndLayout<'tcx>, - f: impl FnOnce( - &mut InterpCx<'mir, 'tcx, M>, - &PlaceTy<'tcx, M::Provenance>, - ) -> InterpResult<'tcx, ()>, + f: impl FnOnce(&mut InterpCx<'tcx, M>, &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx, ()>, ) -> InterpResult<'tcx, AllocId> { // `allocate` picks a fresh AllocId that we will associate with its data below. let dest = self.allocate(layout, MemoryKind::Stack)?; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 3a8f8dc4cb9d..18b76443cd95 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -98,7 +98,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( }) } -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Returns `true` if emulation happened. /// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own /// intrinsic handling. @@ -605,9 +605,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Copy `count*size_of::()` many bytes from `*src` to `*dst`. pub(crate) fn copy_intrinsic( &mut self, - src: &OpTy<'tcx, >::Provenance>, - dst: &OpTy<'tcx, >::Provenance>, - count: &OpTy<'tcx, >::Provenance>, + src: &OpTy<'tcx, >::Provenance>, + dst: &OpTy<'tcx, >::Provenance>, + count: &OpTy<'tcx, >::Provenance>, nonoverlapping: bool, ) -> InterpResult<'tcx> { let count = self.read_target_usize(count)?; @@ -634,8 +634,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Does a *typed* swap of `*left` and `*right`. fn typed_swap_intrinsic( &mut self, - left: &OpTy<'tcx, >::Provenance>, - right: &OpTy<'tcx, >::Provenance>, + left: &OpTy<'tcx, >::Provenance>, + right: &OpTy<'tcx, >::Provenance>, ) -> InterpResult<'tcx> { let left = self.deref_pointer(left)?; let right = self.deref_pointer(right)?; @@ -651,9 +651,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub(crate) fn write_bytes_intrinsic( &mut self, - dst: &OpTy<'tcx, >::Provenance>, - byte: &OpTy<'tcx, >::Provenance>, - count: &OpTy<'tcx, >::Provenance>, + dst: &OpTy<'tcx, >::Provenance>, + byte: &OpTy<'tcx, >::Provenance>, + count: &OpTy<'tcx, >::Provenance>, ) -> InterpResult<'tcx> { let layout = self.layout_of(dst.layout.ty.builtin_deref(true).unwrap())?; @@ -673,9 +673,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub(crate) fn compare_bytes_intrinsic( &mut self, - left: &OpTy<'tcx, >::Provenance>, - right: &OpTy<'tcx, >::Provenance>, - byte_count: &OpTy<'tcx, >::Provenance>, + left: &OpTy<'tcx, >::Provenance>, + right: &OpTy<'tcx, >::Provenance>, + byte_count: &OpTy<'tcx, >::Provenance>, ) -> InterpResult<'tcx, Scalar> { let left = self.read_pointer(left)?; let right = self.read_pointer(right)?; @@ -691,14 +691,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub(crate) fn raw_eq_intrinsic( &mut self, - lhs: &OpTy<'tcx, >::Provenance>, - rhs: &OpTy<'tcx, >::Provenance>, + lhs: &OpTy<'tcx, >::Provenance>, + rhs: &OpTy<'tcx, >::Provenance>, ) -> InterpResult<'tcx, Scalar> { let layout = self.layout_of(lhs.layout.ty.builtin_deref(true).unwrap())?; assert!(layout.is_sized()); - let get_bytes = |this: &InterpCx<'mir, 'tcx, M>, - op: &OpTy<'tcx, >::Provenance>, + let get_bytes = |this: &InterpCx<'tcx, M>, + op: &OpTy<'tcx, >::Provenance>, size| -> InterpResult<'tcx, &[u8]> { let ptr = this.read_pointer(op)?; diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 72a16dbe4d6a..5713e7bd82b3 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -94,7 +94,7 @@ pub trait AllocMap { /// Methods of this trait signifies a point where CTFE evaluation would fail /// and some use case dependent behaviour can instead be applied. -pub trait Machine<'mir, 'tcx: 'mir>: Sized { +pub trait Machine<'tcx>: Sized { /// Additional memory kinds a machine wishes to distinguish from the builtin ones type MemoryKind: Debug + std::fmt::Display + MayLeak + Eq + 'static; @@ -145,12 +145,12 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { const ALL_CONSTS_ARE_PRECHECKED: bool = true; /// Whether memory accesses should be alignment-checked. - fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; + fn enforce_alignment(ecx: &InterpCx<'tcx, Self>) -> bool; /// Gives the machine a chance to detect more misalignment than the built-in checks would catch. #[inline(always)] fn alignment_check( - _ecx: &InterpCx<'mir, 'tcx, Self>, + _ecx: &InterpCx<'tcx, Self>, _alloc_id: AllocId, _alloc_align: Align, _alloc_kind: AllocKind, @@ -161,22 +161,22 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { } /// Whether to enforce the validity invariant for a specific layout. - fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool; + fn enforce_validity(ecx: &InterpCx<'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool; /// Whether function calls should be [ABI](CallAbi)-checked. - fn enforce_abi(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { + fn enforce_abi(_ecx: &InterpCx<'tcx, Self>) -> bool { true } /// Whether Assert(OverflowNeg) and Assert(Overflow) MIR terminators should actually /// check for overflow. - fn ignore_optional_overflow_checks(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; + fn ignore_optional_overflow_checks(_ecx: &InterpCx<'tcx, Self>) -> bool; /// Entry point for obtaining the MIR of anything that should get evaluated. /// So not just functions and shims, but also const/static initializers, anonymous /// constants, ... fn load_mir( - ecx: &InterpCx<'mir, 'tcx, Self>, + ecx: &InterpCx<'tcx, Self>, instance: ty::InstanceDef<'tcx>, ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> { Ok(ecx.tcx.instance_mir(instance)) @@ -193,19 +193,19 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// Passing `dest`and `ret` in the same `Option` proved very annoying when only one of them /// was used. fn find_mir_or_eval_fn( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, instance: ty::Instance<'tcx>, abi: CallAbi, args: &[FnArg<'tcx, Self::Provenance>], destination: &MPlaceTy<'tcx, Self::Provenance>, target: Option, unwind: mir::UnwindAction, - ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>>; + ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>>; /// Execute `fn_val`. It is the hook's responsibility to advance the instruction /// pointer as appropriate. fn call_extra_fn( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, fn_val: Self::ExtraFnVal, abi: CallAbi, args: &[FnArg<'tcx, Self::Provenance>], @@ -220,7 +220,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// Returns `None` if the intrinsic was fully handled. /// Otherwise, returns an `Instance` of the function that implements the intrinsic. fn call_intrinsic( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, Self::Provenance>], destination: &MPlaceTy<'tcx, Self::Provenance>, @@ -230,17 +230,17 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// Called to evaluate `Assert` MIR terminators that trigger a panic. fn assert_panic( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, msg: &mir::AssertMessage<'tcx>, unwind: mir::UnwindAction, ) -> InterpResult<'tcx>; /// Called to trigger a non-unwinding panic. - fn panic_nounwind(_ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx>; + fn panic_nounwind(_ecx: &mut InterpCx<'tcx, Self>, msg: &str) -> InterpResult<'tcx>; /// Called when unwinding reached a state where execution should be terminated. fn unwind_terminate( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, reason: mir::UnwindTerminateReason, ) -> InterpResult<'tcx>; @@ -248,7 +248,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// /// Returns a (value, overflowed) pair if the operation succeeded fn binary_ptr_op( - ecx: &InterpCx<'mir, 'tcx, Self>, + ecx: &InterpCx<'tcx, Self>, bin_op: mir::BinOp, left: &ImmTy<'tcx, Self::Provenance>, right: &ImmTy<'tcx, Self::Provenance>, @@ -257,7 +257,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// Generate the NaN returned by a float operation, given the list of inputs. /// (This is all inputs, not just NaN inputs!) fn generate_nan, F2: Float>( - _ecx: &InterpCx<'mir, 'tcx, Self>, + _ecx: &InterpCx<'tcx, Self>, _inputs: &[F1], ) -> F2 { // By default we always return the preferred NaN. @@ -266,14 +266,14 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// Called before a basic block terminator is executed. #[inline] - fn before_terminator(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { + fn before_terminator(_ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> { Ok(()) } /// Called when the interpreter encounters a `StatementKind::ConstEvalCounter` instruction. /// You can use this to detect long or endlessly running programs. #[inline] - fn increment_const_eval_counter(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { + fn increment_const_eval_counter(_ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> { Ok(()) } @@ -293,7 +293,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// Return the `AllocId` for the given thread-local static in the current thread. fn thread_local_static_pointer( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'tcx, Self>, def_id: DefId, ) -> InterpResult<'tcx, Pointer> { throw_unsup!(ThreadLocalStatic(def_id)) @@ -301,20 +301,20 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// Return the `AllocId` for the given `extern static`. fn extern_static_pointer( - ecx: &InterpCx<'mir, 'tcx, Self>, + ecx: &InterpCx<'tcx, Self>, def_id: DefId, ) -> InterpResult<'tcx, Pointer>; /// "Int-to-pointer cast" fn ptr_from_addr_cast( - ecx: &InterpCx<'mir, 'tcx, Self>, + ecx: &InterpCx<'tcx, Self>, addr: u64, ) -> InterpResult<'tcx, Pointer>>; /// Marks a pointer as exposed, allowing it's provenance /// to be recovered. "Pointer-to-int cast" fn expose_ptr( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, ptr: Pointer, ) -> InterpResult<'tcx>; @@ -325,7 +325,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// /// When this fails, that means the pointer does not point to a live allocation. fn ptr_get_alloc( - ecx: &InterpCx<'mir, 'tcx, Self>, + ecx: &InterpCx<'tcx, Self>, ptr: Pointer, ) -> Option<(AllocId, Size, Self::ProvenanceExtra)>; @@ -345,7 +345,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// cache the result. (This relies on `AllocMap::get_or` being able to add the /// owned allocation to the map even when the map is shared.) fn adjust_allocation<'b>( - ecx: &InterpCx<'mir, 'tcx, Self>, + ecx: &InterpCx<'tcx, Self>, id: AllocId, alloc: Cow<'b, Allocation>, kind: Option>, @@ -359,7 +359,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// `kind` is the kind of the allocation the pointer points to; it can be `None` when /// it's a global and `GLOBAL_KIND` is `None`. fn adjust_alloc_root_pointer( - ecx: &InterpCx<'mir, 'tcx, Self>, + ecx: &InterpCx<'tcx, Self>, ptr: Pointer, kind: Option>, ) -> InterpResult<'tcx, Pointer>; @@ -370,7 +370,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// is triggered, `targets[0]` when the assembly falls through, or diverge in case of /// `InlineAsmOptions::NORETURN` being set. fn eval_inline_asm( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'tcx, Self>, _template: &'tcx [InlineAsmTemplatePiece], _operands: &[mir::InlineAsmOperand<'tcx>], _options: InlineAsmOptions, @@ -406,10 +406,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// /// Used to prevent statics from self-initializing by reading from their own memory /// as it is being initialized. - fn before_alloc_read( - _ecx: &InterpCx<'mir, 'tcx, Self>, - _alloc_id: AllocId, - ) -> InterpResult<'tcx> { + fn before_alloc_read(_ecx: &InterpCx<'tcx, Self>, _alloc_id: AllocId) -> InterpResult<'tcx> { Ok(()) } @@ -444,7 +441,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// Returns the possibly adjusted pointer. #[inline] fn retag_ptr_value( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'tcx, Self>, _kind: mir::RetagKind, val: &ImmTy<'tcx, Self::Provenance>, ) -> InterpResult<'tcx, ImmTy<'tcx, Self::Provenance>> { @@ -455,7 +452,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// Replaces all pointers stored in the given place. #[inline] fn retag_place_contents( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'tcx, Self>, _kind: mir::RetagKind, _place: &PlaceTy<'tcx, Self::Provenance>, ) -> InterpResult<'tcx> { @@ -467,7 +464,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// These places need to be protected to make sure the program cannot tell whether the /// argument/return value was actually copied or passed in-place.. fn protect_in_place_function_argument( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, mplace: &MPlaceTy<'tcx, Self::Provenance>, ) -> InterpResult<'tcx> { // Without an aliasing model, all we can do is put `Uninit` into the place. @@ -477,29 +474,29 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// Called immediately before a new stack frame gets pushed. fn init_frame_extra( - ecx: &mut InterpCx<'mir, 'tcx, Self>, - frame: Frame<'mir, 'tcx, Self::Provenance>, - ) -> InterpResult<'tcx, Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>>; + ecx: &mut InterpCx<'tcx, Self>, + frame: Frame<'tcx, Self::Provenance>, + ) -> InterpResult<'tcx, Frame<'tcx, Self::Provenance, Self::FrameExtra>>; /// Borrow the current thread's stack. fn stack<'a>( - ecx: &'a InterpCx<'mir, 'tcx, Self>, - ) -> &'a [Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>]; + ecx: &'a InterpCx<'tcx, Self>, + ) -> &'a [Frame<'tcx, Self::Provenance, Self::FrameExtra>]; /// Mutably borrow the current thread's stack. fn stack_mut<'a>( - ecx: &'a mut InterpCx<'mir, 'tcx, Self>, - ) -> &'a mut Vec>; + ecx: &'a mut InterpCx<'tcx, Self>, + ) -> &'a mut Vec>; /// Called immediately after a stack frame got pushed and its locals got initialized. - fn after_stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { + fn after_stack_push(_ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> { Ok(()) } /// Called just before the return value is copied to the caller-provided return place. fn before_stack_pop( - _ecx: &InterpCx<'mir, 'tcx, Self>, - _frame: &Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>, + _ecx: &InterpCx<'tcx, Self>, + _frame: &Frame<'tcx, Self::Provenance, Self::FrameExtra>, ) -> InterpResult<'tcx> { Ok(()) } @@ -508,8 +505,8 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// The `locals` have already been destroyed! #[inline(always)] fn after_stack_pop( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, - _frame: Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>, + _ecx: &mut InterpCx<'tcx, Self>, + _frame: Frame<'tcx, Self::Provenance, Self::FrameExtra>, unwinding: bool, ) -> InterpResult<'tcx, StackPopJump> { // By default, we do not support unwinding from panics @@ -521,7 +518,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// but before the local's stack frame is updated to point to that memory. #[inline(always)] fn after_local_allocated( - _ecx: &mut InterpCx<'mir, 'tcx, Self>, + _ecx: &mut InterpCx<'tcx, Self>, _local: mir::Local, _mplace: &MPlaceTy<'tcx, Self::Provenance>, ) -> InterpResult<'tcx> { @@ -532,7 +529,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// but this hook has the chance to do some pre/postprocessing. #[inline(always)] fn eval_mir_constant( - ecx: &InterpCx<'mir, 'tcx, Self>, + ecx: &InterpCx<'tcx, Self>, val: mir::Const<'tcx>, span: Span, layout: Option>, @@ -540,7 +537,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { ) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>> where F: Fn( - &InterpCx<'mir, 'tcx, Self>, + &InterpCx<'tcx, Self>, mir::Const<'tcx>, Span, Option>, @@ -552,7 +549,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines /// (CTFE and ConstProp) use the same instance. Here, we share that code. -pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { +pub macro compile_time_machine(<$tcx: lifetime>) { type Provenance = CtfeProvenance; type ProvenanceExtra = bool; // the "immutable" flag @@ -567,13 +564,13 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { type Bytes = Box<[u8]>; #[inline(always)] - fn ignore_optional_overflow_checks(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool { + fn ignore_optional_overflow_checks(_ecx: &InterpCx<$tcx, Self>) -> bool { false } #[inline(always)] fn unwind_terminate( - _ecx: &mut InterpCx<$mir, $tcx, Self>, + _ecx: &mut InterpCx<$tcx, Self>, _reason: mir::UnwindTerminateReason, ) -> InterpResult<$tcx> { unreachable!("unwinding cannot happen during compile-time evaluation") @@ -581,7 +578,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { #[inline(always)] fn call_extra_fn( - _ecx: &mut InterpCx<$mir, $tcx, Self>, + _ecx: &mut InterpCx<$tcx, Self>, fn_val: !, _abi: CallAbi, _args: &[FnArg<$tcx>], @@ -594,7 +591,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { #[inline(always)] fn adjust_allocation<'b>( - _ecx: &InterpCx<$mir, $tcx, Self>, + _ecx: &InterpCx<$tcx, Self>, _id: AllocId, alloc: Cow<'b, Allocation>, _kind: Option>, @@ -603,7 +600,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { } fn extern_static_pointer( - ecx: &InterpCx<$mir, $tcx, Self>, + ecx: &InterpCx<$tcx, Self>, def_id: DefId, ) -> InterpResult<$tcx, Pointer> { // Use the `AllocId` associated with the `DefId`. Any actual *access* will fail. @@ -612,7 +609,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { #[inline(always)] fn adjust_alloc_root_pointer( - _ecx: &InterpCx<$mir, $tcx, Self>, + _ecx: &InterpCx<$tcx, Self>, ptr: Pointer, _kind: Option>, ) -> InterpResult<$tcx, Pointer> { @@ -621,7 +618,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { #[inline(always)] fn ptr_from_addr_cast( - _ecx: &InterpCx<$mir, $tcx, Self>, + _ecx: &InterpCx<$tcx, Self>, addr: u64, ) -> InterpResult<$tcx, Pointer>> { // Allow these casts, but make the pointer not dereferenceable. @@ -632,7 +629,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { #[inline(always)] fn ptr_get_alloc( - _ecx: &InterpCx<$mir, $tcx, Self>, + _ecx: &InterpCx<$tcx, Self>, ptr: Pointer, ) -> Option<(AllocId, Size, Self::ProvenanceExtra)> { // We know `offset` is relative to the allocation, so we can use `into_parts`. diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 23273e694441..40bbfaa92c6f 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -96,7 +96,7 @@ impl<'tcx, Other> FnVal<'tcx, Other> { // `Memory` has to depend on the `Machine` because some of its operations // (e.g., `get`) call a `Machine` hook. -pub struct Memory<'mir, 'tcx, M: Machine<'mir, 'tcx>> { +pub struct Memory<'tcx, M: Machine<'tcx>> { /// Allocations local to this instance of the interpreter. The kind /// helps ensure that the same mechanism is used for allocation and /// deallocation. When an allocation is not found here, it is a @@ -142,7 +142,7 @@ pub struct AllocRefMut<'a, 'tcx, Prov: Provenance, Extra, Bytes: AllocBytes = Bo alloc_id: AllocId, } -impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> Memory<'tcx, M> { pub fn new() -> Self { Memory { alloc_map: M::MemoryMap::default(), @@ -158,7 +158,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } } -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Call this to turn untagged "global" pointers (obtained via `tcx`) into /// the machine pointer to the allocation. Must never be used /// for any other pointers, nor for TLS statics. @@ -524,7 +524,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// This function is used by Miri's provenance GC to remove unreachable entries from the dead_alloc_map. pub fn remove_unreachable_allocs(&mut self, reachable_allocs: &FxHashSet) { // Unlike all the other GC helpers where we check if an `AllocId` is found in the interpreter or @@ -536,7 +536,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } /// Allocation accessors -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Helper function to obtain a global (tcx) allocation. /// This attempts to return a reference to an existing allocation if /// one can be found in `tcx`. That, however, is only possible if `tcx` and @@ -888,14 +888,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Create a lazy debug printer that prints the given allocation and all allocations it points /// to, recursively. #[must_use] - pub fn dump_alloc<'a>(&'a self, id: AllocId) -> DumpAllocs<'a, 'mir, 'tcx, M> { + pub fn dump_alloc<'a>(&'a self, id: AllocId) -> DumpAllocs<'a, 'tcx, M> { self.dump_allocs(vec![id]) } /// Create a lazy debug printer for a list of allocations and all allocations they point to, /// recursively. #[must_use] - pub fn dump_allocs<'a>(&'a self, mut allocs: Vec) -> DumpAllocs<'a, 'mir, 'tcx, M> { + pub fn dump_allocs<'a>(&'a self, mut allocs: Vec) -> DumpAllocs<'a, 'tcx, M> { allocs.sort(); allocs.dedup(); DumpAllocs { ecx: self, allocs } @@ -975,12 +975,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[doc(hidden)] /// There's no way to use this directly, it's just a helper struct for the `dump_alloc(s)` methods. -pub struct DumpAllocs<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> { - ecx: &'a InterpCx<'mir, 'tcx, M>, +pub struct DumpAllocs<'a, 'tcx, M: Machine<'tcx>> { + ecx: &'a InterpCx<'tcx, M>, allocs: Vec, } -impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a, 'mir, 'tcx, M> { +impl<'a, 'tcx, M: Machine<'tcx>> std::fmt::Debug for DumpAllocs<'a, 'tcx, M> { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { // Cannot be a closure because it is generic in `Prov`, `Extra`. fn write_allocation_track_relocs<'tcx, Prov: Provenance, Extra, Bytes: AllocBytes>( @@ -1125,7 +1125,7 @@ impl<'tcx, 'a, Prov: Provenance, Extra, Bytes: AllocBytes> AllocRef<'a, 'tcx, Pr } } -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Reads the given number of bytes from memory, and strips their provenance if possible. /// Returns them as a slice. /// @@ -1338,7 +1338,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } /// Machine pointer introspection. -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Test if this value might be null. /// If the machine does not support ptr-to-int casts, this is conservative. pub fn scalar_may_be_null(&self, scalar: Scalar) -> InterpResult<'tcx, bool> { diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 8f01b8720104..bbb2c2f39385 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -374,21 +374,21 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for ImmTy<'tcx, Prov> { MemPlaceMeta::None } - fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn offset_with_meta>( &self, offset: Size, _mode: OffsetMode, meta: MemPlaceMeta, layout: TyAndLayout<'tcx>, - ecx: &InterpCx<'mir, 'tcx, M>, + ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, Self> { assert_matches!(meta, MemPlaceMeta::None); // we can't store this anywhere anyway Ok(self.offset_(offset, layout, ecx)) } - fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn to_op>( &self, - _ecx: &InterpCx<'mir, 'tcx, M>, + _ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { Ok(self.clone().into()) } @@ -457,13 +457,13 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for OpTy<'tcx, Prov> { } } - fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn offset_with_meta>( &self, offset: Size, mode: OffsetMode, meta: MemPlaceMeta, layout: TyAndLayout<'tcx>, - ecx: &InterpCx<'mir, 'tcx, M>, + ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, Self> { match self.as_mplace_or_imm() { Left(mplace) => Ok(mplace.offset_with_meta(offset, mode, meta, layout, ecx)?.into()), @@ -475,9 +475,9 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for OpTy<'tcx, Prov> { } } - fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn to_op>( &self, - _ecx: &InterpCx<'mir, 'tcx, M>, + _ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { Ok(self.clone()) } @@ -509,7 +509,7 @@ impl<'tcx, Prov: Provenance> Readable<'tcx, Prov> for ImmTy<'tcx, Prov> { } } -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Try reading an immediate in memory; this is interesting particularly for `ScalarPair`. /// Returns `None` if the layout does not permit loading this as a value. /// diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 62641b868e62..d23f0c4d45b0 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -11,7 +11,7 @@ use tracing::trace; use super::{err_ub, throw_ub, ImmTy, InterpCx, Machine}; -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { fn three_way_compare(&self, lhs: T, rhs: T) -> ImmTy<'tcx, M::Provenance> { let res = Ord::cmp(&lhs, &rhs); return ImmTy::from_ordering(res, *self.tcx); diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 588db0f547f8..4a86ec3f57a4 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -77,12 +77,12 @@ impl MemPlace { #[inline] // Not called `offset_with_meta` to avoid confusion with the trait method. - fn offset_with_meta_<'mir, 'tcx, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn offset_with_meta_<'tcx, M: Machine<'tcx, Provenance = Prov>>( self, offset: Size, mode: OffsetMode, meta: MemPlaceMeta, - ecx: &InterpCx<'mir, 'tcx, M>, + ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, Self> { debug_assert!( !meta.has_meta() || self.meta.has_meta(), @@ -162,20 +162,20 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for MPlaceTy<'tcx, Prov> { self.mplace.meta } - fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn offset_with_meta>( &self, offset: Size, mode: OffsetMode, meta: MemPlaceMeta, layout: TyAndLayout<'tcx>, - ecx: &InterpCx<'mir, 'tcx, M>, + ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, Self> { Ok(MPlaceTy { mplace: self.mplace.offset_with_meta_(offset, mode, meta, ecx)?, layout }) } - fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn to_op>( &self, - _ecx: &InterpCx<'mir, 'tcx, M>, + _ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { Ok(self.clone().into()) } @@ -274,13 +274,13 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for PlaceTy<'tcx, Prov> { } } - fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn offset_with_meta>( &self, offset: Size, mode: OffsetMode, meta: MemPlaceMeta, layout: TyAndLayout<'tcx>, - ecx: &InterpCx<'mir, 'tcx, M>, + ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, Self> { Ok(match self.as_mplace_or_local() { Left(mplace) => mplace.offset_with_meta(offset, mode, meta, layout, ecx)?.into(), @@ -305,9 +305,9 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for PlaceTy<'tcx, Prov> { }) } - fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn to_op>( &self, - ecx: &InterpCx<'mir, 'tcx, M>, + ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { ecx.place_to_op(self) } @@ -341,9 +341,9 @@ pub trait Writeable<'tcx, Prov: Provenance>: Projectable<'tcx, Prov> { &self, ) -> Either, (mir::Local, Option, usize, TyAndLayout<'tcx>)>; - fn force_mplace<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn force_mplace>( &self, - ecx: &mut InterpCx<'mir, 'tcx, M>, + ecx: &mut InterpCx<'tcx, M>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, Prov>>; } @@ -357,9 +357,9 @@ impl<'tcx, Prov: Provenance> Writeable<'tcx, Prov> for PlaceTy<'tcx, Prov> { } #[inline(always)] - fn force_mplace<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn force_mplace>( &self, - ecx: &mut InterpCx<'mir, 'tcx, M>, + ecx: &mut InterpCx<'tcx, M>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, Prov>> { ecx.force_allocation(self) } @@ -374,19 +374,19 @@ impl<'tcx, Prov: Provenance> Writeable<'tcx, Prov> for MPlaceTy<'tcx, Prov> { } #[inline(always)] - fn force_mplace<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn force_mplace>( &self, - _ecx: &mut InterpCx<'mir, 'tcx, M>, + _ecx: &mut InterpCx<'tcx, M>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, Prov>> { Ok(self.clone()) } } // FIXME: Working around https://github.com/rust-lang/rust/issues/54385 -impl<'mir, 'tcx: 'mir, Prov, M> InterpCx<'mir, 'tcx, M> +impl<'tcx, Prov, M> InterpCx<'tcx, M> where Prov: Provenance, - M: Machine<'mir, 'tcx, Provenance = Prov>, + M: Machine<'tcx, Provenance = Prov>, { pub fn ptr_with_meta_to_mplace( &self, diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index cfc4d701aa7b..0e594914c3a7 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -43,9 +43,9 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug { fn meta(&self) -> MemPlaceMeta; /// Get the length of a slice/string/array stored here. - fn len<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn len>( &self, - ecx: &InterpCx<'mir, 'tcx, M>, + ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, u64> { let layout = self.layout(); if layout.is_unsized() { @@ -65,29 +65,29 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug { } /// Offset the value by the given amount, replacing the layout and metadata. - fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn offset_with_meta>( &self, offset: Size, mode: OffsetMode, meta: MemPlaceMeta, layout: TyAndLayout<'tcx>, - ecx: &InterpCx<'mir, 'tcx, M>, + ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, Self>; - fn offset<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn offset>( &self, offset: Size, layout: TyAndLayout<'tcx>, - ecx: &InterpCx<'mir, 'tcx, M>, + ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, Self> { assert!(layout.is_sized()); self.offset_with_meta(offset, OffsetMode::Inbounds, MemPlaceMeta::None, layout, ecx) } - fn transmute<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn transmute>( &self, layout: TyAndLayout<'tcx>, - ecx: &InterpCx<'mir, 'tcx, M>, + ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, Self> { assert!(self.layout().is_sized() && layout.is_sized()); assert_eq!(self.layout().size, layout.size); @@ -96,9 +96,9 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug { /// Convert this to an `OpTy`. This might be an irreversible transformation, but is useful for /// reading from this thing. - fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + fn to_op>( &self, - ecx: &InterpCx<'mir, 'tcx, M>, + ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>>; } @@ -113,9 +113,9 @@ pub struct ArrayIterator<'tcx, 'a, Prov: Provenance, P: Projectable<'tcx, Prov>> impl<'tcx, 'a, Prov: Provenance, P: Projectable<'tcx, Prov>> ArrayIterator<'tcx, 'a, Prov, P> { /// Should be the same `ecx` on each call, and match the one used to create the iterator. - pub fn next<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( + pub fn next>( &mut self, - ecx: &InterpCx<'mir, 'tcx, M>, + ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, Option<(u64, P)>> { let Some(idx) = self.range.next() else { return Ok(None) }; // We use `Wrapping` here since the offset has already been checked when the iterator was created. @@ -133,10 +133,10 @@ impl<'tcx, 'a, Prov: Provenance, P: Projectable<'tcx, Prov>> ArrayIterator<'tcx, } // FIXME: Working around https://github.com/rust-lang/rust/issues/54385 -impl<'mir, 'tcx: 'mir, Prov, M> InterpCx<'mir, 'tcx, M> +impl<'tcx, Prov, M> InterpCx<'tcx, M> where Prov: Provenance, - M: Machine<'mir, 'tcx, Provenance = Prov>, + M: Machine<'tcx, Provenance = Prov>, { /// Offset a pointer to project to a field of a struct/union. Unlike `place_field`, this is /// always possible without allocating, so it can take `&self`. Also return the field's layout. diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 58210fe39713..d0bb821862aa 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -16,7 +16,7 @@ use super::{ }; use crate::util; -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Returns `true` as long as there are more things to do. /// /// This is used by [priroda](https://github.com/oli-obk/priroda) diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 360cefb5a1fe..0649bb5617ce 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -46,7 +46,7 @@ impl<'tcx, Prov: Provenance> FnArg<'tcx, Prov> { } } -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Make a copy of the given fn_arg. Any `InPlace` are degenerated to copies, no protection of the /// original memory occurs. pub fn copy_fn_arg(&self, arg: &FnArg<'tcx, M::Provenance>) -> OpTy<'tcx, M::Provenance> { diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index 8b5904594051..244a6ba48a4d 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -7,7 +7,7 @@ use tracing::trace; use super::util::ensure_monomorphic_enough; use super::{InterpCx, Machine}; -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Creates a dynamic vtable for the given type and vtable origin. This is used only for /// objects. /// diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index f0f9df73d947..10fd6399b9a3 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -82,9 +82,9 @@ where } impl<'tcx> InterpretationResult<'tcx> for mir::interpret::ConstAllocation<'tcx> { - fn make_result<'mir>( + fn make_result( mplace: MPlaceTy<'tcx>, - ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, + ecx: &mut InterpCx<'tcx, CompileTimeInterpreter<'tcx>>, ) -> Self { let alloc_id = mplace.ptr().provenance.unwrap().alloc_id(); let alloc = ecx.memory.alloc_map.swap_remove(&alloc_id).unwrap().1; @@ -92,8 +92,8 @@ impl<'tcx> InterpretationResult<'tcx> for mir::interpret::ConstAllocation<'tcx> } } -pub(crate) fn create_static_alloc<'mir, 'tcx: 'mir>( - ecx: &mut CompileTimeEvalContext<'mir, 'tcx>, +pub(crate) fn create_static_alloc<'tcx>( + ecx: &mut CompileTimeEvalContext<'tcx>, static_def_id: LocalDefId, layout: TyAndLayout<'tcx>, ) -> InterpResult<'tcx, MPlaceTy<'tcx>> { diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index cf6027a312fa..e35ce9ef28d6 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -205,7 +205,7 @@ fn write_path(out: &mut String, path: &[PathElem]) { } } -struct ValidityVisitor<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> { +struct ValidityVisitor<'rt, 'tcx, M: Machine<'tcx>> { /// The `path` may be pushed to, but the part that is present when a function /// starts must not be changed! `visit_fields` and `visit_array` rely on /// this stack discipline. @@ -213,10 +213,10 @@ struct ValidityVisitor<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> { ref_tracking: Option<&'rt mut RefTracking, Vec>>, /// `None` indicates this is not validating for CTFE (but for runtime). ctfe_mode: Option, - ecx: &'rt InterpCx<'mir, 'tcx, M>, + ecx: &'rt InterpCx<'tcx, M>, } -impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M> { +impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { fn aggregate_field_path_elem(&mut self, layout: TyAndLayout<'tcx>, field: usize) -> PathElem { // First, check if we are projecting to a variant. match layout.variants { @@ -706,10 +706,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' /// Returns whether the allocation is mutable, and whether it's actually a static. /// For "root" statics we look at the type to account for interior /// mutability; for nested statics we have no type and directly use the annotated mutability. -fn mutability<'mir, 'tcx: 'mir>( - ecx: &InterpCx<'mir, 'tcx, impl Machine<'mir, 'tcx>>, - alloc_id: AllocId, -) -> Mutability { +fn mutability<'tcx>(ecx: &InterpCx<'tcx, impl Machine<'tcx>>, alloc_id: AllocId) -> Mutability { // Let's see what kind of memory this points to. // We're not using `try_global_alloc` since dangling pointers have already been handled. match ecx.tcx.global_alloc(alloc_id) { @@ -751,13 +748,11 @@ fn mutability<'mir, 'tcx: 'mir>( } } -impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> - for ValidityVisitor<'rt, 'mir, 'tcx, M> -{ +impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, 'tcx, M> { type V = OpTy<'tcx, M::Provenance>; #[inline(always)] - fn ecx(&self) -> &InterpCx<'mir, 'tcx, M> { + fn ecx(&self) -> &InterpCx<'tcx, M> { self.ecx } @@ -1009,7 +1004,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } } -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { fn validate_operand_internal( &self, op: &OpTy<'tcx, M::Provenance>, diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index 692eb6c17e6c..b812e89854b2 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -13,11 +13,11 @@ use std::num::NonZero; use super::{throw_inval, InterpCx, MPlaceTy, Machine, Projectable}; /// How to traverse a value and what to do when we are at the leaves. -pub trait ValueVisitor<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized { +pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { type V: Projectable<'tcx, M::Provenance> + From>; /// The visitor must have an `InterpCx` in it. - fn ecx(&self) -> &InterpCx<'mir, 'tcx, M>; + fn ecx(&self) -> &InterpCx<'tcx, M>; /// `read_discriminant` can be hooked for better error messages. #[inline(always)] diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index bc5fe39f8673..62c5f8734a24 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -11,8 +11,8 @@ use crate::const_eval::{mk_eval_cx_to_read_const_val, CanAccessMutGlobal, Compil use crate::interpret::*; /// Allocate a `const core::panic::Location` with the provided filename and line/column numbers. -fn alloc_caller_location<'mir, 'tcx>( - ecx: &mut CompileTimeEvalContext<'mir, 'tcx>, +fn alloc_caller_location<'tcx>( + ecx: &mut CompileTimeEvalContext<'tcx>, filename: Symbol, line: u32, col: u32, diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 85b5a3cdb7c3..9781aae22eb3 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -24,7 +24,6 @@ #![feature(extend_one)] #![feature(hash_raw_entry)] #![feature(hasher_prefixfree_extras)] -#![feature(lazy_cell)] #![feature(lint_reasons)] #![feature(macro_metavar_expr)] #![feature(map_try_insert)] diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 5532eff7be66..2bd58680eef5 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -57,7 +57,7 @@ use std::process::{self, Command, Stdio}; use std::str; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, OnceLock}; -use std::time::{Instant, SystemTime}; +use std::time::{Duration, Instant, SystemTime}; use time::OffsetDateTime; use tracing::trace; @@ -1502,14 +1502,13 @@ pub fn init_logger(early_dcx: &EarlyDiagCtxt, cfg: rustc_log::LoggerConfig) { pub fn install_ctrlc_handler() { #[cfg(not(target_family = "wasm"))] ctrlc::set_handler(move || { - // Indicate that we have been signaled to stop. If we were already signaled, exit - // immediately. In our interpreter loop we try to consult this value often, but if for - // whatever reason we don't get to that check or the cleanup we do upon finding that - // this bool has become true takes a long time, the exit here will promptly exit the - // process on the second Ctrl-C. - if CTRL_C_RECEIVED.swap(true, Ordering::Relaxed) { - std::process::exit(1); - } + // Indicate that we have been signaled to stop, then give the rest of the compiler a bit of + // time to check CTRL_C_RECEIVED and run its own shutdown logic, but after a short amount + // of time exit the process. This sleep+exit ensures that even if nobody is checking + // CTRL_C_RECEIVED, the compiler exits reasonably promptly. + CTRL_C_RECEIVED.store(true, Ordering::Relaxed); + std::thread::sleep(Duration::from_millis(100)); + std::process::exit(1); }) .expect("Unable to install ctrlc handler"); } diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 2a8f42220640..4eb4e77d69cb 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -1,6 +1,5 @@ #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![feature(lazy_cell)] #![feature(rustc_attrs)] #![feature(type_alias_impl_trait)] #![allow(internal_features)] @@ -365,17 +364,6 @@ impl From> for DiagMessage { } } -/// A workaround for must_produce_diag ICEs when formatting types in disabled lints. -/// -/// Delays formatting until `.into(): DiagMessage` is used. -pub struct DelayDm(pub F); - -impl String> From> for DiagMessage { - fn from(DelayDm(f): DelayDm) -> Self { - DiagMessage::from(f()) - } -} - /// Translating *into* a subdiagnostic message from a diagnostic message is a little strange - but /// the subdiagnostic functions (e.g. `span_label`) take a `SubdiagMessage` and the /// subdiagnostic derive refers to typed identifiers that are `DiagMessage`s, so need to be diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 18bb71bd99f7..34b569c42068 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -200,8 +200,6 @@ pub trait SubdiagMessageOp = pub trait LintDiagnostic<'a, G: EmissionGuarantee> { /// Decorate and emit a lint. fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>); - - fn msg(&self) -> DiagMessage; } #[derive(Clone, Debug, Encodable, Decodable)] diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 3b884ff864ab..4dc5d84b318b 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -39,7 +39,7 @@ pub use diagnostic_impls::{ }; pub use emitter::ColorConfig; pub use rustc_error_messages::{ - fallback_fluent_bundle, fluent_bundle, DelayDm, DiagMessage, FluentBundle, LanguageIdentifier, + fallback_fluent_bundle, fluent_bundle, DiagMessage, FluentBundle, LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagMessage, }; pub use rustc_lint_defs::{pluralize, Applicability}; @@ -572,8 +572,8 @@ impl Drop for DiagCtxtInner { if let Some(backtrace) = &self.must_produce_diag { panic!( "must_produce_diag: `trimmed_def_paths` called but no diagnostics emitted; \ - use `DelayDm` for lints or `with_no_trimmed_paths` for debugging. \ - called at: {backtrace}" + `with_no_trimmed_paths` for debugging. \ + called at: {backtrace}" ); } } diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 36ef8fe7816f..9cbf836ec76f 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -14,7 +14,6 @@ #![allow(internal_features)] #![feature(rustdoc_internals)] #![doc(rust_logo)] -#![feature(lazy_cell)] mod accepted; mod builtin_attrs; diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index b5c067514059..3904f14b0f6e 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -46,13 +46,9 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) { .emit(); } None => { - tcx.node_span_lint( - UNSUPPORTED_CALLING_CONVENTIONS, - hir_id, - span, - "use of calling convention not supported on this target", - |_| {}, - ); + tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| { + lint.primary_message("use of calling convention not supported on this target"); + }); } } @@ -243,8 +239,8 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { UNINHABITED_STATIC, tcx.local_def_id_to_hir_id(def_id), span, - "static of uninhabited type", |lint| { + lint.primary_message("static of uninhabited type"); lint .note("uninhabited statics cannot be initialized, and any access would be an immediate error"); }, @@ -538,11 +534,9 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe // the cases that were stabilized with the `impl_trait_projection` // feature -- see . if let DefKind::LifetimeParam = tcx.def_kind(def_id) - && let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) - | ty::ReLateParam(ty::LateParamRegion { - bound_region: ty::BoundRegionKind::BrNamed(def_id, _), - .. - }) = *tcx.map_opaque_lifetime_to_parent_lifetime(def_id.expect_local()) + && let Some(def_id) = tcx + .map_opaque_lifetime_to_parent_lifetime(def_id.expect_local()) + .opt_param_def_id(tcx, tcx.parent(opaque_def_id.to_def_id())) { shadowed_captures.insert(def_id); } @@ -585,12 +579,9 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe // Check if the lifetime param was captured but isn't named in the precise captures list. if variances[param.index as usize] == ty::Invariant { if let DefKind::OpaqueTy = tcx.def_kind(tcx.parent(param.def_id)) - && let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) - | ty::ReLateParam(ty::LateParamRegion { - bound_region: ty::BoundRegionKind::BrNamed(def_id, _), - .. - }) = *tcx + && let Some(def_id) = tcx .map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()) + .opt_param_def_id(tcx, tcx.parent(opaque_def_id.to_def_id())) { tcx.dcx().emit_err(errors::LifetimeNotCaptured { opaque_span, @@ -1315,9 +1306,11 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, tcx.local_def_id_to_hir_id(adt.did().expect_local()), span, - "zero-sized fields in `repr(transparent)` cannot \ - contain external non-exhaustive types", |lint| { + lint.primary_message( + "zero-sized fields in `repr(transparent)` cannot \ + contain external non-exhaustive types", + ); let note = if non_exhaustive { "is marked with `#[non_exhaustive]`" } else { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 44bf8fd2d93e..39ced1c803f7 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -876,7 +876,8 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> { ty::ReLateParam(_) => {} // Remap early-bound regions as long as they don't come from the `impl` itself, // in which case we don't really need to renumber them. - ty::ReEarlyParam(ebr) if self.tcx.parent(ebr.def_id) != self.impl_def_id => {} + ty::ReEarlyParam(ebr) + if ebr.index >= self.tcx.generics_of(self.impl_def_id).count() as u32 => {} _ => return Ok(region), } @@ -889,12 +890,8 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> { ); } } else { - let guar = match region.kind() { - ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) - | ty::ReLateParam(ty::LateParamRegion { - bound_region: ty::BoundRegionKind::BrNamed(def_id, _), - .. - }) => { + let guar = match region.opt_param_def_id(self.tcx, self.tcx.parent(self.def_id)) { + Some(def_id) => { let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() { self.tcx.def_span(opaque_ty.def_id) } else { @@ -914,7 +911,7 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> { .with_note(format!("hidden type inferred to be `{}`", self.ty)) .emit() } - _ => { + None => { // This code path is not reached in any tests, but may be // reachable. If this is triggered, it should be converted // to `delayed_bug` and the triggering case turned into a @@ -928,7 +925,6 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> { Ok(ty::Region::new_early_param( self.tcx, ty::EarlyParamRegion { - def_id: e.def_id, name: e.name, index: (e.index as usize - self.num_trait_args + self.num_impl_args) as u32, }, diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index b09de1a4a098..2672614a8954 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -281,8 +281,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { lint::builtin::ASM_SUB_REGISTER, expr.hir_id, spans, - "formatting may not be suitable for sub-register argument", |lint| { + lint.primary_message("formatting may not be suitable for sub-register argument"); lint.span_label(expr.span, "for this argument"); lint.help(format!( "use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}` (for {suggested_size}-bit values)", diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index e8ede804c3f3..81e3d8c7ece2 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -675,11 +675,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable>>( let region_param = gat_generics.param_at(*region_a_idx, tcx); let region_param = ty::Region::new_early_param( tcx, - ty::EarlyParamRegion { - def_id: region_param.def_id, - index: region_param.index, - name: region_param.name, - }, + ty::EarlyParamRegion { index: region_param.index, name: region_param.name }, ); // The predicate we expect to see. (In our example, // `Self: 'me`.) @@ -708,21 +704,13 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable>>( let region_a_param = gat_generics.param_at(*region_a_idx, tcx); let region_a_param = ty::Region::new_early_param( tcx, - ty::EarlyParamRegion { - def_id: region_a_param.def_id, - index: region_a_param.index, - name: region_a_param.name, - }, + ty::EarlyParamRegion { index: region_a_param.index, name: region_a_param.name }, ); // Same for the region. let region_b_param = gat_generics.param_at(*region_b_idx, tcx); let region_b_param = ty::Region::new_early_param( tcx, - ty::EarlyParamRegion { - def_id: region_b_param.def_id, - index: region_b_param.index, - name: region_b_param.name, - }, + ty::EarlyParamRegion { index: region_b_param.index, name: region_b_param.name }, ); // The predicate we expect to see. bounds.insert( @@ -2101,16 +2089,14 @@ fn lint_redundant_lifetimes<'tcx>( } for &victim in &lifetimes[(idx + 1)..] { - // We should only have late-bound lifetimes of the `BrNamed` variety, - // since we get these signatures straight from `hir_lowering`. And any - // other regions (ReError/ReStatic/etc.) shouldn't matter, since we + // All region parameters should have a `DefId` available as: + // - Late-bound parameters should be of the`BrNamed` variety, + // since we get these signatures straight from `hir_lowering`. + // - Early-bound parameters unconditionally have a `DefId` available. + // + // Any other regions (ReError/ReStatic/etc.) shouldn't matter, since we // can't really suggest to remove them. - let (ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) - | ty::ReLateParam(ty::LateParamRegion { - bound_region: ty::BoundRegionKind::BrNamed(def_id, _), - .. - })) = victim.kind() - else { + let Some(def_id) = victim.opt_param_def_id(tcx, owner_id.to_def_id()) else { continue; }; diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index aa5db4f6aa7b..ed23dc2a827b 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -35,11 +35,12 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) { continue; } let (path, _) = item.expect_use(); - let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) { - format!("unused import: `{snippet}`") - } else { - "unused import".to_owned() - }; - tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, msg, |_| {}); + tcx.node_span_lint(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, |lint| { + if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) { + lint.primary_message(format!("unused import: `{snippet}`")); + } else { + lint.primary_message("unused import"); + } + }); } } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index b760b86a7bfb..40cd65b899e2 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -453,7 +453,6 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { poly_trait_ref, |_| { ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion { - def_id: item_def_id, index: 0, name: Symbol::intern(<_name), }) diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 6b41f79cf1e7..abdf85ad707b 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -317,8 +317,9 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { lint::builtin::INVALID_TYPE_PARAM_DEFAULT, param.hir_id, param.span, - TYPE_DEFAULT_NOT_ALLOWED, - |_| {}, + |lint| { + lint.primary_message(TYPE_DEFAULT_NOT_ALLOWED); + }, ); } Defaults::Deny => { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 606f16537678..072bb7279016 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -323,7 +323,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>( if let ty::ReEarlyParam(..) = *orig_lifetime { let dup_lifetime = ty::Region::new_early_param( tcx, - ty::EarlyParamRegion { def_id: param.def_id, index: param.index, name: param.name }, + ty::EarlyParamRegion { index: param.index, name: param.name }, ); let span = tcx.def_span(param.def_id); predicates.push(( diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 749f78e79201..7b67030836d1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -646,8 +646,9 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes( LATE_BOUND_LIFETIME_ARGUMENTS, args.args[0].hir_id(), multispan, - msg, - |_| {}, + |lint| { + lint.primary_message(msg); + }, ); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index d9d36f5299b5..997db338a43f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -72,8 +72,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag); diag.stash(self_ty.span, StashKey::TraitMissingMethod); } else { - let msg = "trait objects without an explicit `dyn` are deprecated"; - tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| { + tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, |lint| { + lint.primary_message("trait objects without an explicit `dyn` are deprecated"); if self_ty.span.can_be_used_for_suggestions() { lint.multipart_suggestion_verbose( "if this is an object-safe trait, use `dyn`", diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 4b1c0da6ce11..3f66f971b171 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -280,7 +280,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local()); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id]; - ty::Region::new_early_param(tcx, ty::EarlyParamRegion { def_id, index, name }) + ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name }) } Some(rbv::ResolvedArg::Free(scope, id)) => { @@ -1165,33 +1165,28 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let ty = self.lower_assoc_ty(span, assoc_ty_did, assoc_segment, bound); if let Some(variant_def_id) = variant_resolution { - tcx.node_span_lint( - AMBIGUOUS_ASSOCIATED_ITEMS, - hir_ref_id, - span, - "ambiguous associated item", - |lint| { - let mut could_refer_to = |kind: DefKind, def_id, also| { - let note_msg = format!( - "`{}` could{} refer to the {} defined here", - assoc_ident, - also, - tcx.def_kind_descr(kind, def_id) - ); - lint.span_note(tcx.def_span(def_id), note_msg); - }; - - could_refer_to(DefKind::Variant, variant_def_id, ""); - could_refer_to(DefKind::AssocTy, assoc_ty_did, " also"); - - lint.span_suggestion( - span, - "use fully-qualified syntax", - format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident), - Applicability::MachineApplicable, + tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| { + lint.primary_message("ambiguous associated item"); + let mut could_refer_to = |kind: DefKind, def_id, also| { + let note_msg = format!( + "`{}` could{} refer to the {} defined here", + assoc_ident, + also, + tcx.def_kind_descr(kind, def_id) ); - }, - ); + lint.span_note(tcx.def_span(def_id), note_msg); + }; + + could_refer_to(DefKind::Variant, variant_def_id, ""); + could_refer_to(DefKind::AssocTy, assoc_ty_did, " also"); + + lint.span_suggestion( + span, + "use fully-qualified syntax", + format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident), + Applicability::MachineApplicable, + ); + }); } Ok((ty, DefKind::AssocTy, assoc_ty_did)) } diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index d1e50e13894a..8fe81851f932 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -68,7 +68,6 @@ This API is completely unstable and subject to change. #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(never_type)] -#![feature(lazy_cell)] #![feature(slice_partition_dedup)] #![feature(try_blocks)] diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 11a1c65b7495..ebdc558282a9 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1871,11 +1871,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // If this is due to a block, then maybe we forgot a `return`/`break`. if due_to_block && let Some(expr) = expression - && let Some((parent_fn_decl, parent_id)) = fcx - .tcx - .hir() - .parent_iter(block_or_return_id) - .find_map(|(_, node)| Some((node.fn_decl()?, node.associated_body()?.0))) + && let Some(parent_fn_decl) = + fcx.tcx.hir().fn_decl_by_hir_id(fcx.tcx.local_def_id_to_hir_id(fcx.body_id)) { fcx.suggest_missing_break_or_return_expr( &mut err, @@ -1884,7 +1881,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { expected, found, block_or_return_id, - parent_id, + fcx.body_id, ); } diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 89f62577506f..0ba4bd090f5e 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -1741,7 +1741,11 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx } PatKind::Slice(before, ref slice, after) => { - let Some(element_ty) = place_with_id.place.ty().builtin_index() else { + let Some(element_ty) = self + .cx + .try_structurally_resolve_type(pat.span, place_with_id.place.ty()) + .builtin_index() + else { debug!("explicit index of non-indexable type {:?}", place_with_id); return Err(self .cx diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 074aca78933b..b40bb74d7be1 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -64,19 +64,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind); let msg = format!("unreachable {kind}"); - self.tcx().node_span_lint( - lint::builtin::UNREACHABLE_CODE, - id, - span, - msg.clone(), - |lint| { - lint.span_label(span, msg).span_label( - orig_span, - custom_note - .unwrap_or("any code following this expression is unreachable"), - ); - }, - ) + self.tcx().node_span_lint(lint::builtin::UNREACHABLE_CODE, id, span, |lint| { + lint.primary_message(msg.clone()); + lint.span_label(span, msg).span_label( + orig_span, + custom_note.unwrap_or("any code following this expression is unreachable"), + ); + }) } } } diff --git a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs index e9eab6969b34..3ee10f74d98a 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs @@ -91,11 +91,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { prelude_or_array_lint, self_expr.hir_id, self_expr.span, - format!( - "trait method `{}` will become ambiguous in Rust {edition}", - segment.ident.name - ), |lint| { + lint.primary_message(format!( + "trait method `{}` will become ambiguous in Rust {edition}", + segment.ident.name + )); + let sp = self_expr.span; let derefs = "*".repeat(pick.autoderefs); @@ -144,11 +145,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { prelude_or_array_lint, call_expr.hir_id, call_expr.span, - format!( - "trait method `{}` will become ambiguous in Rust {edition}", - segment.ident.name - ), |lint| { + lint.primary_message(format!( + "trait method `{}` will become ambiguous in Rust {edition}", + segment.ident.name + )); + let sp = call_expr.span; let trait_name = self.trait_path_or_bare_name( span, @@ -251,73 +253,67 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - self.tcx.node_span_lint( - RUST_2021_PRELUDE_COLLISIONS, - expr_id, - span, - format!( + self.tcx.node_span_lint(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| { + lint.primary_message(format!( "trait-associated function `{}` will become ambiguous in Rust 2021", method_name.name - ), - |lint| { - // "type" refers to either a type or, more likely, a trait from which - // the associated function or method is from. - let container_id = pick.item.container_id(self.tcx); - let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id); - let trait_generics = self.tcx.generics_of(container_id); + )); - let trait_name = - if trait_generics.own_params.len() <= trait_generics.has_self as usize { - trait_path - } else { - let counts = trait_generics.own_counts(); - format!( - "{}<{}>", - trait_path, + // "type" refers to either a type or, more likely, a trait from which + // the associated function or method is from. + let container_id = pick.item.container_id(self.tcx); + let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id); + let trait_generics = self.tcx.generics_of(container_id); + + let trait_name = + if trait_generics.own_params.len() <= trait_generics.has_self as usize { + trait_path + } else { + let counts = trait_generics.own_counts(); + format!( + "{}<{}>", + trait_path, + std::iter::repeat("'_") + .take(counts.lifetimes) + .chain(std::iter::repeat("_").take( + counts.types + counts.consts - trait_generics.has_self as usize + )) + .collect::>() + .join(", ") + ) + }; + + let mut self_ty_name = self_ty_span + .find_ancestor_inside(span) + .and_then(|span| self.sess().source_map().span_to_snippet(span).ok()) + .unwrap_or_else(|| self_ty.to_string()); + + // Get the number of generics the self type has (if an Adt) unless we can determine that + // the user has written the self type with generics already which we (naively) do by looking + // for a "<" in `self_ty_name`. + if !self_ty_name.contains('<') { + if let ty::Adt(def, _) = self_ty.kind() { + let generics = self.tcx.generics_of(def.did()); + if !generics.is_own_empty() { + let counts = generics.own_counts(); + self_ty_name += &format!( + "<{}>", std::iter::repeat("'_") .take(counts.lifetimes) - .chain(std::iter::repeat("_").take( - counts.types + counts.consts - trait_generics.has_self as usize - )) + .chain(std::iter::repeat("_").take(counts.types + counts.consts)) .collect::>() .join(", ") - ) - }; - - let mut self_ty_name = self_ty_span - .find_ancestor_inside(span) - .and_then(|span| self.sess().source_map().span_to_snippet(span).ok()) - .unwrap_or_else(|| self_ty.to_string()); - - // Get the number of generics the self type has (if an Adt) unless we can determine that - // the user has written the self type with generics already which we (naively) do by looking - // for a "<" in `self_ty_name`. - if !self_ty_name.contains('<') { - if let ty::Adt(def, _) = self_ty.kind() { - let generics = self.tcx.generics_of(def.did()); - if !generics.is_own_empty() { - let counts = generics.own_counts(); - self_ty_name += &format!( - "<{}>", - std::iter::repeat("'_") - .take(counts.lifetimes) - .chain( - std::iter::repeat("_").take(counts.types + counts.consts) - ) - .collect::>() - .join(", ") - ); - } + ); } } - lint.span_suggestion( - span, - "disambiguate the associated function", - format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,), - Applicability::MachineApplicable, - ); - }, - ); + } + lint.span_suggestion( + span, + "disambiguate the associated function", + format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,), + Applicability::MachineApplicable, + ); + }); } fn trait_path_or_bare_name( diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index e0a60337c3ba..97a74b55c535 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -395,8 +395,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // ambiguous. if let Some(bad_ty) = &steps.opt_bad_ty { if is_suggestion.0 { - // Ambiguity was encountered during a suggestion. Just keep going. - debug!("ProbeContext: encountered ambiguity in suggestion"); + // Ambiguity was encountered during a suggestion. There's really + // not much use in suggesting methods in this case. + return Err(MethodError::NoMatch(NoMatchData { + static_candidates: Vec::new(), + unsatisfied_predicates: Vec::new(), + out_of_scope_traits: Vec::new(), + similar_candidate: None, + mode, + })); } else if bad_ty.reached_raw_pointer && !self.tcx.features().arbitrary_self_types && !self.tcx.sess.at_least_rust_2018() @@ -408,8 +415,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint::builtin::TYVAR_BEHIND_RAW_POINTER, scope_expr_id, span, - "type annotations needed", - |_| {}, + |lint| { + lint.primary_message("type annotations needed"); + }, ); } else { // Ended up encountering a type variable when doing autoderef, @@ -1279,53 +1287,49 @@ impl<'tcx> Pick<'tcx> { return; } let def_kind = self.item.kind.as_def_kind(); - tcx.node_span_lint( - lint::builtin::UNSTABLE_NAME_COLLISIONS, - scope_expr_id, - span, - format!( + tcx.node_span_lint(lint::builtin::UNSTABLE_NAME_COLLISIONS, scope_expr_id, span, |lint| { + lint.primary_message(format!( "{} {} with this name may be added to the standard library in the future", tcx.def_kind_descr_article(def_kind, self.item.def_id), tcx.def_kind_descr(def_kind, self.item.def_id), - ), - |lint| { - match (self.item.kind, self.item.container) { - (ty::AssocKind::Fn, _) => { - // FIXME: This should be a `span_suggestion` instead of `help` - // However `self.span` only - // highlights the method name, so we can't use it. Also consider reusing - // the code from `report_method_error()`. - lint.help(format!( - "call with fully qualified syntax `{}(...)` to keep using the current \ + )); + + match (self.item.kind, self.item.container) { + (ty::AssocKind::Fn, _) => { + // FIXME: This should be a `span_suggestion` instead of `help` + // However `self.span` only + // highlights the method name, so we can't use it. Also consider reusing + // the code from `report_method_error()`. + lint.help(format!( + "call with fully qualified syntax `{}(...)` to keep using the current \ method", - tcx.def_path_str(self.item.def_id), - )); - } - (ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => { - let def_id = self.item.container_id(tcx); - lint.span_suggestion( - span, - "use the fully qualified path to the associated const", - format!( - "<{} as {}>::{}", - self.self_ty, - tcx.def_path_str(def_id), - self.item.name - ), - Applicability::MachineApplicable, - ); - } - _ => {} + tcx.def_path_str(self.item.def_id), + )); } - tcx.disabled_nightly_features( - lint, - Some(scope_expr_id), - self.unstable_candidates.iter().map(|(candidate, feature)| { - (format!(" `{}`", tcx.def_path_str(candidate.item.def_id)), *feature) - }), - ); - }, - ); + (ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => { + let def_id = self.item.container_id(tcx); + lint.span_suggestion( + span, + "use the fully qualified path to the associated const", + format!( + "<{} as {}>::{}", + self.self_ty, + tcx.def_path_str(def_id), + self.item.name + ), + Applicability::MachineApplicable, + ); + } + _ => {} + } + tcx.disabled_nightly_features( + lint, + Some(scope_expr_id), + self.unstable_candidates.iter().map(|(candidate, feature)| { + (format!(" `{}`", tcx.def_path_str(candidate.item.def_id)), *feature) + }), + ); + }); } } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index b9b220d5af8e..b37aba386196 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1950,15 +1950,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &unmentioned_fields.iter().map(|(_, i)| i).collect::>(), ); - self.tcx.node_span_lint(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, "some fields are not explicitly listed", |lint| { - lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns)); - lint.help( - "ensure that all fields are mentioned explicitly by adding the suggested fields", - ); - lint.note(format!( - "the pattern is of type `{ty}` and the `non_exhaustive_omitted_patterns` attribute was found", - )); - }); + self.tcx.node_span_lint(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, |lint| { + lint.primary_message("some fields are not explicitly listed"); + lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns)); + lint.help( + "ensure that all fields are mentioned explicitly by adding the suggested fields", + ); + lint.note(format!( + "the pattern is of type `{ty}` and the `non_exhaustive_omitted_patterns` attribute was found", + )); + }); } /// Returns a diagnostic reporting a struct pattern which does not mention some fields. diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index e29a410e2e54..466397817dae 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -955,8 +955,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint::builtin::RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, closure_hir_id, closure_head_span, - reasons.migration_message(), |lint| { + lint.primary_message(reasons.migration_message()); + for NeededMigration { var_hir_id, diagnostics_info } in &need_migrations { // Labels all the usage of the captured variable and why they are responsible // for migration being needed diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 8bb0dc39143c..a801001eaf98 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -5,6 +5,7 @@ use rustc_errors::{ MultiSpan, SubdiagMessageOp, Subdiagnostic, }; use rustc_hir as hir; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{walk_ty, Visitor}; use rustc_hir::FnRetTy; use rustc_macros::{Diagnostic, Subdiagnostic}; @@ -344,6 +345,7 @@ impl Subdiagnostic for LifetimeMismatchLabels { pub struct AddLifetimeParamsSuggestion<'a> { pub tcx: TyCtxt<'a>, + pub generic_param_scope: LocalDefId, pub sub: Region<'a>, pub ty_sup: &'a hir::Ty<'a>, pub ty_sub: &'a hir::Ty<'a>, @@ -357,7 +359,8 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> { _f: &F, ) { let mut mk_suggestion = || { - let Some(anon_reg) = self.tcx.is_suitable_region(self.sub) else { + let Some(anon_reg) = self.tcx.is_suitable_region(self.generic_param_scope, self.sub) + else { return false; }; diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index f0b336ca0461..4fbeb0ec1024 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -1,6 +1,7 @@ use crate::fluent_generated as fluent; use crate::infer::error_reporting::nice_region_error::find_anon_type; use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, SubdiagMessageOp, Subdiagnostic}; +use rustc_hir::def_id::LocalDefId; use rustc_middle::bug; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{symbol::kw, Span}; @@ -14,12 +15,15 @@ struct DescriptionCtx<'a> { impl<'a> DescriptionCtx<'a> { fn new<'tcx>( tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, region: ty::Region<'tcx>, alt_span: Option, ) -> Option { let (span, kind, arg) = match *region { - ty::ReEarlyParam(ref br) => { - let scope = region.free_region_binding_scope(tcx).expect_local(); + ty::ReEarlyParam(br) => { + let scope = tcx + .parent(tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id) + .expect_local(); let span = if let Some(param) = tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name)) { @@ -35,11 +39,12 @@ impl<'a> DescriptionCtx<'a> { } ty::ReLateParam(ref fr) => { if !fr.bound_region.is_named() - && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) + && let Some((ty, _)) = + find_anon_type(tcx, generic_param_scope, region, &fr.bound_region) { (Some(ty.span), "defined_here", String::new()) } else { - let scope = region.free_region_binding_scope(tcx).expect_local(); + let scope = fr.scope.expect_local(); match fr.bound_region { ty::BoundRegionKind::BrNamed(_, name) => { let span = if let Some(param) = tcx @@ -143,12 +148,17 @@ pub struct RegionExplanation<'a> { impl RegionExplanation<'_> { pub fn new<'tcx>( tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, region: ty::Region<'tcx>, alt_span: Option, prefix: PrefixKind, suffix: SuffixKind, ) -> Option { - Some(Self { desc: DescriptionCtx::new(tcx, region, alt_span)?, prefix, suffix }) + Some(Self { + desc: DescriptionCtx::new(tcx, generic_param_scope, region, alt_span)?, + prefix, + suffix, + }) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index e0894ed31bfc..7ab148e70a13 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -161,6 +161,7 @@ impl<'tcx> Deref for TypeErrCtxt<'_, 'tcx> { pub(super) fn note_and_explain_region<'tcx>( tcx: TyCtxt<'tcx>, err: &mut Diag<'_>, + generic_param_scope: LocalDefId, prefix: &str, region: ty::Region<'tcx>, suffix: &str, @@ -168,7 +169,7 @@ pub(super) fn note_and_explain_region<'tcx>( ) { let (description, span) = match *region { ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReStatic => { - msg_span_from_named_region(tcx, region, alt_span) + msg_span_from_named_region(tcx, generic_param_scope, region, alt_span) } ty::ReError(_) => return, @@ -187,23 +188,27 @@ pub(super) fn note_and_explain_region<'tcx>( fn explain_free_region<'tcx>( tcx: TyCtxt<'tcx>, err: &mut Diag<'_>, + generic_param_scope: LocalDefId, prefix: &str, region: ty::Region<'tcx>, suffix: &str, ) { - let (description, span) = msg_span_from_named_region(tcx, region, None); + let (description, span) = msg_span_from_named_region(tcx, generic_param_scope, region, None); label_msg_span(err, prefix, description, span, suffix); } fn msg_span_from_named_region<'tcx>( tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, region: ty::Region<'tcx>, alt_span: Option, ) -> (String, Option) { match *region { - ty::ReEarlyParam(ref br) => { - let scope = region.free_region_binding_scope(tcx).expect_local(); + ty::ReEarlyParam(br) => { + let scope = tcx + .parent(tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id) + .expect_local(); let span = if let Some(param) = tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name)) { @@ -220,21 +225,21 @@ fn msg_span_from_named_region<'tcx>( } ty::ReLateParam(ref fr) => { if !fr.bound_region.is_named() - && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) + && let Some((ty, _)) = + find_anon_type(tcx, generic_param_scope, region, &fr.bound_region) { ("the anonymous lifetime defined here".to_string(), Some(ty.span)) } else { - let scope = region.free_region_binding_scope(tcx).expect_local(); match fr.bound_region { ty::BoundRegionKind::BrNamed(_, name) => { let span = if let Some(param) = tcx .hir() - .get_generics(scope) + .get_generics(generic_param_scope) .and_then(|generics| generics.get_named(name)) { param.span } else { - tcx.def_span(scope) + tcx.def_span(generic_param_scope) }; let text = if name == kw::UnderscoreLifetime { "the anonymous lifetime as defined here".to_string() @@ -245,11 +250,11 @@ fn msg_span_from_named_region<'tcx>( } ty::BrAnon => ( "the anonymous lifetime as defined here".to_string(), - Some(tcx.def_span(scope)), + Some(tcx.def_span(generic_param_scope)), ), _ => ( format!("the lifetime `{region}` as defined here"), - Some(tcx.def_span(scope)), + Some(tcx.def_span(generic_param_scope)), ), } } @@ -302,6 +307,7 @@ fn label_msg_span( #[instrument(level = "trace", skip(tcx))] pub fn unexpected_hidden_region_diagnostic<'tcx>( tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, span: Span, hidden_ty: Ty<'tcx>, hidden_region: ty::Region<'tcx>, @@ -327,11 +333,12 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( explain_free_region( tcx, &mut err, + generic_param_scope, &format!("hidden type `{hidden_ty}` captures "), hidden_region, "", ); - if let Some(reg_info) = tcx.is_suitable_region(hidden_region) { + if let Some(reg_info) = tcx.is_suitable_region(generic_param_scope, hidden_region) { let fn_returns = tcx.return_type_impl_or_dyn_traits(reg_info.def_id); nice_region_error::suggest_new_region_bound( tcx, @@ -349,6 +356,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( explain_free_region( tcx, &mut err, + generic_param_scope, &format!("hidden type `{}` captures ", hidden_ty), hidden_region, "", @@ -376,6 +384,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( note_and_explain_region( tcx, &mut err, + generic_param_scope, &format!("hidden type `{hidden_ty}` captures "), hidden_region, "", @@ -450,7 +459,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { for error in errors { debug!("report_region_errors: error = {:?}", error); - guar = Some(if let Some(guar) = self.try_report_nice_region_error(&error) { + let e = if let Some(guar) = + self.try_report_nice_region_error(generic_param_scope, &error) + { guar } else { match error.clone() { @@ -463,9 +474,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // general bit of code that displays the error information RegionResolutionError::ConcreteFailure(origin, sub, sup) => { if sub.is_placeholder() || sup.is_placeholder() { - self.report_placeholder_failure(origin, sub, sup).emit() + self.report_placeholder_failure(generic_param_scope, origin, sub, sup) + .emit() } else { - self.report_concrete_failure(origin, sub, sup).emit() + self.report_concrete_failure(generic_param_scope, origin, sub, sup) + .emit() } } @@ -488,12 +501,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { _, ) => { if sub_r.is_placeholder() { - self.report_placeholder_failure(sub_origin, sub_r, sup_r).emit() + self.report_placeholder_failure( + generic_param_scope, + sub_origin, + sub_r, + sup_r, + ) + .emit() } else if sup_r.is_placeholder() { - self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit() + self.report_placeholder_failure( + generic_param_scope, + sup_origin, + sub_r, + sup_r, + ) + .emit() } else { self.report_sub_sup_conflict( - var_origin, sub_origin, sub_r, sup_origin, sup_r, + generic_param_scope, + var_origin, + sub_origin, + sub_r, + sup_origin, + sup_r, ) } } @@ -514,7 +544,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // value. let sub_r = self.tcx.lifetimes.re_erased; - self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit() + self.report_placeholder_failure( + generic_param_scope, + sup_origin, + sub_r, + sup_r, + ) + .emit() } RegionResolutionError::CannotNormalize(clause, origin) => { @@ -526,7 +562,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .emit() } } - }) + }; + + guar = Some(e) } guar.unwrap() @@ -2347,7 +2385,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { '_explain: { let (description, span) = match sub.kind() { ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => { - msg_span_from_named_region(self.tcx, sub, Some(span)) + msg_span_from_named_region(self.tcx, generic_param_scope, sub, Some(span)) } _ => (format!("lifetime `{sub}`"), Some(span)), }; @@ -2398,7 +2436,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let suggestion_scope = { let lifetime_scope = match sub.kind() { ty::ReStatic => hir::def_id::CRATE_DEF_ID, - _ => match self.tcx.is_suitable_region(sub) { + _ => match self.tcx.is_suitable_region(generic_param_scope, sub) { Some(info) => info.def_id, None => generic_param_scope, }, @@ -2410,7 +2448,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; let mut suggs = vec![]; - let lt_name = self.suggest_name_region(sub, &mut suggs); + let lt_name = self.suggest_name_region(generic_param_scope, sub, &mut suggs); if let Some((sp, has_lifetimes, open_paren_sp)) = type_param_sugg_span && suggestion_scope == type_scope @@ -2455,6 +2493,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { pub fn suggest_name_region( &self, + generic_param_scope: LocalDefId, lifetime: Region<'tcx>, add_lt_suggs: &mut Vec<(Span, String)>, ) -> String { @@ -2501,12 +2540,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - let (lifetime_def_id, lifetime_scope) = match self.tcx.is_suitable_region(lifetime) { - Some(info) if !lifetime.has_name() => { - (info.bound_region.get_id().unwrap().expect_local(), info.def_id) - } - _ => return lifetime.get_name_or_anon().to_string(), - }; + let (lifetime_def_id, lifetime_scope) = + match self.tcx.is_suitable_region(generic_param_scope, lifetime) { + Some(info) if !lifetime.has_name() => { + (info.bound_region.get_id().unwrap().expect_local(), info.def_id) + } + _ => return lifetime.get_name_or_anon().to_string(), + }; let new_lt = { let generics = self.tcx.generics_of(lifetime_scope); @@ -2557,6 +2597,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn report_sub_sup_conflict( &self, + generic_param_scope: LocalDefId, var_origin: RegionVariableOrigin, sub_origin: SubregionOrigin<'tcx>, sub_region: Region<'tcx>, @@ -2568,6 +2609,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { note_and_explain_region( self.tcx, &mut err, + generic_param_scope, "first, the lifetime cannot outlive ", sup_region, "...", @@ -2590,6 +2632,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { note_and_explain_region( self.tcx, &mut err, + generic_param_scope, "...but the lifetime must also be valid for ", sub_region, "...", @@ -2613,6 +2656,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { note_and_explain_region( self.tcx, &mut err, + generic_param_scope, "but, the lifetime must be valid for ", sub_region, "...", diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index 84bfa5b5af7f..cbeec591960b 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -13,6 +13,7 @@ use crate::infer::TyCtxt; use rustc_errors::Subdiagnostic; use rustc_errors::{Diag, ErrorGuaranteed}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::Ty; use rustc_middle::ty::Region; @@ -66,17 +67,17 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } // Determine whether the sub and sup consist of both anonymous (elided) regions. - let anon_reg_sup = self.tcx().is_suitable_region(sup)?; + let anon_reg_sup = self.tcx().is_suitable_region(self.generic_param_scope, sup)?; - let anon_reg_sub = self.tcx().is_suitable_region(sub)?; + let anon_reg_sub = self.tcx().is_suitable_region(self.generic_param_scope, sub)?; let scope_def_id_sup = anon_reg_sup.def_id; let bregion_sup = anon_reg_sup.bound_region; let scope_def_id_sub = anon_reg_sub.def_id; let bregion_sub = anon_reg_sub.bound_region; - let ty_sup = find_anon_type(self.tcx(), sup, &bregion_sup)?; + let ty_sup = find_anon_type(self.tcx(), self.generic_param_scope, sup, &bregion_sup)?; - let ty_sub = find_anon_type(self.tcx(), sub, &bregion_sub)?; + let ty_sub = find_anon_type(self.tcx(), self.generic_param_scope, sub, &bregion_sub)?; debug!( "try_report_anon_anon_conflict: found_param1={:?} sup={:?} br1={:?}", @@ -127,8 +128,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { }, }; - let suggestion = - AddLifetimeParamsSuggestion { tcx: self.tcx(), sub, ty_sup, ty_sub, add_note: true }; + let suggestion = AddLifetimeParamsSuggestion { + tcx: self.tcx(), + sub, + ty_sup, + ty_sub, + add_note: true, + generic_param_scope: self.generic_param_scope, + }; let err = LifetimeMismatch { span, labels, suggestion }; let reported = self.tcx().dcx().emit_err(err); Some(reported) @@ -139,11 +146,19 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// removed in favour of public_errors::AddLifetimeParamsSuggestion pub fn suggest_adding_lifetime_params<'tcx>( tcx: TyCtxt<'tcx>, + err: &mut Diag<'_>, + generic_param_scope: LocalDefId, sub: Region<'tcx>, ty_sup: &'tcx Ty<'_>, ty_sub: &'tcx Ty<'_>, - err: &mut Diag<'_>, ) { - let suggestion = AddLifetimeParamsSuggestion { tcx, sub, ty_sup, ty_sub, add_note: false }; + let suggestion = AddLifetimeParamsSuggestion { + tcx, + sub, + ty_sup, + ty_sub, + add_note: false, + generic_param_scope, + }; suggestion.add_to_diag(err); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs index 265a315a5597..b91b755d6837 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -1,5 +1,6 @@ use core::ops::ControlFlow; use rustc_hir as hir; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter; @@ -23,10 +24,11 @@ use rustc_middle::ty::{self, Region, TyCtxt}; /// for e.g., `&u8` and `Vec<&u8>`. pub fn find_anon_type<'tcx>( tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, region: Region<'tcx>, br: &ty::BoundRegionKind, ) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnSig<'tcx>)> { - let anon_reg = tcx.is_suitable_region(region)?; + let anon_reg = tcx.is_suitable_region(generic_param_scope, region)?; let fn_sig = tcx.hir_node_by_def_id(anon_reg.def_id).fn_sig()?; fn_sig diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index 45dce0a0e330..7996b4bf65b4 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -57,6 +57,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let expl = note_and_explain::RegionExplanation::new( self.tcx(), + self.generic_param_scope, sup, Some(binding_span), note_and_explain::PrefixKind::Empty, diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs index 62c163f0b7f6..cffdfa887523 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs @@ -2,6 +2,7 @@ use crate::infer::error_reporting::TypeErrCtxt; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::lexical_region_resolve::RegionResolutionError::*; use rustc_errors::{Diag, ErrorGuaranteed}; +use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::Span; @@ -23,30 +24,39 @@ pub use util::find_param_with_region; impl<'cx, 'tcx> TypeErrCtxt<'cx, 'tcx> { pub fn try_report_nice_region_error( &'cx self, + generic_param_scope: LocalDefId, error: &RegionResolutionError<'tcx>, ) -> Option { - NiceRegionError::new(self, error.clone()).try_report() + NiceRegionError::new(self, generic_param_scope, error.clone()).try_report() } } pub struct NiceRegionError<'cx, 'tcx> { cx: &'cx TypeErrCtxt<'cx, 'tcx>, + /// The innermost definition that introduces generic parameters that may be involved in + /// the region errors we are dealing with. + generic_param_scope: LocalDefId, error: Option>, regions: Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)>, } impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> { - pub fn new(cx: &'cx TypeErrCtxt<'cx, 'tcx>, error: RegionResolutionError<'tcx>) -> Self { - Self { cx, error: Some(error), regions: None } + pub fn new( + cx: &'cx TypeErrCtxt<'cx, 'tcx>, + generic_param_scope: LocalDefId, + error: RegionResolutionError<'tcx>, + ) -> Self { + Self { cx, error: Some(error), regions: None, generic_param_scope } } pub fn new_from_span( cx: &'cx TypeErrCtxt<'cx, 'tcx>, + generic_param_scope: LocalDefId, span: Span, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>, ) -> Self { - Self { cx, error: None, regions: Some((span, sub, sup)) } + Self { cx, error: None, regions: Some((span, sub, sup)), generic_param_scope } } fn tcx(&self) -> TyCtxt<'tcx> { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 239c2db30e2d..29da12e7d151 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -27,12 +27,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // version new_ty of its type where the anonymous region is replaced // with the named one. let (named, anon, anon_param_info, region_info) = if sub.has_name() - && let Some(region_info) = self.tcx().is_suitable_region(sup) + && let Some(region_info) = self.tcx().is_suitable_region(self.generic_param_scope, sup) && let Some(anon_param_info) = self.find_param_with_region(sup, sub) { (sub, sup, anon_param_info, region_info) } else if sup.has_name() - && let Some(region_info) = self.tcx().is_suitable_region(sub) + && let Some(region_info) = self.tcx().is_suitable_region(self.generic_param_scope, sub) && let Some(anon_param_info) = self.find_param_with_region(sub, sup) { (sup, sub, anon_param_info, region_info) @@ -72,7 +72,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { return None; } - if find_anon_type(self.tcx(), anon, &br).is_some() + if find_anon_type(self.tcx(), self.generic_param_scope, anon, &br).is_some() && self.is_self_anon(is_first, scope_def_id) { return None; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 8a1e3a7ac71b..71a86683c212 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -49,7 +49,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { if let ObligationCauseCode::UnifyReceiver(ctxt) = cause.code() { // This may have a closure and it would cause ICE // through `find_param_with_region` (#78262). - let anon_reg_sup = tcx.is_suitable_region(*sup_r)?; + let anon_reg_sup = tcx.is_suitable_region(self.generic_param_scope, *sup_r)?; let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id); if fn_returns.is_empty() { return None; @@ -92,7 +92,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { "try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})", var_origin, sub_origin, sub_r, sup_origin, sup_r ); - let anon_reg_sup = tcx.is_suitable_region(*sup_r)?; + let anon_reg_sup = tcx.is_suitable_region(self.generic_param_scope, *sup_r)?; debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup); let sp = var_origin.span(); let return_sp = sub_origin.span(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index f1f8314661f3..5f3f1081ca8f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -37,13 +37,15 @@ pub struct AnonymousParamInfo<'tcx> { #[instrument(skip(tcx), level = "debug")] pub fn find_param_with_region<'tcx>( tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, anon_region: Region<'tcx>, replace_region: Region<'tcx>, ) -> Option> { let (id, bound_region) = match *anon_region { ty::ReLateParam(late_param) => (late_param.scope, late_param.bound_region), ty::ReEarlyParam(ebr) => { - (tcx.parent(ebr.def_id), ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name)) + let region_def = tcx.generics_of(generic_param_scope).region_param(ebr, tcx).def_id; + (tcx.parent(region_def), ty::BoundRegionKind::BrNamed(region_def, ebr.name)) } _ => return None, // not a free region }; @@ -53,7 +55,7 @@ pub fn find_param_with_region<'tcx>( // FIXME: use def_kind // Don't perform this on closures - match tcx.hir_node_by_def_id(def_id) { + match tcx.hir_node_by_def_id(generic_param_scope) { hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => { return None; } @@ -110,7 +112,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { anon_region: Region<'tcx>, replace_region: Region<'tcx>, ) -> Option> { - find_param_with_region(self.tcx(), anon_region, replace_region) + find_param_with_region(self.tcx(), self.generic_param_scope, anon_region, replace_region) } // Here, we check for the case where the anonymous region diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 00dd20a2cc27..acb74f8a82ce 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -75,6 +75,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { pub(super) fn report_concrete_failure( &self, + generic_param_scope: LocalDefId, origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx>, @@ -89,6 +90,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { note_and_explain_region( self.tcx, &mut err, + generic_param_scope, "", sup, " doesn't meet the lifetime requirements", @@ -99,6 +101,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { note_and_explain_region( self.tcx, &mut err, + generic_param_scope, "the required lifetime does not necessarily outlive ", sub, "", @@ -106,10 +109,19 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); } _ => { - note_and_explain_region(self.tcx, &mut err, "", sup, "...", None); note_and_explain_region( self.tcx, &mut err, + generic_param_scope, + "", + sup, + "...", + None, + ); + note_and_explain_region( + self.tcx, + &mut err, + generic_param_scope, "...does not necessarily outlive ", sub, "", @@ -122,6 +134,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::Reborrow(span) => { let reference_valid = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sub, None, note_and_explain::PrefixKind::RefValidFor, @@ -129,6 +142,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); let content_valid = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sup, None, note_and_explain::PrefixKind::ContentValidFor, @@ -142,6 +156,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::RelateObjectBound(span) => { let object_valid = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sub, None, note_and_explain::PrefixKind::TypeObjValidFor, @@ -149,6 +164,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); let pointer_valid = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sup, None, note_and_explain::PrefixKind::SourcePointerValidFor, @@ -170,7 +186,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { note_and_explain::SuffixKind::Empty }; let note = note_and_explain::RegionExplanation::new( - self.tcx, sub, opt_span, prefix, suffix, + self.tcx, + generic_param_scope, + sub, + opt_span, + prefix, + suffix, ); self.dcx().create_err(FulfillReqLifetime { span, @@ -181,6 +202,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::RelateRegionParamBound(span) => { let param_instantiated = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sup, None, note_and_explain::PrefixKind::LfParamInstantiatedWith, @@ -188,6 +210,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); let param_must_outlive = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sub, None, note_and_explain::PrefixKind::LfParamMustOutlive, @@ -201,6 +224,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::ReferenceOutlivesReferent(ty, span) => { let pointer_valid = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sub, None, note_and_explain::PrefixKind::PointerValidFor, @@ -208,6 +232,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); let data_valid = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sup, None, note_and_explain::PrefixKind::DataValidFor, @@ -239,7 +264,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err } infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => { - let mut err = self.report_concrete_failure(*parent, sub, sup); + let mut err = self.report_concrete_failure(generic_param_scope, *parent, sub, sup); // Don't mention the item name if it's an RPITIT, since that'll just confuse // folks. @@ -262,6 +287,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::AscribeUserTypeProvePredicate(span) => { let instantiated = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sup, None, note_and_explain::PrefixKind::LfInstantiatedWith, @@ -269,6 +295,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); let must_outlive = note_and_explain::RegionExplanation::new( self.tcx, + generic_param_scope, sub, None, note_and_explain::PrefixKind::LfMustOutlive, @@ -347,6 +374,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { pub(super) fn report_placeholder_failure( &self, + generic_param_scope: LocalDefId, placeholder_origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx>, @@ -368,7 +396,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { && !span.is_dummy() { let span = *span; - self.report_concrete_failure(placeholder_origin, sub, sup) + self.report_concrete_failure(generic_param_scope, placeholder_origin, sub, sup) .with_span_note(span, "the lifetime requirement is introduced here") } else { unreachable!( @@ -380,7 +408,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let terr = TypeError::RegionsPlaceholderMismatch; return self.report_and_explain_type_error(trace, terr); } - _ => return self.report_concrete_failure(placeholder_origin, sub, sup), + _ => { + return self.report_concrete_failure( + generic_param_scope, + placeholder_origin, + sub, + sup, + ); + } } } } diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 101598c59512..7e7d4f43c7cc 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -22,11 +22,11 @@ use super::glb::Glb; use super::lub::Lub; use super::type_relating::TypeRelating; use super::StructurallyRelateAliases; -use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace}; +use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, TypeTrace}; use crate::traits::{Obligation, PredicateObligations}; use rustc_middle::bug; -use rustc_middle::infer::canonical::OriginalQueryValues; use rustc_middle::infer::unify_key::EffectVarValue; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::relate::{RelateResult, TypeRelation}; use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast}; @@ -159,36 +159,11 @@ impl<'tcx> InferCtxt<'tcx> { let a = self.shallow_resolve_const(a); let b = self.shallow_resolve_const(b); - // We should never have to relate the `ty` field on `Const` as it is checked elsewhere that consts have the - // correct type for the generic param they are an argument for. However there have been a number of cases - // historically where asserting that the types are equal has found bugs in the compiler so this is valuable - // to check even if it is a bit nasty impl wise :( - // - // This probe is probably not strictly necessary but it seems better to be safe and not accidentally find - // ourselves with a check to find bugs being required for code to compile because it made inference progress. - self.probe(|_| { - if a.ty() == b.ty() { - return; - } - - // We don't have access to trait solving machinery in `rustc_infer` so the logic for determining if the - // two const param's types are able to be equal has to go through a canonical query with the actual logic - // in `rustc_trait_selection`. - let canonical = self.canonicalize_query( - relation.param_env().and((a.ty(), b.ty())), - &mut OriginalQueryValues::default(), - ); - self.tcx.check_tys_might_be_eq(canonical).unwrap_or_else(|_| { - // The error will only be reported later. If we emit an ErrorGuaranteed - // here, then we will never get to the code that actually emits the error. - self.tcx.dcx().delayed_bug(format!( - "cannot relate consts of different types (a={a:?}, b={b:?})", - )); - // We treat these constants as if they were of the same type, so that any - // such constants being used in impls make these impls match barring other mismatches. - // This helps with diagnostics down the road. - }); - }); + // It is always an error if the types of two constants that are related are not equal. + let InferOk { value: (), obligations } = self + .at(&ObligationCause::dummy_with_span(relation.span()), relation.param_env()) + .eq(DefineOpaqueTypes::No, a.ty(), b.ty())?; + relation.register_obligations(obligations); match (a.kind(), b.kind()) { ( diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index c1d460ddd086..8b1d9b706cac 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -1,5 +1,4 @@ #![feature(decl_macro)] -#![feature(lazy_cell)] #![feature(let_chains)] #![feature(thread_spawn_unchecked)] #![feature(try_blocks)] diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 36f9dda7250c..c6cf7cf4f3f7 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -799,10 +799,7 @@ fn test_unstable_options_tracking_hash() { tracked!(mir_opt_level, Some(4)); tracked!(move_size_limit, Some(4096)); tracked!(mutable_noalias, false); - tracked!( - next_solver, - Some(NextSolverConfig { coherence: true, globally: false, dump_tree: Default::default() }) - ); + tracked!(next_solver, Some(NextSolverConfig { coherence: true, globally: false })); tracked!(no_generate_arange_section, true); tracked!(no_jump_tables, true); tracked!(no_link, true); diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 85d54ce563d2..ba42eae34415 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1950,14 +1950,22 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN impl ExplicitOutlivesRequirements { fn lifetimes_outliving_lifetime<'tcx>( + tcx: TyCtxt<'tcx>, inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)], - def_id: DefId, + item: DefId, + lifetime: DefId, ) -> Vec> { + let item_generics = tcx.generics_of(item); + inferred_outlives .iter() .filter_map(|(clause, _)| match clause.kind().skip_binder() { ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a { - ty::ReEarlyParam(ebr) if ebr.def_id == def_id => Some(b), + ty::ReEarlyParam(ebr) + if item_generics.region_param(ebr, tcx).def_id == lifetime => + { + Some(b) + } _ => None, }, _ => None, @@ -1986,9 +1994,12 @@ impl ExplicitOutlivesRequirements { bounds: &hir::GenericBounds<'_>, inferred_outlives: &[ty::Region<'tcx>], predicate_span: Span, + item: DefId, ) -> Vec<(usize, Span)> { use rustc_middle::middle::resolve_bound_vars::ResolvedArg; + let item_generics = tcx.generics_of(item); + bounds .iter() .enumerate() @@ -2000,7 +2011,7 @@ impl ExplicitOutlivesRequirements { let is_inferred = match tcx.named_bound_var(lifetime.hir_id) { Some(ResolvedArg::EarlyBound(def_id)) => inferred_outlives .iter() - .any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { ebr.def_id == def_id })), + .any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { item_generics.region_param(ebr, tcx).def_id == def_id })), _ => false, }; @@ -2109,7 +2120,9 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { { ( Self::lifetimes_outliving_lifetime( + cx.tcx, inferred_outlives, + item.owner_id.to_def_id(), region_def_id, ), &predicate.bounds, @@ -2152,6 +2165,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { bounds, &relevant_lifetimes, predicate_span, + item.owner_id.to_def_id(), ); bound_count += bound_spans.len(); diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index c23a67f61316..56f07a2b5e99 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -21,7 +21,7 @@ use crate::passes::{EarlyLintPassObject, LateLintPassObject}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync; use rustc_data_structures::unord::UnordMap; -use rustc_errors::{Diag, DiagMessage, LintDiagnostic, MultiSpan}; +use rustc_errors::{Diag, LintDiagnostic, MultiSpan}; use rustc_feature::Features; use rustc_hir as hir; use rustc_hir::def::Res; @@ -539,7 +539,9 @@ impl EarlyContext<'_> { span: MultiSpan, diagnostic: BuiltinLintDiag, ) { - diagnostics::emit_buffered_lint(self, lint, span, diagnostic) + self.opt_span_lint(lint, Some(span), |diag| { + diagnostics::decorate_lint(self.sess(), diagnostic, diag); + }); } } @@ -556,7 +558,6 @@ pub trait LintContext { &self, lint: &'static Lint, span: Option, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ); @@ -568,8 +569,8 @@ pub trait LintContext { span: S, decorator: impl for<'a> LintDiagnostic<'a, ()>, ) { - self.opt_span_lint(lint, Some(span), decorator.msg(), |diag| { - decorator.decorate_lint(diag); + self.opt_span_lint(lint, Some(span), |lint| { + decorator.decorate_lint(lint); }); } @@ -581,17 +582,16 @@ pub trait LintContext { &self, lint: &'static Lint, span: S, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { - self.opt_span_lint(lint, Some(span), msg, decorate); + self.opt_span_lint(lint, Some(span), decorate); } /// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically /// generated by `#[derive(LintDiagnostic)]`). fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> LintDiagnostic<'a, ()>) { - self.opt_span_lint(lint, None as Option, decorator.msg(), |diag| { - decorator.decorate_lint(diag); + self.opt_span_lint(lint, None as Option, |lint| { + decorator.decorate_lint(lint); }); } @@ -599,13 +599,8 @@ pub trait LintContext { /// /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature #[rustc_lint_diagnostics] - fn lint( - &self, - lint: &'static Lint, - msg: impl Into, - decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), - ) { - self.opt_span_lint(lint, None as Option, msg, decorate); + fn lint(&self, lint: &'static Lint, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>)) { + self.opt_span_lint(lint, None as Option, decorate); } /// This returns the lint level for the given lint at the current location. @@ -668,14 +663,13 @@ impl<'tcx> LintContext for LateContext<'tcx> { &self, lint: &'static Lint, span: Option, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { let hir_id = self.last_node_with_lint_attrs; match span { - Some(s) => self.tcx.node_span_lint(lint, hir_id, s, msg, decorate), - None => self.tcx.node_lint(lint, hir_id, msg, decorate), + Some(s) => self.tcx.node_span_lint(lint, hir_id, s, decorate), + None => self.tcx.node_lint(lint, hir_id, decorate), } } @@ -695,10 +689,9 @@ impl LintContext for EarlyContext<'_> { &self, lint: &'static Lint, span: Option, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { - self.builder.opt_span_lint(lint, span.map(|s| s.into()), msg, decorate) + self.builder.opt_span_lint(lint, span.map(|s| s.into()), decorate) } fn get_lint_level(&self, lint: &'static Lint) -> Level { diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index 23c5e0a9f5fa..26f34486a3de 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -4,24 +4,19 @@ use std::borrow::Cow; use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; -use rustc_errors::Applicability; -use rustc_errors::{elided_lifetime_in_path_suggestion, DiagArgValue, MultiSpan}; +use rustc_errors::elided_lifetime_in_path_suggestion; +use rustc_errors::{Applicability, Diag, DiagArgValue, LintDiagnostic}; use rustc_middle::middle::stability; -use rustc_session::lint::{BuiltinLintDiag, Lint}; +use rustc_session::lint::BuiltinLintDiag; +use rustc_session::Session; use rustc_span::BytePos; use tracing::debug; -use crate::{lints, EarlyContext, LintContext as _}; +use crate::lints; mod check_cfg; -pub(super) fn emit_buffered_lint( - ctx: &EarlyContext<'_>, - lint: &'static Lint, - span: MultiSpan, - diagnostic: BuiltinLintDiag, -) { - let sess = ctx.sess(); +pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) { match diagnostic { BuiltinLintDiag::UnicodeTextFlow(comment_span, content) => { let spans: Vec<_> = content @@ -40,16 +35,14 @@ pub(super) fn emit_buffered_lint( let suggestions = (!spans.is_empty()).then_some(lints::UnicodeTextFlowSuggestion { spans: spans.iter().map(|(_c, span)| *span).collect(), }); - ctx.emit_span_lint( - lint, - span, - lints::UnicodeTextFlow { - comment_span, - characters, - suggestions, - num_codepoints: spans.len(), - }, - ) + + lints::UnicodeTextFlow { + comment_span, + characters, + suggestions, + num_codepoints: spans.len(), + } + .decorate_lint(diag); } BuiltinLintDiag::AbsPathWithModule(mod_span) => { let (replacement, applicability) = match sess.source_map().span_to_snippet(mod_span) { @@ -62,48 +55,35 @@ pub(super) fn emit_buffered_lint( } Err(_) => ("crate::".to_string(), Applicability::HasPlaceholders), }; - ctx.emit_span_lint( - lint, - span, - lints::AbsPathWithModule { - sugg: lints::AbsPathWithModuleSugg { - span: mod_span, - applicability, - replacement, - }, - }, - ); + lints::AbsPathWithModule { + sugg: lints::AbsPathWithModuleSugg { span: mod_span, applicability, replacement }, + } + .decorate_lint(diag); } - BuiltinLintDiag::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident } => ctx - .emit_span_lint( - lint, - span, - lints::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident }, - ), - BuiltinLintDiag::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => ctx - .emit_span_lint( - lint, - span, - lints::MacroExpandedMacroExportsAccessedByAbsolutePaths { definition: span_def }, - ), + BuiltinLintDiag::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident } => { + lints::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident } + .decorate_lint(diag) + } + BuiltinLintDiag::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => { + lints::MacroExpandedMacroExportsAccessedByAbsolutePaths { definition: span_def } + .decorate_lint(diag) + } + BuiltinLintDiag::ElidedLifetimesInPaths(n, path_span, incl_angl_brckt, insertion_span) => { - ctx.emit_span_lint( - lint, - span, - lints::ElidedLifetimesInPaths { - subdiag: elided_lifetime_in_path_suggestion( - sess.source_map(), - n, - path_span, - incl_angl_brckt, - insertion_span, - ), - }, - ); + lints::ElidedLifetimesInPaths { + subdiag: elided_lifetime_in_path_suggestion( + sess.source_map(), + n, + path_span, + incl_angl_brckt, + insertion_span, + ), + } + .decorate_lint(diag); } BuiltinLintDiag::UnknownCrateTypes { span, candidate } => { let sugg = candidate.map(|candidate| lints::UnknownCrateTypesSub { span, candidate }); - ctx.emit_span_lint(lint, span, lints::UnknownCrateTypes { sugg }); + lints::UnknownCrateTypes { sugg }.decorate_lint(diag); } BuiltinLintDiag::UnusedImports { remove_whole_use, @@ -120,18 +100,15 @@ pub(super) fn emit_buffered_lint( let test_module_span = test_module_span.map(|span| sess.source_map().guess_head_span(span)); - ctx.emit_span_lint( - lint, - span, - lints::UnusedImports { - sugg, - test_module_span, - num_snippets: span_snippets.len(), - span_snippets: DiagArgValue::StrListSepByAnd( - span_snippets.into_iter().map(Cow::Owned).collect(), - ), - }, - ); + lints::UnusedImports { + sugg, + test_module_span, + num_snippets: span_snippets.len(), + span_snippets: DiagArgValue::StrListSepByAnd( + span_snippets.into_iter().map(Cow::Owned).collect(), + ), + } + .decorate_lint(diag); } BuiltinLintDiag::RedundantImport(spans, ident) => { let subs = spans @@ -145,7 +122,7 @@ pub(super) fn emit_buffered_lint( })(span) }) .collect(); - ctx.emit_span_lint(lint, span, lints::RedundantImport { subs, ident }); + lints::RedundantImport { subs, ident }.decorate_lint(diag); } BuiltinLintDiag::DeprecatedMacro { suggestion, @@ -159,90 +136,63 @@ pub(super) fn emit_buffered_lint( kind: "macro".to_owned(), suggestion, }); - ctx.emit_span_lint( - lint, - span, - stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind }, - ); + + stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind } + .decorate_lint(diag); } BuiltinLintDiag::UnusedDocComment(attr_span) => { - ctx.emit_span_lint(lint, span, lints::UnusedDocComment { span: attr_span }); + lints::UnusedDocComment { span: attr_span }.decorate_lint(diag); } BuiltinLintDiag::PatternsInFnsWithoutBody { span: remove_span, ident, is_foreign } => { let sub = lints::PatternsInFnsWithoutBodySub { ident, span: remove_span }; - - ctx.emit_span_lint( - lint, - span, - if is_foreign { - lints::PatternsInFnsWithoutBody::Foreign { sub } - } else { - lints::PatternsInFnsWithoutBody::Bodiless { sub } - }, - ); + if is_foreign { + lints::PatternsInFnsWithoutBody::Foreign { sub } + } else { + lints::PatternsInFnsWithoutBody::Bodiless { sub } + } + .decorate_lint(diag); } BuiltinLintDiag::MissingAbi(label_span, default_abi) => { - ctx.emit_span_lint( - lint, - span, - lints::MissingAbi { span: label_span, default_abi: default_abi.name() }, - ); + lints::MissingAbi { span: label_span, default_abi: default_abi.name() } + .decorate_lint(diag); } BuiltinLintDiag::LegacyDeriveHelpers(label_span) => { - ctx.emit_span_lint(lint, span, lints::LegacyDeriveHelpers { span: label_span }); + lints::LegacyDeriveHelpers { span: label_span }.decorate_lint(diag); } BuiltinLintDiag::ProcMacroBackCompat { crate_name, fixed_version } => { - ctx.emit_span_lint( - lint, - span, - lints::ProcMacroBackCompat { crate_name, fixed_version }, - ); + lints::ProcMacroBackCompat { crate_name, fixed_version }.decorate_lint(diag); } BuiltinLintDiag::OrPatternsBackCompat(suggestion_span, suggestion) => { - ctx.emit_span_lint( - lint, - span, - lints::OrPatternsBackCompat { span: suggestion_span, suggestion }, - ); + lints::OrPatternsBackCompat { span: suggestion_span, suggestion }.decorate_lint(diag); } BuiltinLintDiag::ReservedPrefix(label_span, prefix) => { - ctx.emit_span_lint( - lint, - span, - lints::ReservedPrefix { - label: label_span, - suggestion: label_span.shrink_to_hi(), - prefix, - }, - ); + lints::ReservedPrefix { + label: label_span, + suggestion: label_span.shrink_to_hi(), + prefix, + } + .decorate_lint(diag); } BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, macro_name, invoc_span } => { - ctx.emit_span_lint( - lint, - span, - lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name }, - ); + lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name }.decorate_lint(diag); } BuiltinLintDiag::TrailingMacro(is_trailing, name) => { - ctx.emit_span_lint(lint, span, lints::TrailingMacro { is_trailing, name }); + lints::TrailingMacro { is_trailing, name }.decorate_lint(diag); } BuiltinLintDiag::BreakWithLabelAndLoop(sugg_span) => { - ctx.emit_span_lint( - lint, - span, - lints::BreakWithLabelAndLoop { - sub: lints::BreakWithLabelAndLoopSub { - left: sugg_span.shrink_to_lo(), - right: sugg_span.shrink_to_hi(), - }, + lints::BreakWithLabelAndLoop { + sub: lints::BreakWithLabelAndLoopSub { + left: sugg_span.shrink_to_lo(), + right: sugg_span.shrink_to_hi(), }, - ); + } + .decorate_lint(diag); } BuiltinLintDiag::UnexpectedCfgName(name, value) => { - ctx.emit_span_lint(lint, span, check_cfg::unexpected_cfg_name(sess, name, value)); + check_cfg::unexpected_cfg_name(sess, name, value).decorate_lint(diag); } BuiltinLintDiag::UnexpectedCfgValue(name, value) => { - ctx.emit_span_lint(lint, span, check_cfg::unexpected_cfg_value(sess, name, value)); + check_cfg::unexpected_cfg_value(sess, name, value).decorate_lint(diag); } BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => { let suggestion = match sugg { @@ -253,7 +203,7 @@ pub(super) fn emit_buffered_lint( }, None => lints::DeprecatedWhereClauseLocationSugg::RemoveWhere { span: left_sp }, }; - ctx.emit_span_lint(lint, span, lints::DeprecatedWhereClauseLocation { suggestion }); + lints::DeprecatedWhereClauseLocation { suggestion }.decorate_lint(diag); } BuiltinLintDiag::SingleUseLifetime { param_span, @@ -280,15 +230,12 @@ pub(super) fn emit_buffered_lint( None }; - ctx.emit_span_lint( - lint, - span, - lints::SingleUseLifetime { suggestion, param_span, use_span, ident }, - ); + lints::SingleUseLifetime { suggestion, param_span, use_span, ident } + .decorate_lint(diag); } BuiltinLintDiag::SingleUseLifetime { use_span: None, deletion_span, ident, .. } => { debug!(?deletion_span); - ctx.emit_span_lint(lint, span, lints::UnusedLifetime { deletion_span, ident }); + lints::UnusedLifetime { deletion_span, ident }.decorate_lint(diag); } BuiltinLintDiag::NamedArgumentUsedPositionally { position_sp_to_replace, @@ -316,35 +263,29 @@ pub(super) fn emit_buffered_lint( (None, String::new()) }; - ctx.emit_span_lint( - lint, - span, - lints::NamedArgumentUsedPositionally { - named_arg_sp, - position_label_sp: position_sp_for_msg, - suggestion, - name, - named_arg_name, - }, - ) + lints::NamedArgumentUsedPositionally { + named_arg_sp, + position_label_sp: position_sp_for_msg, + suggestion, + name, + named_arg_name, + } + .decorate_lint(diag); } BuiltinLintDiag::ByteSliceInPackedStructWithDerive { ty } => { - ctx.emit_span_lint(lint, span, lints::ByteSliceInPackedStructWithDerive { ty }) + lints::ByteSliceInPackedStructWithDerive { ty }.decorate_lint(diag); } BuiltinLintDiag::UnusedExternCrate { removal_span } => { - ctx.emit_span_lint(lint, span, lints::UnusedExternCrate { removal_span }) + lints::UnusedExternCrate { removal_span }.decorate_lint(diag); } BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span } => { let suggestion_span = vis_span.between(ident_span); let code = if vis_span.is_empty() { "use " } else { " use " }; - ctx.emit_span_lint( - lint, - span, - lints::ExternCrateNotIdiomatic { span: suggestion_span, code }, - ); + + lints::ExternCrateNotIdiomatic { span: suggestion_span, code }.decorate_lint(diag); } BuiltinLintDiag::AmbiguousGlobImports { diag: ambiguity } => { - ctx.emit_span_lint(lint, span, lints::AmbiguousGlobImports { ambiguity }); + lints::AmbiguousGlobImports { ambiguity }.decorate_lint(diag); } BuiltinLintDiag::AmbiguousGlobReexports { name, @@ -352,16 +293,13 @@ pub(super) fn emit_buffered_lint( first_reexport_span, duplicate_reexport_span, } => { - ctx.emit_span_lint( - lint, - span, - lints::AmbiguousGlobReexports { - first_reexport: first_reexport_span, - duplicate_reexport: duplicate_reexport_span, - name, - namespace, - }, - ); + lints::AmbiguousGlobReexports { + first_reexport: first_reexport_span, + duplicate_reexport: duplicate_reexport_span, + name, + namespace, + } + .decorate_lint(diag); } BuiltinLintDiag::HiddenGlobReexports { name, @@ -369,127 +307,112 @@ pub(super) fn emit_buffered_lint( glob_reexport_span, private_item_span, } => { - ctx.emit_span_lint( - lint, - span, - lints::HiddenGlobReexports { - glob_reexport: glob_reexport_span, - private_item: private_item_span, + lints::HiddenGlobReexports { + glob_reexport: glob_reexport_span, + private_item: private_item_span, - name, - namespace, - }, - ); + name, + namespace, + } + .decorate_lint(diag); } BuiltinLintDiag::UnusedQualifications { removal_span } => { - ctx.emit_span_lint(lint, span, lints::UnusedQualifications { removal_span }); + lints::UnusedQualifications { removal_span }.decorate_lint(diag); } BuiltinLintDiag::AssociatedConstElidedLifetime { elided, span: lt_span } => { let lt_span = if elided { lt_span.shrink_to_hi() } else { lt_span }; let code = if elided { "'static " } else { "'static" }; - ctx.emit_span_lint( - lint, - span, - lints::AssociatedConstElidedLifetime { span: lt_span, code, elided }, - ); + lints::AssociatedConstElidedLifetime { span: lt_span, code, elided } + .decorate_lint(diag); } BuiltinLintDiag::RedundantImportVisibility { max_vis, span: vis_span, import_vis } => { - ctx.emit_span_lint( - lint, - span, - lints::RedundantImportVisibility { span: vis_span, help: (), max_vis, import_vis }, - ); + lints::RedundantImportVisibility { span: vis_span, help: (), max_vis, import_vis } + .decorate_lint(diag); } BuiltinLintDiag::UnknownDiagnosticAttribute { span: typo_span, typo_name } => { let typo = typo_name.map(|typo_name| lints::UnknownDiagnosticAttributeTypoSugg { span: typo_span, typo_name, }); - ctx.emit_span_lint(lint, span, lints::UnknownDiagnosticAttribute { typo }); + lints::UnknownDiagnosticAttribute { typo }.decorate_lint(diag); } BuiltinLintDiag::MacroUseDeprecated => { - ctx.emit_span_lint(lint, span, lints::MacroUseDeprecated) + lints::MacroUseDeprecated.decorate_lint(diag); } - BuiltinLintDiag::UnusedMacroUse => ctx.emit_span_lint(lint, span, lints::UnusedMacroUse), + BuiltinLintDiag::UnusedMacroUse => lints::UnusedMacroUse.decorate_lint(diag), BuiltinLintDiag::PrivateExternCrateReexport(ident) => { - ctx.emit_span_lint(lint, span, lints::PrivateExternCrateReexport { ident }) + lints::PrivateExternCrateReexport { ident }.decorate_lint(diag); } - BuiltinLintDiag::UnusedLabel => ctx.emit_span_lint(lint, span, lints::UnusedLabel), + BuiltinLintDiag::UnusedLabel => lints::UnusedLabel.decorate_lint(diag), BuiltinLintDiag::MacroIsPrivate(ident) => { - ctx.emit_span_lint(lint, span, lints::MacroIsPrivate { ident }) + lints::MacroIsPrivate { ident }.decorate_lint(diag); } BuiltinLintDiag::UnusedMacroDefinition(name) => { - ctx.emit_span_lint(lint, span, lints::UnusedMacroDefinition { name }) + lints::UnusedMacroDefinition { name }.decorate_lint(diag); } BuiltinLintDiag::MacroRuleNeverUsed(n, name) => { - ctx.emit_span_lint(lint, span, lints::MacroRuleNeverUsed { n: n + 1, name }) + lints::MacroRuleNeverUsed { n: n + 1, name }.decorate_lint(diag); } BuiltinLintDiag::UnstableFeature(msg) => { - ctx.emit_span_lint(lint, span, lints::UnstableFeature { msg }) + lints::UnstableFeature { msg }.decorate_lint(diag); } BuiltinLintDiag::AvoidUsingIntelSyntax => { - ctx.emit_span_lint(lint, span, lints::AvoidIntelSyntax) + lints::AvoidIntelSyntax.decorate_lint(diag); } BuiltinLintDiag::AvoidUsingAttSyntax => { - ctx.emit_span_lint(lint, span, lints::AvoidAttSyntax) + lints::AvoidAttSyntax.decorate_lint(diag); } BuiltinLintDiag::IncompleteInclude => { - ctx.emit_span_lint(lint, span, lints::IncompleteInclude) + lints::IncompleteInclude.decorate_lint(diag); } BuiltinLintDiag::UnnameableTestItems => { - ctx.emit_span_lint(lint, span, lints::UnnameableTestItems) + lints::UnnameableTestItems.decorate_lint(diag); } BuiltinLintDiag::DuplicateMacroAttribute => { - ctx.emit_span_lint(lint, span, lints::DuplicateMacroAttribute) + lints::DuplicateMacroAttribute.decorate_lint(diag); } BuiltinLintDiag::CfgAttrNoAttributes => { - ctx.emit_span_lint(lint, span, lints::CfgAttrNoAttributes) + lints::CfgAttrNoAttributes.decorate_lint(diag); } BuiltinLintDiag::CrateTypeInCfgAttr => { - ctx.emit_span_lint(lint, span, lints::CrateTypeInCfgAttr) + lints::CrateTypeInCfgAttr.decorate_lint(diag); } BuiltinLintDiag::CrateNameInCfgAttr => { - ctx.emit_span_lint(lint, span, lints::CrateNameInCfgAttr) + lints::CrateNameInCfgAttr.decorate_lint(diag); } BuiltinLintDiag::MissingFragmentSpecifier => { - ctx.emit_span_lint(lint, span, lints::MissingFragmentSpecifier) + lints::MissingFragmentSpecifier.decorate_lint(diag); } BuiltinLintDiag::MetaVariableStillRepeating(name) => { - ctx.emit_span_lint(lint, span, lints::MetaVariableStillRepeating { name }) + lints::MetaVariableStillRepeating { name }.decorate_lint(diag); } BuiltinLintDiag::MetaVariableWrongOperator => { - ctx.emit_span_lint(lint, span, lints::MetaVariableWrongOperator) + lints::MetaVariableWrongOperator.decorate_lint(diag); } BuiltinLintDiag::DuplicateMatcherBinding => { - ctx.emit_span_lint(lint, span, lints::DuplicateMatcherBinding) + lints::DuplicateMatcherBinding.decorate_lint(diag); } BuiltinLintDiag::UnknownMacroVariable(name) => { - ctx.emit_span_lint(lint, span, lints::UnknownMacroVariable { name }) + lints::UnknownMacroVariable { name }.decorate_lint(diag); } - BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => ctx.emit_span_lint( - lint, - span, - lints::UnusedCrateDependency { extern_crate, local_crate }, - ), - BuiltinLintDiag::WasmCAbi => ctx.emit_span_lint(lint, span, lints::WasmCAbi), - BuiltinLintDiag::IllFormedAttributeInput { suggestions } => ctx.emit_span_lint( - lint, - span, + BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => { + lints::UnusedCrateDependency { extern_crate, local_crate }.decorate_lint(diag) + } + BuiltinLintDiag::WasmCAbi => lints::WasmCAbi.decorate_lint(diag), + BuiltinLintDiag::IllFormedAttributeInput { suggestions } => { lints::IllFormedAttributeInput { num_suggestions: suggestions.len(), suggestions: DiagArgValue::StrListSepByAnd( suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), ), - }, - ), - BuiltinLintDiag::InnerAttributeUnstable { is_macro } => ctx.emit_span_lint( - lint, - span, - if is_macro { - lints::InnerAttributeUnstable::InnerMacroAttribute - } else { - lints::InnerAttributeUnstable::CustomInnerAttribute - }, - ), + } + .decorate_lint(diag) + } + BuiltinLintDiag::InnerAttributeUnstable { is_macro } => if is_macro { + lints::InnerAttributeUnstable::InnerMacroAttribute + } else { + lints::InnerAttributeUnstable::CustomInnerAttribute + } + .decorate_lint(diag), } } diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 30bf80b915b8..a311c274a6ba 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -5,11 +5,11 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::LintDiagnostic; +use rustc_middle::bug; use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; -use rustc_middle::{bug, span_bug}; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{sym, BytePos, Span}; @@ -303,20 +303,12 @@ impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { ResolvedArg::EarlyBound(def_id) | ResolvedArg::LateBound(_, _, def_id), ) => { if self.tcx.def_kind(self.tcx.parent(def_id)) == DefKind::OpaqueTy { - let (ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) - | ty::ReLateParam(ty::LateParamRegion { - bound_region: ty::BoundRegionKind::BrNamed(def_id, _), - .. - })) = self + let def_id = self .tcx .map_opaque_lifetime_to_parent_lifetime(def_id.expect_local()) - .kind() - else { - span_bug!( - self.tcx.def_span(def_id), - "variable should have been duplicated from a parent" - ); - }; + .opt_param_def_id(self.tcx, self.parent_def_id.to_def_id()) + .expect("variable should have been duplicated from parent"); + explicitly_captured.insert(def_id); } else { explicitly_captured.insert(def_id); @@ -369,6 +361,7 @@ struct ImplTraitOvercapturesLint<'tcx> { impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { + diag.primary_message(fluent::lint_impl_trait_overcaptures); diag.arg("self_ty", self.self_ty.to_string()) .arg("num_captured", self.num_captured) .span_note(self.uncaptured_spans, fluent::lint_note) @@ -382,10 +375,6 @@ impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { ); } } - - fn msg(&self) -> rustc_errors::DiagMessage { - fluent::lint_impl_trait_overcaptures - } } #[derive(LintDiagnostic)] diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 98e321076c59..84645e0ce7fc 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -16,7 +16,7 @@ use crate::{ use rustc_ast as ast; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxIndexMap; -use rustc_errors::{Diag, DiagMessage, LintDiagnostic, MultiSpan}; +use rustc_errors::{Diag, LintDiagnostic, MultiSpan}; use rustc_feature::{Features, GateIssue}; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; @@ -1064,26 +1064,19 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { // FIXME: make this translatable #[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::untranslatable_diagnostic)] - lint_level( - self.sess, - lint, - level, - src, - Some(span.into()), - fluent::lint_unknown_gated_lint, - |lint| { - lint.arg("name", lint_id.lint.name_lower()); - lint.note(fluent::lint_note); - rustc_session::parse::add_feature_diagnostics_for_issue( - lint, - &self.sess, - feature, - GateIssue::Language, - lint_from_cli, - None, - ); - }, - ); + lint_level(self.sess, lint, level, src, Some(span.into()), |lint| { + lint.primary_message(fluent::lint_unknown_gated_lint); + lint.arg("name", lint_id.lint.name_lower()); + lint.note(fluent::lint_note); + rustc_session::parse::add_feature_diagnostics_for_issue( + lint, + &self.sess, + feature, + GateIssue::Language, + lint_from_cli, + None, + ); + }); } false @@ -1104,11 +1097,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { &self, lint: &'static Lint, span: Option, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { let (level, src) = self.lint_level(lint); - lint_level(self.sess, lint, level, src, span, msg, decorate) + lint_level(self.sess, lint, level, src, span, decorate) } #[track_caller] @@ -1119,7 +1111,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { decorate: impl for<'a> LintDiagnostic<'a, ()>, ) { let (level, src) = self.lint_level(lint); - lint_level(self.sess, lint, level, src, Some(span), decorate.msg(), |lint| { + lint_level(self.sess, lint, level, src, Some(span), |lint| { decorate.decorate_lint(lint); }); } @@ -1127,7 +1119,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { #[track_caller] pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> LintDiagnostic<'a, ()>) { let (level, src) = self.lint_level(lint); - lint_level(self.sess, lint, level, src, None, decorate.msg(), |lint| { + lint_level(self.sess, lint, level, src, None, |lint| { decorate.decorate_lint(lint); }); } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 0ccfe23ae372..bcb714ae4ce2 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -539,6 +539,16 @@ fn register_builtins(store: &mut LintStore) { "converted into hard error, see RFC #3535 \ for more information", ); + store.register_removed( + "indirect_structural_match", + "converted into hard error, see RFC #3535 \ + for more information", + ); + store.register_removed( + "pointer_structural_match", + "converted into hard error, see RFC #3535 \ + for more information", + ); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 2f44bc4764e3..42963a11f71a 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -145,12 +145,9 @@ pub struct BuiltinMissingDebugImpl<'a> { // Needed for def_path_str impl<'a> LintDiagnostic<'a, ()> for BuiltinMissingDebugImpl<'_> { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { + diag.primary_message(fluent::lint_builtin_missing_debug_impl); diag.arg("debug", self.tcx.def_path_str(self.def_id)); } - - fn msg(&self) -> DiagMessage { - fluent::lint_builtin_missing_debug_impl - } } #[derive(LintDiagnostic)] @@ -250,6 +247,7 @@ pub struct BuiltinUngatedAsyncFnTrackCaller<'a> { impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_ungated_async_fn_track_caller); diag.span_label(self.label, fluent::lint_label); rustc_session::parse::add_feature_diagnostics( diag, @@ -257,10 +255,6 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> { sym::async_fn_track_caller, ); } - - fn msg(&self) -> DiagMessage { - fluent::lint_ungated_async_fn_track_caller - } } #[derive(LintDiagnostic)] @@ -432,6 +426,7 @@ pub struct BuiltinUnpermittedTypeInit<'a> { impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(self.msg); diag.arg("ty", self.ty); diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label); if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) { @@ -443,10 +438,6 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> { } self.sub.add_to_diag(diag); } - - fn msg(&self) -> DiagMessage { - self.msg.clone() - } } // FIXME(davidtwco): make translatable @@ -1169,6 +1160,7 @@ pub struct NonFmtPanicUnused { // Used because of two suggestions based on one Option impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_non_fmt_panic_unused); diag.arg("count", self.count); diag.note(fluent::lint_note); if let Some(span) = self.suggestion { @@ -1186,10 +1178,6 @@ impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused { ); } } - - fn msg(&self) -> DiagMessage { - fluent::lint_non_fmt_panic_unused - } } #[derive(LintDiagnostic)] @@ -1411,13 +1399,10 @@ pub struct DropTraitConstraintsDiag<'a> { // Needed for def_path_str impl<'a> LintDiagnostic<'a, ()> for DropTraitConstraintsDiag<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_drop_trait_constraints); diag.arg("predicate", self.predicate); diag.arg("needs_drop", self.tcx.def_path_str(self.def_id)); } - - fn msg(&self) -> DiagMessage { - fluent::lint_drop_trait_constraints - } } pub struct DropGlue<'a> { @@ -1428,12 +1413,9 @@ pub struct DropGlue<'a> { // Needed for def_path_str impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_drop_glue); diag.arg("needs_drop", self.tcx.def_path_str(self.def_id)); } - - fn msg(&self) -> DiagMessage { - fluent::lint_drop_glue - } } // types.rs @@ -1711,6 +1693,7 @@ pub struct ImproperCTypes<'a> { // Used because of the complexity of Option, DiagMessage, and Option impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_improper_ctypes); diag.arg("ty", self.ty); diag.arg("desc", self.desc); diag.span_label(self.label, fluent::lint_label); @@ -1722,10 +1705,6 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> { diag.span_note(note, fluent::lint_note); } } - - fn msg(&self) -> DiagMessage { - fluent::lint_improper_ctypes - } } #[derive(LintDiagnostic)] @@ -1854,6 +1833,7 @@ pub enum UnusedDefSuggestion { // Needed because of def_path_str impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_unused_def); diag.arg("pre", self.pre); diag.arg("post", self.post); diag.arg("def", self.cx.tcx.def_path_str(self.def_id)); @@ -1865,10 +1845,6 @@ impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> { diag.subdiagnostic(diag.dcx, sugg); } } - - fn msg(&self) -> DiagMessage { - fluent::lint_unused_def - } } #[derive(LintDiagnostic)] @@ -1937,15 +1913,12 @@ pub struct AsyncFnInTraitDiag { impl<'a> LintDiagnostic<'a, ()> for AsyncFnInTraitDiag { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(fluent::lint_async_fn_in_trait); diag.note(fluent::lint_note); if let Some(sugg) = self.sugg { diag.multipart_suggestion(fluent::lint_suggestion, sugg, Applicability::MaybeIncorrect); } } - - fn msg(&self) -> DiagMessage { - fluent::lint_async_fn_in_trait - } } #[derive(LintDiagnostic)] @@ -2273,10 +2246,8 @@ pub struct UnstableFeature { } impl<'a> LintDiagnostic<'a, ()> for UnstableFeature { - fn decorate_lint<'b>(self, _diag: &'b mut Diag<'a, ()>) {} - - fn msg(&self) -> DiagMessage { - self.msg.clone() + fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + diag.primary_message(self.msg); } } @@ -2738,12 +2709,9 @@ pub struct AmbiguousGlobImports { impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) { + diag.primary_message(self.ambiguity.msg.clone()); rustc_errors::report_ambiguity_error(diag, self.ambiguity); } - - fn msg(&self) -> DiagMessage { - DiagMessage::Str(self.ambiguity.msg.clone().into()) - } } #[derive(LintDiagnostic)] diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index a6057afcbd6b..c9d678541123 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -123,7 +123,8 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc } #[allow(rustc::diagnostic_outside_of_impl)] - cx.span_lint(NON_FMT_PANICS, arg_span, fluent::lint_non_fmt_panic, |lint| { + cx.span_lint(NON_FMT_PANICS, arg_span, |lint| { + lint.primary_message(fluent::lint_non_fmt_panic); lint.arg("name", symbol); lint.note(fluent::lint_note); lint.note(fluent::lint_more_info_note); diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 617fe99ef6a7..42e12a88fa53 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -49,7 +49,6 @@ declare_lint_pass! { HIDDEN_GLOB_REEXPORTS, ILL_FORMED_ATTRIBUTE_INPUT, INCOMPLETE_INCLUDE, - INDIRECT_STRUCTURAL_MATCH, INEFFECTIVE_UNSTABLE_TRAIT_IMPL, INLINE_NO_SANITIZE, INVALID_DOC_ATTRIBUTES, @@ -74,7 +73,6 @@ declare_lint_pass! { ORDER_DEPENDENT_TRAIT_OBJECTS, OVERLAPPING_RANGE_ENDPOINTS, PATTERNS_IN_FNS_WITHOUT_BODY, - POINTER_STRUCTURAL_MATCH, PRIVATE_BOUNDS, PRIVATE_INTERFACES, PROC_MACRO_BACK_COMPAT, @@ -1316,10 +1314,8 @@ declare_lint! { /// * If you are trying to perform a one-time initialization of a global: /// * If the value can be computed at compile-time, consider using /// const-compatible values (see [Constant Evaluation]). - /// * For more complex single-initialization cases, consider using a - /// third-party crate, such as [`lazy_static`] or [`once_cell`]. - /// * If you are using the [nightly channel], consider the new - /// [`lazy`] module in the standard library. + /// * For more complex single-initialization cases, consider using + /// [`std::sync::LazyLock`]. /// * If you truly need a mutable global, consider using a [`static`], /// which has a variety of options: /// * Simple data types can be directly defined and mutated with an @@ -1334,9 +1330,7 @@ declare_lint! { /// [Constant Evaluation]: https://doc.rust-lang.org/reference/const_eval.html /// [`static`]: https://doc.rust-lang.org/reference/items/static-items.html /// [mutable `static`]: https://doc.rust-lang.org/reference/items/static-items.html#mutable-statics - /// [`lazy`]: https://doc.rust-lang.org/nightly/std/lazy/index.html - /// [`lazy_static`]: https://crates.io/crates/lazy_static - /// [`once_cell`]: https://crates.io/crates/once_cell + /// [`std::sync::LazyLock`]: https://doc.rust-lang.org/stable/std/sync/struct.LazyLock.html /// [`atomic`]: https://doc.rust-lang.org/std/sync/atomic/index.html /// [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html pub CONST_ITEM_MUTATION, @@ -2355,52 +2349,6 @@ declare_lint! { "outlives requirements can be inferred" } -declare_lint! { - /// The `indirect_structural_match` lint detects a `const` in a pattern - /// that manually implements [`PartialEq`] and [`Eq`]. - /// - /// [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html - /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(indirect_structural_match)] - /// - /// struct NoDerive(i32); - /// impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } - /// impl Eq for NoDerive { } - /// #[derive(PartialEq, Eq)] - /// struct WrapParam(T); - /// const WRAP_INDIRECT_PARAM: & &WrapParam = & &WrapParam(NoDerive(0)); - /// fn main() { - /// match WRAP_INDIRECT_PARAM { - /// WRAP_INDIRECT_PARAM => { } - /// _ => { } - /// } - /// } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// The compiler unintentionally accepted this form in the past. This is a - /// [future-incompatible] lint to transition this to a hard error in the - /// future. See [issue #62411] for a complete description of the problem, - /// and some possible solutions. - /// - /// [issue #62411]: https://github.com/rust-lang/rust/issues/62411 - /// [future-incompatible]: ../index.md#future-incompatible-lints - pub INDIRECT_STRUCTURAL_MATCH, - Warn, - "constant used in pattern contains value of non-structural-match type in a field or a variant", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, - reference: "issue #120362 ", - }; -} - declare_lint! { /// The `deprecated_in_future` lint is internal to rustc and should not be /// used by user code. @@ -2418,45 +2366,6 @@ declare_lint! { report_in_external_macro } -declare_lint! { - /// The `pointer_structural_match` lint detects pointers used in patterns whose behaviour - /// cannot be relied upon across compiler versions and optimization levels. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(pointer_structural_match)] - /// fn foo(a: usize, b: usize) -> usize { a + b } - /// const FOO: fn(usize, usize) -> usize = foo; - /// fn main() { - /// match FOO { - /// FOO => {}, - /// _ => {}, - /// } - /// } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// Previous versions of Rust allowed function pointers and all raw pointers in patterns. - /// While these work in many cases as expected by users, it is possible that due to - /// optimizations pointers are "not equal to themselves" or pointers to different functions - /// compare as equal during runtime. This is because LLVM optimizations can deduplicate - /// functions if their bodies are the same, thus also making pointers to these functions point - /// to the same location. Additionally functions may get duplicated if they are instantiated - /// in different crates and not deduplicated again via LTO. Pointer identity for memory - /// created by `const` is similarly unreliable. - pub POINTER_STRUCTURAL_MATCH, - Warn, - "pointers are not structural-match", - @future_incompatible = FutureIncompatibleInfo { - reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, - reference: "issue #120362 ", - }; -} - declare_lint! { /// The `ambiguous_associated_items` lint detects ambiguity between /// [associated items] and [enum variants]. diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 1941b0b12643..c8a9fb02bf2e 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -764,19 +764,7 @@ pub struct LintBuffer { impl LintBuffer { pub fn add_early_lint(&mut self, early_lint: BufferedEarlyLint) { - let arr = self.map.entry(early_lint.node_id).or_default(); - arr.push(early_lint); - } - - pub fn add_lint( - &mut self, - lint: &'static Lint, - node_id: NodeId, - span: MultiSpan, - diagnostic: BuiltinLintDiag, - ) { - let lint_id = LintId::of(lint); - self.add_early_lint(BufferedEarlyLint { lint_id, node_id, span, diagnostic }); + self.map.entry(early_lint.node_id).or_default().push(early_lint); } pub fn take(&mut self, id: NodeId) -> Vec { @@ -787,11 +775,16 @@ impl LintBuffer { pub fn buffer_lint( &mut self, lint: &'static Lint, - id: NodeId, - sp: impl Into, + node_id: NodeId, + span: impl Into, diagnostic: BuiltinLintDiag, ) { - self.add_lint(lint, id, sp.into(), diagnostic) + self.add_early_lint(BufferedEarlyLint { + lint_id: LintId::of(lint), + node_id, + span: span.into(), + diagnostic, + }); } } diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 9d21d88165e0..ef6005283d6b 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -105,25 +105,12 @@ impl<'a> LintDiagnosticDerive<'a> { pub(crate) fn into_tokens(self) -> TokenStream { let LintDiagnosticDerive { mut structure } = self; let kind = DiagnosticDeriveKind::LintDiagnostic; + let slugs = RefCell::new(Vec::new()); let implementation = kind.each_variant(&mut structure, |mut builder, variant| { let preamble = builder.preamble(variant); let body = builder.body(variant); - let formatting_init = &builder.formatting_init; - quote! { - #preamble - #formatting_init - #body - diag - } - }); - - let slugs = RefCell::new(Vec::new()); - let msg = kind.each_variant(&mut structure, |mut builder, variant| { - // Collect the slug by generating the preamble. - let _ = builder.preamble(variant); - - match builder.slug.value_ref() { + let primary_message = match builder.slug.value_ref() { None => { span_err(builder.span, "diagnostic slug not specified") .help( @@ -146,9 +133,18 @@ impl<'a> LintDiagnosticDerive<'a> { Some(slug) => { slugs.borrow_mut().push(slug.clone()); quote! { - crate::fluent_generated::#slug.into() + diag.primary_message(crate::fluent_generated::#slug); } } + }; + + let formatting_init = &builder.formatting_init; + quote! { + #primary_message + #preamble + #formatting_init + #body + diag } }); @@ -161,10 +157,6 @@ impl<'a> LintDiagnosticDerive<'a> { ) { #implementation; } - - fn msg(&self) -> rustc_errors::DiagMessage { - #msg - } } }); for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) { diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index 389d88bebc78..134045d0644c 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -91,7 +91,7 @@ pub fn diagnostic_derive(mut s: Structure<'_>) -> TokenStream { /// Then, later, to emit the error: /// /// ```ignore (rust) -/// cx.span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg_span, AtomicOrderingInvalidLint { +/// cx.emit_span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg_span, AtomicOrderingInvalidLint { /// method, /// success_ordering, /// fail_ordering, diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 7392eb6c2bb4..b0e72eaf5a4c 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -61,7 +61,10 @@ macro_rules! arena_types { [] dtorck_constraint: rustc_middle::traits::query::DropckConstraint<'tcx>, [] candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>, [] autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>, - [] canonical_goal_evaluation: rustc_next_trait_solver::solve::inspect::GoalEvaluationStep>, + [] canonical_goal_evaluation: + rustc_next_trait_solver::solve::inspect::CanonicalGoalEvaluationStep< + rustc_middle::ty::TyCtxt<'tcx> + >, [] query_region_constraints: rustc_middle::infer::canonical::QueryRegionConstraints<'tcx>, [] type_op_subtype: rustc_middle::infer::canonical::Canonical<'tcx, diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index d82d23d62afa..4e655ca2027f 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -2,7 +2,7 @@ use std::cmp; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sorted_map::SortedMap; -use rustc_errors::{Diag, DiagMessage, MultiSpan}; +use rustc_errors::{Diag, MultiSpan}; use rustc_hir::{HirId, ItemLocalId}; use rustc_macros::HashStable; use rustc_session::lint::{ @@ -270,7 +270,6 @@ pub fn lint_level( level: Level, src: LintLevelSource, span: Option, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to @@ -282,7 +281,6 @@ pub fn lint_level( level: Level, src: LintLevelSource, span: Option, - msg: impl Into, decorate: Box FnOnce(&'b mut Diag<'a, ()>)>, ) { // Check for future incompatibility lints and issue a stronger warning. @@ -351,10 +349,6 @@ pub fn lint_level( } } - // Delay evaluating and setting the primary message until after we've - // suppressed the lint due to macros. - err.primary_message(msg); - err.is_lint(lint.name_lower(), has_future_breakage); // Lint diagnostics that are covered by the expect level will not be emitted outside @@ -419,7 +413,7 @@ pub fn lint_level( explain_lint_level_source(lint, level, src, &mut err); err.emit() } - lint_level_impl(sess, lint, level, src, span, msg, Box::new(decorate)) + lint_level_impl(sess, lint, level, src, span, Box::new(decorate)) } /// Returns whether `span` originates in a foreign crate's external macro. diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index a377e35b2e9e..8cf1bedf0dae 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -157,6 +157,13 @@ pub struct Deprecated { impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) { + diag.primary_message(match &self.since_kind { + DeprecatedSinceKind::InEffect => crate::fluent_generated::middle_deprecated, + DeprecatedSinceKind::InFuture => crate::fluent_generated::middle_deprecated_in_future, + DeprecatedSinceKind::InVersion(_) => { + crate::fluent_generated::middle_deprecated_in_version + } + }); diag.arg("kind", self.kind); diag.arg("path", self.path); if let DeprecatedSinceKind::InVersion(version) = self.since_kind { @@ -172,16 +179,6 @@ impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecate diag.subdiagnostic(diag.dcx, sub); } } - - fn msg(&self) -> rustc_errors::DiagMessage { - match &self.since_kind { - DeprecatedSinceKind::InEffect => crate::fluent_generated::middle_deprecated, - DeprecatedSinceKind::InFuture => crate::fluent_generated::middle_deprecated_in_future, - DeprecatedSinceKind::InVersion(_) => { - crate::fluent_generated::middle_deprecated_in_version - } - } - } } fn deprecated_since_kind(is_in_effect: bool, since: DeprecatedSince) -> DeprecatedSinceKind { @@ -598,7 +595,9 @@ impl<'tcx> TyCtxt<'tcx> { unmarked: impl FnOnce(Span, DefId), ) -> bool { let soft_handler = |lint, span, msg: String| { - self.node_span_lint(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |_| {}) + self.node_span_lint(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| { + lint.primary_message(msg); + }) }; let eval_result = self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable); diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index a85181954696..fe743fa4aac2 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -113,8 +113,7 @@ impl<'tcx> TyCtxt<'tcx> { lint::builtin::CONST_EVALUATABLE_UNCHECKED, self.local_def_id_to_hir_id(local_def_id), self.def_span(ct.def), - "cannot use constants which depend on generic parameters in types", - |_| {}, + |lint| { lint.primary_message("cannot use constants which depend on generic parameters in types"); }, ) } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 5a6decc4f949..8ca7a465c2a8 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2218,15 +2218,6 @@ rustc_queries! { separate_provide_extern } - /// Used in `super_combine_consts` to ICE if the type of the two consts are definitely not going to end up being - /// equal to eachother. This might return `Ok` even if the types are not equal, but will never return `Err` if - /// the types might be equal. - query check_tys_might_be_eq( - arg: Canonical<'tcx, ty::ParamEnvAnd<'tcx, (Ty<'tcx>, Ty<'tcx>)>> - ) -> Result<(), NoSolution> { - desc { "check whether two const param are definitely not equal to eachother"} - } - /// Get all item paths that were stripped by a `#[cfg]` in a particular crate. /// Should not be called for the local crate before the resolver outputs are created, as it /// is only fed there. diff --git a/compiler/rustc_middle/src/traits/solve/cache.rs b/compiler/rustc_middle/src/traits/solve/cache.rs index 2ff4ade21d08..dc31114b2c45 100644 --- a/compiler/rustc_middle/src/traits/solve/cache.rs +++ b/compiler/rustc_middle/src/traits/solve/cache.rs @@ -17,7 +17,7 @@ pub struct EvaluationCache<'tcx> { #[derive(Debug, PartialEq, Eq)] pub struct CacheData<'tcx> { pub result: QueryResult<'tcx>, - pub proof_tree: Option<&'tcx [inspect::GoalEvaluationStep>]>, + pub proof_tree: Option<&'tcx inspect::CanonicalGoalEvaluationStep>>, pub additional_depth: usize, pub encountered_overflow: bool, } @@ -28,7 +28,7 @@ impl<'tcx> EvaluationCache<'tcx> { &self, tcx: TyCtxt<'tcx>, key: CanonicalInput<'tcx>, - proof_tree: Option<&'tcx [inspect::GoalEvaluationStep>]>, + proof_tree: Option<&'tcx inspect::CanonicalGoalEvaluationStep>>, additional_depth: usize, encountered_overflow: bool, cycle_participants: FxHashSet>, @@ -107,7 +107,7 @@ struct Success<'tcx> { #[derive(Clone, Copy)] pub struct QueryData<'tcx> { pub result: QueryResult<'tcx>, - pub proof_tree: Option<&'tcx [inspect::GoalEvaluationStep>]>, + pub proof_tree: Option<&'tcx inspect::CanonicalGoalEvaluationStep>>, } /// The cache entry for a goal `CanonicalInput`. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6e53b5bb5206..e618323c810d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -47,9 +47,7 @@ use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, RwLock, Work #[cfg(parallel_compiler)] use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_data_structures::unord::UnordSet; -use rustc_errors::{ - Applicability, Diag, DiagCtxt, DiagMessage, ErrorGuaranteed, LintDiagnostic, MultiSpan, -}; +use rustc_errors::{Applicability, Diag, DiagCtxt, ErrorGuaranteed, LintDiagnostic, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; @@ -103,7 +101,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type PredefinedOpaques = solve::PredefinedOpaques<'tcx>; type DefiningOpaqueTypes = &'tcx ty::List; type ExternalConstraints = ExternalConstraints<'tcx>; - type GoalEvaluationSteps = &'tcx [solve::inspect::GoalEvaluationStep>]; + type CanonicalGoalEvaluationStepRef = + &'tcx solve::inspect::CanonicalGoalEvaluationStep>; type Ty = Ty<'tcx>; type Tys = &'tcx List>; @@ -1488,13 +1487,14 @@ impl<'tcx> TyCtxt<'tcx> { } /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region. - pub fn is_suitable_region(self, mut region: Region<'tcx>) -> Option { + pub fn is_suitable_region( + self, + generic_param_scope: LocalDefId, + mut region: Region<'tcx>, + ) -> Option { let (suitable_region_binding_scope, bound_region) = loop { - let def_id = match region.kind() { - ty::ReLateParam(fr) => fr.bound_region.get_id()?.as_local()?, - ty::ReEarlyParam(ebr) => ebr.def_id.as_local()?, - _ => return None, // not a free region - }; + let def_id = + region.opt_param_def_id(self, generic_param_scope.to_def_id())?.as_local()?; let scope = self.local_parent(def_id); if self.def_kind(scope) == DefKind::OpaqueTy { // Lifetime params of opaque types are synthetic and thus irrelevant to @@ -2469,10 +2469,9 @@ impl<'tcx> TyCtxt<'tcx> { span: impl Into, decorator: impl for<'a> LintDiagnostic<'a, ()>, ) { - let msg = decorator.msg(); let (level, src) = self.lint_level_at_node(lint, hir_id); - lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| { - decorator.decorate_lint(diag); + lint_level(self.sess, lint, level, src, Some(span.into()), |lint| { + decorator.decorate_lint(lint); }) } @@ -2486,11 +2485,10 @@ impl<'tcx> TyCtxt<'tcx> { lint: &'static Lint, hir_id: HirId, span: impl Into, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { let (level, src) = self.lint_level_at_node(lint, hir_id); - lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate); + lint_level(self.sess, lint, level, src, Some(span.into()), decorate); } /// Find the crate root and the appropriate span where `use` and outer attributes can be @@ -2541,8 +2539,8 @@ impl<'tcx> TyCtxt<'tcx> { id: HirId, decorator: impl for<'a> LintDiagnostic<'a, ()>, ) { - self.node_lint(lint, id, decorator.msg(), |diag| { - decorator.decorate_lint(diag); + self.node_lint(lint, id, |lint| { + decorator.decorate_lint(lint); }) } @@ -2555,11 +2553,10 @@ impl<'tcx> TyCtxt<'tcx> { self, lint: &'static Lint, id: HirId, - msg: impl Into, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ) { let (level, src) = self.lint_level_at_node(lint, id); - lint_level(self.sess, lint, level, src, None, msg, decorate); + lint_level(self.sess, lint, level, src, None, decorate); } pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> { @@ -2633,7 +2630,6 @@ impl<'tcx> TyCtxt<'tcx> { return ty::Region::new_early_param( self, ty::EarlyParamRegion { - def_id: ebv, index: generics .param_def_id_to_index(self, ebv) .expect("early-bound var should be present in fn generics"), diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 1c4462fc1dcb..69a86bda43ba 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -66,7 +66,7 @@ pub struct GenericParamDef { impl GenericParamDef { pub fn to_early_bound_region_data(&self) -> ty::EarlyParamRegion { if let GenericParamDefKind::Lifetime = self.kind { - ty::EarlyParamRegion { def_id: self.def_id, index: self.index, name: self.name } + ty::EarlyParamRegion { index: self.index, name: self.name } } else { bug!("cannot convert a non-lifetime parameter def to an early bound region") } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 0bcd02aaa3ac..3c0f2578284a 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3314,7 +3314,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N /// /// The implementation uses similar import discovery logic to that of 'use' suggestions. /// -/// See also [`DelayDm`](rustc_error_messages::DelayDm) and [`with_no_trimmed_paths!`]. +/// See also [`with_no_trimmed_paths!`]. // this is pub to be able to intra-doc-link it pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap { // Trimming paths is expensive and not optimized, since we expect it to only be used for error diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 958e7e401684..0807cbf91d16 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -265,33 +265,6 @@ impl<'tcx> Region<'tcx> { flags } - /// Given an early-bound or free region, returns the `DefId` where it was bound. - /// For example, consider the regions in this snippet of code: - /// - /// ```ignore (illustrative) - /// impl<'a> Foo { - /// // ^^ -- early bound, declared on an impl - /// - /// fn bar<'b, 'c>(x: &self, y: &'b u32, z: &'c u64) where 'static: 'c - /// // ^^ ^^ ^ anonymous, late-bound - /// // | early-bound, appears in where-clauses - /// // late-bound, appears only in fn args - /// {..} - /// } - /// ``` - /// - /// Here, `free_region_binding_scope('a)` would return the `DefId` - /// of the impl, and for all the other highlighted regions, it - /// would return the `DefId` of the function. In other cases (not shown), this - /// function might return the `DefId` of a closure. - pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId { - match *self { - ty::ReEarlyParam(br) => tcx.parent(br.def_id), - ty::ReLateParam(fr) => fr.scope, - _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self), - } - } - /// True for free regions other than `'static`. pub fn is_param(self) -> bool { matches!(*self, ty::ReEarlyParam(_) | ty::ReLateParam(_)) @@ -321,6 +294,21 @@ impl<'tcx> Region<'tcx> { _ => bug!("expected region {:?} to be of kind ReVar", self), } } + + /// Given some item `binding_item`, check if this region is a generic parameter introduced by it + /// or one of the parent generics. Returns the `DefId` of the parameter definition if so. + pub fn opt_param_def_id(self, tcx: TyCtxt<'tcx>, binding_item: DefId) -> Option { + match self.kind() { + ty::ReEarlyParam(ebr) => { + Some(tcx.generics_of(binding_item).region_param(ebr, tcx).def_id) + } + ty::ReLateParam(ty::LateParamRegion { + bound_region: ty::BoundRegionKind::BrNamed(def_id, _), + .. + }) => Some(def_id), + _ => None, + } + } } impl<'tcx> Deref for Region<'tcx> { @@ -335,16 +323,13 @@ impl<'tcx> Deref for Region<'tcx> { #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable)] pub struct EarlyParamRegion { - pub def_id: DefId, pub index: u32, pub name: Symbol, } impl std::fmt::Debug for EarlyParamRegion { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - // FIXME(BoxyUwU): self.def_id goes first because of `erased-regions-in-hidden-ty.rs` being impossible to write - // error annotations for otherwise. :). Ideally this would be `self.name, self.index, self.def_id`. - write!(f, "{:?}_{}/#{}", self.def_id, self.name, self.index) + write!(f, "{}/#{}", self.name, self.index) } } @@ -352,6 +337,12 @@ impl std::fmt::Debug for EarlyParamRegion { #[derive(HashStable)] /// The parameter representation of late-bound function parameters, "some region /// at least as big as the scope `fr.scope`". +/// +/// Similar to a placeholder region as we create `LateParam` regions when entering a binder +/// except they are always in the root universe and instead of using a boundvar to distinguish +/// between others we use the `DefId` of the parameter. For this reason the `bound_region` field +/// should basically always be `BoundRegionKind::BrNamed` as otherwise there is no way of telling +/// different parameters apart. pub struct LateParamRegion { pub scope: DefId, pub bound_region: BoundRegionKind, diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 67e1e15defab..4ba61226a3fd 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -109,9 +109,6 @@ mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = .note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior .label = use of extern static -mir_build_indirect_structural_match = - to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]` - mir_build_inform_irrefutable = `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant mir_build_initializing_type_with_requires_unsafe = @@ -257,9 +254,6 @@ mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type mir_build_non_partial_eq_match = to use a constant of type `{$non_peq_ty}` in a pattern, the type must implement `PartialEq` -mir_build_nontrivial_structural_match = - to use a constant of type `{$non_sm_ty}` in a pattern, the constant's initializer must be trivial or `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]` - mir_build_pattern_not_covered = refutable pattern in {$origin} .pattern_ty = the matched value is of type `{$pattern_ty}` diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 93d0d4e59ba9..4b62afa61bbd 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -4,7 +4,6 @@ use crate::build::expr::category::Category; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder, Capture, CaptureMap}; use rustc_hir::def_id::LocalDefId; -use rustc_middle::bug; use rustc_middle::hir::place::Projection as HirProjection; use rustc_middle::hir::place::ProjectionKind as HirProjectionKind; use rustc_middle::middle::region; @@ -13,6 +12,7 @@ use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::AdtDef; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, Variance}; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use tracing::{debug, instrument, trace}; @@ -252,7 +252,18 @@ fn strip_prefix<'a, 'tcx>( impl<'tcx> PlaceBuilder<'tcx> { pub(in crate::build) fn to_place(&self, cx: &Builder<'_, 'tcx>) -> Place<'tcx> { - self.try_to_place(cx).unwrap() + self.try_to_place(cx).unwrap_or_else(|| match self.base { + PlaceBase::Local(local) => span_bug!( + cx.local_decls[local].source_info.span, + "could not resolve local: {local:#?} + {:?}", + self.projection + ), + PlaceBase::Upvar { var_hir_id, closure_def_id: _ } => span_bug!( + cx.tcx.hir().span(var_hir_id.0), + "could not resolve upvar: {var_hir_id:?} + {:?}", + self.projection + ), + }) } /// Creates a `Place` or returns `None` if an upvar cannot be resolved diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 38e6c00add81..ae6e126a4e2c 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -794,9 +794,12 @@ pub struct NaNPattern { pub span: Span, } -#[derive(LintDiagnostic)] +#[derive(Diagnostic)] #[diag(mir_build_pointer_pattern)] -pub struct PointerPattern; +pub struct PointerPattern { + #[primary_span] + pub span: Span, +} #[derive(Diagnostic)] #[diag(mir_build_non_empty_never_pattern)] @@ -808,22 +811,6 @@ pub struct NonEmptyNeverPattern<'tcx> { pub ty: Ty<'tcx>, } -#[derive(LintDiagnostic)] -#[diag(mir_build_indirect_structural_match)] -#[note(mir_build_type_not_structural_tip)] -#[note(mir_build_type_not_structural_more_info)] -pub struct IndirectStructuralMatch<'tcx> { - pub non_sm_ty: Ty<'tcx>, -} - -#[derive(LintDiagnostic)] -#[diag(mir_build_nontrivial_structural_match)] -#[note(mir_build_type_not_structural_tip)] -#[note(mir_build_type_not_structural_more_info)] -pub struct NontrivialStructuralMatch<'tcx> { - pub non_sm_ty: Ty<'tcx>, -} - #[derive(Diagnostic)] #[diag(mir_build_exceeds_mcdc_condition_num_limit)] pub(crate) struct MCDCExceedsConditionNumLimit { diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index bac47fafbfd7..8d881713eeb3 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -7,7 +7,6 @@ use rustc_middle::mir; use rustc_middle::span_bug; use rustc_middle::thir::{FieldPat, Pat, PatKind}; use rustc_middle::ty::{self, Ty, TyCtxt, ValTree}; -use rustc_session::lint; use rustc_span::{ErrorGuaranteed, Span}; use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; @@ -18,8 +17,8 @@ use std::cell::Cell; use super::PatCtxt; use crate::errors::{ - IndirectStructuralMatch, InvalidPattern, NaNPattern, PointerPattern, TypeNotPartialEq, - TypeNotStructural, UnionPattern, UnsizedPattern, + InvalidPattern, NaNPattern, PointerPattern, TypeNotPartialEq, TypeNotStructural, UnionPattern, + UnsizedPattern, }; impl<'a, 'tcx> PatCtxt<'a, 'tcx> { @@ -51,15 +50,6 @@ struct ConstToPat<'tcx> { // value. saw_const_match_error: Cell>, - // This tracks if we emitted some diagnostic for a given const value, so that - // we will not subsequently issue an irrelevant lint for the same const - // value. - saw_const_match_lint: Cell, - - // For backcompat we need to keep allowing non-structurally-eq types behind references. - // See also all the `cant-hide-behind` tests. - behind_reference: Cell, - // inference context used for checking `T: Structural` bounds. infcx: InferCtxt<'tcx>, @@ -86,8 +76,6 @@ impl<'tcx> ConstToPat<'tcx> { infcx, param_env: pat_ctxt.param_env, saw_const_match_error: Cell::new(None), - saw_const_match_lint: Cell::new(false), - behind_reference: Cell::new(false), treat_byte_string_as_slice: pat_ctxt .typeck_results .treat_byte_string_as_slice @@ -199,15 +187,12 @@ impl<'tcx> ConstToPat<'tcx> { // complained about structural match violations there, so we don't // have to check anything any more. } - } else if !have_valtree && !self.saw_const_match_lint.get() { + } else if !have_valtree { // The only way valtree construction can fail without the structural match // checker finding a violation is if there is a pointer somewhere. - self.tcx().emit_node_span_lint( - lint::builtin::POINTER_STRUCTURAL_MATCH, - self.id, - self.span, - PointerPattern, - ); + let e = self.tcx().dcx().emit_err(PointerPattern { span: self.span }); + let kind = PatKind::Error(e); + return Box::new(Pat { span: self.span, ty: cv.ty(), kind }); } // Always check for `PartialEq` if we had no other errors yet. @@ -276,36 +261,11 @@ impl<'tcx> ConstToPat<'tcx> { cv: ValTree<'tcx>, ty: Ty<'tcx>, ) -> Result>, FallbackToOpaqueConst> { - let id = self.id; let span = self.span; let tcx = self.tcx(); let param_env = self.param_env; let kind = match ty.kind() { - // If the type is not structurally comparable, just emit the constant directly, - // causing the pattern match code to treat it opaquely. - // FIXME: This code doesn't emit errors itself, the caller emits the errors. - // So instead of specific errors, you just get blanket errors about the whole - // const type. See - // https://github.com/rust-lang/rust/pull/70743#discussion_r404701963 for - // details. - // Backwards compatibility hack because we can't cause hard errors on these - // types, so we compare them via `PartialEq::eq` at runtime. - ty::Adt(..) if !self.type_marked_structural(ty) && self.behind_reference.get() => { - if self.saw_const_match_error.get().is_none() && !self.saw_const_match_lint.get() { - self.saw_const_match_lint.set(true); - tcx.emit_node_span_lint( - lint::builtin::INDIRECT_STRUCTURAL_MATCH, - id, - span, - IndirectStructuralMatch { non_sm_ty: ty }, - ); - } - // Since we are behind a reference, we can just bubble the error up so we get a - // constant at reference type, making it easy to let the fallback call - // `PartialEq::eq` on it. - return Err(FallbackToOpaqueConst); - } ty::FnDef(..) => { let e = tcx.dcx().emit_err(InvalidPattern { span, non_sm_ty: ty }); self.saw_const_match_error.set(Some(e)); @@ -379,38 +339,6 @@ impl<'tcx> ConstToPat<'tcx> { ty::Str => { PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) } } - // Backwards compatibility hack: support references to non-structural types, - // but hard error if we aren't behind a double reference. We could just use - // the fallback code path below, but that would allow *more* of this fishy - // code to compile, as then it only goes through the future incompat lint - // instead of a hard error. - ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => { - if self.behind_reference.get() { - if self.saw_const_match_error.get().is_none() - && !self.saw_const_match_lint.get() - { - self.saw_const_match_lint.set(true); - tcx.emit_node_span_lint( - lint::builtin::INDIRECT_STRUCTURAL_MATCH, - self.id, - span, - IndirectStructuralMatch { non_sm_ty: *pointee_ty }, - ); - } - return Err(FallbackToOpaqueConst); - } else { - if let Some(e) = self.saw_const_match_error.get() { - // We already errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Error(e) - } else { - let err = TypeNotStructural { span, non_sm_ty: *pointee_ty }; - let e = tcx.dcx().emit_err(err); - self.saw_const_match_error.set(Some(e)); - // We errored. Signal that in the pattern, so that follow up errors can be silenced. - PatKind::Error(e) - } - } - } // All other references are converted into deref patterns and then recursively // convert the dereferenced constant to a pattern that is the sub-pattern of the // deref pattern. @@ -421,7 +349,6 @@ impl<'tcx> ConstToPat<'tcx> { // We errored. Signal that in the pattern, so that follow up errors can be silenced. PatKind::Error(e) } else { - let old = self.behind_reference.replace(true); // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when // matching against references, you can only use byte string literals. // The typechecker has a special case for byte string literals, by treating them @@ -436,7 +363,6 @@ impl<'tcx> ConstToPat<'tcx> { }; // References have the same valtree representation as their pointee. let subpattern = self.recur(cv, pointee_ty)?; - self.behind_reference.set(old); PatKind::Deref { subpattern } } } diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 53a016f01ece..e88b727a21e9 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -69,7 +69,7 @@ struct ConstAnalysis<'a, 'tcx> { map: Map, tcx: TyCtxt<'tcx>, local_decls: &'a LocalDecls<'tcx>, - ecx: InterpCx<'tcx, 'tcx, DummyMachine>, + ecx: InterpCx<'tcx, DummyMachine>, param_env: ty::ParamEnv<'tcx>, } @@ -142,11 +142,10 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { _ => return, }; if let Some(variant_target_idx) = variant_target { - for (field_index, operand) in operands.iter().enumerate() { - if let Some(field) = self.map().apply( - variant_target_idx, - TrackElem::Field(FieldIdx::from_usize(field_index)), - ) { + for (field_index, operand) in operands.iter_enumerated() { + if let Some(field) = + self.map().apply(variant_target_idx, TrackElem::Field(field_index)) + { self.assign_operand(state, field, operand); } } @@ -565,7 +564,7 @@ impl<'tcx, 'locals> Collector<'tcx, 'locals> { fn try_make_constant( &self, - ecx: &mut InterpCx<'tcx, 'tcx, DummyMachine>, + ecx: &mut InterpCx<'tcx, DummyMachine>, place: Place<'tcx>, state: &State>, map: &Map, @@ -618,7 +617,7 @@ fn propagatable_scalar( #[instrument(level = "trace", skip(ecx, state, map))] fn try_write_constant<'tcx>( - ecx: &mut InterpCx<'_, 'tcx, DummyMachine>, + ecx: &mut InterpCx<'tcx, DummyMachine>, dest: &PlaceTy<'tcx>, place: PlaceIndex, ty: Ty<'tcx>, @@ -836,7 +835,7 @@ impl<'tcx> MutVisitor<'tcx> for Patch<'tcx> { struct OperandCollector<'tcx, 'map, 'locals, 'a> { state: &'a State>, visitor: &'a mut Collector<'tcx, 'locals>, - ecx: &'map mut InterpCx<'tcx, 'tcx, DummyMachine>, + ecx: &'map mut InterpCx<'tcx, DummyMachine>, map: &'map Map, } diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index 0634e321ea30..b28dcb38cb6b 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -1,4 +1,4 @@ -use rustc_errors::{codes::*, Diag, DiagMessage, LintDiagnostic}; +use rustc_errors::{codes::*, Diag, LintDiagnostic}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::mir::AssertKind; use rustc_middle::ty::TyCtxt; @@ -50,18 +50,15 @@ pub(crate) enum AssertLintKind { impl<'a, P: std::fmt::Debug> LintDiagnostic<'a, ()> for AssertLint

{ fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { - let message = self.assert_kind.diagnostic_message(); + diag.primary_message(match self.lint_kind { + AssertLintKind::ArithmeticOverflow => fluent::mir_transform_arithmetic_overflow, + AssertLintKind::UnconditionalPanic => fluent::mir_transform_operation_will_panic, + }); + let label = self.assert_kind.diagnostic_message(); self.assert_kind.add_args(&mut |name, value| { diag.arg(name, value); }); - diag.span_label(self.span, message); - } - - fn msg(&self) -> DiagMessage { - match self.lint_kind { - AssertLintKind::ArithmeticOverflow => fluent::mir_transform_arithmetic_overflow, - AssertLintKind::UnconditionalPanic => fluent::mir_transform_operation_will_panic, - } + diag.span_label(self.span, label); } } @@ -104,6 +101,7 @@ pub(crate) struct MustNotSupend<'tcx, 'a> { // Needed for def_path_str impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> { fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { + diag.primary_message(fluent::mir_transform_must_not_suspend); diag.span_label(self.yield_sp, fluent::_subdiag::label); if let Some(reason) = self.reason { diag.subdiagnostic(diag.dcx, reason); @@ -113,10 +111,6 @@ impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> { diag.arg("def_path", self.tcx.def_path_str(self.def_id)); diag.arg("post", self.post); } - - fn msg(&self) -> rustc_errors::DiagMessage { - fluent::mir_transform_must_not_suspend - } } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 9d2e7153eb56..fadb5edefdfb 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -234,7 +234,7 @@ enum Value<'tcx> { struct VnState<'body, 'tcx> { tcx: TyCtxt<'tcx>, - ecx: InterpCx<'tcx, 'tcx, DummyMachine>, + ecx: InterpCx<'tcx, DummyMachine>, param_env: ty::ParamEnv<'tcx>, local_decls: &'body LocalDecls<'tcx>, /// Value stored in each local. @@ -1139,7 +1139,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } fn op_to_prop_const<'tcx>( - ecx: &mut InterpCx<'_, 'tcx, DummyMachine>, + ecx: &mut InterpCx<'tcx, DummyMachine>, op: &OpTy<'tcx>, ) -> Option> { // Do not attempt to propagate unsized locals. diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index f1adeab3f884..5e70b300f338 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -9,7 +9,6 @@ use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt}; use rustc_span::sym; use rustc_span::symbol::Symbol; -use rustc_target::abi::FieldIdx; use rustc_target::spec::abi::Abi; pub struct InstSimplify; @@ -217,11 +216,11 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { && let Some(place) = operand.place() { let variant = adt_def.non_enum_variant(); - for (i, field) in variant.fields.iter().enumerate() { + for (i, field) in variant.fields.iter_enumerated() { let field_ty = field.ty(self.tcx, args); if field_ty == *cast_ty { let place = place.project_deeper( - &[ProjectionElem::Field(FieldIdx::from_usize(i), *cast_ty)], + &[ProjectionElem::Field(i, *cast_ty)], self.tcx, ); let operand = if operand.is_move() { diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index ae807655b68d..23cc0c46e739 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -155,7 +155,7 @@ struct ThreadingOpportunity { struct TOFinder<'tcx, 'a> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - ecx: InterpCx<'tcx, 'tcx, DummyMachine>, + ecx: InterpCx<'tcx, DummyMachine>, body: &'a Body<'tcx>, map: &'a Map, loop_headers: &'a BitSet, diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 0fa5c1b91261..9ba22870403f 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -64,7 +64,7 @@ impl<'tcx> MirLint<'tcx> for KnownPanicsLint { /// Visits MIR nodes, performs const propagation /// and runs lint checks as it goes struct ConstPropagator<'mir, 'tcx> { - ecx: InterpCx<'mir, 'tcx, DummyMachine>, + ecx: InterpCx<'tcx, DummyMachine>, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, worklist: Vec, diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index cdf3305b5609..f19c34cae7a7 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -70,6 +70,11 @@ fn escaping_locals<'tcx>( // Exclude #[repr(simd)] types so that they are not de-optimized into an array return true; } + if Some(def.did()) == tcx.lang_items().dyn_metadata() { + // codegen wants to see the `DynMetadata`, + // not the inner reference-to-opaque-type. + return true; + } // We already excluded unions and enums, so this ADT must have one variant let variant = def.variant(FIRST_VARIANT); if variant.fields.len() > 1 { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 76972ff2263d..9487692662bb 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1434,6 +1434,15 @@ impl<'v> RootCollector<'_, 'v> { { debug!("RootCollector: ADT drop-glue for `{id:?}`",); + // This type is impossible to instantiate, so we should not try to + // generate a `drop_in_place` instance for it. + if self.tcx.instantiate_and_check_impossible_predicates(( + id.owner_id.to_def_id(), + ty::List::empty(), + )) { + return; + } + let ty = self.tcx.type_of(id.owner_id.to_def_id()).no_bound_vars().unwrap(); visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output); } diff --git a/compiler/rustc_pattern_analysis/src/lints.rs b/compiler/rustc_pattern_analysis/src/lints.rs index 1d10c9df4ab2..892aacd7ac5d 100644 --- a/compiler/rustc_pattern_analysis/src/lints.rs +++ b/compiler/rustc_pattern_analysis/src/lints.rs @@ -99,7 +99,6 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'p, 'tcx>( use rustc_errors::LintDiagnostic; let mut err = rcx.tcx.dcx().struct_span_warn(arm.pat.data().span, ""); - err.primary_message(decorator.msg()); decorator.decorate_lint(&mut err); err.emit(); } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 5ac4d194e872..c90da966e708 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -796,16 +796,6 @@ pub struct NextSolverConfig { /// Whether the new trait solver should be enabled everywhere. /// This is only `true` if `coherence` is also enabled. pub globally: bool, - /// Whether to dump proof trees after computing a proof tree. - pub dump_tree: DumpSolverProofTree, -} - -#[derive(Default, Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub enum DumpSolverProofTree { - Always, - OnError, - #[default] - Never, } #[derive(Clone)] diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index ce866906e1e6..cb02fbdfee9e 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -1,5 +1,4 @@ #![feature(let_chains)] -#![feature(lazy_cell)] #![feature(option_get_or_insert_default)] #![feature(rustc_attrs)] #![feature(map_many_mut)] diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 65660286dd73..6309fcdd2db3 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -399,7 +399,8 @@ mod desc { pub const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`"; pub const parse_unpretty: &str = "`string` or `string=string`"; pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number"; - pub const parse_next_solver_config: &str = "a comma separated list of solver configurations: `globally` (default), `coherence`, `dump-tree`, `dump-tree-on-error"; + pub const parse_next_solver_config: &str = + "a comma separated list of solver configurations: `globally` (default), and `coherence`"; pub const parse_lto: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted"; pub const parse_linker_plugin_lto: &str = @@ -1058,7 +1059,6 @@ mod parse { if let Some(config) = v { let mut coherence = false; let mut globally = true; - let mut dump_tree = None; for c in config.split(',') { match c { "globally" => globally = true, @@ -1066,31 +1066,13 @@ mod parse { globally = false; coherence = true; } - "dump-tree" => { - if dump_tree.replace(DumpSolverProofTree::Always).is_some() { - return false; - } - } - "dump-tree-on-error" => { - if dump_tree.replace(DumpSolverProofTree::OnError).is_some() { - return false; - } - } _ => return false, } } - *slot = Some(NextSolverConfig { - coherence: coherence || globally, - globally, - dump_tree: dump_tree.unwrap_or_default(), - }); + *slot = Some(NextSolverConfig { coherence: coherence || globally, globally }); } else { - *slot = Some(NextSolverConfig { - coherence: true, - globally: true, - dump_tree: Default::default(), - }); + *slot = Some(NextSolverConfig { coherence: true, globally: true }); } true diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index be20924670c3..a511989d972c 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -771,7 +771,6 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { use stable_mir::ty::{BoundRegion, EarlyParamRegion, RegionKind}; match self { ty::ReEarlyParam(early_reg) => RegionKind::ReEarlyParam(EarlyParamRegion { - def_id: tables.region_def(early_reg.def_id), index: early_reg.index, name: early_reg.name.to_string(), }), diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 1b507bb2a155..d9812540e497 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -199,11 +199,9 @@ const X86_ALLOWED_FEATURES: &[(&str, Stability)] = &[ ("avx512bw", Unstable(sym::avx512_target_feature)), ("avx512cd", Unstable(sym::avx512_target_feature)), ("avx512dq", Unstable(sym::avx512_target_feature)), - ("avx512er", Unstable(sym::avx512_target_feature)), ("avx512f", Unstable(sym::avx512_target_feature)), ("avx512fp16", Unstable(sym::avx512_target_feature)), ("avx512ifma", Unstable(sym::avx512_target_feature)), - ("avx512pf", Unstable(sym::avx512_target_feature)), ("avx512vbmi", Unstable(sym::avx512_target_feature)), ("avx512vbmi2", Unstable(sym::avx512_target_feature)), ("avx512vl", Unstable(sym::avx512_target_feature)), diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 7e1d7d73e0b3..ce408ddea378 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -1,6 +1,3 @@ -use std::io::Write; -use std::ops::ControlFlow; - use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::def_id::DefId; use rustc_infer::infer::at::ToTrace; @@ -20,10 +17,10 @@ use rustc_middle::ty::{ self, InferCtxtLike, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; -use rustc_session::config::DumpSolverProofTree; use rustc_span::DUMMY_SP; use rustc_type_ir::{self as ir, CanonicalVarValues, Interner}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use std::ops::ControlFlow; use crate::traits::coherence; use crate::traits::vtable::{count_own_vtable_entries, prepare_vtable_segments, VtblSegment}; @@ -135,8 +132,7 @@ impl NestedGoals { #[derive(PartialEq, Eq, Debug, Hash, HashStable, Clone, Copy)] pub enum GenerateProofTree { Yes, - IfEnabled, - Never, + No, } #[extension(pub trait InferCtxtEvalExt<'tcx>)] @@ -182,7 +178,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { infcx, search_graph: &mut search_graph, nested_goals: NestedGoals::new(), - inspect: ProofTreeBuilder::new_maybe_root(infcx.tcx, generate_proof_tree), + inspect: ProofTreeBuilder::new_maybe_root(generate_proof_tree), // Only relevant when canonicalizing the response, // which we don't do within this evaluation context. @@ -197,23 +193,14 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { }; let result = f(&mut ecx); - let tree = ecx.inspect.finalize(); - if let (Some(tree), DumpSolverProofTree::Always) = ( - &tree, - infcx.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default(), - ) { - let mut lock = std::io::stdout().lock(); - let _ = lock.write_fmt(format_args!("{tree:?}\n")); - let _ = lock.flush(); - } - + let proof_tree = ecx.inspect.finalize(); assert!( ecx.nested_goals.is_empty(), "root `EvalCtxt` should not have any goals added to it" ); assert!(search_graph.is_empty()); - (result, tree) + (result, proof_tree) } /// Creates a nested evaluation context that shares the same search graph as the @@ -483,7 +470,6 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { // the certainty of all the goals. #[instrument(level = "trace", skip(self))] pub(super) fn try_evaluate_added_goals(&mut self) -> Result { - self.inspect.start_evaluate_added_goals(); let mut response = Ok(Certainty::overflow(false)); for _ in 0..FIXPOINT_STEP_LIMIT { // FIXME: This match is a bit ugly, it might be nice to change the inspect @@ -501,8 +487,6 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { } } - self.inspect.evaluate_added_goals_result(response); - if response.is_err() { self.tainted = Err(NoSolution); } @@ -515,7 +499,6 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { /// Goals for the next step get directly added to the nested goals of the `EvalCtxt`. fn evaluate_added_goals_step(&mut self) -> Result, NoSolution> { let tcx = self.tcx(); - self.inspect.start_evaluate_added_goals_step(); let mut goals = core::mem::take(&mut self.nested_goals); // If this loop did not result in any progress, what's our final certainty. diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 7291eb00e727..d28cf834032d 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -79,7 +79,7 @@ impl<'tcx> ObligationStorage<'tcx> { // change. self.overflowed.extend(self.pending.extract_if(|o| { let goal = o.clone().into(); - let result = infcx.evaluate_root_goal(goal, GenerateProofTree::Never).0; + let result = infcx.evaluate_root_goal(goal, GenerateProofTree::No).0; match result { Ok((has_changed, _)) => has_changed, _ => false, @@ -159,7 +159,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { let mut has_changed = false; for obligation in self.obligations.unstalled_for_select() { let goal = obligation.clone().into(); - let result = infcx.evaluate_root_goal(goal, GenerateProofTree::IfEnabled).0; + let result = infcx.evaluate_root_goal(goal, GenerateProofTree::No).0; self.inspect_evaluated_obligation(infcx, &obligation, &result); let (changed, certainty) = match result { Ok(result) => result, @@ -246,7 +246,7 @@ fn fulfillment_error_for_stalled<'tcx>( root_obligation: PredicateObligation<'tcx>, ) -> FulfillmentError<'tcx> { let (code, refine_obligation) = infcx.probe(|_| { - match infcx.evaluate_root_goal(root_obligation.clone().into(), GenerateProofTree::Never).0 { + match infcx.evaluate_root_goal(root_obligation.clone().into(), GenerateProofTree::No).0 { Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => { (FulfillmentErrorCode::Ambiguity { overflow: None }, true) } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 737d03f73f00..447357f8b3f6 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -317,7 +317,6 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { inspect::ProbeStep::RecordImplArgs { impl_args: i } => { assert_eq!(impl_args.replace(i), None); } - inspect::ProbeStep::EvaluateGoals(_) => (), } } @@ -359,13 +358,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { warn!("unexpected root evaluation: {:?}", self.evaluation_kind); return vec![]; } - inspect::CanonicalGoalEvaluationKind::Evaluation { revisions } => { - if let Some(last) = revisions.last() { - last - } else { - return vec![]; - } - } + inspect::CanonicalGoalEvaluationKind::Evaluation { final_revision } => final_revision, }; let mut nested_goals = vec![]; @@ -392,9 +385,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { normalizes_to_term_hack: Option>, source: GoalSource, ) -> Self { - let inspect::GoalEvaluation { uncanonicalized_goal, kind, evaluation } = root; - let inspect::GoalEvaluationKind::Root { orig_values } = kind else { unreachable!() }; - + let inspect::GoalEvaluation { uncanonicalized_goal, orig_values, evaluation } = root; let result = evaluation.result.and_then(|ok| { if let Some(term_hack) = normalizes_to_term_hack { infcx diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs index 803300c5196c..3c6333626483 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs @@ -5,20 +5,17 @@ //! see the comment on [ProofTreeBuilder]. use std::mem; +use crate::solve::eval_ctxt::canonical; +use crate::solve::{self, inspect, GenerateProofTree}; use rustc_infer::infer::InferCtxt; use rustc_middle::bug; use rustc_middle::infer::canonical::CanonicalVarValues; -use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{self, TyCtxt}; use rustc_next_trait_solver::solve::{ CanonicalInput, Certainty, Goal, GoalSource, QueryInput, QueryResult, }; -use rustc_session::config::DumpSolverProofTree; use rustc_type_ir::Interner; -use crate::solve::eval_ctxt::canonical; -use crate::solve::{self, inspect, GenerateProofTree}; - /// The core data structure when building proof trees. /// /// In case the current evaluation does not generate a proof @@ -53,7 +50,7 @@ enum DebugSolver { Root, GoalEvaluation(WipGoalEvaluation), CanonicalGoalEvaluation(WipCanonicalGoalEvaluation), - GoalEvaluationStep(WipGoalEvaluationStep), + CanonicalGoalEvaluationStep(WipCanonicalGoalEvaluationStep), } impl From> for DebugSolver { @@ -68,9 +65,9 @@ impl From> for DebugSolver { } } -impl From> for DebugSolver { - fn from(g: WipGoalEvaluationStep) -> DebugSolver { - DebugSolver::GoalEvaluationStep(g) +impl From> for DebugSolver { + fn from(g: WipCanonicalGoalEvaluationStep) -> DebugSolver { + DebugSolver::CanonicalGoalEvaluationStep(g) } } @@ -78,7 +75,7 @@ impl From> for DebugSolver { #[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))] struct WipGoalEvaluation { pub uncanonicalized_goal: Goal, - pub kind: WipGoalEvaluationKind, + pub orig_values: Vec, pub evaluation: Option>, } @@ -86,31 +83,19 @@ impl WipGoalEvaluation { fn finalize(self) -> inspect::GoalEvaluation { inspect::GoalEvaluation { uncanonicalized_goal: self.uncanonicalized_goal, - kind: match self.kind { - WipGoalEvaluationKind::Root { orig_values } => { - inspect::GoalEvaluationKind::Root { orig_values } - } - WipGoalEvaluationKind::Nested => inspect::GoalEvaluationKind::Nested, - }, + orig_values: self.orig_values, evaluation: self.evaluation.unwrap().finalize(), } } } -#[derive(derivative::Derivative)] -#[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))] -pub(in crate::solve) enum WipGoalEvaluationKind { - Root { orig_values: Vec }, - Nested, -} - #[derive(derivative::Derivative)] #[derivative(PartialEq(bound = ""), Eq(bound = ""))] pub(in crate::solve) enum WipCanonicalGoalEvaluationKind { Overflow, CycleInStack, ProvisionalCacheHit, - Interned { revisions: I::GoalEvaluationSteps }, + Interned { final_revision: I::CanonicalGoalEvaluationStepRef }, } impl std::fmt::Debug for WipCanonicalGoalEvaluationKind { @@ -119,7 +104,9 @@ impl std::fmt::Debug for WipCanonicalGoalEvaluationKind { Self::Overflow => write!(f, "Overflow"), Self::CycleInStack => write!(f, "CycleInStack"), Self::ProvisionalCacheHit => write!(f, "ProvisionalCacheHit"), - Self::Interned { revisions: _ } => f.debug_struct("Interned").finish_non_exhaustive(), + Self::Interned { final_revision: _ } => { + f.debug_struct("Interned").finish_non_exhaustive() + } } } } @@ -131,13 +118,15 @@ struct WipCanonicalGoalEvaluation { kind: Option>, /// Only used for uncached goals. After we finished evaluating /// the goal, this is interned and moved into `kind`. - revisions: Vec>, + final_revision: Option>, result: Option>, } impl WipCanonicalGoalEvaluation { fn finalize(self) -> inspect::CanonicalGoalEvaluation { - assert!(self.revisions.is_empty()); + // We've already interned the final revision in + // `fn finalize_canonical_goal_evaluation`. + assert!(self.final_revision.is_none()); let kind = match self.kind.unwrap() { WipCanonicalGoalEvaluationKind::Overflow => { inspect::CanonicalGoalEvaluationKind::Overflow @@ -148,8 +137,8 @@ impl WipCanonicalGoalEvaluation { WipCanonicalGoalEvaluationKind::ProvisionalCacheHit => { inspect::CanonicalGoalEvaluationKind::ProvisionalCacheHit } - WipCanonicalGoalEvaluationKind::Interned { revisions } => { - inspect::CanonicalGoalEvaluationKind::Evaluation { revisions } + WipCanonicalGoalEvaluationKind::Interned { final_revision } => { + inspect::CanonicalGoalEvaluationKind::Evaluation { final_revision } } }; @@ -159,29 +148,7 @@ impl WipCanonicalGoalEvaluation { #[derive(derivative::Derivative)] #[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))] -struct WipAddedGoalsEvaluation { - evaluations: Vec>>, - result: Option>, -} - -impl WipAddedGoalsEvaluation { - fn finalize(self) -> inspect::AddedGoalsEvaluation { - inspect::AddedGoalsEvaluation { - evaluations: self - .evaluations - .into_iter() - .map(|evaluations| { - evaluations.into_iter().map(WipGoalEvaluation::finalize).collect() - }) - .collect(), - result: self.result.unwrap(), - } - } -} - -#[derive(derivative::Derivative)] -#[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))] -struct WipGoalEvaluationStep { +struct WipCanonicalGoalEvaluationStep { /// Unlike `EvalCtxt::var_values`, we append a new /// generic arg here whenever we create a new inference /// variable. @@ -194,7 +161,7 @@ struct WipGoalEvaluationStep { evaluation: WipProbe, } -impl WipGoalEvaluationStep { +impl WipCanonicalGoalEvaluationStep { fn current_evaluation_scope(&mut self) -> &mut WipProbe { let mut current = &mut self.evaluation; for _ in 0..self.probe_depth { @@ -206,24 +173,16 @@ impl WipGoalEvaluationStep { current } - fn added_goals_evaluation(&mut self) -> &mut WipAddedGoalsEvaluation { - let mut current = &mut self.evaluation; - loop { - match current.steps.last_mut() { - Some(WipProbeStep::NestedProbe(p)) => current = p, - Some(WipProbeStep::EvaluateGoals(evaluation)) => return evaluation, - _ => bug!(), - } - } - } - - fn finalize(self) -> inspect::GoalEvaluationStep { + fn finalize(self) -> inspect::CanonicalGoalEvaluationStep { let evaluation = self.evaluation.finalize(); match evaluation.kind { inspect::ProbeKind::Root { .. } => (), _ => unreachable!("unexpected root evaluation: {evaluation:?}"), } - inspect::GoalEvaluationStep { instantiated_goal: self.instantiated_goal, evaluation } + inspect::CanonicalGoalEvaluationStep { + instantiated_goal: self.instantiated_goal, + evaluation, + } } } @@ -250,7 +209,6 @@ impl WipProbe { #[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))] enum WipProbeStep { AddGoal(GoalSource, inspect::CanonicalState>), - EvaluateGoals(WipAddedGoalsEvaluation), NestedProbe(WipProbe), MakeCanonicalResponse { shallow_certainty: Certainty }, RecordImplArgs { impl_args: inspect::CanonicalState }, @@ -260,7 +218,6 @@ impl WipProbeStep { fn finalize(self) -> inspect::ProbeStep { match self { WipProbeStep::AddGoal(source, goal) => inspect::ProbeStep::AddGoal(source, goal), - WipProbeStep::EvaluateGoals(eval) => inspect::ProbeStep::EvaluateGoals(eval.finalize()), WipProbeStep::NestedProbe(probe) => inspect::ProbeStep::NestedProbe(probe.finalize()), WipProbeStep::RecordImplArgs { impl_args } => { inspect::ProbeStep::RecordImplArgs { impl_args } @@ -278,6 +235,15 @@ impl<'tcx> ProofTreeBuilder> { ProofTreeBuilder { state: Some(Box::new(state.into())) } } + fn opt_nested>>>( + &self, + state: impl FnOnce() -> Option, + ) -> Self { + ProofTreeBuilder { + state: self.state.as_ref().and_then(|_| Some(state()?.into())).map(Box::new), + } + } + fn nested>>>(&self, state: impl FnOnce() -> T) -> Self { ProofTreeBuilder { state: self.state.as_ref().map(|_| Box::new(state().into())) } } @@ -302,22 +268,10 @@ impl<'tcx> ProofTreeBuilder> { } pub fn new_maybe_root( - tcx: TyCtxt<'tcx>, generate_proof_tree: GenerateProofTree, ) -> ProofTreeBuilder> { match generate_proof_tree { - GenerateProofTree::Never => ProofTreeBuilder::new_noop(), - GenerateProofTree::IfEnabled => { - let opts = &tcx.sess.opts.unstable_opts; - match opts.next_solver.map(|c| c.dump_tree).unwrap_or_default() { - DumpSolverProofTree::Always => ProofTreeBuilder::new_root(), - // `OnError` is handled by reevaluating goals in error - // reporting with `GenerateProofTree::Yes`. - DumpSolverProofTree::OnError | DumpSolverProofTree::Never => { - ProofTreeBuilder::new_noop() - } - } - } + GenerateProofTree::No => ProofTreeBuilder::new_noop(), GenerateProofTree::Yes => ProofTreeBuilder::new_root(), } } @@ -340,15 +294,13 @@ impl<'tcx> ProofTreeBuilder> { orig_values: &[ty::GenericArg<'tcx>], kind: solve::GoalEvaluationKind, ) -> ProofTreeBuilder> { - self.nested(|| WipGoalEvaluation { - uncanonicalized_goal: goal, - kind: match kind { - solve::GoalEvaluationKind::Root => { - WipGoalEvaluationKind::Root { orig_values: orig_values.to_vec() } - } - solve::GoalEvaluationKind::Nested => WipGoalEvaluationKind::Nested, - }, - evaluation: None, + self.opt_nested(|| match kind { + solve::GoalEvaluationKind::Root => Some(WipGoalEvaluation { + uncanonicalized_goal: goal, + orig_values: orig_values.to_vec(), + evaluation: None, + }), + solve::GoalEvaluationKind::Nested => None, }) } @@ -359,24 +311,22 @@ impl<'tcx> ProofTreeBuilder> { self.nested(|| WipCanonicalGoalEvaluation { goal, kind: None, - revisions: vec![], + final_revision: None, result: None, }) } - pub fn finalize_evaluation( + pub fn finalize_canonical_goal_evaluation( &mut self, tcx: TyCtxt<'tcx>, - ) -> Option<&'tcx [inspect::GoalEvaluationStep>]> { + ) -> Option<&'tcx inspect::CanonicalGoalEvaluationStep>> { self.as_mut().map(|this| match this { DebugSolver::CanonicalGoalEvaluation(evaluation) => { - let revisions = mem::take(&mut evaluation.revisions) - .into_iter() - .map(WipGoalEvaluationStep::finalize); - let revisions = &*tcx.arena.alloc_from_iter(revisions); - let kind = WipCanonicalGoalEvaluationKind::Interned { revisions }; + let final_revision = mem::take(&mut evaluation.final_revision).unwrap(); + let final_revision = &*tcx.arena.alloc(final_revision.finalize()); + let kind = WipCanonicalGoalEvaluationKind::Interned { final_revision }; assert_eq!(evaluation.kind.replace(kind), None); - revisions + final_revision } _ => unreachable!(), }) @@ -400,7 +350,10 @@ impl<'tcx> ProofTreeBuilder> { } } - pub fn goal_evaluation_kind(&mut self, kind: WipCanonicalGoalEvaluationKind>) { + pub fn canonical_goal_evaluation_kind( + &mut self, + kind: WipCanonicalGoalEvaluationKind>, + ) { if let Some(this) = self.as_mut() { match this { DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => { @@ -413,17 +366,11 @@ impl<'tcx> ProofTreeBuilder> { pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder>) { if let Some(this) = self.as_mut() { - match (this, *goal_evaluation.state.unwrap()) { - ( - DebugSolver::GoalEvaluationStep(state), - DebugSolver::GoalEvaluation(goal_evaluation), - ) => state - .added_goals_evaluation() - .evaluations - .last_mut() - .unwrap() - .push(goal_evaluation), - (this @ DebugSolver::Root, goal_evaluation) => *this = goal_evaluation, + match this { + DebugSolver::Root => *this = *goal_evaluation.state.unwrap(), + DebugSolver::CanonicalGoalEvaluationStep(_) => { + assert!(goal_evaluation.state.is_none()) + } _ => unreachable!(), } } @@ -434,7 +381,7 @@ impl<'tcx> ProofTreeBuilder> { var_values: CanonicalVarValues<'tcx>, instantiated_goal: QueryInput, ty::Predicate<'tcx>>, ) -> ProofTreeBuilder> { - self.nested(|| WipGoalEvaluationStep { + self.nested(|| WipCanonicalGoalEvaluationStep { var_values: var_values.var_values.to_vec(), instantiated_goal, evaluation: WipProbe { @@ -452,9 +399,9 @@ impl<'tcx> ProofTreeBuilder> { match (this, *goal_evaluation_step.state.unwrap()) { ( DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluations), - DebugSolver::GoalEvaluationStep(goal_evaluation_step), + DebugSolver::CanonicalGoalEvaluationStep(goal_evaluation_step), ) => { - canonical_goal_evaluations.revisions.push(goal_evaluation_step); + canonical_goal_evaluations.final_revision = Some(goal_evaluation_step); } _ => unreachable!(), } @@ -464,7 +411,7 @@ impl<'tcx> ProofTreeBuilder> { pub fn add_var_value>>(&mut self, arg: T) { match self.as_mut() { None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { state.var_values.push(arg.into()); } Some(s) => bug!("tried to add var values to {s:?}"), @@ -474,7 +421,7 @@ impl<'tcx> ProofTreeBuilder> { pub fn enter_probe(&mut self) { match self.as_mut() { None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { let initial_num_var_values = state.var_values.len(); state.current_evaluation_scope().steps.push(WipProbeStep::NestedProbe(WipProbe { initial_num_var_values, @@ -491,7 +438,7 @@ impl<'tcx> ProofTreeBuilder> { pub fn probe_kind(&mut self, probe_kind: inspect::ProbeKind>) { match self.as_mut() { None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { let prev = state.current_evaluation_scope().kind.replace(probe_kind); assert_eq!(prev, None); } @@ -506,7 +453,7 @@ impl<'tcx> ProofTreeBuilder> { ) { match self.as_mut() { None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { let final_state = canonical::make_canonical_state( infcx, &state.var_values, @@ -543,7 +490,7 @@ impl<'tcx> ProofTreeBuilder> { ) { match self.as_mut() { None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { let goal = canonical::make_canonical_state( infcx, &state.var_values, @@ -563,7 +510,7 @@ impl<'tcx> ProofTreeBuilder> { impl_args: ty::GenericArgsRef<'tcx>, ) { match self.as_mut() { - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { let impl_args = canonical::make_canonical_state( infcx, &state.var_values, @@ -582,7 +529,7 @@ impl<'tcx> ProofTreeBuilder> { pub fn make_canonical_response(&mut self, shallow_certainty: Certainty) { match self.as_mut() { - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { state .current_evaluation_scope() .steps @@ -596,7 +543,7 @@ impl<'tcx> ProofTreeBuilder> { pub fn finish_probe(mut self) -> ProofTreeBuilder> { match self.as_mut() { None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { + Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { assert_ne!(state.probe_depth, 0); let num_var_values = state.current_evaluation_scope().initial_num_var_values; state.var_values.truncate(num_var_values); @@ -608,46 +555,13 @@ impl<'tcx> ProofTreeBuilder> { self } - pub fn start_evaluate_added_goals(&mut self) { - match self.as_mut() { - None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { - state.current_evaluation_scope().steps.push(WipProbeStep::EvaluateGoals( - WipAddedGoalsEvaluation { evaluations: vec![], result: None }, - )); - } - _ => bug!(), - } - } - - pub fn start_evaluate_added_goals_step(&mut self) { - match self.as_mut() { - None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { - state.added_goals_evaluation().evaluations.push(vec![]); - } - _ => bug!(), - } - } - - pub fn evaluate_added_goals_result(&mut self, result: Result) { - match self.as_mut() { - None => {} - Some(DebugSolver::GoalEvaluationStep(state)) => { - let prev = state.added_goals_evaluation().result.replace(result); - assert_eq!(prev, None); - } - _ => bug!(), - } - } - pub fn query_result(&mut self, result: QueryResult>) { if let Some(this) = self.as_mut() { match this { DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => { assert_eq!(canonical_goal_evaluation.result.replace(result), None); } - DebugSolver::GoalEvaluationStep(evaluation_step) => { + DebugSolver::CanonicalGoalEvaluationStep(evaluation_step) => { assert_eq!( evaluation_step .evaluation diff --git a/compiler/rustc_trait_selection/src/solve/search_graph.rs b/compiler/rustc_trait_selection/src/solve/search_graph.rs index bcd210f789bf..6be623b6044f 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph.rs @@ -274,7 +274,8 @@ impl<'tcx> SearchGraph> { last.encountered_overflow = true; } - inspect.goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::Overflow); + inspect + .canonical_goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::Overflow); return Self::response_no_constraints(tcx, input, Certainty::overflow(true)); }; @@ -302,8 +303,9 @@ impl<'tcx> SearchGraph> { // We have a nested goal which is already in the provisional cache, use // its result. We do not provide any usage kind as that should have been // already set correctly while computing the cache entry. - inspect - .goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::ProvisionalCacheHit); + inspect.canonical_goal_evaluation_kind( + inspect::WipCanonicalGoalEvaluationKind::ProvisionalCacheHit, + ); Self::tag_cycle_participants(&mut self.stack, HasBeenUsed::empty(), entry.head); return entry.result; } else if let Some(stack_depth) = cache_entry.stack_depth { @@ -314,7 +316,9 @@ impl<'tcx> SearchGraph> { // // Finally we can return either the provisional response or the initial response // in case we're in the first fixpoint iteration for this goal. - inspect.goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::CycleInStack); + inspect.canonical_goal_evaluation_kind( + inspect::WipCanonicalGoalEvaluationKind::CycleInStack, + ); let is_coinductive_cycle = Self::stack_coinductive_from(tcx, &self.stack, stack_depth); let usage_kind = if is_coinductive_cycle { HasBeenUsed::COINDUCTIVE_CYCLE @@ -371,7 +375,7 @@ impl<'tcx> SearchGraph> { (current_entry, result) }); - let proof_tree = inspect.finalize_evaluation(tcx); + let proof_tree = inspect.finalize_canonical_goal_evaluation(tcx); // We're now done with this goal. In case this goal is involved in a larger cycle // do not remove it from the provisional cache and update its provisional result. @@ -433,9 +437,9 @@ impl<'tcx> SearchGraph> { // the goal. We simply overwrite the existing entry once we're done, // caching the proof tree. if !inspect.is_noop() { - if let Some(revisions) = proof_tree { - let kind = inspect::WipCanonicalGoalEvaluationKind::Interned { revisions }; - inspect.goal_evaluation_kind(kind); + if let Some(final_revision) = proof_tree { + let kind = inspect::WipCanonicalGoalEvaluationKind::Interned { final_revision }; + inspect.canonical_goal_evaluation_kind(kind); } else { return None; } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index e50edfdc656c..633d488f7be5 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -7,15 +7,11 @@ pub mod suggestions; mod type_err_ctxt_ext; use super::{Obligation, ObligationCause, ObligationCauseCode, PredicateObligation}; -use crate::infer::InferCtxt; -use crate::solve::{GenerateProofTree, InferCtxtEvalExt}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; -use rustc_middle::traits::solve::Goal; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; -use std::io::Write; use std::ops::ControlFlow; pub use self::infer_ctxt_ext::*; @@ -184,16 +180,3 @@ pub enum DefIdOrName { DefId(DefId), Name(&'static str), } - -pub fn dump_proof_tree<'tcx>(o: &Obligation<'tcx, ty::Predicate<'tcx>>, infcx: &InferCtxt<'tcx>) { - infcx.probe(|_| { - let goal = Goal { predicate: o.predicate, param_env: o.param_env }; - let tree = infcx - .evaluate_root_goal(goal, GenerateProofTree::Yes) - .1 - .expect("proof tree should have been generated"); - let mut lock = std::io::stdout().lock(); - let _ = lock.write_fmt(format_args!("{tree:?}\n")); - let _ = lock.flush(); - }); -} diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 494fca0336cc..46953a61296a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -46,7 +46,6 @@ use rustc_middle::ty::{ TypeVisitableExt, Upcast, }; use rustc_middle::{bug, span_bug}; -use rustc_session::config::DumpSolverProofTree; use rustc_session::Limit; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::symbol::sym; @@ -56,8 +55,8 @@ use std::fmt; use std::iter; use super::{ - dump_proof_tree, ArgKind, CandidateSimilarity, FindExprBySpan, FindTypeParam, - GetSafeTransmuteErrorAndReason, HasNumericInferVisitor, ImplCandidate, UnsatisfiedConst, + ArgKind, CandidateSimilarity, FindExprBySpan, FindTypeParam, GetSafeTransmuteErrorAndReason, + HasNumericInferVisitor, ImplCandidate, UnsatisfiedConst, }; pub use rustc_infer::traits::error_reporting::*; @@ -369,13 +368,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { error: &SelectionError<'tcx>, ) -> ErrorGuaranteed { let tcx = self.tcx; - - if tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default() - == DumpSolverProofTree::OnError - { - dump_proof_tree(root_obligation, self.infcx); - } - let mut span = obligation.cause.span; let mut err = match *error { @@ -1529,12 +1521,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { #[instrument(skip(self), level = "debug")] fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed { - if self.tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default() - == DumpSolverProofTree::OnError - { - dump_proof_tree(&error.root_obligation, self.infcx); - } - match error.code { FulfillmentErrorCode::Select(ref selection_error) => self.report_selection_error( error.obligation.clone(), diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index da2b004761fc..a1094d982768 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -1,17 +1,14 @@ //! Miscellaneous type-system utilities that are too small to deserve their own modules. use crate::regions::InferCtxtRegionExt; -use crate::traits::{self, ObligationCause, ObligationCtxt}; +use crate::traits::{self, ObligationCause}; use hir::LangItem; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; -use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; -use rustc_infer::traits::query::NoSolution; use rustc_infer::{infer::outlives::env::OutlivesEnvironment, traits::FulfillmentError}; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt}; -use rustc_span::DUMMY_SP; use super::outlives_bounds::InferCtxtExt; @@ -207,19 +204,3 @@ pub fn all_fields_implement_trait<'tcx>( if infringing.is_empty() { Ok(()) } else { Err(infringing) } } - -pub fn check_tys_might_be_eq<'tcx>( - tcx: TyCtxt<'tcx>, - canonical: Canonical<'tcx, ty::ParamEnvAnd<'tcx, (Ty<'tcx>, Ty<'tcx>)>>, -) -> Result<(), NoSolution> { - let (infcx, key, _) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical); - let (param_env, (ty_a, ty_b)) = key.into_parts(); - let ocx = ObligationCtxt::new(&infcx); - - let result = ocx.eq(&ObligationCause::dummy(), param_env, ty_a, ty_b); - // use `select_where_possible` instead of `select_all_or_error` so that - // we don't get errors from obligations being ambiguous. - let errors = ocx.select_where_possible(); - - if errors.len() > 0 || result.is_err() { Err(NoSolution) } else { Ok(()) } -} diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 204bb487c860..ab4d06f26603 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -185,6 +185,7 @@ fn do_normalize_predicates<'tcx>( predicates: Vec>, ) -> Result>, ErrorGuaranteed> { let span = cause.span; + // FIXME. We should really... do something with these region // obligations. But this call just continues the older // behavior (i.e., doesn't cause any new bugs), and it would @@ -551,7 +552,6 @@ pub fn provide(providers: &mut Providers) { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, instantiate_and_check_impossible_predicates, - check_tys_might_be_eq: misc::check_tys_might_be_eq, is_impossible_associated_item, ..*providers }; diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 8ce1271fc17a..f4051561dae4 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -13,7 +13,7 @@ use super::elaborate; use crate::infer::TyCtxtInferExt; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{self, Obligation, ObligationCause}; -use rustc_errors::{DelayDm, FatalError, MultiSpan}; +use rustc_errors::{FatalError, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::query::Providers; @@ -162,41 +162,36 @@ fn lint_object_unsafe_trait( ) { // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. // It's also hard to get a use site span, so we use the method definition span. - tcx.node_span_lint( - WHERE_CLAUSES_OBJECT_SAFETY, - hir::CRATE_HIR_ID, - span, - DelayDm(|| format!("the trait `{}` cannot be made into an object", tcx.def_path_str(trait_def_id))), - |err| { - let node = tcx.hir().get_if_local(trait_def_id); - let mut spans = MultiSpan::from_span(span); - if let Some(hir::Node::Item(item)) = node { - spans.push_span_label( - item.ident.span, - "this trait cannot be made into an object...", - ); - spans.push_span_label(span, format!("...because {}", violation.error_msg())); - } else { - spans.push_span_label( - span, - format!( - "the trait cannot be made into an object because {}", - violation.error_msg() - ), - ); - }; - err.span_note( - spans, - "for a trait to be \"object safe\" it needs to allow building a vtable to allow the \ + tcx.node_span_lint(WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, span, |err| { + err.primary_message(format!( + "the trait `{}` cannot be made into an object", + tcx.def_path_str(trait_def_id) + )); + let node = tcx.hir().get_if_local(trait_def_id); + let mut spans = MultiSpan::from_span(span); + if let Some(hir::Node::Item(item)) = node { + spans.push_span_label(item.ident.span, "this trait cannot be made into an object..."); + spans.push_span_label(span, format!("...because {}", violation.error_msg())); + } else { + spans.push_span_label( + span, + format!( + "the trait cannot be made into an object because {}", + violation.error_msg() + ), + ); + }; + err.span_note( + spans, + "for a trait to be \"object safe\" it needs to allow building a vtable to allow the \ call to be resolvable dynamically; for more information visit \ ", - ); - if node.is_some() { - // Only provide the help if its a local trait, otherwise it's not - violation.solution().add_to(err); - } - }, - ); + ); + if node.is_some() { + // Only provide the help if its a local trait, otherwise it's not + violation.solution().add_to(err); + } + }); } fn sized_trait_bound_spans<'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4a94643d908b..696b1c151153 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2539,7 +2539,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let InferOk { obligations, .. } = self .infcx .at(&cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, placeholder_obligation_trait_ref, impl_trait_ref) + .eq(DefineOpaqueTypes::Yes, placeholder_obligation_trait_ref, impl_trait_ref) .map_err(|e| { debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx())) })?; @@ -2594,7 +2594,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { self.infcx .at(&obligation.cause, obligation.param_env) .eq( - DefineOpaqueTypes::No, + DefineOpaqueTypes::Yes, upcast_principal.map_bound(|trait_ref| { ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) }), @@ -2631,7 +2631,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { nested.extend( self.infcx .at(&obligation.cause, obligation.param_env) - .eq(DefineOpaqueTypes::No, source_projection, target_projection) + .eq(DefineOpaqueTypes::Yes, source_projection, target_projection) .map_err(|_| SelectionError::Unimplemented)? .into_obligations(), ); diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 826bb706f48b..c2727ae6bfd9 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -21,7 +21,7 @@ use crate::traits::{ self, coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt, }; use rustc_data_structures::fx::FxIndexSet; -use rustc_errors::{codes::*, DelayDm, Diag, EmissionGuarantee}; +use rustc_errors::{codes::*, Diag, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::bug; use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt}; @@ -449,7 +449,7 @@ fn report_conflicting_impls<'tcx>( } } - let msg = DelayDm(|| { + let msg = || { format!( "conflicting implementations of trait `{}`{}{}", overlap.trait_ref.print_trait_sugared(), @@ -459,7 +459,7 @@ fn report_conflicting_impls<'tcx>( _ => "", } ) - }); + }; // Don't report overlap errors if the header references error if let Err(err) = (overlap.trait_ref, overlap.self_ty).error_reported() { @@ -471,7 +471,7 @@ fn report_conflicting_impls<'tcx>( let reported = if overlap.with_impl.is_local() || tcx.ensure().orphan_check_impl(impl_def_id).is_ok() { - let mut err = tcx.dcx().struct_span_err(impl_span, msg); + let mut err = tcx.dcx().struct_span_err(impl_span, msg()); err.code(E0119); decorate(tcx, &overlap, impl_span, &mut err); err.emit() @@ -485,15 +485,10 @@ fn report_conflicting_impls<'tcx>( FutureCompatOverlapErrorKind::OrderDepTraitObjects => ORDER_DEPENDENT_TRAIT_OBJECTS, FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK, }; - tcx.node_span_lint( - lint, - tcx.local_def_id_to_hir_id(impl_def_id), - impl_span, - msg, - |err| { - decorate(tcx, &overlap, impl_span, err); - }, - ); + tcx.node_span_lint(lint, tcx.local_def_id_to_hir_id(impl_def_id), impl_span, |err| { + err.primary_message(msg()); + decorate(tcx, &overlap, impl_span, err); + }); Ok(()) } } diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index e87058f9ba48..6f71951b5162 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -79,11 +79,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' orig_lt, ty::Region::new_early_param( tcx, - ty::EarlyParamRegion { - def_id: param.def_id, - index: param.index, - name: param.name, - }, + ty::EarlyParamRegion { index: param.index, name: param.name }, ), ); } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 9b8bb210ff42..c77414afc52c 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -5,7 +5,7 @@ use std::ops::Deref; use crate::inherent::*; use crate::ir_print::IrPrint; -use crate::solve::inspect::GoalEvaluationStep; +use crate::solve::inspect::CanonicalGoalEvaluationStep; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; use crate::{ AliasTerm, AliasTermKind, AliasTy, AliasTyKind, CanonicalVarInfo, CoercePredicate, @@ -55,7 +55,11 @@ pub trait Interner: type PredefinedOpaques: Copy + Debug + Hash + Eq; type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable; type ExternalConstraints: Copy + Debug + Hash + Eq; - type GoalEvaluationSteps: Copy + Debug + Hash + Eq + Deref]>; + type CanonicalGoalEvaluationStepRef: Copy + + Debug + + Hash + + Eq + + Deref>; // Kinds of tys type Ty: Ty; diff --git a/compiler/rustc_type_ir/src/solve/inspect.rs b/compiler/rustc_type_ir/src/solve/inspect.rs index c4f6ee2669be..0733c730064b 100644 --- a/compiler/rustc_type_ir/src/solve/inspect.rs +++ b/compiler/rustc_type_ir/src/solve/inspect.rs @@ -1,36 +1,29 @@ //! Data structure used to inspect trait solver behavior. //! //! During trait solving we optionally build "proof trees", the root of -//! which is a [GoalEvaluation] with [GoalEvaluationKind::Root]. These -//! trees are used to improve the debug experience and are also used by -//! the compiler itself to provide necessary context for error messages. +//! which is a [GoalEvaluation]. These trees are used by the compiler +//! to inspect the behavior of the trait solver and to access its internal +//! state, e.g. for diagnostics and when selecting impls during codegen. //! //! Because each nested goal in the solver gets [canonicalized] separately //! and we discard inference progress via "probes", we cannot mechanically //! use proof trees without somehow "lifting up" data local to the current -//! `InferCtxt`. Any data used mechanically is therefore canonicalized and -//! stored as [CanonicalState]. As printing canonicalized data worsens the -//! debugging dumps, we do not simply canonicalize everything. +//! `InferCtxt`. To use the data from evaluation we therefore canonicalize +//! it and store it as a [CanonicalState]. //! -//! This means proof trees contain inference variables and placeholders -//! local to a different `InferCtxt` which must not be used with the -//! current one. +//! Proof trees are only shallow, we do not compute the proof tree for nested +//! goals. Visiting proof trees instead recomputes nested goals in the parents +//! inference context when necessary. //! //! [canonicalized]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html -mod format; - -use std::fmt::{Debug, Write}; -use std::hash::Hash; - -use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; - -use self::format::ProofTreeFormatter; use crate::solve::{ - CandidateSource, CanonicalInput, Certainty, Goal, GoalSource, NoSolution, QueryInput, - QueryResult, + CandidateSource, CanonicalInput, Certainty, Goal, GoalSource, QueryInput, QueryResult, }; use crate::{Canonical, CanonicalVarValues, Interner}; +use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; +use std::fmt::Debug; +use std::hash::Hash; /// Some `data` together with information about how they relate to the input /// of the canonical query. @@ -55,23 +48,15 @@ pub struct State { pub type CanonicalState = Canonical>; -/// When evaluating the root goals we also store the -/// original values for the `CanonicalVarValues` of the -/// canonicalized goal. We use this to map any [CanonicalState] -/// from the local `InferCtxt` of the solver query to -/// the `InferCtxt` of the caller. -#[derive(derivative::Derivative)] -#[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""), Debug(bound = ""))] -pub enum GoalEvaluationKind { - Root { orig_values: Vec }, - Nested, -} - +/// When evaluating a goal we also store the original values +/// for the `CanonicalVarValues` of the canonicalized goal. +/// We use this to map any [CanonicalState] from the local `InferCtxt` +/// of the solver query to the `InferCtxt` of the caller. #[derive(derivative::Derivative)] #[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""))] pub struct GoalEvaluation { pub uncanonicalized_goal: Goal, - pub kind: GoalEvaluationKind, + pub orig_values: Vec, pub evaluation: CanonicalGoalEvaluation, } @@ -89,24 +74,12 @@ pub enum CanonicalGoalEvaluationKind { Overflow, CycleInStack, ProvisionalCacheHit, - Evaluation { revisions: I::GoalEvaluationSteps }, -} -impl Debug for GoalEvaluation { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - ProofTreeFormatter::new(f).format_goal_evaluation(self) - } + Evaluation { final_revision: I::CanonicalGoalEvaluationStepRef }, } #[derive(derivative::Derivative)] #[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""), Debug(bound = ""))] -pub struct AddedGoalsEvaluation { - pub evaluations: Vec>>, - pub result: Result, -} - -#[derive(derivative::Derivative)] -#[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""), Debug(bound = ""))] -pub struct GoalEvaluationStep { +pub struct CanonicalGoalEvaluationStep { pub instantiated_goal: QueryInput, /// The actual evaluation of the goal, always `ProbeKind::Root`. @@ -117,7 +90,7 @@ pub struct GoalEvaluationStep { /// corresponds to a `EvalCtxt::probe(_X)` call or the root evaluation /// of a goal. #[derive(derivative::Derivative)] -#[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""))] +#[derivative(Debug(bound = ""), PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""))] pub struct Probe { /// What happened inside of this probe in chronological order. pub steps: Vec>, @@ -125,23 +98,15 @@ pub struct Probe { pub final_state: CanonicalState, } -impl Debug for Probe { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - ProofTreeFormatter::new(f).format_probe(self) - } -} - #[derive(derivative::Derivative)] #[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""), Debug(bound = ""))] pub enum ProbeStep { /// We added a goal to the `EvalCtxt` which will get proven /// the next time `EvalCtxt::try_evaluate_added_goals` is called. AddGoal(GoalSource, CanonicalState>), - /// The inside of a `EvalCtxt::try_evaluate_added_goals` call. - EvaluateGoals(AddedGoalsEvaluation), /// A call to `probe` while proving the current goal. This is /// used whenever there are multiple candidates to prove the - /// current goalby . + /// current goal. NestedProbe(Probe), /// A trait goal was satisfied by an impl candidate. RecordImplArgs { impl_args: CanonicalState }, diff --git a/compiler/rustc_type_ir/src/solve/inspect/format.rs b/compiler/rustc_type_ir/src/solve/inspect/format.rs deleted file mode 100644 index 44ade04cf98c..000000000000 --- a/compiler/rustc_type_ir/src/solve/inspect/format.rs +++ /dev/null @@ -1,173 +0,0 @@ -use std::marker::PhantomData; - -use super::*; - -pub(super) struct ProofTreeFormatter<'a, 'b, I> { - f: &'a mut (dyn Write + 'b), - _interner: PhantomData, -} - -enum IndentorState { - StartWithNewline, - OnNewline, - Inline, -} - -/// A formatter which adds 4 spaces of indentation to its input before -/// passing it on to its nested formatter. -/// -/// We can use this for arbitrary levels of indentation by nesting it. -struct Indentor<'a, 'b> { - f: &'a mut (dyn Write + 'b), - state: IndentorState, -} - -impl Write for Indentor<'_, '_> { - fn write_str(&mut self, s: &str) -> std::fmt::Result { - for line in s.split_inclusive('\n') { - match self.state { - IndentorState::StartWithNewline => self.f.write_str("\n ")?, - IndentorState::OnNewline => self.f.write_str(" ")?, - IndentorState::Inline => {} - } - self.state = - if line.ends_with('\n') { IndentorState::OnNewline } else { IndentorState::Inline }; - self.f.write_str(line)?; - } - - Ok(()) - } -} - -impl<'a, 'b, I: Interner> ProofTreeFormatter<'a, 'b, I> { - pub(super) fn new(f: &'a mut (dyn Write + 'b)) -> Self { - ProofTreeFormatter { f, _interner: PhantomData } - } - - fn nested(&mut self, func: F) -> std::fmt::Result - where - F: FnOnce(&mut ProofTreeFormatter<'_, '_, I>) -> std::fmt::Result, - { - write!(self.f, " {{")?; - func(&mut ProofTreeFormatter { - f: &mut Indentor { f: self.f, state: IndentorState::StartWithNewline }, - _interner: PhantomData, - })?; - writeln!(self.f, "}}") - } - - pub(super) fn format_goal_evaluation(&mut self, eval: &GoalEvaluation) -> std::fmt::Result { - let goal_text = match eval.kind { - GoalEvaluationKind::Root { orig_values: _ } => "ROOT GOAL", - GoalEvaluationKind::Nested => "GOAL", - }; - write!(self.f, "{}: {:?}", goal_text, eval.uncanonicalized_goal)?; - self.nested(|this| this.format_canonical_goal_evaluation(&eval.evaluation)) - } - - pub(super) fn format_canonical_goal_evaluation( - &mut self, - eval: &CanonicalGoalEvaluation, - ) -> std::fmt::Result { - writeln!(self.f, "GOAL: {:?}", eval.goal)?; - - match &eval.kind { - CanonicalGoalEvaluationKind::Overflow => { - writeln!(self.f, "OVERFLOW: {:?}", eval.result) - } - CanonicalGoalEvaluationKind::CycleInStack => { - writeln!(self.f, "CYCLE IN STACK: {:?}", eval.result) - } - CanonicalGoalEvaluationKind::ProvisionalCacheHit => { - writeln!(self.f, "PROVISIONAL CACHE HIT: {:?}", eval.result) - } - CanonicalGoalEvaluationKind::Evaluation { revisions } => { - for (n, step) in revisions.iter().enumerate() { - write!(self.f, "REVISION {n}")?; - self.nested(|this| this.format_evaluation_step(step))?; - } - writeln!(self.f, "RESULT: {:?}", eval.result) - } - } - } - - pub(super) fn format_evaluation_step( - &mut self, - evaluation_step: &GoalEvaluationStep, - ) -> std::fmt::Result { - writeln!(self.f, "INSTANTIATED: {:?}", evaluation_step.instantiated_goal)?; - self.format_probe(&evaluation_step.evaluation) - } - - pub(super) fn format_probe(&mut self, probe: &Probe) -> std::fmt::Result { - match &probe.kind { - ProbeKind::Root { result } => { - write!(self.f, "ROOT RESULT: {result:?}") - } - ProbeKind::TryNormalizeNonRigid { result } => { - write!(self.f, "TRY NORMALIZE NON-RIGID: {result:?}") - } - ProbeKind::NormalizedSelfTyAssembly => { - write!(self.f, "NORMALIZING SELF TY FOR ASSEMBLY:") - } - ProbeKind::UnsizeAssembly => { - write!(self.f, "ASSEMBLING CANDIDATES FOR UNSIZING:") - } - ProbeKind::UpcastProjectionCompatibility => { - write!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:") - } - ProbeKind::OpaqueTypeStorageLookup { result } => { - write!(self.f, "PROBING FOR AN EXISTING OPAQUE: {result:?}") - } - ProbeKind::TraitCandidate { source, result } => { - write!(self.f, "CANDIDATE {source:?}: {result:?}") - } - ProbeKind::ShadowedEnvProbing => { - write!(self.f, "PROBING FOR IMPLS SHADOWED BY PARAM-ENV CANDIDATE:") - } - }?; - - self.nested(|this| { - for step in &probe.steps { - match step { - ProbeStep::AddGoal(source, goal) => { - let source = match source { - GoalSource::Misc => "misc", - GoalSource::ImplWhereBound => "impl where-bound", - GoalSource::InstantiateHigherRanked => "higher-ranked goal", - }; - writeln!(this.f, "ADDED GOAL ({source}): {goal:?}")? - } - ProbeStep::EvaluateGoals(eval) => this.format_added_goals_evaluation(eval)?, - ProbeStep::NestedProbe(probe) => this.format_probe(probe)?, - ProbeStep::MakeCanonicalResponse { shallow_certainty } => { - writeln!(this.f, "EVALUATE GOALS AND MAKE RESPONSE: {shallow_certainty:?}")? - } - ProbeStep::RecordImplArgs { impl_args } => { - writeln!(this.f, "RECORDED IMPL ARGS: {impl_args:?}")? - } - } - } - Ok(()) - }) - } - - pub(super) fn format_added_goals_evaluation( - &mut self, - added_goals_evaluation: &AddedGoalsEvaluation, - ) -> std::fmt::Result { - writeln!(self.f, "TRY_EVALUATE_ADDED_GOALS: {:?}", added_goals_evaluation.result)?; - - for (n, iterations) in added_goals_evaluation.evaluations.iter().enumerate() { - write!(self.f, "ITERATION {n}")?; - self.nested(|this| { - for goal_evaluation in iterations { - this.format_goal_evaluation(goal_evaluation)?; - } - Ok(()) - })?; - } - - Ok(()) - } -} diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index f3ac2bfcdb01..d62054eff609 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -190,7 +190,6 @@ pub(crate) type DebruijnIndex = u32; #[derive(Clone, Debug, Eq, PartialEq)] pub struct EarlyParamRegion { - pub def_id: RegionDef, pub index: u32, pub name: Symbol, } diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 3960f7168126..024b92790e97 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -20,6 +20,10 @@ rand_xorshift = "0.3.0" name = "alloctests" path = "tests/lib.rs" +[[test]] +name = "vec_deque_alloc_error" +path = "tests/vec_deque_alloc_error.rs" + [[bench]] name = "allocbenches" path = "benches/lib.rs" @@ -45,7 +49,6 @@ optimize_for_size = ["core/optimize_for_size"] level = "warn" # x.py uses beta cargo, so `check-cfg` entries do not yet take effect # for rust-lang/rust. But for users of `-Zbuild-std` it does. -# The unused warning is waiting for rust-lang/cargo#13925 to reach beta. check-cfg = [ 'cfg(bootstrap)', 'cfg(no_global_oom_handling)', diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 4643a6bbe2ec..61d05afccfd1 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -982,6 +982,8 @@ impl VecDeque { // `head` and `len` are at most `isize::MAX` and `target_cap < self.capacity()`, so nothing can // overflow. let tail_outside = (target_cap + 1..=self.capacity()).contains(&(self.head + self.len)); + // Used in the drop guard below. + let old_head = self.head; if self.len == 0 { self.head = 0; @@ -1034,12 +1036,74 @@ impl VecDeque { } self.head = new_head; } - self.buf.shrink_to_fit(target_cap); + + struct Guard<'a, T, A: Allocator> { + deque: &'a mut VecDeque, + old_head: usize, + target_cap: usize, + } + + impl Drop for Guard<'_, T, A> { + #[cold] + fn drop(&mut self) { + unsafe { + // SAFETY: This is only called if `buf.shrink_to_fit` unwinds, + // which is the only time it's safe to call `abort_shrink`. + self.deque.abort_shrink(self.old_head, self.target_cap) + } + } + } + + let guard = Guard { deque: self, old_head, target_cap }; + + guard.deque.buf.shrink_to_fit(target_cap); + + // Don't drop the guard if we didn't unwind. + mem::forget(guard); debug_assert!(self.head < self.capacity() || self.capacity() == 0); debug_assert!(self.len <= self.capacity()); } + /// Reverts the deque back into a consistent state in case `shrink_to` failed. + /// This is necessary to prevent UB if the backing allocator returns an error + /// from `shrink` and `handle_alloc_error` subsequently unwinds (see #123369). + /// + /// `old_head` refers to the head index before `shrink_to` was called. `target_cap` + /// is the capacity that it was trying to shrink to. + unsafe fn abort_shrink(&mut self, old_head: usize, target_cap: usize) { + // Moral equivalent of self.head + self.len <= target_cap. Won't overflow + // because `self.len <= target_cap`. + if self.head <= target_cap - self.len { + // The deque's buffer is contiguous, so no need to copy anything around. + return; + } + + // `shrink_to` already copied the head to fit into the new capacity, so this won't overflow. + let head_len = target_cap - self.head; + // `self.head > target_cap - self.len` => `self.len > target_cap - self.head =: head_len` so this must be positive. + let tail_len = self.len - head_len; + + if tail_len <= cmp::min(head_len, self.capacity() - target_cap) { + // There's enough spare capacity to copy the tail to the back (because `tail_len < self.capacity() - target_cap`), + // and copying the tail should be cheaper than copying the head (because `tail_len <= head_len`). + + unsafe { + // The old tail and the new tail can't overlap because the head slice lies between them. The + // head slice ends at `target_cap`, so that's where we copy to. + self.copy_nonoverlapping(0, target_cap, tail_len); + } + } else { + // Either there's not enough spare capacity to make the deque contiguous, or the head is shorter than the tail + // (and therefore hopefully cheaper to copy). + unsafe { + // The old and the new head slice can overlap, so we can't use `copy_nonoverlapping` here. + self.copy(self.head, old_head, head_len); + self.head = old_head; + } + } + } + /// Shortens the deque, keeping the first `len` elements and dropping /// the rest. /// diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index b2e22d8715a8..aa9b632cbed9 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2643,15 +2643,13 @@ impl Vec<[T; N], A> { /// # Examples /// /// ``` - /// #![feature(slice_flatten)] - /// /// let mut vec = vec![[1, 2, 3], [4, 5, 6], [7, 8, 9]]; /// assert_eq!(vec.pop(), Some([7, 8, 9])); /// /// let mut flattened = vec.into_flattened(); /// assert_eq!(flattened.pop(), Some(6)); /// ``` - #[unstable(feature = "slice_flatten", issue = "95629")] + #[stable(feature = "slice_flatten", since = "CURRENT_RUSTC_VERSION")] pub fn into_flattened(self) -> Vec { let (ptr, len, cap, alloc) = self.into_raw_parts_with_alloc(); let (new_len, new_cap) = if T::IS_ZST { diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 0eae4ca4b8ba..8451be63c2b9 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -36,7 +36,6 @@ #![feature(const_str_from_utf8)] #![feature(panic_update_hook)] #![feature(pointer_is_aligned_to)] -#![feature(slice_flatten)] #![feature(thin_box)] #![feature(strict_provenance)] #![feature(drain_keep_rest)] diff --git a/library/alloc/tests/vec_deque_alloc_error.rs b/library/alloc/tests/vec_deque_alloc_error.rs new file mode 100644 index 000000000000..c11f4556da9a --- /dev/null +++ b/library/alloc/tests/vec_deque_alloc_error.rs @@ -0,0 +1,49 @@ +#![feature(alloc_error_hook, allocator_api)] + +use std::{ + alloc::{set_alloc_error_hook, AllocError, Allocator, Layout, System}, + collections::VecDeque, + panic::{catch_unwind, AssertUnwindSafe}, + ptr::NonNull, +}; + +#[test] +fn test_shrink_to_unwind() { + // This tests that `shrink_to` leaves the deque in a consistent state when + // the call to `RawVec::shrink_to_fit` unwinds. The code is adapted from #123369 + // but changed to hopefully not have any UB even if the test fails. + + struct BadAlloc; + + unsafe impl Allocator for BadAlloc { + fn allocate(&self, l: Layout) -> Result, AllocError> { + // We allocate zeroed here so that the whole buffer of the deque + // is always initialized. That way, even if the deque is left in + // an inconsistent state, no uninitialized memory should be accessed. + System.allocate_zeroed(l) + } + + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + unsafe { System.deallocate(ptr, layout) } + } + + unsafe fn shrink( + &self, + _ptr: NonNull, + _old_layout: Layout, + _new_layout: Layout, + ) -> Result, AllocError> { + Err(AllocError) + } + } + + set_alloc_error_hook(|_| panic!("alloc error")); + + let mut v = VecDeque::with_capacity_in(15, BadAlloc); + v.push_back(1); + v.push_front(2); + // This should unwind because it calls `BadAlloc::shrink` and then `handle_alloc_error` which unwinds. + assert!(catch_unwind(AssertUnwindSafe(|| v.shrink_to_fit())).is_err()); + // This should only pass if the deque is left in a consistent state. + assert_eq!(v, [2, 1]); +} diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index 0c2642341235..cf9fddd269aa 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -41,7 +41,6 @@ debug_refcell = [] level = "warn" # x.py uses beta cargo, so `check-cfg` entries do not yet take effect # for rust-lang/rust. But for users of `-Zbuild-std` it does. -# The unused warning is waiting for rust-lang/cargo#13925 to reach beta. check-cfg = [ 'cfg(bootstrap)', 'cfg(no_fp_fmt_parse)', diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 4b491ffdafa7..ac026de95da1 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -245,7 +245,7 @@ use crate::ptr::{self, NonNull}; mod lazy; mod once; -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub use lazy::LazyCell; #[stable(feature = "once_cell", since = "1.70.0")] pub use once::OnceCell; diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 1b213f6a2941..47eab6fd0163 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -18,8 +18,6 @@ enum State { /// # Examples /// /// ``` -/// #![feature(lazy_cell)] -/// /// use std::cell::LazyCell; /// /// let lazy: LazyCell = LazyCell::new(|| { @@ -36,7 +34,7 @@ enum State { /// // 92 /// // 92 /// ``` -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub struct LazyCell T> { state: UnsafeCell>, } @@ -47,8 +45,6 @@ impl T> LazyCell { /// # Examples /// /// ``` - /// #![feature(lazy_cell)] - /// /// use std::cell::LazyCell; /// /// let hello = "Hello, World!".to_string(); @@ -58,7 +54,8 @@ impl T> LazyCell { /// assert_eq!(&*lazy, "HELLO, WORLD!"); /// ``` #[inline] - #[unstable(feature = "lazy_cell", issue = "109736")] + #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub const fn new(f: F) -> LazyCell { LazyCell { state: UnsafeCell::new(State::Uninit(f)) } } @@ -70,7 +67,6 @@ impl T> LazyCell { /// # Examples /// /// ``` - /// #![feature(lazy_cell)] /// #![feature(lazy_cell_consume)] /// /// use std::cell::LazyCell; @@ -99,8 +95,6 @@ impl T> LazyCell { /// # Examples /// /// ``` - /// #![feature(lazy_cell)] - /// /// use std::cell::LazyCell; /// /// let lazy = LazyCell::new(|| 92); @@ -109,7 +103,7 @@ impl T> LazyCell { /// assert_eq!(&*lazy, &92); /// ``` #[inline] - #[unstable(feature = "lazy_cell", issue = "109736")] + #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub fn force(this: &LazyCell) -> &T { // SAFETY: // This invalidates any mutable references to the data. The resulting @@ -173,7 +167,7 @@ impl LazyCell { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl T> Deref for LazyCell { type Target = T; #[inline] @@ -182,7 +176,7 @@ impl T> Deref for LazyCell { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl Default for LazyCell { /// Creates a new lazy value using `Default` as the initializing function. #[inline] @@ -191,7 +185,7 @@ impl Default for LazyCell { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for LazyCell { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut d = f.debug_tuple("LazyCell"); diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 27dacbb23d95..618897b3abab 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -133,7 +133,8 @@ mod c_char_definition { any(target_arch = "aarch64", target_arch = "riscv64") ), all(target_os = "nto", target_arch = "aarch64"), - target_os = "horizon" + target_os = "horizon", + target_os = "aix", ))] { pub type c_char = u8; } else { diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 1324fb6e056b..c25bc5a1b13c 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -338,23 +338,19 @@ pub struct Arguments<'a> { impl<'a> Arguments<'a> { #[inline] #[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")] - pub const fn new_const(pieces: &'a [&'static str]) -> Self { - if pieces.len() > 1 { - // Since panic!() expands to panic_fmt(format_args!()), using panic! here is both a - // bit silly and also significantly increases the amount of MIR generated by panics. - crate::panicking::panic_nounwind("invalid args"); - } + pub const fn new_const(pieces: &'a [&'static str; N]) -> Self { + const { assert!(N <= 1) }; Arguments { pieces, fmt: None, args: &[] } } /// When using the format_args!() macro, this function is used to generate the /// Arguments structure. #[inline] - pub fn new_v1(pieces: &'a [&'static str], args: &'a [rt::Argument<'a>]) -> Arguments<'a> { - if pieces.len() < args.len() || pieces.len() > args.len() + 1 { - // See Arguments::new_const for why we don't use panic!. - crate::panicking::panic_nounwind("invalid args"); - } + pub fn new_v1( + pieces: &'a [&'static str; P], + args: &'a [rt::Argument<'a>; A], + ) -> Arguments<'a> { + const { assert!(P >= A && P <= A + 1, "invalid args") } Arguments { pieces, fmt: None, args } } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 206d1ab88529..86078c8377bd 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -191,6 +191,7 @@ #![feature(str_split_remainder)] #![feature(strict_provenance)] #![feature(ub_checks)] +#![feature(unchecked_neg)] #![feature(unchecked_shifts)] #![feature(utf16_extra)] #![feature(utf16_extra_const)] diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 2e715fb0bdde..19fc4489618f 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -901,8 +901,8 @@ impl f32 { #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")] #[inline] pub fn to_radians(self) -> f32 { - let value: f32 = consts::PI; - self * (value / 180.0f32) + const RADS_PER_DEG: f32 = consts::PI / 180.0; + self * RADS_PER_DEG } /// Returns the maximum of the two numbers, ignoring NaN. diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index db8e1f318adb..34357d1b05ad 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -912,8 +912,8 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn to_radians(self) -> f64 { - let value: f64 = consts::PI; - self * (value / 180.0) + const RADS_PER_DEG: f64 = consts::PI / 180.0; + self * RADS_PER_DEG } /// Returns the maximum of the two numbers, ignoring NaN. diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 77b1039039b1..c9c6e34eaad8 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -488,9 +488,19 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_add`. - unsafe { intrinsics::unchecked_add(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_add cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_add(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_add(self, rhs) + } } /// Checked addition with an unsigned integer. Computes `self + rhs`, @@ -630,9 +640,19 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_sub`. - unsafe { intrinsics::unchecked_sub(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_sub(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_sub(self, rhs) + } } /// Checked subtraction with an unsigned integer. Computes `self - rhs`, @@ -772,9 +792,19 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_mul`. - unsafe { intrinsics::unchecked_mul(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_mul(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_mul(self, rhs) + } } /// Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0` @@ -1111,9 +1141,22 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_neg(self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_neg`. - unsafe { intrinsics::unchecked_sub(0, self) } + // ICE resolved by #125184 isn't in bootstrap compiler + #[cfg(not(bootstrap))] + { + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_neg cannot overflow"), + ( + lhs: $SelfT = self, + ) => !lhs.overflowing_neg().1, + ); + } + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_sub(0, self) + } } /// Strict negation. Computes `-self`, panicking if `self == MIN`. @@ -1234,9 +1277,18 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shl`. - unsafe { intrinsics::unchecked_shl(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"), + ( + rhs: u32 = rhs, + ) => rhs < <$ActualT>::BITS, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_shl(self, rhs) + } } /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is @@ -1323,9 +1375,18 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shr`. - unsafe { intrinsics::unchecked_shr(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"), + ( + rhs: u32 = rhs, + ) => rhs < <$ActualT>::BITS, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_shr(self, rhs) + } } /// Checked absolute value. Computes `self.abs()`, returning `None` if diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 09a341e4d80a..ab1ede38979d 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -7,6 +7,7 @@ use crate::hint; use crate::intrinsics; use crate::mem; use crate::str::FromStr; +use crate::ub_checks::assert_unsafe_precondition; // Used because the `?` operator is not allowed in a const context. macro_rules! try_opt { diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 446d0658c126..f70c34199ace 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -495,9 +495,19 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_add`. - unsafe { intrinsics::unchecked_add(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_add cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_add(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_add(self, rhs) + } } /// Checked addition with a signed integer. Computes `self + rhs`, @@ -677,9 +687,19 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_sub`. - unsafe { intrinsics::unchecked_sub(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_sub(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_sub(self, rhs) + } } /// Checked integer multiplication. Computes `self * rhs`, returning @@ -763,9 +783,19 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_mul`. - unsafe { intrinsics::unchecked_mul(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => !lhs.overflowing_mul(rhs).1, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_mul(self, rhs) + } } /// Checked integer division. Computes `self / rhs`, returning `None` @@ -1334,9 +1364,18 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shl`. - unsafe { intrinsics::unchecked_shl(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"), + ( + rhs: u32 = rhs, + ) => rhs < <$ActualT>::BITS, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_shl(self, rhs) + } } /// Checked shift right. Computes `self >> rhs`, returning `None` @@ -1423,9 +1462,18 @@ macro_rules! uint_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { - // SAFETY: the caller must uphold the safety contract for - // `unchecked_shr`. - unsafe { intrinsics::unchecked_shr(self, rhs) } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"), + ( + rhs: u32 = rhs, + ) => rhs < <$ActualT>::BITS, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { + intrinsics::unchecked_shr(self, rhs) + } } /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if diff --git a/library/core/src/ops/index_range.rs b/library/core/src/ops/index_range.rs index 65bda9177c7b..64214eae377d 100644 --- a/library/core/src/ops/index_range.rs +++ b/library/core/src/ops/index_range.rs @@ -1,4 +1,3 @@ -use crate::intrinsics::{unchecked_add, unchecked_sub}; use crate::iter::{FusedIterator, TrustedLen}; use crate::num::NonZero; use crate::ub_checks; @@ -46,7 +45,7 @@ impl IndexRange { #[inline] pub const fn len(&self) -> usize { // SAFETY: By invariant, this cannot wrap - unsafe { unchecked_sub(self.end, self.start) } + unsafe { self.end.unchecked_sub(self.start) } } /// # Safety @@ -57,7 +56,7 @@ impl IndexRange { let value = self.start; // SAFETY: The range isn't empty, so this cannot overflow - self.start = unsafe { unchecked_add(value, 1) }; + self.start = unsafe { value.unchecked_add(1) }; value } @@ -68,7 +67,7 @@ impl IndexRange { debug_assert!(self.start < self.end); // SAFETY: The range isn't empty, so this cannot overflow - let value = unsafe { unchecked_sub(self.end, 1) }; + let value = unsafe { self.end.unchecked_sub(1) }; self.end = value; value } @@ -83,7 +82,7 @@ impl IndexRange { let mid = if n <= self.len() { // SAFETY: We just checked that this will be between start and end, // and thus the addition cannot overflow. - unsafe { unchecked_add(self.start, n) } + unsafe { self.start.unchecked_add(n) } } else { self.end }; @@ -102,7 +101,7 @@ impl IndexRange { let mid = if n <= self.len() { // SAFETY: We just checked that this will be between start and end, // and thus the addition cannot overflow. - unsafe { unchecked_sub(self.end, n) } + unsafe { self.end.unchecked_sub(n) } } else { self.start }; diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index c8065b2e7090..8c02aee8bfb4 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1080,6 +1080,7 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + #[rustc_allow_const_fn_unstable(unchecked_neg)] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self @@ -1093,7 +1094,7 @@ impl *const T { // SAFETY: the caller must uphold the safety contract for `offset`. // Because the pointee is *not* a ZST, that means that `count` is // at most `isize::MAX`, and thus the negation cannot overflow. - unsafe { self.offset(intrinsics::unchecked_sub(0, count as isize)) } + unsafe { self.offset((count as isize).unchecked_neg()) } } } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index c53953400add..7c685156cbb0 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1224,6 +1224,7 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + #[rustc_allow_const_fn_unstable(unchecked_neg)] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self @@ -1237,7 +1238,7 @@ impl *mut T { // SAFETY: the caller must uphold the safety contract for `offset`. // Because the pointee is *not* a ZST, that means that `count` is // at most `isize::MAX`, and thus the negation cannot overflow. - unsafe { self.offset(intrinsics::unchecked_sub(0, count as isize)) } + unsafe { self.offset((count as isize).unchecked_neg()) } } } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 617890cf083b..aac5c745d635 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -701,6 +701,7 @@ impl NonNull { #[must_use = "returns a new pointer rather than modifying its argument"] #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(unchecked_neg)] pub const unsafe fn sub(self, count: usize) -> Self where T: Sized, @@ -712,7 +713,7 @@ impl NonNull { // SAFETY: the caller must uphold the safety contract for `offset`. // Because the pointee is *not* a ZST, that means that `count` is // at most `isize::MAX`, and thus the negation cannot overflow. - unsafe { self.offset(intrinsics::unchecked_sub(0, count as isize)) } + unsafe { self.offset((count as isize).unchecked_neg()) } } } diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 8d7b6165510a..98513340a474 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -1,7 +1,6 @@ //! Indexing implementations for `[T]`. use crate::intrinsics::const_eval_select; -use crate::intrinsics::unchecked_sub; use crate::ops; use crate::ptr; use crate::ub_checks::assert_unsafe_precondition; @@ -374,7 +373,7 @@ unsafe impl SliceIndex<[T]> for ops::Range { // `self` is in bounds of `slice` so `self` cannot overflow an `isize`, // so the call to `add` is safe and the length calculation cannot overflow. unsafe { - let new_len = unchecked_sub(self.end, self.start); + let new_len = self.end.unchecked_sub(self.start); ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) } } @@ -392,7 +391,7 @@ unsafe impl SliceIndex<[T]> for ops::Range { ); // SAFETY: see comments for `get_unchecked` above. unsafe { - let new_len = unchecked_sub(self.end, self.start); + let new_len = self.end.unchecked_sub(self.start); ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) } } diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f82f965e67cf..503107c74803 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -4531,8 +4531,6 @@ impl [[T; N]] { /// # Examples /// /// ``` - /// #![feature(slice_flatten)] - /// /// assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]); /// /// assert_eq!( @@ -4546,7 +4544,8 @@ impl [[T; N]] { /// let empty_slice_of_arrays: &[[u32; 10]] = &[]; /// assert!(empty_slice_of_arrays.as_flattened().is_empty()); /// ``` - #[unstable(feature = "slice_flatten", issue = "95629")] + #[stable(feature = "slice_flatten", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")] pub const fn as_flattened(&self) -> &[T] { let len = if T::IS_ZST { self.len().checked_mul(N).expect("slice len overflow") @@ -4572,8 +4571,6 @@ impl [[T; N]] { /// # Examples /// /// ``` - /// #![feature(slice_flatten)] - /// /// fn add_5_to_all(slice: &mut [i32]) { /// for i in slice { /// *i += 5; @@ -4584,7 +4581,7 @@ impl [[T; N]] { /// add_5_to_all(array.as_flattened_mut()); /// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]); /// ``` - #[unstable(feature = "slice_flatten", issue = "95629")] + #[stable(feature = "slice_flatten", since = "CURRENT_RUSTC_VERSION")] pub fn as_flattened_mut(&mut self) -> &mut [T] { let len = if T::IS_ZST { self.len().checked_mul(N).expect("slice len overflow") diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 88fe29c99974..89202e7bb8dd 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -1084,40 +1084,42 @@ impl Duration { /// /// # Examples /// ``` - /// #![feature(div_duration)] /// use std::time::Duration; /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); /// assert_eq!(dur1.div_duration_f64(dur2), 0.5); /// ``` - #[unstable(feature = "div_duration", issue = "63139")] + #[stable(feature = "div_duration", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] pub const fn div_duration_f64(self, rhs: Duration) -> f64 { - self.as_secs_f64() / rhs.as_secs_f64() + let self_nanos = (self.secs as f64) * (NANOS_PER_SEC as f64) + (self.nanos.0 as f64); + let rhs_nanos = (rhs.secs as f64) * (NANOS_PER_SEC as f64) + (rhs.nanos.0 as f64); + self_nanos / rhs_nanos } /// Divide `Duration` by `Duration` and return `f32`. /// /// # Examples /// ``` - /// #![feature(div_duration)] /// use std::time::Duration; /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); /// assert_eq!(dur1.div_duration_f32(dur2), 0.5); /// ``` - #[unstable(feature = "div_duration", issue = "63139")] + #[stable(feature = "div_duration", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] pub const fn div_duration_f32(self, rhs: Duration) -> f32 { - self.as_secs_f32() / rhs.as_secs_f32() + let self_nanos = (self.secs as f32) * (NANOS_PER_SEC as f32) + (self.nanos.0 as f32); + let rhs_nanos = (rhs.secs as f32) * (NANOS_PER_SEC as f32) + (rhs.nanos.0 as f32); + self_nanos / rhs_nanos } } diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 797108a8425d..e0f82c916635 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -29,7 +29,6 @@ #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(dec2flt)] -#![feature(div_duration)] #![feature(duration_abs_diff)] #![feature(duration_consts_float)] #![feature(duration_constants)] @@ -96,7 +95,6 @@ #![feature(pointer_is_aligned_to)] #![feature(portable_simd)] #![feature(ptr_metadata)] -#![feature(lazy_cell)] #![feature(unsized_tuple_coercion)] #![feature(const_option)] #![feature(const_option_ext)] @@ -112,7 +110,6 @@ #![feature(const_array_from_ref)] #![feature(const_slice_from_ref)] #![feature(waker_getters)] -#![feature(slice_flatten)] #![feature(error_generic_member_access)] #![feature(error_in_core)] #![feature(trait_upcasting)] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index e56f03808b31..bc78c63c577c 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -102,7 +102,6 @@ test = true level = "warn" # x.py uses beta cargo, so `check-cfg` entries do not yet take effect # for rust-lang/rust. But for users of `-Zbuild-std` it does. -# The unused warning is waiting for rust-lang/cargo#13925 to reach beta. check-cfg = [ 'cfg(bootstrap)', 'cfg(target_arch, values("xtensa"))', diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 4a18db3d5a3f..9d6576fa8411 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -395,7 +395,6 @@ #![feature(edition_panic)] #![feature(format_args_nl)] #![feature(get_many_mut)] -#![feature(lazy_cell)] #![feature(log_syntax)] #![feature(test)] #![feature(trace_macros)] diff --git a/library/std/src/path.rs b/library/std/src/path.rs index f835b69f0cfb..f4e1e2a38c10 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1425,6 +1425,11 @@ impl PathBuf { /// If `extension` is the empty string, [`self.extension`] will be [`None`] /// afterwards, not `Some("")`. /// + /// # Panics + /// + /// Panics if the passed extension contains a path separator (see + /// [`is_separator`]). + /// /// # Caveats /// /// The new `extension` may contain dots and will be used in its entirety, @@ -1470,6 +1475,14 @@ impl PathBuf { } fn _set_extension(&mut self, extension: &OsStr) -> bool { + for &b in extension.as_encoded_bytes() { + if b < 128 { + if is_separator(b as char) { + panic!("extension cannot contain path separators: {:?}", extension); + } + } + } + let file_stem = match self.file_stem() { None => return false, Some(f) => f.as_encoded_bytes(), diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index fde6ed4f0c05..2d8e50d1f88e 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -1803,6 +1803,29 @@ fn test_windows_absolute() { assert_eq!(absolute(r"COM1").unwrap().as_os_str(), Path::new(r"\\.\COM1").as_os_str()); } +#[test] +#[should_panic = "path separator"] +fn test_extension_path_sep() { + let mut path = PathBuf::from("path/to/file"); + path.set_extension("d/../../../../../etc/passwd"); +} + +#[test] +#[should_panic = "path separator"] +#[cfg(windows)] +fn test_extension_path_sep_alternate() { + let mut path = PathBuf::from("path/to/file"); + path.set_extension("d\\test"); +} + +#[test] +#[cfg(not(windows))] +fn test_extension_path_sep_alternate() { + let mut path = PathBuf::from("path/to/file"); + path.set_extension("d\\test"); + assert_eq!(path, Path::new("path/to/file.d\\test")); +} + #[bench] #[cfg_attr(miri, ignore)] // Miri isn't fast... fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) { diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 27b59cfc8c24..16d5dc30552f 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -31,8 +31,6 @@ union Data { /// Initialize static variables with `LazyLock`. /// /// ``` -/// #![feature(lazy_cell)] -/// /// use std::collections::HashMap; /// /// use std::sync::LazyLock; @@ -61,8 +59,6 @@ union Data { /// ``` /// Initialize fields with `LazyLock`. /// ``` -/// #![feature(lazy_cell)] -/// /// use std::sync::LazyLock; /// /// #[derive(Debug)] @@ -76,8 +72,7 @@ union Data { /// println!("{}", *data.number); /// } /// ``` - -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub struct LazyLock T> { once: Once, data: UnsafeCell>, @@ -85,8 +80,21 @@ pub struct LazyLock T> { impl T> LazyLock { /// Creates a new lazy value with the given initializing function. + /// + /// # Examples + /// + /// ``` + /// use std::sync::LazyLock; + /// + /// let hello = "Hello, World!".to_string(); + /// + /// let lazy = LazyLock::new(|| hello.to_uppercase()); + /// + /// assert_eq!(&*lazy, "HELLO, WORLD!"); + /// ``` #[inline] - #[unstable(feature = "lazy_cell", issue = "109736")] + #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub const fn new(f: F) -> LazyLock { LazyLock { once: Once::new(), data: UnsafeCell::new(Data { f: ManuallyDrop::new(f) }) } } @@ -107,7 +115,6 @@ impl T> LazyLock { /// # Examples /// /// ``` - /// #![feature(lazy_cell)] /// #![feature(lazy_cell_consume)] /// /// use std::sync::LazyLock; @@ -145,8 +152,6 @@ impl T> LazyLock { /// # Examples /// /// ``` - /// #![feature(lazy_cell)] - /// /// use std::sync::LazyLock; /// /// let lazy = LazyLock::new(|| 92); @@ -155,7 +160,7 @@ impl T> LazyLock { /// assert_eq!(&*lazy, &92); /// ``` #[inline] - #[unstable(feature = "lazy_cell", issue = "109736")] + #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub fn force(this: &LazyLock) -> &T { this.once.call_once(|| { // SAFETY: `call_once` only runs this closure once, ever. @@ -191,7 +196,7 @@ impl LazyLock { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl Drop for LazyLock { fn drop(&mut self) { match self.once.state() { @@ -204,7 +209,7 @@ impl Drop for LazyLock { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl T> Deref for LazyLock { type Target = T; @@ -219,7 +224,7 @@ impl T> Deref for LazyLock { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl Default for LazyLock { /// Creates a new lazy value using `Default` as the initializing function. #[inline] @@ -228,7 +233,7 @@ impl Default for LazyLock { } } -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for LazyLock { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut d = f.debug_tuple("LazyLock"); @@ -242,13 +247,13 @@ impl fmt::Debug for LazyLock { // We never create a `&F` from a `&LazyLock` so it is fine // to not impl `Sync` for `F`. -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] unsafe impl Sync for LazyLock {} // auto-derived `Send` impl is OK. -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl RefUnwindSafe for LazyLock {} -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] impl UnwindSafe for LazyLock {} #[cfg(test)] diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs index e8c35bd48a70..fb7d601b0947 100644 --- a/library/std/src/sync/mod.rs +++ b/library/std/src/sync/mod.rs @@ -179,7 +179,7 @@ pub use self::rwlock::{MappedRwLockReadGuard, MappedRwLockWriteGuard}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; -#[unstable(feature = "lazy_cell", issue = "109736")] +#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] pub use self::lazy_lock::LazyLock; #[stable(feature = "once_cell", since = "1.70.0")] pub use self::once_lock::OnceLock; diff --git a/library/std/src/sync/reentrant_lock.rs b/library/std/src/sync/reentrant_lock.rs index 80b9e0cf1521..f7fe8eb1c7fd 100644 --- a/library/std/src/sync/reentrant_lock.rs +++ b/library/std/src/sync/reentrant_lock.rs @@ -116,6 +116,9 @@ pub struct ReentrantLockGuard<'a, T: ?Sized + 'a> { #[unstable(feature = "reentrant_lock", issue = "121440")] impl !Send for ReentrantLockGuard<'_, T> {} +#[unstable(feature = "reentrant_lock", issue = "121440")] +unsafe impl Sync for ReentrantLockGuard<'_, T> {} + #[unstable(feature = "reentrant_lock", issue = "121440")] impl ReentrantLock { /// Creates a new re-entrant lock in an unlocked state ready for use. diff --git a/library/std/src/sys/pal/unix/alloc.rs b/library/std/src/sys/pal/unix/alloc.rs index 2f908e3d0e95..eb3a57c212b4 100644 --- a/library/std/src/sys/pal/unix/alloc.rs +++ b/library/std/src/sys/pal/unix/alloc.rs @@ -59,10 +59,9 @@ unsafe impl GlobalAlloc for System { } cfg_if::cfg_if! { - // We use posix_memalign wherever possible, but not all targets have that function. + // We use posix_memalign wherever possible, but some targets have very incomplete POSIX coverage + // so we need a fallback for those. if #[cfg(any( - target_os = "redox", - target_os = "espidf", target_os = "horizon", target_os = "vita", ))] { @@ -74,12 +73,11 @@ cfg_if::cfg_if! { #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); - // We prefer posix_memalign over aligned_malloc since with aligned_malloc, - // implementations are making almost arbitrary choices for which alignments are - // "supported", making it hard to use. For instance, some implementations require the - // size to be a multiple of the alignment (wasi emmalloc), while others require the - // alignment to be at least the pointer size (Illumos, macOS) -- which may or may not be - // standards-compliant, but that does not help us. + // We prefer posix_memalign over aligned_alloc since it is more widely available, and + // since with aligned_alloc, implementations are making almost arbitrary choices for + // which alignments are "supported", making it hard to use. For instance, some + // implementations require the size to be a multiple of the alignment (wasi emmalloc), + // while others require the alignment to be at least the pointer size (Illumos, macOS). // posix_memalign only has one, clear requirement: that the alignment be a multiple of // `sizeof(void*)`. Since these are all powers of 2, we can just use max. let align = layout.align().max(crate::mem::size_of::()); diff --git a/library/std/src/sys/pal/unix/kernel_copy.rs b/library/std/src/sys/pal/unix/kernel_copy.rs index 18acd5ecccd5..cd38b7c07e2b 100644 --- a/library/std/src/sys/pal/unix/kernel_copy.rs +++ b/library/std/src/sys/pal/unix/kernel_copy.rs @@ -560,6 +560,12 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> // We store the availability in a global to avoid unnecessary syscalls static HAS_COPY_FILE_RANGE: AtomicU8 = AtomicU8::new(NOT_PROBED); + let mut have_probed = match HAS_COPY_FILE_RANGE.load(Ordering::Relaxed) { + NOT_PROBED => false, + UNAVAILABLE => return CopyResult::Fallback(0), + _ => true, + }; + syscall! { fn copy_file_range( fd_in: libc::c_int, @@ -571,25 +577,22 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> ) -> libc::ssize_t } - match HAS_COPY_FILE_RANGE.load(Ordering::Relaxed) { - NOT_PROBED => { - // EPERM can indicate seccomp filters or an immutable file. - // To distinguish these cases we probe with invalid file descriptors which should result in EBADF if the syscall is supported - // and some other error (ENOSYS or EPERM) if it's not available - let result = unsafe { - cvt(copy_file_range(INVALID_FD, ptr::null_mut(), INVALID_FD, ptr::null_mut(), 1, 0)) - }; - - if matches!(result.map_err(|e| e.raw_os_error()), Err(Some(EBADF))) { - HAS_COPY_FILE_RANGE.store(AVAILABLE, Ordering::Relaxed); - } else { - HAS_COPY_FILE_RANGE.store(UNAVAILABLE, Ordering::Relaxed); - return CopyResult::Fallback(0); - } + fn probe_copy_file_range_support() -> u8 { + // In some cases, we cannot determine availability from the first + // `copy_file_range` call. In this case, we probe with an invalid file + // descriptor so that the results are easily interpretable. + match unsafe { + cvt(copy_file_range(INVALID_FD, ptr::null_mut(), INVALID_FD, ptr::null_mut(), 1, 0)) + .map_err(|e| e.raw_os_error()) + } { + Err(Some(EPERM | ENOSYS)) => UNAVAILABLE, + Err(Some(EBADF)) => AVAILABLE, + Ok(_) => panic!("unexpected copy_file_range probe success"), + // Treat other errors as the syscall + // being unavailable. + Err(_) => UNAVAILABLE, } - UNAVAILABLE => return CopyResult::Fallback(0), - _ => {} - }; + } let mut written = 0u64; while written < max_len { @@ -604,6 +607,11 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> cvt(copy_file_range(reader, ptr::null_mut(), writer, ptr::null_mut(), bytes_to_copy, 0)) }; + if !have_probed && copy_result.is_ok() { + have_probed = true; + HAS_COPY_FILE_RANGE.store(AVAILABLE, Ordering::Relaxed); + } + match copy_result { Ok(0) if written == 0 => { // fallback to work around several kernel bugs where copy_file_range will fail to @@ -619,7 +627,28 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> return match err.raw_os_error() { // when file offset + max_length > u64::MAX Some(EOVERFLOW) => CopyResult::Fallback(written), - Some(ENOSYS | EXDEV | EINVAL | EPERM | EOPNOTSUPP | EBADF) if written == 0 => { + Some(raw_os_error @ (ENOSYS | EXDEV | EINVAL | EPERM | EOPNOTSUPP | EBADF)) + if written == 0 => + { + if !have_probed { + let available = if matches!(raw_os_error, ENOSYS | EOPNOTSUPP | EPERM) { + // EPERM can indicate seccomp filters or an + // immutable file. To distinguish these + // cases we probe with invalid file + // descriptors which should result in EBADF + // if the syscall is supported and EPERM or + // ENOSYS if it's not available. + // + // For EOPNOTSUPP, see below. In the case of + // ENOSYS, we try to cover for faulty FUSE + // drivers. + probe_copy_file_range_support() + } else { + AVAILABLE + }; + HAS_COPY_FILE_RANGE.store(available, Ordering::Relaxed); + } + // Try fallback io::copy if either: // - Kernel version is < 4.5 (ENOSYS¹) // - Files are mounted on different fs (EXDEV) diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs index c9b9c54e3d49..694867056566 100644 --- a/library/std/tests/run-time-detect.rs +++ b/library/std/tests/run-time-detect.rs @@ -121,10 +121,8 @@ fn x86_all() { println!("avx512bw: {:?}", is_x86_feature_detected!("avx512bw")); println!("avx512cd: {:?}", is_x86_feature_detected!("avx512cd")); println!("avx512dq: {:?}", is_x86_feature_detected!("avx512dq")); - println!("avx512er: {:?}", is_x86_feature_detected!("avx512er")); println!("avx512f: {:?}", is_x86_feature_detected!("avx512f")); println!("avx512ifma: {:?}", is_x86_feature_detected!("avx512ifma")); - println!("avx512pf: {:?}", is_x86_feature_detected!("avx512pf")); println!("avx512vbmi2: {:?}", is_x86_feature_detected!("avx512vbmi2")); println!("avx512vbmi: {:?}", is_x86_feature_detected!("avx512vbmi")); println!("avx512vl: {:?}", is_x86_feature_detected!("avx512vl")); diff --git a/library/test/src/term/win.rs b/library/test/src/term/win.rs index 55020141a827..65764c0ffc1b 100644 --- a/library/test/src/term/win.rs +++ b/library/test/src/term/win.rs @@ -22,6 +22,8 @@ type WORD = u16; type DWORD = u32; type BOOL = i32; type HANDLE = *mut u8; +// https://docs.microsoft.com/en-us/windows/console/getstdhandle +const STD_OUTPUT_HANDLE: DWORD = -11 as _; #[allow(non_snake_case)] #[repr(C)] @@ -99,16 +101,13 @@ impl WinConsole { accum |= color_to_bits(self.background) << 4; unsafe { - // Magic -11 means stdout, from - // https://docs.microsoft.com/en-us/windows/console/getstdhandle - // // You may be wondering, "but what about stderr?", and the answer // to that is that setting terminal attributes on the stdout // handle also sets them for stderr, since they go to the same // terminal! Admittedly, this is fragile, since stderr could be // redirected to a different console. This is good enough for // rustc though. See #13400. - let out = GetStdHandle(-11i32 as DWORD); + let out = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(out, accum); } } @@ -120,9 +119,8 @@ impl WinConsole { let bg; unsafe { let mut buffer_info = MaybeUninit::::uninit(); - if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as DWORD), buffer_info.as_mut_ptr()) - != 0 - { + let handle = GetStdHandle(STD_OUTPUT_HANDLE); + if GetConsoleScreenBufferInfo(handle, buffer_info.as_mut_ptr()) != 0 { let buffer_info = buffer_info.assume_init(); fg = bits_to_color(buffer_info.wAttributes); bg = bits_to_color(buffer_info.wAttributes >> 4); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 19119a073c5f..d13dc9d1d177 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -360,7 +360,7 @@ pub enum RustfmtState { LazyEvaluated, } -#[derive(Debug, Default, Clone, Copy, PartialEq)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] pub enum LlvmLibunwind { #[default] No, @@ -381,7 +381,7 @@ impl FromStr for LlvmLibunwind { } } -#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum SplitDebuginfo { Packed, Unpacked, @@ -542,7 +542,7 @@ impl PartialEq<&str> for TargetSelection { } /// Per-target configuration stored in the global configuration structure. -#[derive(Default, Clone)] +#[derive(Debug, Default, Clone, PartialEq, Eq)] pub struct Target { /// Some(path to llvm-config) if using an external LLVM. pub llvm_config: Option, @@ -644,7 +644,20 @@ impl Merge for TomlConfig { do_merge(&mut self.llvm, llvm, replace); do_merge(&mut self.rust, rust, replace); do_merge(&mut self.dist, dist, replace); - assert!(target.is_none(), "merging target-specific config is not currently supported"); + + match (self.target.as_mut(), target) { + (_, None) => {} + (None, Some(target)) => self.target = Some(target), + (Some(original_target), Some(new_target)) => { + for (triple, new) in new_target { + if let Some(original) = original_target.get_mut(&triple) { + original.merge(new, replace); + } else { + original_target.insert(triple, new); + } + } + } + } } } @@ -899,7 +912,7 @@ define_config! { } } -#[derive(Clone, Debug, Deserialize)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq)] #[serde(untagged)] pub enum StringOrBool { String(String), diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 59e16b654272..c4073910623a 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -1,5 +1,7 @@ use super::{flags::Flags, ChangeIdWrapper, Config}; use crate::core::build_steps::clippy::get_clippy_rules_in_order; +use crate::core::config::Target; +use crate::core::config::TargetSelection; use crate::core::config::{LldMode, TomlConfig}; use clap::CommandFactory; @@ -124,6 +126,10 @@ fn override_toml() { "--set=build.gdb=\"bar\"".to_owned(), "--set=build.tools=[\"cargo\"]".to_owned(), "--set=llvm.build-config={\"foo\" = \"bar\"}".to_owned(), + "--set=target.x86_64-unknown-linux-gnu.runner=bar".to_owned(), + "--set=target.x86_64-unknown-linux-gnu.rpath=false".to_owned(), + "--set=target.aarch64-unknown-linux-gnu.sanitizers=false".to_owned(), + "--set=target.aarch64-apple-darwin.runner=apple".to_owned(), ], |&_| { toml::from_str( @@ -140,6 +146,17 @@ tools = [] [llvm] download-ci-llvm = false build-config = {} + +[target.aarch64-unknown-linux-gnu] +sanitizers = true +rpath = true +runner = "aarch64-runner" + +[target.x86_64-unknown-linux-gnu] +sanitizers = true +rpath = true +runner = "x86_64-runner" + "#, ) .unwrap() @@ -163,6 +180,30 @@ build-config = {} [("foo".to_string(), "bar".to_string())].into_iter().collect(), "setting dictionary value" ); + + let x86_64 = TargetSelection::from_user("x86_64-unknown-linux-gnu"); + let x86_64_values = Target { + sanitizers: Some(true), + rpath: Some(false), + runner: Some("bar".into()), + ..Default::default() + }; + let aarch64 = TargetSelection::from_user("aarch64-unknown-linux-gnu"); + let aarch64_values = Target { + sanitizers: Some(false), + rpath: Some(true), + runner: Some("aarch64-runner".into()), + ..Default::default() + }; + let darwin = TargetSelection::from_user("aarch64-apple-darwin"); + let darwin_values = Target { runner: Some("apple".into()), ..Default::default() }; + assert_eq!( + config.target_config, + [(x86_64, x86_64_values), (aarch64, aarch64_values), (darwin, darwin_values)] + .into_iter() + .collect(), + "setting dictionary value" + ); } #[test] diff --git a/src/ci/scripts/install-mingw.sh b/src/ci/scripts/install-mingw.sh index 87b835b63db5..45541b8b6934 100755 --- a/src/ci/scripts/install-mingw.sh +++ b/src/ci/scripts/install-mingw.sh @@ -12,7 +12,7 @@ source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" MINGW_ARCHIVE_32="i686-12.2.0-release-posix-dwarf-rt_v10-rev0.7z" MINGW_ARCHIVE_64="x86_64-12.2.0-release-posix-seh-rt_v10-rev0.7z" -if isWindows; then +if isWindows && isKnownToBeMingwBuild; then case "${CI_JOB_NAME}" in *i686*) bits=32 @@ -39,10 +39,7 @@ if isWindows; then esac if [[ "${CUSTOM_MINGW:-0}" == 0 ]]; then - pacboy -S --noconfirm toolchain:p - # According to the comment in the Windows part of install-clang.sh, in the future we might - # want to do this instead: - # pacboy -S --noconfirm clang:p ... + pacman -S --noconfirm --needed mingw-w64-$arch-toolchain else mingw_dir="mingw${bits}" diff --git a/src/ci/scripts/install-msys2.sh b/src/ci/scripts/install-msys2.sh index 2ae782356047..968b1e572e43 100755 --- a/src/ci/scripts/install-msys2.sh +++ b/src/ci/scripts/install-msys2.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Clean up and prepare the MSYS2 installation. MSYS2 is needed primarily for -# the test suite (run-make), but is also used by the MinGW toolchain for assembling things. +# Clean up and prepare the MSYS2 installation. +# MSYS2 is used by the MinGW toolchain for assembling things. set -euo pipefail IFS=$'\n\t' @@ -24,38 +24,4 @@ if isWindows; then fi ciCommandAddPath "C:\\hostedtoolcache\\windows\\Python\\${native_python_version}\\x64" ciCommandAddPath "C:\\hostedtoolcache\\windows\\Python\\${native_python_version}\\x64\\Scripts" - - # Install pacboy for easily installing packages - pacman -S --noconfirm pactoys - - # Remove these pre-installed tools so we can't accidentally use them, because we are using the - # MSYS2 setup action versions instead. Because `rm -r`-ing them is slow, we mv them off path - # instead. - # Remove pre-installed version of MSYS2 - echo "Cleaning up existing tools in PATH" - notpath="/c/NOT/ON/PATH/" - mkdir --parents "$notpath" - mv -t "$notpath" "/c/msys64/" - # Remove Strawberry Perl, which contains a version of mingw - mv -t "$notpath" "/c/Strawberry/" - # Remove these other copies of mingw, I don't even know where they come from. - mv -t "$notpath" "/c/mingw64/" - mv -t "$notpath" "/c/mingw32/" - echo "Finished cleaning up tools in PATH" - - if isKnownToBeMingwBuild; then - # Use the mingw version of CMake for mingw builds. - # However, the MSVC build needs native CMake, as it fails with the mingw one. - # Delete native CMake - rm -r "/c/Program Files/CMake/" - # Install mingw-w64-$arch-cmake - pacboy -S --noconfirm cmake:p - - # It would be nice to use MSYS's git in MinGW builds so that it's tested and known to - # work. But it makes everything extremely slow, so it's commented out for now. - # # Delete Windows-Git - # rm -r "/c/Program Files/Git/" - # # Install MSYS2 git - # pacman -S --noconfirm git - fi fi diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 462b31f159b3..932295270765 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -372,8 +372,8 @@ pub(crate) fn run_global_ctxt( tcx.node_lint( crate::lint::MISSING_CRATE_LEVEL_DOCS, DocContext::as_local_hir_id(tcx, krate.module.item_id).unwrap(), - "no documentation found for this crate's top-level module", |lint| { + lint.primary_message("no documentation found for this crate's top-level module"); lint.help(help); }, ); diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 5c5651f3ef0e..362f9021671f 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -834,8 +834,9 @@ impl<'tcx> ExtraInfo<'tcx> { crate::lint::INVALID_CODEBLOCK_ATTRIBUTES, self.tcx.local_def_id_to_hir_id(def_id), self.sp, - msg, - |_| {}, + |lint| { + lint.primary_message(msg); + }, ); } } @@ -850,8 +851,10 @@ impl<'tcx> ExtraInfo<'tcx> { crate::lint::INVALID_CODEBLOCK_ATTRIBUTES, self.tcx.local_def_id_to_hir_id(def_id), self.sp, - msg, - f, + |lint| { + lint.primary_message(msg); + f(lint); + }, ); } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 0650afb90c7e..55346c768b66 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -8,7 +8,6 @@ #![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] -#![feature(lazy_cell)] #![feature(let_chains)] #![feature(never_type)] #![feature(round_char_boundary)] diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index e85b998bfbe1..257bab3e9fcb 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -125,13 +125,9 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item if should_have_doc_example(cx, item) { debug!("reporting error for {item:?} (hir_id={hir_id:?})"); let sp = item.attr_span(cx.tcx); - cx.tcx.node_span_lint( - crate::lint::MISSING_DOC_CODE_EXAMPLES, - hir_id, - sp, - "missing code example in this documentation", - |_| {}, - ); + cx.tcx.node_span_lint(crate::lint::MISSING_DOC_CODE_EXAMPLES, hir_id, sp, |lint| { + lint.primary_message("missing code example in this documentation"); + }); } } else if tests.found_tests > 0 && !cx.cache.effective_visibilities.is_exported(cx.tcx, item.item_id.expect_def_id()) @@ -140,8 +136,9 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item crate::lint::PRIVATE_DOC_TESTS, hir_id, item.attr_span(cx.tcx), - "documentation test in private item", - |_| {}, + |lint| { + lint.primary_message("documentation test in private item"); + }, ); } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 747f5c0a8356..8ab24a8c12e5 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1689,7 +1689,9 @@ fn report_diagnostic( let sp = item.attr_span(tcx); - tcx.node_span_lint(lint, hir_id, sp, msg, |lint| { + tcx.node_span_lint(lint, hir_id, sp, |lint| { + lint.primary_message(msg); + let (span, link_range) = match link_range { MarkdownLinkRange::Destination(md_range) => { let mut md_range = md_range.clone(); diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs index c6989fbbf255..8f68f6ff4764 100644 --- a/src/librustdoc/passes/lint/bare_urls.rs +++ b/src/librustdoc/passes/lint/bare_urls.rs @@ -24,8 +24,9 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) { let sp = source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs.doc_strings) .unwrap_or_else(|| item.attr_span(cx.tcx)); - cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, msg, |lint| { - lint.note("bare URLs are not automatically turned into clickable links") + cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| { + lint.primary_message(msg) + .note("bare URLs are not automatically turned into clickable links") .span_suggestion( sp, "use an automatic link instead", diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index 7b81b5e63be6..9562559fba26 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -99,7 +99,9 @@ fn check_rust_syntax( // All points of divergence have been handled earlier so this can be // done the same way whether the span is precise or not. let hir_id = cx.tcx.local_def_id_to_hir_id(local_id); - cx.tcx.node_span_lint(crate::lint::INVALID_RUST_CODEBLOCKS, hir_id, sp, msg, |lint| { + cx.tcx.node_span_lint(crate::lint::INVALID_RUST_CODEBLOCKS, hir_id, sp, |lint| { + lint.primary_message(msg); + let explanation = if is_ignore { "`ignore` code blocks require valid Rust code for syntax highlighting; \ mark blocks that do not contain Rust code as text" diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs index da3770aa927a..25b0c61b826f 100644 --- a/src/librustdoc/passes/lint/html_tags.rs +++ b/src/librustdoc/passes/lint/html_tags.rs @@ -25,8 +25,11 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { Some(sp) => sp, None => item.attr_span(tcx), }; - tcx.node_span_lint(crate::lint::INVALID_HTML_TAGS, hir_id, sp, msg, |lint| { + tcx.node_span_lint(crate::lint::INVALID_HTML_TAGS, hir_id, sp, |lint| { use rustc_lint_defs::Applicability; + + lint.primary_message(msg); + // If a tag looks like ``, it might actually be a generic. // We don't try to detect stuff `` because that's not valid HTML, // and we don't try to detect stuff `` because that's not valid Rust. diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index 098860245951..7ab974046b9c 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -188,8 +188,9 @@ fn check_inline_or_reference_unknown_redundancy( &item.attrs.doc_strings, )?; - cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, "redundant explicit link target", |lint| { - lint.span_label(explicit_span, "explicit target is redundant") + cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, |lint| { + lint.primary_message("redundant explicit link target") + .span_label(explicit_span, "explicit target is redundant") .span_label(display_span, "because label contains path that resolves to same destination") .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links") .span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways); @@ -238,8 +239,9 @@ fn check_reference_redundancy( &item.attrs.doc_strings, )?; - cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, "redundant explicit link target", |lint| { - lint.span_label(explicit_span, "explicit target is redundant") + cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, |lint| { + lint.primary_message("redundant explicit link target") + .span_label(explicit_span, "explicit target is redundant") .span_label(display_span, "because label contains path that resolves to same destination") .span_note(def_span, "referenced explicit link target defined here") .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links") diff --git a/src/librustdoc/passes/lint/unescaped_backticks.rs b/src/librustdoc/passes/lint/unescaped_backticks.rs index 4ea926cb79aa..be9670077d17 100644 --- a/src/librustdoc/passes/lint/unescaped_backticks.rs +++ b/src/librustdoc/passes/lint/unescaped_backticks.rs @@ -56,17 +56,28 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { ) .unwrap_or_else(|| item.attr_span(tcx)); - tcx.node_span_lint(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, "unescaped backtick", |lint| { + tcx.node_span_lint(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, |lint| { + lint.primary_message("unescaped backtick"); + let mut help_emitted = false; match element.prev_code_guess { PrevCodeGuess::None => {} PrevCodeGuess::Start { guess, .. } => { // "foo` `bar`" -> "`foo` `bar`" - if let Some(suggest_index) = clamp_start(guess, &element.suggestible_ranges) + if let Some(suggest_index) = + clamp_start(guess, &element.suggestible_ranges) && can_suggest_backtick(&dox, suggest_index) { - suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the opening backtick of a previous inline code may be missing"); + suggest_insertion( + cx, + item, + &dox, + lint, + suggest_index, + '`', + "the opening backtick of a previous inline code may be missing", + ); help_emitted = true; } } @@ -76,7 +87,15 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { // an inline code node and we intentionally "break" the inline code here. let suggest_index = guess; if can_suggest_backtick(&dox, suggest_index) { - suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "a previous inline code might be longer than expected"); + suggest_insertion( + cx, + item, + &dox, + lint, + suggest_index, + '`', + "a previous inline code might be longer than expected", + ); help_emitted = true; } } @@ -84,11 +103,21 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { if !element.prev_code_guess.is_confident() { // "`foo` bar`" -> "`foo` `bar`" - if let Some(guess) = guess_start_of_code(&dox, element.element_range.start..backtick_index) - && let Some(suggest_index) = clamp_start(guess, &element.suggestible_ranges) + if let Some(guess) = + guess_start_of_code(&dox, element.element_range.start..backtick_index) + && let Some(suggest_index) = + clamp_start(guess, &element.suggestible_ranges) && can_suggest_backtick(&dox, suggest_index) { - suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the opening backtick of an inline code may be missing"); + suggest_insertion( + cx, + item, + &dox, + lint, + suggest_index, + '`', + "the opening backtick of an inline code may be missing", + ); help_emitted = true; } @@ -96,21 +125,41 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { // Don't suggest closing backtick after single trailing char, // if we already suggested opening backtick. For example: // "foo`." -> "`foo`." or "foo`s" -> "`foo`s". - if let Some(guess) = guess_end_of_code(&dox, backtick_index + 1..element.element_range.end) - && let Some(suggest_index) = clamp_end(guess, &element.suggestible_ranges) + if let Some(guess) = + guess_end_of_code(&dox, backtick_index + 1..element.element_range.end) + && let Some(suggest_index) = + clamp_end(guess, &element.suggestible_ranges) && can_suggest_backtick(&dox, suggest_index) && (!help_emitted || suggest_index - backtick_index > 2) { - suggest_insertion(cx, item, &dox, lint, suggest_index, '`', "the closing backtick of an inline code may be missing"); + suggest_insertion( + cx, + item, + &dox, + lint, + suggest_index, + '`', + "the closing backtick of an inline code may be missing", + ); help_emitted = true; } } if !help_emitted { - lint.help("the opening or closing backtick of an inline code may be missing"); + lint.help( + "the opening or closing backtick of an inline code may be missing", + ); } - suggest_insertion(cx, item, &dox, lint, backtick_index, '\\', "if you meant to use a literal backtick, escape it"); + suggest_insertion( + cx, + item, + &dox, + lint, + backtick_index, + '\\', + "if you meant to use a literal backtick, escape it", + ); }); } Event::Code(_) => { diff --git a/src/stage0 b/src/stage0 index 5ec8f5b715e0..72f50b787a7a 100644 --- a/src/stage0 +++ b/src/stage0 @@ -14,434 +14,434 @@ nightly_branch=master # All changes below this comment will be overridden the next time the # tool is executed. -compiler_date=2024-04-29 +compiler_date=2024-05-24 compiler_version=beta -rustfmt_date=2024-04-29 +rustfmt_date=2024-05-24 rustfmt_version=nightly -dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.gz=5a8c5e48a88e7c7b41eb720d60fbd2e879b97639c7ff83710526e8e6caaf8afb -dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.xz=0d237535ae8d435d99104fa5b9dbf41878e2304bb0f2eb574bf17dd685caadc2 -dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.gz=c56733bb6198af0a9b0df9a44ef979150e00de33b70853c239cccfcce23c328f -dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.xz=7da5f887151215ddec640684077d98551fe2aed75a3ece2c73b20698754a70bb -dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=73851e304a539d41bedc0d8a5d98800c8279ae623d3e58e863f8c1f8b458b01c -dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=db9c28841344b0154756e19a21795ef6e0c4e27c7844be9996824f1039edaa81 -dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.gz=a706c8c7e37b9e80d7faa000c5d179a772746eef071387fb2879fdeab1f1f891 -dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.xz=2060634afe1b4a19bae874c6ce3cf4256e613af26e06104b45da5bd71cfb133c -dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=7af61e74faea669fdd41793e4b88eb6a37bfacf845af364ee02bb7cf08c612c7 -dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=4759fb3e3d89ead605c4eeba23be5cb9b3ac98086a9de20f8dbfdfa9282ee486 -dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=4cab18df2d94702e8b551357373bcae60d1023e644148f0f82e8971023362121 -dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=7de4f0d72b4e5770376ede82b02d6bcfd450788a40375fad34d75524c941d72c -dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=6401391a426cf33d6c58f07e7b2828b178720cb4f2b8577ae932b5f5b7d6744e -dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=c3f6729bc769325046f0f62c51b5bed30068c37dc2a36a6283e50565d8cb7d5c -dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.gz=d116c97c1242220c7972b63010aee1ed36bf5353e84a06d3561cd5fe9d7dae84 -dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.xz=65eba577f7775b3eef36e7f000b5007264392b20a7759f8ed567f3a45b2877db -dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.gz=d418a3371b3631328bde2b1e0c3159700f12424e83b1d8ece1349fea90f9e403 -dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.xz=23ae73c776fdb0795944656d743444e3b4c440f45084028206c1aec52333b1ba -dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.gz=b6bbdeb7c8bfac2e8a083adb4782caf5321799f47acb4eaf81da32bd11730e9c -dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.xz=6b409691da6ddb8c04409667b2c3d9d6429c6b5bf53ad18177248406a5f06cb9 -dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=24cd888d14a788e8fb5b886735f3c07a028a8681df48a777b2bb971c62a175ae -dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=e8eece6412936fe4dc863a5e19e6766fbb20e81da0069ad7831465e638db23da -dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=8f007a2aa02e35c5ddb2152cc7589092a0e3083211c6aa23e676e3a3ad5a4b8d -dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=3e423e693dd0813f5d87d9eded94894076258ece56684f3598321cd013aeef3c -dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=2eec5e45e389a52b526a5cf683d56a9df92004f6095936b16cd8d7d63722cc6c -dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=64c5135cbff9d4fa9575074c55e79d85f72cb1783498a72e1f77865b9b2d1ba3 -dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=d64552a80ca386728e42f00d7f1c700b5e30e5a6939f32ffa15a7ce715d4c8e9 -dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=fe91adce8ba35bf06251448b5214ed112556dc8814de92e66bc5dc51193c442f -dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=77aafa8b63a4bf4475e82cd777646be5254e1f62d44b2a8fbd40066fdd7020d3 -dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=c38f0b4adcc8e48f70b475636bbd5851406bba296d66df12e1ba54888a4bf21a -dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.gz=c05df24d7e8dff26c01055ad40f9e81e6fcb3ae634ecc1f7cc43c3108677fa0e -dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.xz=47e8f4ec4d996600e60ddc49daeeb43d4c21e0583a86c12395c16eddc7db76ee -dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.gz=f024bd225b77160dc2fabde78002c8deac5cbb9a35345340964c3b988b0d1791 -dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.xz=96c9e44bd9f0c85c793e3dd6043cc4f89fbeeab5ddf0fdb5daefca8f690bce05 -dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.gz=517889f222b62150fe16bcfd3a0eb5f353956b0084d85713480197bff4558145 -dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.xz=a6653ea4aec51569c1300c044d8bf2517a1f5111f710d12cd352190425b8f317 -dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.gz=4cb5b5054dffe6721efbbf29192a67e59cda69ea4ab4791aaec6f314eefa5a5e -dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.xz=08bc45be22e9e4f615d1c9e70500046c8db89045f5d40dcde853c610591712a7 -dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.gz=9661357ee8ea8973016fdbaa2de3cb98713136dcd25f07aa9f9d101180276815 -dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.xz=7fab806227d1a3be817602abb121ac7e039ba0bbf81e0a1d47bdcccca74203c6 -dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.gz=4c79bb48cfe64bd38af7fe3660cd8bdc99ec90738a0d8fdf80843ecda910dab0 -dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.xz=0fb9edfdafde1820ccb25c22369cafb0e75e68795effeb615cb284a5837c75ba -dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=c1902a072e61ab5ae9737a1092732e3972deee426424bc85fcf8702adffdd41d -dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=d39ea1195dcc95e428bd540abd2db5b5d4c997a7661a41a4c0ca41cbdd18d27e -dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.gz=0edfdb6f6bb2a4a1a96a5e95cec897c444c936e6624bb4a530ffed4847b97445 -dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.xz=70c264b7845febdee45d0c6e44b65d47ba7f367ef33ec906a9fd7f992ba7cc13 -dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.gz=f1bd6417a54f3b53d572ce4af799242db7c11265c71201cc09c78d71be38c13a -dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.xz=53569810469c483785333759f86434706ee5368d5e18270ee13a17817ad57d40 -dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.gz=7b693bde61a090854527a145455ff774314c65ec0cd47d25a19c76c6a166d96c -dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.xz=2494e9fdd8d342b6bc3e55eecfd555c43e3cca8421f3236df2d5a366288fec62 -dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.gz=90307f09c6fcb0c1fbe3ad1522a5381a17e2f69637c6d00f4a2cb5f3149bf736 -dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.xz=f7e0dec4a4862bd85d894252366152b3b6a7627e7e5a25ce323fa2db3bd87c2b -dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=7c719e38f2a1030ae61985205df52f9a0c37b659463a5e2dea8e60e632de2d73 -dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=181ff4ae6adced6522a4c29869be3cc5dac8b961c7c88f2957cd31f831490807 -dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.gz=4e0e63e6f200386995e369a2673867d1bc3005d51d6a57c00ca80056dd85316b -dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.xz=3d5b22a13aed6821482e60d9cc8571e2da9d95d82104284b77c56985a35a9c4e -dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=9f788db76a5d55b3ecdd04a70b0e2be466959f76ae9fd3497ca2c503504e0c03 -dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=f4d8fc103807fba61d71d88b8e25a7016bfbd1a2905330f9a9fb3d7ba082713a -dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=d61bec3d017dd0be43e48350190ad18c0a0269e43d964600b62e1f7fd4f84399 -dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=c00cbdc41a4da0c313a1a282b0158b059dd34f640b582cb7ca18e3d290ca8fa5 -dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=52143a530ca5274fbb760beecddff16f860ea787443d3dc708dda7c8f32ca9bd -dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=c6d2dfeac6f40811bc9b4cec3c23f9c3bb46f761e006257b9313aa7c1a647b5a -dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.gz=325d39e426b1907fa17d93c0752d3d73bd95750f4f967c2a84aab2c5dac8a588 -dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.xz=536f591d4da455302029384ed196932d71119ef0160ac5415617d6b777c51123 -dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.gz=c3684c9bf471669d444853bf484880d17e150ecb0e7505de90883382023e343b -dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.xz=0b00e6132f73d5dc762e359b0005fceab0cf7b01337d8f4aa9eacfb4552f9245 -dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.gz=c91c1eadfc4cbae360a0eecf11c32d2509b68aca86c7b1de3b102944f43e1511 -dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.xz=6f7a5a287dd6226c203bb674ff02ec773e5d0813091b2af744b88ecd6997a304 -dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=58383f094995823ea6db6a87b9ad4b33bdae2264d29bab88ab71ec60ccab3b93 -dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=dbf4680a6fd4dca54acca5503a7fd94502b8e85819bc02346ae9cecd275e4514 -dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=e28eb32cda42654c0f0247aa8e15f01f73770b36f7626c8d6f1b7659accc56e6 -dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=fcc48a83b748e1e46f9daef40563f8e5abbb0e3f014a168b04f3c700c2ace2b8 -dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=b626faf3275fcd196cd627e8a36c67721bae16a56f61cd080c79d137b3ec7737 -dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=2c599d2dc719d69f67625f3c6573fcc4f1ea3266801557dd3892bdb7c761b4cf -dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=0bc1f546fe0cef2b9516231ab608de68d55f72022fbc9ced5101b600e005f8c4 -dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=993294f2ae5202785ab242c1c6567df9c8ab1ef44ad35748c526b7fe854fb94e -dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=210a4f0d208e0c8e13a57fb3b3e6c98ab5f620e4988d10a127ff1424ac1d5ca9 -dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=f10f7df41a13ee2ecdc25d60e697cba2342129a912ef20d8bfca5f611a9ec97f -dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.gz=3e24d2af65f0c9667c9997ce091711b2be48e673de3707cddfd8cda455dfecc7 -dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.xz=0e7b8fbd0207489e38c78c2ae1aa0df4fcbdd84741aa50a86379e4d7ede286b1 -dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.gz=9c0c47fd97ce72abcd6126315834c62aa7297fe09d447ee4cefa1eb46a116326 -dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.xz=49dd65c5340fd804399edfa2402cf255fd9bfce1f4aa7fbb3c193c11bc03f8af -dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.gz=6c1c3bdf097a1846ae08b098c555c0c5e9e9b646c744d6bb5a855789196b8bf6 -dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.xz=0a7319d1062f73af1c8f0efe6ad970d10d02259162c5bc84bb1f3a10f3911bcb -dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.gz=52fef3f8a64fa58934a633bd4944e8ba9e15f2c2766d0f302dea1a6523864dab -dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.xz=8fdbe7590e62ab68a2e463b14da2595e8c4592744f578a813f64d430ed7db4b6 -dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.gz=509bf535622bd26385184ee0c17e4e27a5061a8aeebf5759f24bd578692b2f5d -dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.xz=2fcd10ada329ba7633616bebc584dca13f11c465e7cf513e76efeb0c3174486f -dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.gz=ea8cea0d4a2379bcd0693f6174b25bc1f90a016dbe8280159cbb61d859806fb0 -dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.xz=5a243df8d1345db6bd18e4386ba628e6d302bce1cc572fb447cca4264fda3ee9 -dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=2ee560d3c1e306e103eb06d8e8033cd1489b3f6ff9df3bd8a95e25e977befa27 -dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=aaf6e54184a65ad6592bf03955a84ad12b561afd86064b1ac5fa03cf637052f8 -dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.gz=1b3877424a0a0eb507675a50e9d2c793f00ab85f6f12b1e27f871331070325b8 -dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.xz=6df5eaae5afb64557ba5c3a53ee3e56dab85455838a6044c7671c1180acfeaf9 -dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.gz=1ac05ed7b607fff8b77ff203a663e9f4f2487779bc25e2dcd454cdf5b7583328 -dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.xz=da502375b3cee8b254ab5999809f522692c2d1d90ea0544ad03c0ca514c65ef4 -dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.gz=2fdd35ca3b3e3d6f548f11c93337f5bf2e3c088bc78a79881e6f8e230b38b9a5 -dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.xz=bc16b3a1ab6ed69f0121a117c50cbcd201500dae4d72ad0dab148913d04cc529 -dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.gz=9375c786703c17baae1c2066f8d972ac316bc840e478ecd1b94288a1d428324e -dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.xz=50d6818a8dd3ab7a3ddbbd7a062b538d9ff3ceb6eada031d1c22ab1dc7ba512c -dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.gz=56c3a01e8fd5c2ed75df811993b0b724709fb5473cc308ac09e7f5644468f751 -dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.xz=3527d1f2c99c806479fb4b3801335dc921b514f171b82cd252cbbfc9ed30b163 -dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.gz=bf8cae7c66489f1aa27f1dea1b37f0d0ae514a6e21b93ff2dc6400dc88feca03 -dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.xz=46799f0bc1b3c13877f6cb732774cb3b33e0d8a081bfb56d0f877e79482aa1de -dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=9f90fadab5104e1d415edf3b4edfaf7222f9f0d55f849851efdec74ffee16f8d -dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=87ed6774202b18691bd6884df6944c7e9fe9c944b57a2837e7a7647518bf94e8 -dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=4a0692ad28f7f130b472ffa4aa766b745ba01fb75aa921f2da6622c9c68750df -dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=a3d45962489a1e18a87e567cbbc8d3665f38809d0ad2ef15bcf0ff9fb9f470a4 -dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=c724f4eb135f73b9c79618f27a1ab35dc7b9d26ca62ed796accce68f9e747a66 -dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=8eab25782d16bcee75f86ecbb826346beb4a7525b220b45b3ba05a567c6d4391 -dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=33ab1f8410edf590570d7468dbe2ebb5a0907125bbc8d360a928dcb355f0d0e6 -dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=d3d870209a55ac96391affaa347c04f48cf98c089ac5056f340b8bb38bcc8e60 -dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=4d2bb72b898c30a2fc8d5d3333c2e99a8e30c15891fab641b6a519dc9f0cb611 -dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=fa343e6b6110fcd0c5dae4287ff1a799de5d7e4a805dbf4e9a034bbaed2bf269 -dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=f1ec4139783169fd83e1b0184518ed25d26cee7b21f196deecc74e83a1d78725 -dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=d100be2f6f0346c4b1f5b41aec0c13a47426bf4d49127f2341c8332903e4e782 -dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=bab6051e1071a58cd126580f6644decf16edb4473fe4be6a34791610d820a294 -dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=d9b68f06ff23629063e92dfc42aa3115a858238d368e4b52b35c1ea4491b1402 -dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.gz=96804c2d9accd3242bdc22dad688b2ccee071952477b9c592f099377aee6c591 -dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.xz=3fed6812d84bdaf787e85c37e23ba729b81a6d25a2b33fed75320e66e6641c89 -dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.gz=8da5f301bff35fc067ec7cfb878ebfa5607af7dbc276a6b34a77404432c700d2 -dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.xz=80d643189dc9af98b6410a01261ce6ad34b1325f3aebf3ff61fb43f1261b41ff -dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.gz=2e86b54b0d1f7fefead11d6383bdc80fe0a7b3ccf58381d2a731e6f1c62926de -dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.xz=9831a0270457cad2798b5ae4fe956c257c7e10ce5ad211793dc467577cdec29e -dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=f96bc303c0c2be9cf589f00aa63b2cf3fb8585ca9dd8860fe525821bfa1fe19a -dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=e57a053b1c2bb6fad93dfaffedce7f48fa292196fc8ba6fd2f0c74dc810a13a9 -dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=49b2cb2ba5296871b5fac5ad9a74a2891e8b78321078a455ba4a65e003bebd40 -dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=0f9c15d834a9d282a4018934759f7b48ef3d275e09679a68c5fd1b3f047d02e4 -dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=e59f92827241e670c1aa92b35235ad12340869d59327fb83084b5f4149acbe06 -dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=ad1cf96bb1fcceaa016e29e8ad34b4cfd711d2e0bd7cabb9cd7cc28abf64d894 -dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=14a6d318af85bb9fa5c229e45a88a32a71f44ed02cd90a24bb67921eb64dee41 -dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=ed6b48502ab9169818bceb300b4e6b4fd63366ad5808b047bf9988dae04c2729 -dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.gz=345e8a023be55e3b88a0c2677ea28c7bb4fcc5f3ab707638de76065c7592c2d5 -dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.xz=6d9b11d08f2d62611327a893b45ba07c36df11f077250496ab0881eb7ac84c65 -dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.gz=a2ae1bf003a8a12b2ecb6bde9868a978820f184af523f0e4c3fc935edd509423 -dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.xz=3d1dcf8308f9d4590b429f6abbf8f42f04496ab490ccf4ed8c9e381e6d886cae -dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=a54106d27e4ce97463e7867ceff9dd22ba456f840ec23229e6909b37d48ad554 -dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=e6abfaa0905a00efeaee85b9f93793bab93e2cf4e172c9d829c5ba85006c688a -dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=cbed18e5dc61fcecb2920affc3890c3b8ae46b7fe5a80b3288689e18d490f3f4 -dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=2b58bb0dd5cd2c5f7f93f4c6e9135090b931e0ffa27ff9efe2b8ff9fbbb7e48c -dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.gz=6a371c2ececd349dfa76a02563069912fc91577ac4446d36c22f96723d7f5e9f -dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.xz=9325daf41ddab02fa845971c10a5e0538a18c7bea14e66fa0f5f6fb16654c7ae -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=7f5ba76cfb7c85333c8dab76fb4ad3f12ddc254b95f9ee07fadb8e1270a4f767 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=f853b7f929b7a309ed6c08ff8c57d583ce0ccb19270674fb30e63a873834dc87 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=0680005d0a12498b687afc583d4f36bd67d0877cd9d3323bfd2df50d15c27afe -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=a494b78fcad01c83df9522d460ac2d35d2d00736a921381f2c611dc516edaa16 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=cfa555db31b5470e878b0f53d86617e7342e8bf018fe62cb0271dfe13db95f51 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=0a8ccd6d88cbe79a855111fbda45aa1a728de655b6927f3d429d901d2afc6503 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=eac53424001c884a540c42f0b68447349ec5d0601a030c060aaed76d54895728 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=42d78fca62361ff28db5bc43bb01cef7af5c6f4ab2110fe6170c3dce4707aab8 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=c88de9f2e667da73177fb9c9309d7f1f467e31c18e3ae50d722c71ec8dd876a4 -dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=24b3c04a42d511cdc8c6107b597be38981114f0574eced493d0e90fc748094bc -dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.gz=cd4ad182a098c61550265879ccc04733c39110827f7ef62eecfb8c120ae4ece8 -dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.xz=8499a014dfdf448f474a58f148784c2eef245dc909587d876d2fb9ddc6a4ec3f -dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.gz=e8e1870e5b12b3d8643d712efb91eb86b2081284cada4a140c1526692ab183c4 -dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.xz=d6029121eacc44bd4dcd9ef6dd3cd0d775cb6e9a3d99f3d62d746fcbf8981cab -dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.gz=1e0fc42c3802e205130c01ca90f92d793c1c5427b34da66fe77b97cf67b4a5c1 -dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.xz=4c8cfdb11bb686111fa4842d13430c86d9d14ada30e9df334b3777fe899233e0 -dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.gz=ff895c1b39b84587f10903f4be13d275b545e690da6761190d12c01acc25c6d8 -dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.xz=fdcbcff7b740235bb16e44174fff9080a7c0a31be358c8abc41805c02c20c3b2 -dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.gz=6b227f3b9001e148b66b7001f753a6f88fef9677e39d8fcf4d9c35fe8d345568 -dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.xz=1e29297beb8de3778ba958731294823d9a93aac1e0d8833abc5aa99e2935965b -dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.gz=26481ad5f22a319830d42f69b1c0195bd65900ebe112e659432334b3468f3d0e -dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.xz=c8a837e0d9da8ad976fc1539541c085365aac9dd28b34e4a289d38a823d1b065 -dist/2024-04-29/rust-std-beta-i686-linux-android.tar.gz=f05e28a52f17e22f36ffc70018012a1fe6a07f4b461e774b36464f32bc8f8dea -dist/2024-04-29/rust-std-beta-i686-linux-android.tar.xz=f9501b2691c51e54a6f4cc6fb72e41901eb551d3a7be5f82a94ce2d3e217828b -dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.gz=8d9a782d4f7450bca536aab45147c6ef08bc3847b43fdd171c6449e29762eda0 -dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.xz=4008712e03fb6494eaba3d79051c5e3fdd93d4c52ae8d86cf8f344b5f051cbca -dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=cfb23242e495834a3d0f7ffa3da4a0b206dcae35872b1455b11faeee5511ba5f -dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=95415742c0171945ffc2b67c913ebd1330e29634af238f5ccc843a965340374a -dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.gz=e9354d69e39ecfac1d2928664d17d73f808256a4076b849171a9667705c0aa08 -dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.xz=a34bb0a91170d84195f35ba52afa4c9be8a2f2706dbeea02bd6e8908e08ac65e -dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.gz=d65f286de399ccc9e9acaf7a4dc4f885357c750231d54a144ba9a59181814f11 -dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.xz=4c93a7da70a69b2ebbac01df64af16344e523d16470b29e57237b1d0925f7721 -dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.gz=1b978bfd1a9234be7ef197c8c98c5a6b625f6fbb7b0fca58695986768bdca176 -dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.xz=98d4eb5b89a593c8c4f86244c9a7c737d9c18c0168aebe5923b8d9145adcf89a -dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.gz=dbf9b3c5b54b3eb0727f976f5632c5b0fcb2f90ac7453962d6cef20f7dae4284 -dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.xz=f209ade093753342dda6e710ee832a538dbdaa08a24d606f9a2a1bc59b83da29 -dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.gz=3c3ca7f34569b2c70c6b223754418a535dd7dfa087ab6e28ed2ec78d20065887 -dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.xz=72a7cd0f430ab40d80e93f409b8e26a181010ab4bb75d151e829d51ccdcf8c62 -dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=b7dfa59bb05cf806c87854d6fce5ef0f160697052fdf6e5a0cad121499108608 -dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=88bc22f68bab3367cdfa91676418ce1ffc0ec002afb32aed7def880bdd4be402 -dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=d61019048b941064a99d19e46ff3236a88a2e8fcfb963cedd1d9d1c47963c170 -dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=7474bda08134c676d74afe5263317af3f271963d8ceaa5efbfa1b657f885c572 -dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.gz=e089c77d433d838ca02d7531d6f4a1770fb4a0568acbd96c8f43034d76f2990b -dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.xz=364ae6c89c7a930098286e55193d2f5ee3d5ea80b7cca73046e41725f4a8a2f9 -dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=c17bfad87d16f3a8d26646525dc59a352718db9e7572acb583b68a18cfdc338a -dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=f5c4ecef1c08d19ba6fddbd359a0ce94e46888021cae057fce969276026d086c -dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=3e7e13b0d2e804d228e1e3a9dac0205d294ae29dcc37132f15fb1e218861eb39 -dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=ea31b7678e6f64c2f9c28a9af120be04ed6f2a25a496e40afbf6e9aa0dd20b60 -dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=f0e1b314c3d5ad1676c68c112581dce62fa06ad557cd5f61034e147b064ed270 -dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=8ab7bbea6e2f72df1286facc7d306d01809a4dd9f8901dfdec7e50b594658d49 -dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=48f6abda1c7dac185858744aa2cdc3513cdfb6552535282ee83cf9c5365573c7 -dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=d920d97f15b56ba6ea81e08b3c29dc7f44f5f30b7513c53446edf95843c332af -dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=0a198a770f6e6043e923b0ab1a508fd8b190612d0370c33c8dd2c5f63b6f19dd -dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=424a93313cfe2d85acf956be3d9ac71ea8e34ee61617a550ad6ff5360e1dff52 -dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=2e2b0a8e41f4ea774d665d6248cbc2fdbe3e582206efeb87d250786ebaad0b1a -dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=2da372c091017b7096e473e5c7016a504d2e041e14173d2520086cb43e0a615a -dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=69d3b21403181b2df14243816388169db2466477ec34bcca5693fb017703686c -dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=281b9c20f8641a3d1b349e762b7f713fb0b91da0d21eec798e639e36a0ea3dab -dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=dd9bfd3fd8446d35180fe781139dfb4e04dd658b112eb2a749e8f4aea14f0271 -dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=b1366375e0c5f53da581741dec91972b0c46d7d466052539207e8feaab0ba3ec -dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=7c6650d8cf8abd51547010e8211af3ef3195099ef43a563460ad4780de20ba17 -dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=bab46f3c0078ce346de563bb7a248ca92f15dbdc73bf5a3bc520486118442320 -dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=01735b4ad5bc0a53087dd0ccaef2cf174b27e45bf4d2e3c15e64f7522f059c63 -dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=0bb272c2c235583ed3e9ec151b3bfc601f8cd07822c2fe47a1258b358be507f0 -dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=b2c7f8ee0efe6d0812e4b5dd0979f60f105b84d34d4f600ef75f2eacd954893d -dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=0d5301fc553a6911af6643ab7f57b6438bf649ffcd050d486278c0c5fe38eeba -dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=0d1d35ecb88ee717720ad8e74bd5b602fd6011fe321baddb939f3b161e9cd8c5 -dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=a5cf0b98596e68e6f72be2e83c61b8aaa19ead42f248ee2408a3b8f4e97a6657 -dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=629ed749cdae110668ad9ddbc5c61e99e8d400f3dd0981146c3820deadc360f6 -dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=192819438ed27a565cdb67b51d2f5caeb6ae258de86191d6922574327f132acd -dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=84286f6cf6f00f3c92dc881f64a31e1ec5910102d8d3d4faf6fc7e2ddf1544a7 -dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=304b5f876b47dcbb7c3483c49295b822e8ba83234bb568ce67896ae4773ae2fa -dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.gz=25062159b859e21dda76ca22d4a31d3aba4fcdb0def78bc5b5cf9887c07c1be9 -dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.xz=5d557ee86457f288462603fe53bcc2e092d84faee543659419fa68c1bd88f554 -dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.gz=a9663048aad82ef832b2cf82fa9fb94be047f77e283e8aa3e2df6ad957d0782d -dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.xz=4c4b703a846b4123d09c1eace6322e82784a004b278f1f3b1ca1279e96207f18 -dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.gz=32907c33f240abb1cb17ac438da42c5fa3932b270ad08fd6914775c5b59a02f5 -dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.xz=112583227d2b6abfef6eeb78d980bf2efef392f3b66e433c4959a642d72ffc7b -dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.gz=7ba0084527a18479c4b6f6a0dba8ae23a0ed50e9fc5fbfce23cae1babb5a1e12 -dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.xz=49eb4e2efe3a76713ce1fecacaf915717eeed8552912b92895c7fee068a85a36 -dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.gz=518a532b52f2dad2825158614cd00b12aac6c6e1983a1ad53e2b0e26d1f1b845 -dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.xz=2895e5796a29fd016462694d880e38eb191cb92c9bdb14414c1d6e63b23d3394 -dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=2af590c063344c4c3f65d704fa255232b5f5954872d03c4c55d48662cbe6bb17 -dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=a09df5f38183d9fe6116c807619f812410763ddedf06055bfe8040b5794104d3 -dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=eac22c4972bde3a57cf2ec4e31b43db3c4b7d961ae31475d8942e898c07640cc -dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=104f2c6490e30cc47833edbd806c2efe6256d1194600b2278339612f94704d45 -dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=b3c9c9d7ce8c1db6f20e8ede542e67aacd6047c52882a5d06c4f96a40a7304d9 -dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=76bfb114bc7674792934a4892d2db41fdc8f5bd30c3aa96c43e8055199157476 -dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=1308335fe80dcafaba511ee589959d461145533de5f76118fee29a7e9a15841f -dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=cb8acdb8920983c03b9495cf3506a3014384b4d2f6a53e7907924d38a0baf7f0 -dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=9dd2e5ce7534ab4fbb93ff652196e877f4e9eea3863920c3d34a05d9a3598c81 -dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=4b6e962facf7c54846965a8d6880e4a980804459151f2e22ac5af79bc79e26bb -dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.gz=731603392b6e3d36b3a4956928d084e293ef18c8b8593efa756e753a2a309709 -dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.xz=8b681b3af47855eb63c4ffe06a2bc6bc4f365354ffbc171ce8cbd8c2a3588a07 -dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.gz=7b87e59391493c3147c03794061111e25bdae669aea58190a951cdef111e75e0 -dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.xz=d15eaadb101027906c2fce15b95a3f820bdbc4cf145b705bafc2ac5291289c3b -dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.gz=07390ec742b79ec11b2c3ec65f60efe5d7c616f50c33058fce346f6e9ad21af3 -dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.xz=79e34d46621c298cadb98c00ce3b25d97474aec300d85255153b47e21b7bb744 -dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.gz=b916dc9051b0278f820ea0b093db3ecae2e27de641ef67a9b508df75dc92c938 -dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.xz=2867922a39da3b02ebdb93fb78b010695daf468f87485ad8ab79c7f3eeb18b11 -dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.gz=792b718c0a72e97ba85a17ba67ee09e55b85de829fe4021f828ce54ff8cb31e0 -dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.xz=abff86499119bddfeda9059004549941dbcd3d911702d4a9c198b94f60e60f4e -dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.gz=0bcc7698efafb42a37f20815f5660e39829a42a2776304e7129d0a4ec0c7520b -dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.xz=c437626e250b0d06c05dc828ab81d0d2c543ffce4b100567910508974ea50045 -dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.gz=7c98c9f491bfc837111769a45c10ce2f1ef73c22377158ef9ae80b38034892c0 -dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.xz=f4bda724e6e382e02ddf4e4e7a479120420666a5a1ad3c87a85d4d3c763f2cb2 -dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=01efbb2e48045318e18bfc7b6c190b461a219e81fc1cca6c855bf0c658aef556 -dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=9bff316c6d2fbb3c0889f9ffe4eae496b293fb3afaf8d597155e6badbf0c6a8e -dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.gz=5da713547a8af2c86da7db5d8aa4c27188dea1089fded81ffbbeb0f78952a10f -dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.xz=9d6a45d6af395360c63ce97bcfc2f9a2967c708afcd979f17fa447239703a92b -dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.gz=d1a71110bee002c8edfbcc00e0f5eede5afa005b09944bb2cde469c658049e70 -dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.xz=6b8d18c83b9fffdddf9e55c807dc7d5784cc6d7ae90a57c29b87d707f0656964 -dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=28921ee14426f54aa09523547516437130654b2d9814120d286f209666c88533 -dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=7c3125cce30978ca2619e9aab150cb5b9b2535fbb6274d4ac1b1d4342c7b0220 -dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=ee5c237f092f8a4ba797c4c7769dfd4da81b5c86d2f4b88704d127642d222a22 -dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=30c84b04bd2d4d33abf1875cfee5f227ef6484edc67b3cc4c9c96d92c8406d6f -dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=81274050e72c5a8ffdead83f7be62434f35a65517a1b3c6f7d9d14d0d59da710 -dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=215e20c78a2a4edf9b8368a29a09af5f4cf8d0edd1995de3bbf2eff01127cab7 -dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.gz=340131cba121827a9753e19cb3a4b9ba2ebe30569fb20d7f9300b4dbe2a15cf4 -dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.xz=69626178bc5309afc8a02c941bd77e70e1aa6917ffb6bf0d67a57d921b5c664a -dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=22c6c90533dad3a731ad8a6696e6cdc1b15579e25c658fa2b094185e1893934f -dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=30d7ef6684fa98e28037b69d4220cba40489c23e80fe7793c98b388dc161757d -dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.gz=9d7192d32eaa6b6ccb0f615da0f4cd80827ba6484eabeaf401d8217678f1e313 -dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.xz=7a3fb35e0bb252d5f90773136d1417c26d5601beadb77d6da6f5ad3081977f07 -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=e987635519c1edc8a1d147ca4a86283637e4dbd0a49736b01d605e45a3a14e8f -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=c3ab6b97dccc0038c68494b03b6d444d534e447226a2b2e140af54c94fca0b2d -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=72e8113687be8f947c50befb42b0957dd564f01693cf4d68d749a9e074032ada -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=867b24f33b19f40727c71818c8a002718d44d4cd4ceca44314331e19c1adc1a4 -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=f9b0fd9605bd4e264f5303bd740d9a0195bc147132969965b221f9da0d7875bf -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=022dcf4887df41d776ba2666858b9aaab479758134a71f7c6b2172ed7c1a1752 -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=b5ff4a0ecd7e0f71a9557b6096bb907e5cbc8982431f0d9b01d8e1a895d8b37e -dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=e40d5bfb46aadf6faf849df548154db3f35f356f8b98037a056802a235922b8a -dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.gz=57cfb1fa472dd9c01fc0caf605a55b7248375d616acf84ec12f6430d5e07e2ee -dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.xz=e4121f060b917c811d971e85ce02495e83150ddcceb2204615edff24bd55bfa6 -dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.gz=d63559803c8eb47e0d10d9f3a2284477b570a2536bb541762774271451e1f0ce -dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.xz=5388cf8ecaa234d507e505e8c6d433c5de8811b2717aa254e4caac9f4aa6cd97 -dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.gz=0f027163f37618df4330ecd82afece432b0a509ab20333d7b787c0d139ea89c2 -dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.xz=b1c722e894b145c2183183fa58762c64402fac077419dc7874f8b08eee665651 -dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.gz=24e2ac0d44619ef9b76cb1af6178103d65ab12e2677b366e8aee0604798fe5f1 -dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.xz=1d8a45f1bfe6650edc5ddfc8683190eff5a74384abcb2f73eb3d1e88d566ccfc -dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.gz=ea113c567692d54983ab6c376761651b6dcf9bedad5b5d822d28c0d0d0733cf2 -dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.xz=e36363f1ea531d2fd563f471758e387de37a34e7ef6f4c12175979657333c5b4 -dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.gz=52d77d540fc3f83d82f35f358ccd9055fb75453af3e3bee4b11636742559db13 -dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.xz=843c56f5431c1feda85ceaeef0daf988e8ae020b3556326fb1f75ea7968bf2df -dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=ba2fe37dda1a487a2c75151895f4f6e886e9476a992272ce26e9b5fd7adb11f9 -dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=ccb7be3935de1920509d2061d38f92f1fb8d2a5dd6cef392492242a929363fa9 -dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.gz=40636e0936bd311803317825c5fb6b446cdb5536ada1db097b567df04a86d7dd -dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.xz=804ef68f24bc0ba5150177d8b8515daa54aa82fcb61472385ef1a1d897c5c3e1 -dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=a320c2869d1d2c92b698397d4467c8498cad9481f38d28ac810bd165399ca46b -dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=7ce92211d87068d9c223806929adc34ca611a1321cd58b5bd81aabb0ec3ff085 -dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=79c16b902884301882d16be36fe75ecb32a8e49abde0038ce21cfbee883c2c3a -dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=9384eb9bdbb585b414b6c04c592a79e90a0c0ebfeeb970e5e1b920cb638807cc -dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=ff99de5b819a4fb9adce9386a309b9841bd33632eb7d5079415a6ca6fc86b9dd -dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=55635cde13af11dd8cc007d2e0499bfee493bdfba87b6efd7b1fa4115f5728dc -dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.gz=de82ac745275f069225b84574ed145afaf9f54abde5246592e49d5d1cf40cac1 -dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.xz=a8a7bf64d33c95a2f94265fba8dd9ac50bbb727f4bc3e79be5bf61212cb5d22b -dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.gz=88967a99c993d6e0c3c7948308510644286ac826266dbd3d89aaa083100711db -dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.xz=1804f75786482946258ff0e827274357c49e90a7f2f568add7353249f2ab78b9 -dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.gz=3cb7e02c61d4a21d8289289b874b25e8b020c1d553e5af950160bffc14f51c18 -dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.xz=2ad4b1311a0e39c359798375912faa91b4e13cd473bd59efd1e4f721777d254f -dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=ab19efb741a127615b9022dedf1d895b53c69740cc3da745f9b9888bade9d98b -dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=492cc11d54df410c2547890803930fc65950e6b81ced512e24bef56c3e70f3d2 -dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=c5a631a41f417336f3f65c85adefd1fb0bacc02465485f37d29fc1223c9f6cec -dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=0701183b615d9eec9daea724d4cd8fa98dede2260cfb6b137d6cbf8ad6b29a4f -dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=cb70e92d5275862b500614d79eaea3d19319b96798f4850cb19dea9a8038a651 -dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=908cbe562d82cca1bf176fdc99af867966ea423d244c4a50e14bad19f6878201 -dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=8580a3eb6d6df1774f4b6ca06dc1195c42b1e2a463488a5d851e99b0ca6d0249 -dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=2627948036e905f2e280663c56c86c172e2b0d057311ade7ca238953b7e0c36a -dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=526e4f129fdb4b2c8f4317c57105a09ff03e71771d6d6bbbc9380917b5440d71 -dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=fd9dcf60838376478d7cc505ec7fc39f86f9d042646a3b836e9c06825927c7eb -dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.gz=664c1255a9435d1ad086329a3c215974b9302d481762240cc9d0328d9f1b8c9a -dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.xz=a585ce7684e4174f03adb09df17221e1729e8179dbc91b9a0f8813c3ecc0822d -dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.gz=59a1d91009b506a5bce3c276993cb8acfd71f73d01f9eaf4195b36114ac822c3 -dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.xz=f86f3309cf2784b076f14e7da9e921c294a7701ea92d378c609061deccbc6bff -dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.gz=f5c074461409b33a9791325d4014e6861ad36f99b9e48e54ecceb73986450be1 -dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.xz=045431eec6f839b1c40b5a75c5000f80bd6351274a59b29d962833495324ecb6 -dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.gz=a3abfb68e60544170f47209bbf048f1374e5bb75901a529e2ac2f315758155f8 -dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.xz=398c41a3219781c7cf1a907406506526b672abca6d3ab59c30556390a5f992c9 -dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.gz=38895e615efd0bf75ca14b0ab0a085527cca64fae17631d1780a8f51acd26d17 -dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.xz=786f40030dbe5e6897aafe4bda44770920b2010b93fc5ce86574774e531e2eff -dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.gz=7003cab7650dae7e3d29032422a57782a2c146024c437a6466ae1dd2b61a6618 -dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.xz=bed3cc10203e8bd4d43b6245928c8a607acc5b6e633635caea45eb4eef4bda56 -dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=84cdea91c9f1e848ea17f554229ca80d18d093fc609641d8f003c4f2d4871866 -dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=a20fce7512f7c8cc6230a0f63f12855b04370d25e621183f71aa444c90c36b4b -dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.gz=87e0c484ade99efab57c655ef96dbabf7a02314540575b65a14372ab5496c36c -dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.xz=469757d8f35c9f4210aefd2ba660ee249e4409d47b908a6c68c1e650ee81ae67 -dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.gz=4a38000480fe78fd5da7f9b71d36f296a6ae103254d932c4de6b902354e86bbf -dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.xz=45945d6af237fe4c91fde7db02ca19e99bac56a911b8db79be9b6ab8bb3934e1 -dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.gz=0b07375a9a6507fd4932a05b5aaf28ed349fe2040103f1cb69c8a2494437258f -dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.xz=143bd7ed3ca7b913ddd0cea7cda8d1a0e4c29cc2ccbb7d29f0e45c2a87c3ec46 -dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=9404c111b91fd092367b88adbc37dce10a98c443bd8d9e13a860e1fb4e3af96e -dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=f9f432907c276edcae5ad8ade0264f3c03109be02e791a814edc8ad3d229637a -dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=33425c90427424f0b30fa2a6331a3b59c680f1c1bd0d8845d7e6bc1e2f80292d -dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=03792890c64c72f30143849894b15f0eb3d6ad735fceede9092abd900ee733e4 -dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=cf6f2bffa0db1b4b9b8e95801bf415dcce413f902e26f4c1831dff1a00752b99 -dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=9192fdb668df8d4cab776623db7d01e35af42fea94098c1d4ba53190825d81a8 -dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=a174e7e08da2abc6b84499360670188f5cc61b6d055967e04bf602ff3d831f45 -dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=5a59811027586863852b15fc2b603e7e69b19841f4c10d2527ef1fc5b77d8af2 -dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=645bb5dd7a96bb9292b9956cb9705e9aed2408e47728f245564f1f7404ede783 -dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=1fe34911b082c3a5ca4f24656675c095d2cf56f8005be9ca2517d0ef7d0a2b37 -dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=f2d6403d81bb0afe2e14956828987a0bb044c95f2d9566e1d792dd922dad7914 -dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=d93fdafcbbfd50c88c3f4feb4c68b053882ccae02c45e1615aeeae5a86f4aa98 -dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.gz=a9e997b03559b3dfa2a0eba6ed7a142d7651ea7f4ba4e788d9de807b50558e58 -dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.xz=4412b5fbfab8c5b31e57cf8c4ce9a9d13cfc9c0a8174ea1fc8a7c05281e1cb54 -dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.gz=1725c41500dbf6bea554f3d4acaba70167f0e89087aaa3eb3c0f8a99047c55c4 -dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.xz=27db022494afebbe05605f134191e8b2e78bfdeaa638d4215174038ca9dd2fd7 -dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.gz=dc1a05d49b773dba06808c1c50653ecac506b3433f0f6dfa307109a7c621cc1a -dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.xz=cc58ce3af8f5481ada4dc129079cd558664717526b2f7f9a02bde6bafb6f45ad -dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=34cfe803126ae9218b17adfe833a55c697dfa50729ac83b642529f3682d12d15 -dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=c752dc8962656c09047151fd24166f3134fbeed85006b5d22496691079c7fb9c -dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=386b086b8aad922050c813dd58bb79a52ef806b2d1413e2e9cc46d6e43b81d7c -dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=d9eec9ab7c265444ac5f04d4ec9e77d4c0c3c2e34c5804db8abf5f94c8fd2272 -dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=91df129046443554bfb836d25886aa9807b917acbc9dcf30f6531cde7bf912fa -dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=ca9b574b9f2e914b5a6d9e011aba805d1e6f9b687dc1a1868e88f0e4d9e4401c -dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=8b44f96a1ccd6d501b0af3960edb2c1a6c93957676a1c2cdb831e614de398f8b -dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=f8a10a6767b80bf24f73223b9e46e1b18b6bf6746ad2115eb8968a0e482f0e4e -dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=a197208807503a9cfbc6df938d614a192da48884b2e4892f7b1d234579091be1 -dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=af3a1a33942bd8a3417593dc118abb1db0373f5410f54771713c05bb86724fed -dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=5a3a3aa73b6a0f21c63b9a40bdbd0bb4dc59bd75add0a06e292ced791fad31be -dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=6d7903f1c9fc95a23448717326d667dce59e54aaff821443d3cd9137cf3537fb -dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.gz=64eede54da4bf88b0a42ecf7f7a4bf8002b5550e60a64e1e48244c7f5b04768c -dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.xz=0a8f95e3bb0bebf9bcc8116b91bab3ba97cb6ff4021713586280aaceed9da030 -dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=58f9e0dd9c1aadde2dfd869528adadd4acc29ab0850236f3cee5f023d4211939 -dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=a211a962093e0d09358d51a6eb48da0966a02383c6b00c8acc077b5663d7d707 -dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=5631926874dc54204c319137a77a89de5e6f408de2a832109e2be71ea79f27d1 -dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=a8cf87bc663b5e3dbcc97b0eb58bb1b9b5b0100aacb47dc0c372fe1612517244 -dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.gz=1011f98197a9fe82d6095f4521934a06eea5f7e9719a6e4c9e3bf13d68f799ca -dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.xz=79599b3f91f9372262e97a417f4e104ef5192c0f6f8df204aea9c8b3ee39430e -dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.gz=7179a453bdcb17e401c0af8f4ab86cb5a4752a8ec80b0cbdd4cf1854c7f36a35 -dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.xz=d565fc366fdbc305fbfe59e72b971c58f201d69e03a9ffa667d2ca0735cdb7f3 -dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=ae6bd8e20560d48519290d78e3d21f84b983403ca1f8f466a85496276d7866da -dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=c7c0f8f44b0275456a27952178caa04c32eb9a1507056ddc05926a0730e17359 -dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=3246797ddbc9118de819b13b005b83748338f3c825a7436ebd5aa79ca55539c0 -dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=c7e784e77dbabedad88d24d2ae6dc4abb68bc04b1cd6c9d45f6dc28b6d0e2edc -dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.gz=c9452de4b3f15f0cf0b7d737b217b2cc7b88a96543bd8ce587ee14be1e21a90a -dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.xz=de9b05278a5c69d53ccbb31223526ea2aa2275c0fb3f046d1c1b4d67c0b0c275 -dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.gz=3734353a58dbf6c3831cc6b4ea606357140c191c89e8dfca1d7aa2f3fb8ac53d -dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.xz=e5e3a6e609fbfd537aa4acfefd3681d4b6c8029e2801a1ef23e8b09cf5a47bfe -dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=22f54857e01d759301d099b67547cdc485596499088d0d749d38058c28e0f752 -dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=db48a9d45dc7c7aad4c9bb0d20789dd35fb6ef7a966948c44fbbae132de4c16b -dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=fa5d1fb9f3627e7d59269a1f8008d780c685ea04975473f1808287134e7bc5a7 -dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=61ab625b47fa9097af90a79a1e75a2f2492a415f4009c9043cf453bd4128f031 -dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=cc79969341fc60991059d0e3f13a69489c1e0915ea5787a88b8605ed5b7f3cd0 -dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=bbdb75f922b4b1716b033d91c76c4c0aa53061d6e7fa53a9bf16fe076814bbb2 -dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=13ca68afc3f3970a37951504664b58035102e1ae06d10a744389603b2f7499f5 -dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=04b174aa724945b6359a555892506c6a742a7c427464e8206433bb3f9a65fc02 -dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=430333380a590a9de211c8d735989fedb89321cf9f5f9a0b1ef651ec8b598691 -dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=924713e648806945cd56e54d4c11dc74b65241c8dbf6cc7b401c5c93d0f7ffdb -dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=bb6e5a8b5cc88099e613aa5f4d926165976d8e4a7fccbecf4ac3b0eb966d7a0f -dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=34d5e970304e1734aacb26c095e926c27a07e1a41fe70db9fa2997bef97ad3ec -dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=835447a1d9d60659e99903275f327641809fc0148f35149f980d1a17ff87cc9a -dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=ddd84a7f900aa239f93711f7da71e57aaedeeba2c9c8a8f23608acc7e48613c0 -dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=02f0af2bdae167c6091099a9b54ceb150c22b0f20dc861587a02cac78deb0b39 -dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=822f78f39dcbe3282bf7888a8cdae04efe7b023ded026a7e7f430e4ff15e7942 -dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=68a6189652c11a2c142c5339e2f5fb09d5f3e85d860bff063f62d5d3a3d111bf -dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=6740ea882effa2fb87dd72744c08888ce5ec59c9797c00369156b24847bb180e -dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=0bb365e2d895ef3c39c4899a01187a23f9b7c5195c30bf845da3917f62f5eafd -dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=2e54c9887bc6ed1eb09b9f69c8425da843ea12bf33248fa0ccdc0d14387c1c57 -dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=b0c0fe437921d17e2f50cbff87beeac067efa3d5211a241fb6f4c10b8ab500ac -dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=64e7282c0cf4a714b11eed1d28be3a64ba0ccc6d899211a872a5a7809d514c08 -dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=100cfde057c81460b8cfde2047fe83ddde360a6df1ff178da5a968b17ecc9df8 -dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=38e8712e98fa0bc6962ab2fd2e3b96a2a5dcaa6c16161d8caf71131a1ca5031e -dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=4dab52b50e19348fb39fdad39ab44189c27c10f80b5fbe2cc4723b644611fa87 -dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=36d1b2c9150fafc5976c296200ba3fac3e923df3e6f18032068200e2a887146c -dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=7cb4a536320c23d305ce3bd3b7a954d951bf4d358ef3732be75b9b290c4818a5 -dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=ede1afc7dc5892ef6f780e987737e145c4b4d00495da8c2e9902182a3a174e20 -dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=e2d2d561cbfa0add0e5349682976216d3a7cff4094372c1ed26854bb4e4d93fd -dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=e0380e65e83e4131f6aa7ee4e185689add4372b0c1653312e2ffd56072fdd0fe -dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.gz=73a140c7ed9c80f209ff976c63b0a34d625d651553c38692c91f048f4e0ae470 -dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.xz=9946b7120465181e05916b8023bc075b32bd85cf45a3b1d8bfba2f94ac78d927 -dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=eda273f27714b1e45adcc2388149f48de0e32a9104db0b9d1a02f6d37de43fef -dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=f2955a4b696d050c219a96c093162b42a2fab921f9f3cb7570f8462928306c6d -dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=ec900cc2d3c6d45ef039653f4418f9b9a4a5fddd5d7e8077c3fb08b36c539a28 -dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=04e6999a3405acc79f5fdcafeeab52880e5eeeedd3909b5f3c57e7647c86ef99 -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=0730c5ebd576fec5371085f9fac0adde9424e1d7626456ed33bc66351b0ad307 -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=90cbd84b8d48f0235a1954166f5edd53dc3031532ec6dfcb364f9a9624c9ce11 -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=5f5c62d321db27eb495f6ea312ef8bea0bf17a7a501a44e062986c416951700f -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=a3bf64e2f22436e4484fc818f69d2f750fddd05a96463fd4abfcf655edce36b9 -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=a847a6f9c7a3ce71c7cd8d81bdfcfcd8e4d128aa28ba0dafea89b0cc37c6c36c -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=21fa794456566c64d08f629a385f89b3cfe9d9b69f317ae85fbe7425419108ff -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=b3f792f10a98993b4b55d1df951727a4422102d51b1145e51824268d48587ad0 -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=d791f0ec3c004e7baa0381962bf8ca2f18a3c861152702de5301d0149260e7fa -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=9807b2887e976d29f0c04484f8459175b4f6b70ef000037cdc4dada48e3cbd74 -dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=019920d64778af62879e2146c2c13d9f6e2165a38bbfa1982694bfb48864d308 \ No newline at end of file +dist/2024-05-24/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=502e7f1a05acd503079654dca24a1a9945452580d835d0b6a2cc21155837a4c7 +dist/2024-05-24/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=0bcf49fe166183955a27a0be2e83aa6d6ee9820a475323d8f61c6b159960d3f8 +dist/2024-05-24/rustc-beta-aarch64-pc-windows-msvc.tar.gz=234d90368b765cbe8824068eb2d21ca4c9d7f5cd401f686ef5b338a1781d1468 +dist/2024-05-24/rustc-beta-aarch64-pc-windows-msvc.tar.xz=085cc56230431db4c6088e0f9c4d63fb5af2a7064a5a7e21d5d19be1d3026d18 +dist/2024-05-24/rustc-beta-i686-unknown-linux-gnu.tar.gz=790bcf8e2fe47efc4a0071093df383d70c3383ba3290aaa2f6b5eade8e2f35f0 +dist/2024-05-24/rustc-beta-i686-unknown-linux-gnu.tar.xz=7f8df95a04a6e57db99fb84d60baeddef4a69f13f026f5cc5719a8b6c231d4b8 +dist/2024-05-24/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=939759a91a408b4ecd8921e0cf07676cc473d1c23a2021a57f0f8b04465e9ed4 +dist/2024-05-24/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=5ac62bb9f5d7e7e499598f5579156e593d07c91eadfd1326b29f2bea29122164 +dist/2024-05-24/rustc-beta-aarch64-apple-darwin.tar.gz=134d09a9f7c51f1862f1b361da5608bdae02bef2fdb994e30404a8b0e309b7d6 +dist/2024-05-24/rustc-beta-aarch64-apple-darwin.tar.xz=c3eae7e3583a6f4e68d388a73d2414ca355ef98215417f908ac81e1ea90b2d51 +dist/2024-05-24/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=0f9aa17c2a8748cdf06bbd77bb948ba65794b89587744839db503bb0988e0824 +dist/2024-05-24/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=390c430ffe5f237d547ae2c93a058122d3b8fbf4ea71b20018f0f8bf83858398 +dist/2024-05-24/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=bf6a18c4f54921c46d90fe2a53f6e3044a32f327d6cd13e8308db683a428aef7 +dist/2024-05-24/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=27dcf104f3ca958f0ef3bed47c26e3318e545d1de06f27bf9b25aac97a21c06b +dist/2024-05-24/rustc-beta-x86_64-unknown-linux-musl.tar.gz=07c74d5cc87fba304d33ac7844a1e762225f9ec8ca5a5c6b7bab4c427ffed80a +dist/2024-05-24/rustc-beta-x86_64-unknown-linux-musl.tar.xz=08b6c39e9315c0eee5174d540851c6530e6b1c900db4396fdf8a967b88d69a75 +dist/2024-05-24/rustc-beta-aarch64-unknown-linux-musl.tar.gz=c3aa3cead301f7081c88b5bbd0c0b5a24eab203cbdb2d772ed0ddba8e3034928 +dist/2024-05-24/rustc-beta-aarch64-unknown-linux-musl.tar.xz=943a3fd053657bce6cafb589665c5ad98d5c453ab7c594650ed8c3cd15356647 +dist/2024-05-24/rustc-beta-s390x-unknown-linux-gnu.tar.gz=b8db693c04ad41d1e90b7a3bec7f41a0a21872a220342742402dcd0cb4f28799 +dist/2024-05-24/rustc-beta-s390x-unknown-linux-gnu.tar.xz=ec509af079e002d181b092f1a9e768744656b93fc78466efad8fac567d2184f1 +dist/2024-05-24/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=50f60b246b50778720557f16e87cc19373dd44a77e423bc1e2db1e504557cb58 +dist/2024-05-24/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=ed2a36058a7f0a2393309fbbe435a0c498ab682e91d757f6d70d9c16091dd646 +dist/2024-05-24/rustc-beta-x86_64-unknown-illumos.tar.gz=9b931dc596fd980a66507ca9c83b17c4e6d376a9741361a41dfb176f41b4bd2c +dist/2024-05-24/rustc-beta-x86_64-unknown-illumos.tar.xz=e1bb3f44adf89ff9900ed3bdabb7ab386018c8894d6d92c68f3881077f777a1c +dist/2024-05-24/rustc-beta-x86_64-pc-windows-msvc.tar.gz=c5427a8ba5dc41aa00b8194c49b711685a6c6bd0674ab93ec44b953897def2f4 +dist/2024-05-24/rustc-beta-x86_64-pc-windows-msvc.tar.xz=274545121eb6003eb52fddf030f8893ad63cebee564648dbef312aa28853cb54 +dist/2024-05-24/rustc-beta-i686-pc-windows-msvc.tar.gz=36185524fe00de47a92cb0fb766a4a7afadee469cd5f1ef1345ac24364499425 +dist/2024-05-24/rustc-beta-i686-pc-windows-msvc.tar.xz=7681b6695ac56c50277318fb9deec495fcadcb266a763f1ad3d19b88c9a520fb +dist/2024-05-24/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=d1115327b8cfb23e60a70510f78e39329f2092a0a99763b2cbd25929c41cb24f +dist/2024-05-24/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=7bb0b5b15e5218d9e4554ff2eec03cbe2fde2e957f954fa08aa7079b334bad05 +dist/2024-05-24/rustc-beta-x86_64-unknown-netbsd.tar.gz=6a46a111e30efc6f8f090b2c9e547465e6fcf836b9433fc1f8c53276a0ef63fb +dist/2024-05-24/rustc-beta-x86_64-unknown-netbsd.tar.xz=9516471cb5d3377e1430e64171b7a289bd8a8674032d73c739e0cffa85e87e92 +dist/2024-05-24/rustc-beta-x86_64-apple-darwin.tar.gz=63331eea78233ec4ee4d9390a509a587bbb6e07ce0748fca36cf93a0f4ecb216 +dist/2024-05-24/rustc-beta-x86_64-apple-darwin.tar.xz=b668abe9cb4c5366ee866f8e399ced6c9a8b560f5e5adbe7d6c07058762be21d +dist/2024-05-24/rustc-beta-x86_64-pc-windows-gnu.tar.gz=076e95ca2413fc3f07257ce0b94212db0331e797679a60695929cb588c6047cf +dist/2024-05-24/rustc-beta-x86_64-pc-windows-gnu.tar.xz=d1d006a216c2358a33000e400b5a2c223ee0ab875cfd57eca95b9bd230494d62 +dist/2024-05-24/rustc-beta-x86_64-unknown-freebsd.tar.gz=48ccaab8b59f8bb3e1e0fb82368b79d317e66e4b6a2c6d18d0d49b32e96b2e95 +dist/2024-05-24/rustc-beta-x86_64-unknown-freebsd.tar.xz=a050b10d6f67c1f1d2cdb2425ffb51445ade293328ec3e235400c151a447beb9 +dist/2024-05-24/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=21f26e3028f1174184be66ce88597e1551d2dbf7d9458f528f15366c6cf52c30 +dist/2024-05-24/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=fe504571f52c9eaba68fcc07398db049e3dd6131daa14c2b999540b84cec4885 +dist/2024-05-24/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=082828da023201d2b8f84e686d727f77b76a71c929c5588098d8c4609ffca336 +dist/2024-05-24/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=13bf4a5f012b29334dececacfe16ab6755f7b97165229cff7c27d37b6acb455f +dist/2024-05-24/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=f4584c00af06eb05e6f238f3ce8cbb39ace84e3aad7a3b158b5bb591e522eab8 +dist/2024-05-24/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=8fe01de1853880df20e355ba3925eb1cc537a6fb6aca53b638ee74f689f15cdf +dist/2024-05-24/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=7a24b865db48708120ad670811238fccfd054bba0a92d6b436237c0726678413 +dist/2024-05-24/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=3716d2a3896a2f3cb774c265e58d29e4f8ea35228261f499b96887cb40ff5cd9 +dist/2024-05-24/rustc-beta-i686-pc-windows-gnu.tar.gz=336dd7b17d5ea546f359fff5e7697f82022b0710e1d6ab513370f21741d6f737 +dist/2024-05-24/rustc-beta-i686-pc-windows-gnu.tar.xz=829a078f5d4126d90e117c2c5d31f259b3ba4960b834830c0e49a23ce3bb339f +dist/2024-05-24/rust-std-beta-x86_64-unknown-uefi.tar.gz=3522e09c17465ceda12ad69adc341cda01171cc7275623ea55cc0a56611fcff9 +dist/2024-05-24/rust-std-beta-x86_64-unknown-uefi.tar.xz=d71dac0e0316928d2e5c83c092fab2605b3e46b75a0de867e838067a5134851d +dist/2024-05-24/rust-std-beta-armv7r-none-eabihf.tar.gz=d9fe62eafe589b5223097d35104c5d32b623e98a0e60284254770dc5a760ded8 +dist/2024-05-24/rust-std-beta-armv7r-none-eabihf.tar.xz=0ed3d3b74882594f08be828a491bad42c5b73914c461346e634a38dbf609de0e +dist/2024-05-24/rust-std-beta-wasm32-wasip1-threads.tar.gz=850236f8f00bfdf0f032a2f4b2c3ee1c71ddd7fe11a87648066eb63801d302ff +dist/2024-05-24/rust-std-beta-wasm32-wasip1-threads.tar.xz=db1c182ddbb3276752c16d4d9c9ee94f97b426349fb44a456c276268c4aa8be4 +dist/2024-05-24/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=ce22565ddab95e2f43abc8a864787820f3b1dd0a0f174639b90c26726da667ab +dist/2024-05-24/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=214c16191cc3a3623a7b8d3a995c50132c03f90b3fad0d08927a5e449ea13923 +dist/2024-05-24/rust-std-beta-i686-unknown-freebsd.tar.gz=478c1de19c252d581b4438af70b37b36c0bd240e5bf5ca5ba4e752438e80707b +dist/2024-05-24/rust-std-beta-i686-unknown-freebsd.tar.xz=0948aa34ea060445ca2a410df33622a9228f3fe0f24a94442799568b251c1e10 +dist/2024-05-24/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=e139b5a0151a1a3ff8e6bc94ff856522be558cffbf51fd76a434591e30d51ccd +dist/2024-05-24/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=dccf2fcff4e0980b3e0edd30a565c6bc3f994812f2acce9c7a07eb6ea8ad84ab +dist/2024-05-24/rust-std-beta-wasm32-unknown-unknown.tar.gz=2f6aff225189a507b79e84388b69fdcfe12ac29a6a955cd60d34298bb7435c79 +dist/2024-05-24/rust-std-beta-wasm32-unknown-unknown.tar.xz=2b623f3318ff77aada72d0ca8ce46e807f8e4833dd74717d1a4102f1ee3bef78 +dist/2024-05-24/rust-std-beta-i686-unknown-linux-musl.tar.gz=85e016d2c36da363618b184576e35263034ef0291e8a36f9380879917e757f67 +dist/2024-05-24/rust-std-beta-i686-unknown-linux-musl.tar.xz=fb0be15c71068cdec7e8b75f6ebcf1094d610c0e41d1cec08c2031d8583d10c5 +dist/2024-05-24/rust-std-beta-thumbv6m-none-eabi.tar.gz=96c68111c9a491f816f56ae8f1f552ce31738fa9b9d9d00e42c2d1f0a3628ef0 +dist/2024-05-24/rust-std-beta-thumbv6m-none-eabi.tar.xz=a6e20d5c434cbe9b86e406c6132d1986489fe76168be7a60b6459b0f2691877b +dist/2024-05-24/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=933e7b14c199d36f6eb51ae6527c9af2d094ec13bb1299bcf8c72ba9b0d69515 +dist/2024-05-24/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=ade7325d0787ade9c3122a042baf7238ba5d493a6b7b7ea311421e11a15586cb +dist/2024-05-24/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=8816d3c9fbe0dfadfab0ba7db858bfd32546161f6460b4c9160a4e77ab54ac8f +dist/2024-05-24/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=da52d6feb060edada6fb0f747ef1c1ea658f2070c024a873c69ba909ade175b2 +dist/2024-05-24/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=b699e48e19a1860132719487bf287a3a3f014257182a53b4ed95f1316f401fec +dist/2024-05-24/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=402cad3c14a356f7345bb8cc93ef7186fd09b4ae1abdd13bc020c7e424a941d3 +dist/2024-05-24/rust-std-beta-aarch64-unknown-none.tar.gz=d875d0e34057c77c34e2020310f33a56f08f3b063b202f513be8de96319e9e4b +dist/2024-05-24/rust-std-beta-aarch64-unknown-none.tar.xz=3f489181280332f0d7169f656d03252f7de43b84a6fd6de9fb9c6906c09f7b72 +dist/2024-05-24/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=072503fd29be4101f8e1f75bad03a5b2486fd2e8e2f217f651d6cee2e0b2f032 +dist/2024-05-24/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=b96a542616a05b2ccaad49d9e22273341df7000ca63e4eb91ee219e8b931f4b0 +dist/2024-05-24/rust-std-beta-wasm32-wasip1.tar.gz=ccae6a247c76bbe08216faad0faff0d2052982baa1cba8d403f3182bd3d92e46 +dist/2024-05-24/rust-std-beta-wasm32-wasip1.tar.xz=ceb781289ab079bbab947f366eeb4087b04082326c4f935c78b3887351fe6c89 +dist/2024-05-24/rust-std-beta-i686-unknown-uefi.tar.gz=ed888cc3847b8616d50e80d6c3c0116c8c0e73c6b7fc3b39bb04bced9fb8d9fa +dist/2024-05-24/rust-std-beta-i686-unknown-uefi.tar.xz=51ef73968d5e9ae2b7d857befa8827aac37c490f2051f526ad1b5089ee9fa550 +dist/2024-05-24/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=226d46a2cf4e5c58f1ad1357bfc607d23c195122c7a74a5ddb6636ed35d295a4 +dist/2024-05-24/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=27e68d85bfbc8302e68aea58bc57d1d8ff038a0eee7629f17f479d0ea1a6acaa +dist/2024-05-24/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=132be65f60c5d0b7d6293495acf51559b8855c80498befe98d6cef752deb1a71 +dist/2024-05-24/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=7f938a1bfcea115c99e7e813c9737f86788d78af8f97265ce8f7ebde52dca54b +dist/2024-05-24/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=186c252edf1497a5f559dabbd8245491e3fef7caa6a80b5dc989275caeed95af +dist/2024-05-24/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=3be2944eee2ec57d7ae3d2eb87b7b1881590adaa68c5c6851fa7c027b4f7c4a1 +dist/2024-05-24/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=ae9bfb56c1be153d29371a75141471f676cdf5ec6e8b6af252f4a6f3a1054712 +dist/2024-05-24/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=1387267e76f332fdfaea426468a45ad5d967f1ee9a211b9b72c6cace0b746ad1 +dist/2024-05-24/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=ef44a8ad9b1e07d240a00a2bec592d4f19a099ddfd8b2398f4ea2d50216548e0 +dist/2024-05-24/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=25d0da3cc4616bf6778af8277341b3e436300865245d016a370892d1afcfef31 +dist/2024-05-24/rust-std-beta-x86_64-unknown-freebsd.tar.gz=d5da4fed34f7c008e6365475e2c9a8ac6b74468839fe017827e3c884fca95b1c +dist/2024-05-24/rust-std-beta-x86_64-unknown-freebsd.tar.xz=7aeade644917bfb22fe68f427a46e21834d45fcc626755b0af806ae28d018518 +dist/2024-05-24/rust-std-beta-wasm32-wasi.tar.gz=3c5d32303ca72eb469730421945f2d2216f8f96aa160d11d6b2e38c6350763dd +dist/2024-05-24/rust-std-beta-wasm32-wasi.tar.xz=9705313b0e7d696b4e7c4ae6201e1dd2a02c51b5d0caac730591419322462f0a +dist/2024-05-24/rust-std-beta-armv7a-none-eabi.tar.gz=afc32902cd96bfd1c72e5d2cda240a2275f8b8262a0f952e53b39bdf267ffe18 +dist/2024-05-24/rust-std-beta-armv7a-none-eabi.tar.xz=8a34c9025601a2ee0dabce89ec195fa3bf990986517955768409f3620ae90efa +dist/2024-05-24/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=dddbace8cce3233b6a906ea75032e21c7f2a07be131ff7c356f9d7d59bf90fee +dist/2024-05-24/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=b833758c5555d8805191527f676a20ba6e902fb4da538df8795c5282f495ab65 +dist/2024-05-24/rust-std-beta-aarch64-unknown-uefi.tar.gz=2750fc63254bdb773423483808363048126f20246d8d1a26800d06dc7489807c +dist/2024-05-24/rust-std-beta-aarch64-unknown-uefi.tar.xz=ccef9823e93948996965f9ed2e73f9dd1638a840c57ef96e5c8df525ac241af3 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=47ebc0eb1bbfa824df620a73d1253f22dda9a2f0810c9b6c542e4a3ed545e899 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=6b5d87a1de21c15352121a9380449ae1df9e49b983ffa2431e3e2767a1b36501 +dist/2024-05-24/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=6e3adc75a553a2d97214d2147340ce23a09a2cad1f5e411048b17f74cc735128 +dist/2024-05-24/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=473c1a57e19527a5a710b5ee59692a1f9d0759d5163de0337e061b006765f197 +dist/2024-05-24/rust-std-beta-i586-pc-windows-msvc.tar.gz=eebbea699b2cd32d14123af5ce49ed2fc81f8b2b8de8a83048bdaaae3d0ddbd9 +dist/2024-05-24/rust-std-beta-i586-pc-windows-msvc.tar.xz=2a9591eeebfa1ebb4af31ec8c0929b9bdb353ed92c1f22f4a5651d0578a6a5fb +dist/2024-05-24/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=036a0bea6dbf65183a3d772fe2cf79c9ad86100274680b639e23683b5a29aa6a +dist/2024-05-24/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=ebb328a83ad6cdee2e2b26fce63e6ad57293726a59352eb7bb9ac2d022504c33 +dist/2024-05-24/rust-std-beta-i586-unknown-linux-gnu.tar.gz=254ba6539d9c7b3b7d1b7ef92056c8c4dc7a9378da7da2575b4010cdbf9ca718 +dist/2024-05-24/rust-std-beta-i586-unknown-linux-gnu.tar.xz=9dfb77901799850f50ae983d05aa9467fbf50d0995b3dd1de880dcb48663706c +dist/2024-05-24/rust-std-beta-arm-linux-androideabi.tar.gz=d99a69e9dd172506a73412c5d3b338a0df798ef77e20e5d8376989d74ada2289 +dist/2024-05-24/rust-std-beta-arm-linux-androideabi.tar.xz=35f9022e3aff144157a504e73107cdc4fd7aab4e175eb193d240cdbc539d587f +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=aca1d6e2bafd7a446a52bd5a6b6daddb36a2e76f29ffac3ba17cc47f80c2af9c +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=f967c44f7ed974abf292f4b77ddf1e875f08eecb9f8ad930f7d22ca49253b59e +dist/2024-05-24/rust-std-beta-i686-pc-windows-gnu.tar.gz=61da28d58e15c845d96ae5c1aa93710c47cc3f1903e001bac55e208ea76693a5 +dist/2024-05-24/rust-std-beta-i686-pc-windows-gnu.tar.xz=6aae3ee172ed6ea5c4f547841c70bfbf26879698c984c4b94f295846282a8643 +dist/2024-05-24/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=aa7cd934f8d17ed79c1d5e37acd67e3f988a0b727a72960b7d9858f965694c19 +dist/2024-05-24/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=2ab9fe2d4e6679ab880ff27addee27c9efa6c851e4781f20971ce035b5037b86 +dist/2024-05-24/rust-std-beta-thumbv7em-none-eabi.tar.gz=96281c576bbf4a1eb9ce814517040189be4529050af2fbce9d20cdf0549154e1 +dist/2024-05-24/rust-std-beta-thumbv7em-none-eabi.tar.xz=1f37734d1987dd0c58f03ee1374a214ef3d35244d455908ca9b346d5945e3aaa +dist/2024-05-24/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=515f28e48b0237144bb4110b15c1dfa9dbbd23167b3798a32cd8cf28e741e2d6 +dist/2024-05-24/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=469ee9ef8ec15d8203f07630d72ac32ac262a0708617b712f139f1f3adfc7e62 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=066b9b8550ad7960bf6653bdc762ad5264f697ce2122b6789175d270ed0ff9ae +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=7dcde7ccfd02c980ddc33ebb980b1fc364aab099ffd7698a758a375102d48ed0 +dist/2024-05-24/rust-std-beta-aarch64-apple-ios.tar.gz=b54b1fe276bf44c39f55678aa4b5c8d50c44332d8ba515d94d057da2e1e036c1 +dist/2024-05-24/rust-std-beta-aarch64-apple-ios.tar.xz=1ed8171e1e957aec55be7410f5f9fd7e1b48473f4bc85d1f81360502ddf562a2 +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=b85f3e30dada40bc826daa9f02883924cabcf25dd0738e9f783b4185e5bcd6fb +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=4a5642069ce14b53a0ebedf808e9580cf145e30f0e8e61400a27ed14956ed295 +dist/2024-05-24/rust-std-beta-i686-pc-windows-msvc.tar.gz=3296a8cbcbbc8296a28d1f97bf24f0c47142c7524ca83d1e215adc6cf1ae459e +dist/2024-05-24/rust-std-beta-i686-pc-windows-msvc.tar.xz=5ff405dfdbc42805f8fadd06323066e2a0aa238517871c65198e0c7eb8f6c210 +dist/2024-05-24/rust-std-beta-thumbv7em-none-eabihf.tar.gz=01893bc682d37aa38bff5d41e8b61d23ece07f64f950b2efefa2e67efeb47081 +dist/2024-05-24/rust-std-beta-thumbv7em-none-eabihf.tar.xz=fcf60f22fab4d53f0352f98c1def023ec174d4d930b7ec0eef71e4ca6a1315de +dist/2024-05-24/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=39feeb9da7f9901db336af32543785fd3b0a587684aabf42254efd763461c820 +dist/2024-05-24/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=f14b77154f905166c769012e600321f1ff9cf79155f9031d7a05eb7469353569 +dist/2024-05-24/rust-std-beta-armv7-linux-androideabi.tar.gz=49c2f372740848e34c8a60256ffde8c578be529087855e517af27a3f4f440428 +dist/2024-05-24/rust-std-beta-armv7-linux-androideabi.tar.xz=5dfc8fdffd7f502ff05f50b8834424f7129b0f7be80647eac466e9fa19660e12 +dist/2024-05-24/rust-std-beta-i586-unknown-linux-musl.tar.gz=7dcdd118d7f862b7bb532fdbfa94a92d88a035a22310c4c2f6c9fc2230467d6c +dist/2024-05-24/rust-std-beta-i586-unknown-linux-musl.tar.xz=dbccad2e2b705f2b38ad2b0a8da9bdd3ab58849818051674c26cf516ad7fb37b +dist/2024-05-24/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=06ad4618876e3c9413fde9763b93271e15451ab91c65b56ad6f8be958d2651ff +dist/2024-05-24/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=079120eec04d3940aa4f96627fd6d9ef8f74662eb132f52f4e5c797f5dd16678 +dist/2024-05-24/rust-std-beta-thumbv7m-none-eabi.tar.gz=2b0c040d29177a6a1829b3f4e5f5be9313c70205366707d586f4290e80c081d2 +dist/2024-05-24/rust-std-beta-thumbv7m-none-eabi.tar.xz=7487ecd436a99fbea0a968c082b42c6036ea0a7f66e8175e61aa0139ff2f80bd +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=041e08179dd50bf95ca4f66bc5b1a10b958bc696774997139fa6754587c45336 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=4a7e06b730d3e35318690fc2927e4084062754c2256e5ea2bb37014e3c66101b +dist/2024-05-24/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=e0cbee59a29d119616e60766eb68b581e27a661498c6af8b7e3cb8279078ba49 +dist/2024-05-24/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=7a21de0bf78aa43cba18f560bf2668c902ee4755fc74f7fee7128f0fa9ded5f3 +dist/2024-05-24/rust-std-beta-aarch64-apple-darwin.tar.gz=dfd520844463a19cb99dc9c33849d646970166e3424c5dd96fb69c4483bd14f7 +dist/2024-05-24/rust-std-beta-aarch64-apple-darwin.tar.xz=7aa566be6a31bc5ebe6f588f521933d2d30514a3caa29332c91a9bba2f41f37d +dist/2024-05-24/rust-std-beta-wasm32-unknown-emscripten.tar.gz=70efc840eb8b45f0c4f527165ca87a913d18661cf4996766448c03bacc5ac429 +dist/2024-05-24/rust-std-beta-wasm32-unknown-emscripten.tar.xz=b19493c7894240666496a4cde38cda7dbcce3977c0014cc531f27fedfaabeb6b +dist/2024-05-24/rust-std-beta-loongarch64-unknown-none.tar.gz=ae808e787aa5997f2f6ab0fa4bcd65c3c3724d909738b9f78998796c939c6d83 +dist/2024-05-24/rust-std-beta-loongarch64-unknown-none.tar.xz=2bb6da4f902a8f1d6725705c16d513478c027cbf82c8ab9948feeeed028f60e3 +dist/2024-05-24/rust-std-beta-x86_64-linux-android.tar.gz=f29b6c9b9f507858c08a560569bea2a65a749f3f906caa92a2f78998e3530d25 +dist/2024-05-24/rust-std-beta-x86_64-linux-android.tar.xz=7b79450216d0e11e6c3cf241cd57b5064388a8d6d7c0b0e52d29f8373ff97da1 +dist/2024-05-24/rust-std-beta-x86_64-unknown-none.tar.gz=37b03d9f74ec899fde6ae56eb6af8e6b04c2bf8fdf2de08f14fd576569c7f78f +dist/2024-05-24/rust-std-beta-x86_64-unknown-none.tar.xz=6d212f421ff3b67ed0c0b205a1c3af1df6c5210d21127faf53f906ddc46f1758 +dist/2024-05-24/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=53d0a088e7e70b333a72a83bd42f57c81c24520bad9ae89ef710bc2ad658984b +dist/2024-05-24/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=f26ac1c83990634235b44e14884307a8cc35ab730747b6e4fc90542a985d164d +dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=d8385e3c27433ca0898344dad62a91a5bc29b5cbacc5660cef82db0475ce9a04 +dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=4478fe4b44978f4000708014802365ff25dde402acdf1546101fa07fef329c9e +dist/2024-05-24/rust-std-beta-x86_64-unknown-netbsd.tar.gz=ebeb2599218420288ea2b95dc5c1a30f4482a37ff28b06bfc945569f60c8b914 +dist/2024-05-24/rust-std-beta-x86_64-unknown-netbsd.tar.xz=5610b2b28f534eec0003b848621881d3b0addbefdfd69666dc555124aa6dd600 +dist/2024-05-24/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=5bed751da30f4ec0d76613ab04b5e7687b0928539215241988ae792e93fc1ac6 +dist/2024-05-24/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=a46f5557facf0e7fe88cb70a52afe1bf7329836ea3379e9eb3d2823884806f35 +dist/2024-05-24/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=ae040d65d4a52e5369c212f3f3e8986eb92e903d2661734831d253d24efd9f57 +dist/2024-05-24/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=5bfc44c33c26cba4d381b3a4ec0821ed6fe7597ba1ea33f53f4ed5b9e883aa88 +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=7a85f404f581debe2802c64da4e421eab591a47ca40518249c3293d5f3fa109e +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=02b85ff8b77947f53e0bd70c9a40c5bc55fb820f86efb40c2e985266153553ec +dist/2024-05-24/rust-std-beta-x86_64-apple-ios.tar.gz=db60e79cb4497d46467de9e2e808ae58ee329e2cfc7a114f97d7455c756ced38 +dist/2024-05-24/rust-std-beta-x86_64-apple-ios.tar.xz=fd7c3fac452faaadf1f907a270daf4e6b09063d9023d0a00bcfbbeffa66aaba5 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=6ef5201b5b5ddc2c8ea7fb20186f086e0ebba77992b86ee9517973063dde8393 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=32744f5af908ff5c925f5b6fe9f2ddb985b23b3a707aa61c5bfbbc4754838d52 +dist/2024-05-24/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=857d39bbcd5b8ea6ecefbbbf5a082b11e0e96e51e85c06b33aebc0b96bc48a5f +dist/2024-05-24/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=d51e77d6fc82bdbae84d4bb787e4df4167a3bdea6ab211d9b8ddf79c285547c9 +dist/2024-05-24/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=8b5578ab21645fd5ae11dd8e1c6bcd6ff8f402da94345a5a5c462ebddacdf733 +dist/2024-05-24/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=d3f1f2821af7ec976fc5f68cdcea77b3b36d0e1f54ca17e86fd92b0083d113fa +dist/2024-05-24/rust-std-beta-aarch64-linux-android.tar.gz=09095551ce4bca6bb872b07c4a5d62cf96915fcdb95f6e36884b2f6758464e5c +dist/2024-05-24/rust-std-beta-aarch64-linux-android.tar.xz=5ab50b5e63d10c1a2edcb7c60cddb081f2779dfcdb6ddfd1785c282c775c4128 +dist/2024-05-24/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=85633e33d5c82d99cb59d9ac2cf6811b871db12ca3530293ffdd73870a3ee758 +dist/2024-05-24/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=cfabeb1cecc122b16ff8c63a09e25c15b4855ae30fb71d631ae106150fa10595 +dist/2024-05-24/rust-std-beta-armebv7r-none-eabihf.tar.gz=79532507392a67355c649f92c575ccacce0c73e5c3bec969b0f501e82c3ed291 +dist/2024-05-24/rust-std-beta-armebv7r-none-eabihf.tar.xz=c47637bcf4a3b031f43c5225daa76bd29bb747104ce34d3020328f677b186246 +dist/2024-05-24/rust-std-beta-sparcv9-sun-solaris.tar.gz=b64d6b7272689d68074fc15779bb2dd625a897b2afdcc400d6b21f3d64aea45d +dist/2024-05-24/rust-std-beta-sparcv9-sun-solaris.tar.xz=54688000828eda67b5761e405f3318f97f58616ecc0fd4b67a3da1ad5fe24471 +dist/2024-05-24/rust-std-beta-x86_64-unknown-redox.tar.gz=6ba9d6456afab0e61593e12a34bb50cbdb8bd78def16eece0f0c79703fd31499 +dist/2024-05-24/rust-std-beta-x86_64-unknown-redox.tar.xz=4b88c220a125af0d7c3a8b50c2edb3acbac9f5a3d54630e5aa926a898c8c5ee4 +dist/2024-05-24/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=194780953225139f9c3ca0ed92106a34fd7466aeae3b92aece0fbed31c22ae7c +dist/2024-05-24/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=7907a4234a8cd358df1ef1e462136d1c31435461806b7581e621698afce8f1a4 +dist/2024-05-24/rust-std-beta-aarch64-apple-ios-sim.tar.gz=faa185048776def01bd11870e2d1d0bde2fca0654ffe01614f36a2602523f261 +dist/2024-05-24/rust-std-beta-aarch64-apple-ios-sim.tar.xz=07a424016f695d47ceacb6966983a2fec1414caa9ef5bf84d72540283686c639 +dist/2024-05-24/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=c083674853c3412de578f469e50a367bff77f5f3f8e85bff082200f769150bb4 +dist/2024-05-24/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=2e29b73c2942fad3f2a79ad294e16b124c7c271ce26c6e2b65d5cfadb9709c3e +dist/2024-05-24/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=f5e0be0aa0ce467db0bf18fb9d306f88efa36786ea28539fec841300f13fc926 +dist/2024-05-24/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=e7c5d53eeb250006c2ff5c90bdc3a31fd19edde7f9022b96f86655889a2ffe43 +dist/2024-05-24/rust-std-beta-armebv7r-none-eabi.tar.gz=d78c22fb8862dd3bd258e7982dcce54b859756b8f3bede42097873dd7239e14b +dist/2024-05-24/rust-std-beta-armebv7r-none-eabi.tar.xz=bb1ca2a1bf420f5feb10133ac208f1be8fe54927af236855202758959d933019 +dist/2024-05-24/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=3bc49069aaba38a7ac627181b73f6249d707be590d77bd410a90a59c9ae98378 +dist/2024-05-24/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=a66a7b99c95b600abba03330e9f26fdcf87860259f81d41ab629643663c188e3 +dist/2024-05-24/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=c17554b2eeaf0af3115fbf3659ca22be0ca1ef7b4c64c831a18466db04cc8d02 +dist/2024-05-24/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=f4b21bf361ffcab4abc8ecbcc0c671788f4f2df058a24334d0aa0c2567c86fbc +dist/2024-05-24/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=1e99b060eb7686203e8b49a2ead224ae3a28456b14a7db89585fe547673ab0c2 +dist/2024-05-24/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=dca7426cdc98b799cade30c8adb4386c4fd0be2d1e6fd055615a0d0350dfe396 +dist/2024-05-24/rust-std-beta-x86_64-apple-darwin.tar.gz=2d683687edd6df5f650979fe8d4ded9c813a695033f11be7444fec7599f58225 +dist/2024-05-24/rust-std-beta-x86_64-apple-darwin.tar.xz=f14f1f132b28d67737fd7d2eaa740a74bce2f19443f0e938c26e182be97404c0 +dist/2024-05-24/rust-std-beta-i686-linux-android.tar.gz=3b812e866ad74e542fe32c625ffac712ee1bf3d101f73828cd938bdbc688b7dd +dist/2024-05-24/rust-std-beta-i686-linux-android.tar.xz=6cd72f9ae6b0459f57e8cc7c5161efb0b0477bbac33339951c9b4ca4f4512de0 +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=cf0436b2a84bdb83af01a9383dadb2d0bdb43edbcb959c28d20d8874a4b6bc3c +dist/2024-05-24/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=afd01da46d82692d8bea9eefa31000ca10372ee7bdc5a9d8c6b5c4bcecd930cd +dist/2024-05-24/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=3f90c703dd67cee0972536caccc6641dbe5bf38eb8dc822937ff3c98abc97710 +dist/2024-05-24/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=a79012cb247484db2df607a63e451cb6748be1a103d6e368883d95e92fd5ee8f +dist/2024-05-24/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=8df8df9a6eb55bc9b63dbb4b1fbf3e15ba6f95b0ae1e901d4f3d2e594d4fbaef +dist/2024-05-24/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=f110b657611fd530af1fdb20b06384a41db126832ff9a0b8e3e53b508addf1ff +dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=f89ad7191d2eb0c5d8b01892e61e68747e66d18214152cdef5c5b191a1606981 +dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=729057537bb4494e3d060c26867bd6695f62a096eaf33582010d583c7234a313 +dist/2024-05-24/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=ea83d20d4dc99b7e9eeef69eeba2224015fc1bd0b0ad4695ca6dcb537a5f610b +dist/2024-05-24/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=b3615738d1c067d22327b62e416e06cc57c08c2141c0a478f265fd888ce6f655 +dist/2024-05-24/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=7915fd0662c2cc9724395745bb23d6589e48b74c11151b5674fdd7834483c54a +dist/2024-05-24/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=d868ffc4f8b60bd61d862e83f445c783b9b98b11041ba9d284354d1c7c5c81b3 +dist/2024-05-24/rust-std-beta-x86_64-unknown-illumos.tar.gz=9d4ec9d659228b86780d29f183b7b1d8d9087290d9602659d985b5a4adaefe52 +dist/2024-05-24/rust-std-beta-x86_64-unknown-illumos.tar.xz=315ef515146f4de92935fd02a458bf71cbfa967d426b7d781b361f650752fb0d +dist/2024-05-24/rust-std-beta-i686-unknown-linux-gnu.tar.gz=c3cfe615737af46a5de0c0c71cd530d8f1b8fe5d8c9c89865ba5d127c71ebbed +dist/2024-05-24/rust-std-beta-i686-unknown-linux-gnu.tar.xz=fb375bcafb3d35146ee387772440921cf1ec737f48e035bb34a6772ed6f98435 +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=0b5253ef9d9d1298423e6fbc1170e3a7173717ebfc57653debdeceb80df74d8f +dist/2024-05-24/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=f1ca8bde4ca0621bba03e94de67167c01a2cc5b37f5b77e600986c67cb477ad8 +dist/2024-05-24/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=9eaa5a78691b16244bb8d2d4f1e22b3548243967b49572a276a66997a04733a1 +dist/2024-05-24/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=f4919dd99711b1b0c7c533a2301423a3c6b01534fb8dfb7811356ea827b43b3e +dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=9c5156e544557ba6cdc366407cac81b90255b0759c7e9ecf19d15560f8da0338 +dist/2024-05-24/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=8f9841d0d6bf623330e497304efed6bffb96f081208be5b5952c493884d803f7 +dist/2024-05-24/rust-std-beta-armv7r-none-eabi.tar.gz=6fbf1ea31e37333c52e2c28d92baadac89bdb2c53fabe18b3977c2a837f69606 +dist/2024-05-24/rust-std-beta-armv7r-none-eabi.tar.xz=e1b656df5f54c6317ebbe660ca9488a6c93e1516e4d8cd13d4d601d98e18cc71 +dist/2024-05-24/rust-std-beta-x86_64-pc-solaris.tar.gz=d5831bd26c24ee90134178a0877944ebfc5fa743e4b6644308f2e6f9480cbb94 +dist/2024-05-24/rust-std-beta-x86_64-pc-solaris.tar.xz=3441e45c78e670b2cbb5becd10fb1a20232adfba8a3b27534b364fad47a8b14f +dist/2024-05-24/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=3ca6068a2b62dc715fba00c8f8c231465a8cb918bcc0ec28ba5eefd6322509ae +dist/2024-05-24/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=3674d1fb506ee0237f8dc359ebce38aaa1f302e0cfda1a23ca083596aa6ed1cc +dist/2024-05-24/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=6150c318589db8d2243619b85e0bdbf4433dedd1f6bdaf8ab5a0c48d0fd9a62f +dist/2024-05-24/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=3a03e4ee500596e03335f7d01e666727ca35f861a82dad214ca06c09c11246a0 +dist/2024-05-24/cargo-beta-aarch64-apple-darwin.tar.gz=39998995295e1c03bf81c2f384d871a0270e3b87ca87b23c61642e6455c83287 +dist/2024-05-24/cargo-beta-aarch64-apple-darwin.tar.xz=4a837a5313c2b7c340c1df32f37679975abb7263966d90f755e87c4925262065 +dist/2024-05-24/cargo-beta-x86_64-unknown-illumos.tar.gz=6f6b434451c5e08e89feaab897d6d70445b380e12ad398453ec36425954c1d09 +dist/2024-05-24/cargo-beta-x86_64-unknown-illumos.tar.xz=183082bd9b3ecb97831d22a1f88820a9622cef480db113695907fd00eac25602 +dist/2024-05-24/cargo-beta-aarch64-unknown-linux-musl.tar.gz=7d500984773dea88db82653b5565f6d73a622cbaf9da2db942b3453f0b965296 +dist/2024-05-24/cargo-beta-aarch64-unknown-linux-musl.tar.xz=9e9a890b7314a731ce63d57c325cd6476c6fa50e0364b4c7b8e2e5620c83ae05 +dist/2024-05-24/cargo-beta-s390x-unknown-linux-gnu.tar.gz=5a3bd87bf129c826ec705b94f0ebca06fc2b3629d191b76fafc09cff8c59adc3 +dist/2024-05-24/cargo-beta-s390x-unknown-linux-gnu.tar.xz=24fcbcea1863cf45eadef4fa575d3ec1faded48ddd9aa02f45d199a4b09c136c +dist/2024-05-24/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=6a844b4584ea5c89556518ad063ff6298e6c47853d23f7d8f96a07774b0329e3 +dist/2024-05-24/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=4f20df4cd9832304e4a5963b27f7caa3d5cf7d1d8ca7a203db3c3f30552bf2e5 +dist/2024-05-24/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=d986028f54153318e862d42bc6f6858b88dfb32089d1039e7cf1bba384ccae1e +dist/2024-05-24/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=a6ecc5e601620ce896f4371487a7cd9ae529dd20f760d44c498fd705fc4140d0 +dist/2024-05-24/cargo-beta-aarch64-pc-windows-msvc.tar.gz=59f6d05082f4feb8d1fdedc513c27f4d1680280daa40889aeada106c8d363678 +dist/2024-05-24/cargo-beta-aarch64-pc-windows-msvc.tar.xz=820c078d60cf6530f1c67111c99ecfc492b564e4f48113770c684677a553864a +dist/2024-05-24/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=8c89e03e9c8f41f2efc8c0c05397051dc67505b634d9b9b7a076471b334a6b8c +dist/2024-05-24/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=592c740d96a1d78711c8a861b3ea17c36a806ca2dc1d869d51dc6e5de456ee60 +dist/2024-05-24/cargo-beta-i686-pc-windows-gnu.tar.gz=9db89655fecd5169d7cfe6869bd901abd621f6f5ccc9c2928ca52a666ef11eb8 +dist/2024-05-24/cargo-beta-i686-pc-windows-gnu.tar.xz=9a37c1efbc17ee392784109db3d5674d95b68829ef87895c2f7dcdedc2271952 +dist/2024-05-24/cargo-beta-i686-unknown-linux-gnu.tar.gz=0b6e0cde1312e5294efd1f9ff94a7448e8025b755d02fb36b0e15b2642069cde +dist/2024-05-24/cargo-beta-i686-unknown-linux-gnu.tar.xz=5b96820f5ef0f04afeda2fc4052788a0a5c17f24a73680abe265d4a52a27d266 +dist/2024-05-24/cargo-beta-x86_64-unknown-freebsd.tar.gz=42a56ca6639895afcc379daa674270aafed270ed3698ac7a16d2180b67d78da3 +dist/2024-05-24/cargo-beta-x86_64-unknown-freebsd.tar.xz=9dc792621d33faaf4c5b779df0b72eeb87ff2756bd7347517f50ae0a41d067ac +dist/2024-05-24/cargo-beta-x86_64-pc-windows-msvc.tar.gz=e30d1feb140198a1cccba94f1f4f12a1e5446c6925c4bc35a82dd8fed54be079 +dist/2024-05-24/cargo-beta-x86_64-pc-windows-msvc.tar.xz=b754bb31b01483bbb92b14f1fb7de241295223c58a84059f36b2237c93963bad +dist/2024-05-24/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=de99b7e5b35a756f4d3ae4f780a154310c6062dbcb9c9ab0083d061976634d0e +dist/2024-05-24/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=224f4a46d4cc3ea797fd7cf70f80e2c16ee758cec23aa1816964d9128264928e +dist/2024-05-24/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=0e3907c9e2d11bcf9ae9739c01608f66048a63c343cb006374ddec08d6ea7c78 +dist/2024-05-24/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=981ce940535a7684952299c1be88378c6763ee91d3765b014330aca0fbc65ce9 +dist/2024-05-24/cargo-beta-x86_64-pc-windows-gnu.tar.gz=ae0074711a8ee88061859789dbe7c7ba9f4f306d5d99fbcdf1a4fb0aef7ec2a8 +dist/2024-05-24/cargo-beta-x86_64-pc-windows-gnu.tar.xz=40de1cd1454bb99a8c3ff18bbf2950fcf480152536dba1bc20576e3cb42b62e2 +dist/2024-05-24/cargo-beta-x86_64-unknown-linux-musl.tar.gz=1f849b69e086fde12e342aa935bdde649cc3b18ab9f372c1decdc6ab52ecae77 +dist/2024-05-24/cargo-beta-x86_64-unknown-linux-musl.tar.xz=75e6ca1b2b75de206ae4c6c8b98f36872e00cb92151c064e29bbb9a5bf47d441 +dist/2024-05-24/cargo-beta-x86_64-unknown-netbsd.tar.gz=fb6a694dc1dd5c0f8e0749354b54ec213ae62977d2293b76806da8cf6b4db18a +dist/2024-05-24/cargo-beta-x86_64-unknown-netbsd.tar.xz=5d2bdce7e5ee3be7a46bc55614ff6b35c996eb95cc6348fe982207f183237b47 +dist/2024-05-24/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=551b70fc54e177ee31a33d79ea7c8ae19b81cf3bbbc767e23455f3da4d1d440a +dist/2024-05-24/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=3ceac72674b7ebc33ed3b73057ff93c4569f9bb47d15c743a9ed2775a51d9eb3 +dist/2024-05-24/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=b38fdb21440650b6cbecd6c2e049b95519f60e37af48d1a98d38ea82fe27d908 +dist/2024-05-24/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=74be24ebefc943be201b114d9eb49e15fda0880eb03c0df60ee382f2a48dd0d0 +dist/2024-05-24/cargo-beta-i686-pc-windows-msvc.tar.gz=70d1d27a68f084c133fa0b3c110d43be37de2446a81e27e92fac5678283fa26f +dist/2024-05-24/cargo-beta-i686-pc-windows-msvc.tar.xz=d02feba93e984c5d5aba5018499c830954f3b49f68c9885f11bd04b48b277f0b +dist/2024-05-24/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=f4eab6af2e369b32879a97446c962c67b8733aaccfbfdc60e04f72e2baf6ab82 +dist/2024-05-24/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=a34c6b4298c5b8fdd266b6035b6a3c5b0458fbb64a853830fc6f9df2c1a0bca3 +dist/2024-05-24/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=b6fac94136e6fab6c0b6425890060f20481bffaa98bebde52f99564afe8e2c3e +dist/2024-05-24/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=6dc5ebd5e03441015655d5929825364b9bebe0659df42ddef09fc489fe22155e +dist/2024-05-24/cargo-beta-x86_64-apple-darwin.tar.gz=f08d91646163be427447b11fe7e1214df4444c98c99070d5f154ba79e47cafa1 +dist/2024-05-24/cargo-beta-x86_64-apple-darwin.tar.xz=ac86b164e6a95388510c6cd5ef6fc82cf9794d5f3ebd12f1bc94f16ca2c85ff4 +dist/2024-05-24/clippy-beta-x86_64-unknown-freebsd.tar.gz=07e962b44908356b427c350f1208a9c017ebdbf4bb6d5f952b1625833b552068 +dist/2024-05-24/clippy-beta-x86_64-unknown-freebsd.tar.xz=6e0173c30b8087e9ff2a4d7b46d178d380ec4a1443034d5706dcfeb8dcd8ecfc +dist/2024-05-24/clippy-beta-aarch64-apple-darwin.tar.gz=ebaa62ae3e7191bc5be56f93b47493641e705ea312071e723a9e03bf9fb487ab +dist/2024-05-24/clippy-beta-aarch64-apple-darwin.tar.xz=3d9c9ecbbbfd2d475d4bec4141e5da4559f092d5167127fd4eb13f5397abc693 +dist/2024-05-24/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=ea1d746dfe195065e8d387ee06db4f0d2615814b9c6ef6246f85d1073c471b06 +dist/2024-05-24/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=86387463578f29dbdbb79257ea973a247df4c6774e88df6b38fcf52b79c99e02 +dist/2024-05-24/clippy-beta-x86_64-unknown-linux-musl.tar.gz=383a5528ac4ac0524fadad6e2bb7fef0b3a03d795250057cc816533728fbb4a7 +dist/2024-05-24/clippy-beta-x86_64-unknown-linux-musl.tar.xz=6f796fc9a9039815692dc5e127fe83c5fb71f208f0876a5c6324bfa9953899bb +dist/2024-05-24/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=4538a4c73464791275fb0eb49ef96356966521131a33ed74c5de1ff587b57e3e +dist/2024-05-24/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=e16fd33e2788bfe6d7dfdaf2692b21bf61edf3d34197cd7d32b1ea998ae03000 +dist/2024-05-24/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=61e5c68a5eb0b7ec35b2353dcf19a54e8fd63a4cc8be1e1651138aa8193cd0d6 +dist/2024-05-24/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=6e2a98ffecd48aae032540eaa0c9573317ffa920d6a21e2e2f2e512d8eb3b991 +dist/2024-05-24/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=ae6406baa95d37a95afec6c3cfde8b1fc5b811fa824785ebd6b17d5f1f31d329 +dist/2024-05-24/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=fe98fd0b83763a2b73622ec3ba849ef2e0e31656010b2be3b2ee31875b19a826 +dist/2024-05-24/clippy-beta-x86_64-unknown-illumos.tar.gz=3a4eba33496cf3c1b116524b3f5466426148b5bf84bce2d1b3865c4429277ba6 +dist/2024-05-24/clippy-beta-x86_64-unknown-illumos.tar.xz=17a5a7e10a8821c12a5930fd1ed85e3a545d16471d7948d09fcfe536fb6556a9 +dist/2024-05-24/clippy-beta-aarch64-pc-windows-msvc.tar.gz=176239e95b1efaa8d12a41792d008ffc4919ce49a86cecc1b5a83fbd94983c9c +dist/2024-05-24/clippy-beta-aarch64-pc-windows-msvc.tar.xz=0e4abffe1c361b54572572633cdb57ba4b5e43aba01b1af9298532de8201a2bd +dist/2024-05-24/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=1b36ea0173144992dbef9bfbe7117454b7d4bc3a717bd04c6b8470f9f3feb38d +dist/2024-05-24/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=43371fd91a35451213a5b082190bb18178ad712627f7243feb1acbdcf5b01c21 +dist/2024-05-24/clippy-beta-aarch64-unknown-linux-musl.tar.gz=9ae71ea9dfe0b56882b949321e4a2820bec4883614bb052cd71d9cce3b203ecd +dist/2024-05-24/clippy-beta-aarch64-unknown-linux-musl.tar.xz=92e23034c6287754a5c7d49c3e53313a614addb220fe0eac36d39b2883b445b6 +dist/2024-05-24/clippy-beta-x86_64-pc-windows-gnu.tar.gz=2076ed6ef91cd8febcf7daa894d110a2acb8a5b48a60f050c5e126c9378624a2 +dist/2024-05-24/clippy-beta-x86_64-pc-windows-gnu.tar.xz=e32790707ddd05624a7066c6185283476aafd7a304fe7528587765102d0fb63e +dist/2024-05-24/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=f47378feae7c5b4d15693ce8b170152237e5adfe027e53e4f017dece19da9f68 +dist/2024-05-24/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=af17738279b4acc3c75974b070c63de6385a62e7cb2ced3d445cb2c7d9928653 +dist/2024-05-24/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=1fa14738518c68f24668fe42ed6653b4a80ac12ac121f36b488215901ea49349 +dist/2024-05-24/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=f636b9d9628b5be5cc873b0698bc8d1a8487ca81309e359e60d6065c3771f8c0 +dist/2024-05-24/clippy-beta-x86_64-apple-darwin.tar.gz=14084cadcf4e71259a3a7e2189e648bcc8f8f044b5abf027079ebc140f3593ae +dist/2024-05-24/clippy-beta-x86_64-apple-darwin.tar.xz=6226dbc6d0e180eb7e946606cd7a5879ce558846334bfd79105ae23cfb7eee63 +dist/2024-05-24/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=6c58a39182997f07a7391e069ae6f141af8a2964f8c5583bedd70039a759c52f +dist/2024-05-24/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=a4c33cdb8711b784f533a685c3a6491f4c841fffcf573b1832315360788833d0 +dist/2024-05-24/clippy-beta-x86_64-pc-windows-msvc.tar.gz=f12a529b11e68e8dcbaeefc13e98935171bab78d5aaca0e6ea6d5fccc71b23ab +dist/2024-05-24/clippy-beta-x86_64-pc-windows-msvc.tar.xz=b060a3285527311eda126adc0f70aa6f361718ef397e89d488a58be7ff70d316 +dist/2024-05-24/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=a7a455d8a0f102d83c07987045beae1a9f633adcbb1752a6c338a0056183cf06 +dist/2024-05-24/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=47869852cf4b215d71ffbb67decee05aa4627041353daa9acd36dd6f2cc8ca71 +dist/2024-05-24/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=99c4401de28a11dc31d868d01d8de661f45f6238ab7fa36bc203868bf9977efd +dist/2024-05-24/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=828ffcd6fae6e48d9af7eca3017eec88b5d79ad5f892dc72ec598d908c23a7d8 +dist/2024-05-24/clippy-beta-i686-unknown-linux-gnu.tar.gz=dfe75e08d07df8e2d2f8b7e1d7840a505e42b2267b0f3b63c4cc8356dc3f4519 +dist/2024-05-24/clippy-beta-i686-unknown-linux-gnu.tar.xz=83270728dc14957c00a8801a5a187b9247b7c7bac7347f71eaec5e2fc59e17fa +dist/2024-05-24/clippy-beta-i686-pc-windows-gnu.tar.gz=7bef578957e857cb38b6cdc126bd055b95b5dff54d11d73f68413425cb4cae3e +dist/2024-05-24/clippy-beta-i686-pc-windows-gnu.tar.xz=9492aa7f12aa1f38afaab16f4c1ef4d3fc45169e25575a3c691ef13b0389c2d0 +dist/2024-05-24/clippy-beta-x86_64-unknown-netbsd.tar.gz=e325ee40a680aba2e413ea314e15fd4f9b5394705f72d652d9914b4fbb16e253 +dist/2024-05-24/clippy-beta-x86_64-unknown-netbsd.tar.xz=c499d0bdc755156a058c32d4d9be8e2b358197aa89a161804ccf87b0ce8c90f1 +dist/2024-05-24/clippy-beta-s390x-unknown-linux-gnu.tar.gz=ef245e8ebc4e598ab68b5bd8fbbeaa311e4b4e0471bab961b39c4d5218655712 +dist/2024-05-24/clippy-beta-s390x-unknown-linux-gnu.tar.xz=55ce153227cecea3a6f05807a156bfbea3c7d7aee72fdfa055fb9ddcbabd041f +dist/2024-05-24/clippy-beta-i686-pc-windows-msvc.tar.gz=d2378b267bf3d0e58300d21dd302161eaea8f8e38b7439731a054597970f7195 +dist/2024-05-24/clippy-beta-i686-pc-windows-msvc.tar.xz=87e337e9a584908d6397987b89756a30e6cd4b537fbe5dfe9d4752d9ae17dd51 +dist/2024-05-24/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=9ce0c27f91a3d3a99a0b32d72284827add678b4e6b1377e2fc978397dc897bbd +dist/2024-05-24/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=2c314fcfeed780a18fef9835266a50a8bfd4c63f66033c7a2cb589243d0dea8d +dist/2024-05-24/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=a1691b9a1629b0ab09505c80ef510fba462f41296b45b04bea52aa66e0314cef +dist/2024-05-24/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=6d36402ae66f53c24db57f37e3f78a2bd5a07a238d59d4b4b8c000202e6e6714 +dist/2024-05-24/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=e54ac8103de0de2c4166da6149c0f3da1db29cbf3909844b5fab43e1f56d943f +dist/2024-05-24/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=986bc361afa619b299f1c6674651aa56a344374ab8731c9cb702a651132841bc +dist/2024-05-24/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=0ee19412859c424304a8e2d66798896ab3be24057a6f12383fadd9c8283e5825 +dist/2024-05-24/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=01ff0f61731da21c55618fff0aca2f900c8b1473b7efc12cd8f1d1e49b51ba8a +dist/2024-05-24/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=9d29a9809633b98851a5de84d37cb0b37b4f9e9223b42841ee11e4288dfafd90 +dist/2024-05-24/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=122e2f607f59dbbd82693ece7610d9f9a92c1640e3501921d0f6069d0eaf4ac0 +dist/2024-05-24/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=5d8d0ed9f63eb0f2b8eb43c47f0a6858702cd5e9c8f1b308b570981f54a45ba9 +dist/2024-05-24/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=203c63f477369ce5a6464d0e11a10c5ed11b2e510e6190d6e0ac9993c43f3ffe +dist/2024-05-24/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=cee4cab103bf4c2b244a91c1d7578d5c807307a3367291ef1efd072f975e27ca +dist/2024-05-24/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=813a55dba22fea0203e43339f95ed1ce8b7406d57b5d75cb0d11ed2638402280 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=c9a941b5c05972c0fc875b052728dd5a83dbdcc8437c5509fbc4ca82cefd5866 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=3bb87c7cdfd0b942d8051de34d068d3fe6b4d5c8b52534ff43d6ffd802112d99 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=2bc18cd1444098b36ba3eb0648944caccac1515495c7180d2258bb29c4dbba71 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=a5e49cd58fbe857a2e99dbd9b68aec300dea92a9f840dc564f6f61d71a291cbe +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=7b270dfdcc65d11d0741adf11f62fff5839b4262ca87a84c273c4f54ccdcf404 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=3cfb7ff6d106ee2ca996a7e5790981648e4bca92ae424c780e6d6831dbe5d521 +dist/2024-05-24/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=82ef339de90bd1eb99bdee0ed4ff0431358706cb826c0810c6a05aa7432c56fe +dist/2024-05-24/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=d4332d61ca86a3c561bef17474110dd96fe73789c1fa43ba216be9a0c3690192 +dist/2024-05-24/rustfmt-nightly-aarch64-apple-darwin.tar.gz=5505cd69abfb7cf00ddd32936067088cc4448cfa09e5571516fa2e61d6593e51 +dist/2024-05-24/rustfmt-nightly-aarch64-apple-darwin.tar.xz=0c7cc98f9534c691dcba913b5d40fded47b33ca549ac75098c84d900d8452f01 +dist/2024-05-24/rustfmt-nightly-x86_64-apple-darwin.tar.gz=734c21a4018bf0e5ab561e8e485fd15f9ee38c01685aaf620808edb9a218b476 +dist/2024-05-24/rustfmt-nightly-x86_64-apple-darwin.tar.xz=69e6408ba329925f38522050f84adb20a299960c04ed3012bf075a10c4ad60c0 +dist/2024-05-24/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=d759046124506b761f0d628681e7f5ac73fc23a04f1bab5097e0796b7197097d +dist/2024-05-24/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=fb07a6adc006753ce09457b032d6e1ce06934aa8c009f5d586d3b317dde6ce21 +dist/2024-05-24/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=c7f7195f7c80e9d6afac4fd6cb6f54b4f1c53116cfbbaa06d185bbca4ef2b4d6 +dist/2024-05-24/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=5acb271b43e1f1c186666c33f322b9d3c253b929710eb73000e2eb61b3978dc9 +dist/2024-05-24/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=7aea051dfd13311ef4a95845b6cfb390c6f502ac2bf46fea335abdbcda05a2e4 +dist/2024-05-24/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=832f664b6508735fc91491fef9eca137ea6707cec000ae483d4c8b5ce9abadb4 +dist/2024-05-24/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=a5f79e10a34ad8d02645d1e6ae758812ff16e1c74b63c775c5f840fce5569ed0 +dist/2024-05-24/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=837e8d335322a4d0efb86bf6d6dd65b815548faa9e40135e8cf3b197f6e03960 +dist/2024-05-24/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=c0d3c4786cf4b4c4cf0b8c26d89d6009e3e9d9c1e69092f4b55f0087b08204f2 +dist/2024-05-24/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=0d8a1f390b09f8550c38cd1b74e4e8f7cccc496b86e6f2d6f74291c34cc31bd8 +dist/2024-05-24/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=56ccaaba20445959702503d1aedac87b8a9995bcd8619dd120273d0795859705 +dist/2024-05-24/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=201932eba6521c04367eb682f96a54fec10830fe954bc271ce2766db2afe30a1 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=e8c2324aca7fe35e47088d8c317c7f97d88830629e871987faa197d545ef644f +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=51985f7c0530eb59dce830e1508bc270e1bb3fe7b33a95eb93142611e651a7d5 +dist/2024-05-24/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=a4fa6bcf4c4b9c446236d710c1878efaf1dfdb95a2f5f3c4c374d8fbf49b792e +dist/2024-05-24/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=af0f2443e34c9d6f5d85ff8cb0c0c52fa46b64275c26b57528c1e815edb8f59e +dist/2024-05-24/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=59bd9ccde4722b24b5b746d7e3dfdd48ae8f9c8b142b8c175750b8bdb2c05411 +dist/2024-05-24/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=91dcec67d9382548f89dcaf7c2c6dcaa47f9e04b777f7b8cf047ca0895fd7958 +dist/2024-05-24/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=d16ac0c789f0c79867ca74161214a902f97647d2b448ec510d48b254092ea05b +dist/2024-05-24/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=065d796ed384f07116903ae75dcb4accabb3cd81849a0083fa26b42e5ee3027a +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=bd673c6d23377af5158565bcc48048d5a8febf346d200920e8ca8e661149f600 +dist/2024-05-24/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=7f630e63ea697c95bdd2ea2edd678e8cf999c5ed9e7760c2b631ed6ecc4f112d +dist/2024-05-24/rustc-nightly-aarch64-apple-darwin.tar.gz=1f418de895c28fb684035c38f5f1ad45993ccab9bdbd247958083043ec2904ff +dist/2024-05-24/rustc-nightly-aarch64-apple-darwin.tar.xz=a762ad9b084a4221f5e24ba7cc99bfa20dfba935d267efd36ecf371de5fa6261 +dist/2024-05-24/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=6fc6f1ee02ac5562da863213924a43b8cc914b54b7a7df7c0fa65b51c0cec2ec +dist/2024-05-24/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=3e4343551874ebd6a41912937784938572706896f7b64b246b7630eb2de81e32 +dist/2024-05-24/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=225dfdb7af532a1de12c04bfb4ad41756db6b0c342e3e974a1587b74ac942cc4 +dist/2024-05-24/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=ef45d12cf6c0a00bd62bde5143bace4b9f4dc3d27d0e66274698fd4c12aa644e +dist/2024-05-24/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=cd5c25154d3a24f9fa14bea66c149c8547179e28307989276b3450411db94f1a +dist/2024-05-24/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=07473937fbe50012d4472e283bedb8fa239a02fedc880e8d3cdf96e449a7a237 +dist/2024-05-24/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=3c96788305ae61feba692d7c254c68486e6caa0a7851dc6ee545338260e195bb +dist/2024-05-24/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=f5789e53bd82a6e7593f51248342bea26014770d86b171d1e6182039e96cd008 +dist/2024-05-24/rustc-nightly-x86_64-unknown-netbsd.tar.gz=c7960546ecaf8e190e0e0a6bf21d3259b6098b440e9f8efd455c0e207db14100 +dist/2024-05-24/rustc-nightly-x86_64-unknown-netbsd.tar.xz=dcbd4e5a41496ec3a76a492b6f48a0913f3174f192b0dce38886580fe5866806 +dist/2024-05-24/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=201d715fc46c3b97c6ba56ed89b45870089ead21b5dbe107fc9c11d4e409b594 +dist/2024-05-24/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=5660fc1ea7228b156b070766d568bd27222245f4a8bbd3fa55d53646320594ac +dist/2024-05-24/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=ba5a31b8f6fe6b55976ce3fb7075cf0c539b83b86c029e1dee9259e76eee90c7 +dist/2024-05-24/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=1494876804a4eae08e22a586295d5c75fe611e90e35e98e9d4fd4ce7f08e1648 +dist/2024-05-24/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=e83d8ad735b0c2213613882affea611db0453f2d83dddcdc325100d94ecb8be4 +dist/2024-05-24/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=c41af42429b2322b140d99049fef6a2bfc6950847601ce5daf5e789939ef8383 +dist/2024-05-24/rustc-nightly-i686-unknown-linux-gnu.tar.gz=4fd2063d10fb4ea166c684edb9b790a0decdc602c600208cad2c378cb5b5f04a +dist/2024-05-24/rustc-nightly-i686-unknown-linux-gnu.tar.xz=522f49079f90b469a7580f3cbc8f7ec88f2267a5df9cb0fc06a40fa21a778b1d +dist/2024-05-24/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=622d58678e2aeca83bfa7172c9cd0fc21128917067b6492fc6a966f0715843e0 +dist/2024-05-24/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=2e021443798286eb5bdc855112970862b58bd12ea3b1a3ef7aad178f757004ef +dist/2024-05-24/rustc-nightly-i686-pc-windows-gnu.tar.gz=a14a5f1c16f8ac231083b11075aae0970370f29b7f8a6b952c945c8b4a99a1c4 +dist/2024-05-24/rustc-nightly-i686-pc-windows-gnu.tar.xz=5a389561f37d446433dc4e4d0ac1259fdfa4bb5728863a0b2e00b6575acc8851 +dist/2024-05-24/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=95e73ffa458449089b753f85aaf71581d6229d1fef10f57aa6ac0a9a15f5e2dc +dist/2024-05-24/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=b678c5d611324ced9ec61e36cb2ac53d595ed0d9024e987b658d3708714137d0 +dist/2024-05-24/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=07d9e8f300835045ae9bc9350aaebb0c7994398e92e43ca0baf4d491d5e06a51 +dist/2024-05-24/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=7d40e53082177294ee09d59730526586ee973b9d0aac24b4c9116db306a926e1 +dist/2024-05-24/rustc-nightly-i686-pc-windows-msvc.tar.gz=e88718e456cfc8892fcdafc1c522b67c53ba5faedf80f43f007222a8bec00a01 +dist/2024-05-24/rustc-nightly-i686-pc-windows-msvc.tar.xz=b8320cdfa66421593610eb7299d57ba20381f10bb6f2f82ef5475f86c454c2c7 +dist/2024-05-24/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=65ddf18ce7489b1bcc0d110fbd645326b960230702f6c9ad45680e44e0c1890e +dist/2024-05-24/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=f64735396de921f8b65fd74a3f2c179094770e39549d057e5222085b17976832 +dist/2024-05-24/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=cdacc2d990089859fe21fd779d24b186101bcd03f91b8f9c595ddf26af9ced5b +dist/2024-05-24/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=74c673001e8794afbf085bde1b5e010420458230fa9eadf7f5f76e5ad11f1c8d +dist/2024-05-24/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=76c0a333525099ec78351d29deb0f0c7b72d8a48860c1595442e574bc454ac5a +dist/2024-05-24/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=5ff07cf9292c0ba7e3860e9ec2c1de9810e932dc12d9711ba6f1795a5c90875f +dist/2024-05-24/rustc-nightly-x86_64-unknown-illumos.tar.gz=32e4afe3e4dd9f64c69da73af0c4a1e6e4c8264640b142de6bb9494c567fdfe4 +dist/2024-05-24/rustc-nightly-x86_64-unknown-illumos.tar.xz=f6d8be59445080cc278a152387e47a98d3b371758bc7f36932343d0caa5896e0 +dist/2024-05-24/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=caeefbab1a93f119669078ba91aa821e5aaff5811fb3d0a6b0ec482d7bc1a404 +dist/2024-05-24/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=7032353ac8ba628f8a2648c106c7a3248ebb1f03bc9036cfca61007f9acc3a0b +dist/2024-05-24/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=ca53d272b136d5fa112ede10627880a58f51d99a40a490b2c9fff6c996f9aabf +dist/2024-05-24/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=d24dcd68c9426f1463c60d5075a9a0ecbc494cdc34a434f377a0b09fdeabf914 +dist/2024-05-24/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=c6a05ee622261a0f4b41b1cf26b5461e1247c00376ac61a0fc4faa16ce478140 +dist/2024-05-24/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=c317af1e4bb1551edc046c426da84ad122379e5829b5e97033c94b6844b18e2c +dist/2024-05-24/rustc-nightly-x86_64-unknown-freebsd.tar.gz=3efbcc6e74d9cd4ff86803410bbdce0f1e64741870c32f33e28c660c68155851 +dist/2024-05-24/rustc-nightly-x86_64-unknown-freebsd.tar.xz=3cb7acb1bf66ba39becc6df1cf2727de424ca3ba90e74f0fd7c76f586f868a89 +dist/2024-05-24/rustc-nightly-x86_64-apple-darwin.tar.gz=427b795b94eb4e4e2bd150e98055c5a9a414937ebef7e586bcaf8a1988eb5214 +dist/2024-05-24/rustc-nightly-x86_64-apple-darwin.tar.xz=405b2a99f9a34c1d1195ab88bf6fb696fadb6c2988a3d83555e2ac4de80ba4e5 \ No newline at end of file diff --git a/src/tools/cargo b/src/tools/cargo index 84dc5dc11a90..a8d72c675ee5 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 84dc5dc11a9007a08f27170454da6097265e510e +Subproject commit a8d72c675ee52dd57f0d8f2bae6655913c15b2fb diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs index 385191e0361b..3aa43dbe23ed 100644 --- a/src/tools/clippy/clippy_dev/src/lib.rs +++ b/src/tools/clippy/clippy_dev/src/lib.rs @@ -1,4 +1,3 @@ -#![feature(lazy_cell)] #![feature(let_chains)] #![feature(rustc_private)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index 65929cd5fea9..38580dc58226 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -460,13 +460,19 @@ fn check_fn_args<'cx, 'tcx: 'cx>( } None }) { - if !lifetime.is_anonymous() + if let LifetimeName::Param(param_def_id) = lifetime.res + && !lifetime.is_anonymous() && fn_sig .output() .walk() .filter_map(|arg| { arg.as_region().and_then(|lifetime| match lifetime.kind() { - ty::ReEarlyParam(r) => Some(r.def_id), + ty::ReEarlyParam(r) => Some( + cx.tcx + .generics_of(cx.tcx.parent(param_def_id.to_def_id())) + .region_param(r, cx.tcx) + .def_id, + ), ty::ReBound(_, r) => r.kind.get_id(), ty::ReLateParam(r) => r.bound_region.get_id(), ty::ReStatic @@ -476,14 +482,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>( | ty::ReError(_) => None, }) }) - .any(|def_id| { - matches!( - lifetime.res, - LifetimeName::Param(param_def_id) if def_id - .as_local() - .is_some_and(|def_id| def_id == param_def_id), - ) - }) + .any(|def_id| def_id.as_local().is_some_and(|def_id| def_id == param_def_id)) { // `&Cow<'a, T>` when the return type uses 'a is okay return None; diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs index dc0a139e3c78..0641d37cd9a6 100644 --- a/src/tools/clippy/clippy_utils/src/diagnostics.rs +++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs @@ -61,7 +61,8 @@ fn docs_link(diag: &mut Diag<'_, ()>, lint: &'static Lint) { /// ``` pub fn span_lint(cx: &T, lint: &'static Lint, sp: impl Into, msg: impl Into) { #[expect(clippy::disallowed_methods)] - cx.span_lint(lint, sp, msg.into(), |diag| { + cx.span_lint(lint, sp, |diag| { + diag.primary_message(msg); docs_link(diag, lint); }); } @@ -109,7 +110,8 @@ pub fn span_lint_and_help( help: impl Into, ) { #[expect(clippy::disallowed_methods)] - cx.span_lint(lint, span, msg.into(), |diag| { + cx.span_lint(lint, span, |diag| { + diag.primary_message(msg); if let Some(help_span) = help_span { diag.span_help(help_span, help.into()); } else { @@ -165,7 +167,8 @@ pub fn span_lint_and_note( note: impl Into, ) { #[expect(clippy::disallowed_methods)] - cx.span_lint(lint, span, msg.into(), |diag| { + cx.span_lint(lint, span, |diag| { + diag.primary_message(msg); if let Some(note_span) = note_span { diag.span_note(note_span, note.into()); } else { @@ -201,7 +204,8 @@ where F: FnOnce(&mut Diag<'_, ()>), { #[expect(clippy::disallowed_methods)] - cx.span_lint(lint, sp, msg, |diag| { + cx.span_lint(lint, sp, |diag| { + diag.primary_message(msg); f(diag); docs_link(diag, lint); }); @@ -233,7 +237,8 @@ where /// the `#[allow]` will work. pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: impl Into) { #[expect(clippy::disallowed_methods)] - cx.tcx.node_span_lint(lint, hir_id, sp, msg.into(), |diag| { + cx.tcx.node_span_lint(lint, hir_id, sp, |diag| { + diag.primary_message(msg); docs_link(diag, lint); }); } @@ -271,7 +276,8 @@ pub fn span_lint_hir_and_then( f: impl FnOnce(&mut Diag<'_, ()>), ) { #[expect(clippy::disallowed_methods)] - cx.tcx.node_span_lint(lint, hir_id, sp, msg.into(), |diag| { + cx.tcx.node_span_lint(lint, hir_id, sp, |diag| { + diag.primary_message(msg); f(diag); docs_link(diag, lint); }); diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 9e42abbc9aa9..f79da26964f3 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -2,7 +2,6 @@ #![allow(rustc::untranslatable_diagnostic)] #![feature(rustc_private)] #![feature(let_chains)] -#![feature(lazy_cell)] #![feature(lint_reasons)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] // warn on lints, that are included in `rust-lang/rust`s bootstrap diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs index b06a11702ec8..333a2ab58575 100644 --- a/src/tools/clippy/tests/compile-test.rs +++ b/src/tools/clippy/tests/compile-test.rs @@ -1,4 +1,3 @@ -#![feature(lazy_cell)] #![feature(is_sorted)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![warn(rust_2018_idioms, unused_lifetimes)] diff --git a/src/tools/clippy/tests/dogfood.rs b/src/tools/clippy/tests/dogfood.rs index 3f16c180ea78..36a7a651c4d2 100644 --- a/src/tools/clippy/tests/dogfood.rs +++ b/src/tools/clippy/tests/dogfood.rs @@ -3,7 +3,6 @@ //! //! See [Eating your own dog food](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) for context -#![feature(lazy_cell)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![warn(rust_2018_idioms, unused_lifetimes)] diff --git a/src/tools/clippy/tests/lint_message_convention.rs b/src/tools/clippy/tests/lint_message_convention.rs index 98019c755276..6ce7e44474d8 100644 --- a/src/tools/clippy/tests/lint_message_convention.rs +++ b/src/tools/clippy/tests/lint_message_convention.rs @@ -1,4 +1,3 @@ -#![feature(lazy_cell)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![warn(rust_2018_idioms, unused_lifetimes)] diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs b/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs index 5a2a868ed3ec..b91a83308b5f 100644 --- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs +++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs @@ -11,11 +11,11 @@ use rustc_lint::{Lint, LintContext}; use rustc_middle::ty::TyCtxt; pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into, msg: impl Into) { - cx.span_lint(lint, span, msg, |_| {}); + cx.span_lint(lint, span, |lint| { lint.primary_message(msg); }); } pub fn b(tcx: TyCtxt<'_>, lint: &'static Lint, hir_id: HirId, span: impl Into, msg: impl Into) { - tcx.node_span_lint(lint, hir_id, span, msg, |_| {}); + tcx.node_span_lint(lint, hir_id, span, |lint| { lint.primary_message(msg); }); } fn main() {} diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr index cfc590bed369..1cfbc8efc8ed 100644 --- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr +++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr @@ -1,8 +1,8 @@ error: use of a disallowed method `rustc_lint::context::LintContext::span_lint` --> tests/ui-internal/disallow_span_lint.rs:14:5 | -LL | cx.span_lint(lint, span, msg, |_| {}); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | cx.span_lint(lint, span, |lint| { lint.primary_message(msg); }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint*` functions instead (from clippy.toml) = note: `-D clippy::disallowed-methods` implied by `-D warnings` @@ -11,8 +11,8 @@ LL | cx.span_lint(lint, span, msg, |_| {}); error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_lint` --> tests/ui-internal/disallow_span_lint.rs:18:5 | -LL | tcx.node_span_lint(lint, hir_id, span, msg, |_| {}); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | tcx.node_span_lint(lint, hir_id, span, |lint| { lint.primary_message(msg); }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint_hir*` functions instead (from clippy.toml) diff --git a/src/tools/clippy/tests/workspace.rs b/src/tools/clippy/tests/workspace.rs index 699ab2be199a..19ccc7ae9607 100644 --- a/src/tools/clippy/tests/workspace.rs +++ b/src/tools/clippy/tests/workspace.rs @@ -1,5 +1,3 @@ -#![feature(lazy_cell)] - use std::path::PathBuf; use std::process::Command; use test_utils::{CARGO_CLIPPY_PATH, IS_RUSTC_TEST_SUITE}; diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index aa06a0dbcdc5..3b24a903d3af 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -21e6de7eb64c09102de3f100420a09edc1a2a8d7 +a59072ec4fb6824213df5e9de8cae4812fd4fe97 diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index 9ec9ae317f4f..002e10620610 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -85,7 +85,7 @@ impl GlobalStateInner { } } - pub fn remove_unreachable_allocs(&mut self, allocs: &LiveAllocs<'_, '_, '_>) { + pub fn remove_unreachable_allocs(&mut self, allocs: &LiveAllocs<'_, '_>) { // `exposed` and `int_to_ptr_map` are cleared immediately when an allocation // is freed, so `base_addr` is the only one we have to clean up based on the GC. self.base_addr.retain(|id, _| allocs.is_live(*id)); @@ -101,8 +101,8 @@ fn align_addr(addr: u64, align: u64) -> u64 { } } -impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} +trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Returns the exposed `AllocId` that corresponds to the specified addr, // or `None` if the addr is out of bounds fn alloc_id_from_addr(&self, addr: u64) -> Option { @@ -234,8 +234,8 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn expose_ptr(&mut self, alloc_id: AllocId, tag: BorTag) -> InterpResult<'tcx> { let ecx = self.eval_context_mut(); let global_state = ecx.machine.alloc_addresses.get_mut(); @@ -341,7 +341,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } -impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { +impl<'tcx> MiriMachine<'tcx> { pub fn free_alloc_id(&mut self, dead_id: AllocId, size: Size, align: Align, kind: MemoryKind) { let global_state = self.alloc_addresses.get_mut(); let rng = self.rng.get_mut(); diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index 24e2a9a74bbe..a55ec427d5f0 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -192,7 +192,7 @@ impl GlobalStateInner { id } - pub fn new_frame(&mut self, machine: &MiriMachine<'_, '_>) -> FrameState { + pub fn new_frame(&mut self, machine: &MiriMachine<'_>) -> FrameState { let call_id = self.next_call_id; trace!("new_frame: Assigning call ID {}", call_id); if self.tracked_call_ids.contains(&call_id) { @@ -213,7 +213,7 @@ impl GlobalStateInner { } } - pub fn root_ptr_tag(&mut self, id: AllocId, machine: &MiriMachine<'_, '_>) -> BorTag { + pub fn root_ptr_tag(&mut self, id: AllocId, machine: &MiriMachine<'_>) -> BorTag { self.root_ptr_tags.get(&id).copied().unwrap_or_else(|| { let tag = self.new_ptr(); if self.tracked_pointer_tags.contains(&tag) { @@ -229,7 +229,7 @@ impl GlobalStateInner { }) } - pub fn remove_unreachable_allocs(&mut self, allocs: &LiveAllocs<'_, '_, '_>) { + pub fn remove_unreachable_allocs(&mut self, allocs: &LiveAllocs<'_, '_>) { self.root_ptr_tags.retain(|id, _| allocs.is_live(*id)); } } @@ -261,7 +261,7 @@ impl GlobalStateInner { id: AllocId, alloc_size: Size, kind: MemoryKind, - machine: &MiriMachine<'_, '_>, + machine: &MiriMachine<'_>, ) -> AllocState { match self.borrow_tracker_method { BorrowTrackerMethod::StackedBorrows => @@ -276,8 +276,8 @@ impl GlobalStateInner { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn retag_ptr_value( &mut self, kind: RetagKind, @@ -354,7 +354,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn on_stack_pop( &self, - frame: &Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>, + frame: &Frame<'tcx, Provenance, FrameExtra<'tcx>>, ) -> InterpResult<'tcx> { let this = self.eval_context_ref(); let borrow_tracker = this.machine.borrow_tracker.as_ref().unwrap(); @@ -431,7 +431,7 @@ impl AllocState { alloc_id: AllocId, prov_extra: ProvenanceExtra, range: AllocRange, - machine: &MiriMachine<'_, 'tcx>, + machine: &MiriMachine<'tcx>, ) -> InterpResult<'tcx> { match self { AllocState::StackedBorrows(sb) => @@ -452,7 +452,7 @@ impl AllocState { alloc_id: AllocId, prov_extra: ProvenanceExtra, range: AllocRange, - machine: &MiriMachine<'_, 'tcx>, + machine: &MiriMachine<'tcx>, ) -> InterpResult<'tcx> { match self { AllocState::StackedBorrows(sb) => @@ -473,7 +473,7 @@ impl AllocState { alloc_id: AllocId, prov_extra: ProvenanceExtra, size: Size, - machine: &MiriMachine<'_, 'tcx>, + machine: &MiriMachine<'tcx>, ) -> InterpResult<'tcx> { match self { AllocState::StackedBorrows(sb) => @@ -493,7 +493,7 @@ impl AllocState { /// Tree Borrows needs to be told when a tag stops being protected. pub fn release_protector<'tcx>( &self, - machine: &MiriMachine<'_, 'tcx>, + machine: &MiriMachine<'tcx>, global: &GlobalState, tag: BorTag, alloc_id: AllocId, // diagnostics diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs index cb677b865311..87d9057cb89d 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs @@ -115,29 +115,29 @@ pub struct TagHistory { pub protected: Option<(String, SpanData)>, } -pub struct DiagnosticCxBuilder<'ecx, 'mir, 'tcx> { +pub struct DiagnosticCxBuilder<'ecx, 'tcx> { operation: Operation, - machine: &'ecx MiriMachine<'mir, 'tcx>, + machine: &'ecx MiriMachine<'tcx>, } -pub struct DiagnosticCx<'history, 'ecx, 'mir, 'tcx> { +pub struct DiagnosticCx<'history, 'ecx, 'tcx> { operation: Operation, - machine: &'ecx MiriMachine<'mir, 'tcx>, + machine: &'ecx MiriMachine<'tcx>, history: &'history mut AllocHistory, offset: Size, } -impl<'ecx, 'mir, 'tcx> DiagnosticCxBuilder<'ecx, 'mir, 'tcx> { +impl<'ecx, 'tcx> DiagnosticCxBuilder<'ecx, 'tcx> { pub fn build<'history>( self, history: &'history mut AllocHistory, offset: Size, - ) -> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> { + ) -> DiagnosticCx<'history, 'ecx, 'tcx> { DiagnosticCx { operation: self.operation, machine: self.machine, history, offset } } pub fn retag( - machine: &'ecx MiriMachine<'mir, 'tcx>, + machine: &'ecx MiriMachine<'tcx>, info: RetagInfo, new_tag: BorTag, orig_tag: ProvenanceExtra, @@ -149,17 +149,13 @@ impl<'ecx, 'mir, 'tcx> DiagnosticCxBuilder<'ecx, 'mir, 'tcx> { DiagnosticCxBuilder { machine, operation } } - pub fn read( - machine: &'ecx MiriMachine<'mir, 'tcx>, - tag: ProvenanceExtra, - range: AllocRange, - ) -> Self { + pub fn read(machine: &'ecx MiriMachine<'tcx>, tag: ProvenanceExtra, range: AllocRange) -> Self { let operation = Operation::Access(AccessOp { kind: AccessKind::Read, tag, range }); DiagnosticCxBuilder { machine, operation } } pub fn write( - machine: &'ecx MiriMachine<'mir, 'tcx>, + machine: &'ecx MiriMachine<'tcx>, tag: ProvenanceExtra, range: AllocRange, ) -> Self { @@ -167,14 +163,14 @@ impl<'ecx, 'mir, 'tcx> DiagnosticCxBuilder<'ecx, 'mir, 'tcx> { DiagnosticCxBuilder { machine, operation } } - pub fn dealloc(machine: &'ecx MiriMachine<'mir, 'tcx>, tag: ProvenanceExtra) -> Self { + pub fn dealloc(machine: &'ecx MiriMachine<'tcx>, tag: ProvenanceExtra) -> Self { let operation = Operation::Dealloc(DeallocOp { tag }); DiagnosticCxBuilder { machine, operation } } } -impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> { - pub fn unbuild(self) -> DiagnosticCxBuilder<'ecx, 'mir, 'tcx> { +impl<'history, 'ecx, 'tcx> DiagnosticCx<'history, 'ecx, 'tcx> { + pub fn unbuild(self) -> DiagnosticCxBuilder<'ecx, 'tcx> { DiagnosticCxBuilder { machine: self.machine, operation: self.operation } } } @@ -222,7 +218,7 @@ struct DeallocOp { } impl AllocHistory { - pub fn new(id: AllocId, item: Item, machine: &MiriMachine<'_, '_>) -> Self { + pub fn new(id: AllocId, item: Item, machine: &MiriMachine<'_>) -> Self { Self { id, root: (item, machine.current_span()), @@ -239,7 +235,7 @@ impl AllocHistory { } } -impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> { +impl<'history, 'ecx, 'tcx> DiagnosticCx<'history, 'ecx, 'tcx> { pub fn start_grant(&mut self, perm: Permission) { let Operation::Retag(op) = &mut self.operation else { unreachable!( diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 3da8744626d7..2786668695e2 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -59,11 +59,7 @@ enum NewPermission { impl NewPermission { /// A key function: determine the permissions to grant at a retag for the given kind of /// reference/pointer. - fn from_ref_ty<'tcx>( - ty: Ty<'tcx>, - kind: RetagKind, - cx: &crate::MiriInterpCx<'_, 'tcx>, - ) -> Self { + fn from_ref_ty<'tcx>(ty: Ty<'tcx>, kind: RetagKind, cx: &crate::MiriInterpCx<'tcx>) -> Self { let protector = (kind == RetagKind::FnEntry).then_some(ProtectorKind::StrongProtector); match ty.kind() { ty::Ref(_, pointee, Mutability::Mut) => { @@ -130,11 +126,7 @@ impl NewPermission { } } - fn from_box_ty<'tcx>( - ty: Ty<'tcx>, - kind: RetagKind, - cx: &crate::MiriInterpCx<'_, 'tcx>, - ) -> Self { + fn from_box_ty<'tcx>(ty: Ty<'tcx>, kind: RetagKind, cx: &crate::MiriInterpCx<'tcx>) -> Self { // `ty` is not the `Box` but the field of the Box with this pointer (due to allocator handling). let pointee = ty.builtin_deref(true).unwrap(); if pointee.is_unpin(*cx.tcx, cx.param_env()) { @@ -230,7 +222,7 @@ impl<'tcx> Stack { fn item_invalidated( item: &Item, global: &GlobalStateInner, - dcx: &DiagnosticCx<'_, '_, '_, 'tcx>, + dcx: &DiagnosticCx<'_, '_, 'tcx>, cause: ItemInvalidationCause, ) -> InterpResult<'tcx> { if !global.tracked_pointer_tags.is_empty() { @@ -275,7 +267,7 @@ impl<'tcx> Stack { access: AccessKind, tag: ProvenanceExtra, global: &GlobalStateInner, - dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>, + dcx: &mut DiagnosticCx<'_, '_, 'tcx>, exposed_tags: &FxHashSet, ) -> InterpResult<'tcx> { // Two main steps: Find granting item, remove incompatible items above. @@ -362,7 +354,7 @@ impl<'tcx> Stack { &mut self, tag: ProvenanceExtra, global: &GlobalStateInner, - dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>, + dcx: &mut DiagnosticCx<'_, '_, 'tcx>, exposed_tags: &FxHashSet, ) -> InterpResult<'tcx> { // Step 1: Make a write access. @@ -387,7 +379,7 @@ impl<'tcx> Stack { new: Item, access: Option, global: &GlobalStateInner, - dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>, + dcx: &mut DiagnosticCx<'_, '_, 'tcx>, exposed_tags: &FxHashSet, ) -> InterpResult<'tcx> { dcx.start_grant(new.perm()); @@ -471,7 +463,7 @@ impl<'tcx> Stacks { perm: Permission, tag: BorTag, id: AllocId, - machine: &MiriMachine<'_, '_>, + machine: &MiriMachine<'_>, ) -> Self { let item = Item::new(tag, perm, false); let stack = Stack::new(item); @@ -487,10 +479,10 @@ impl<'tcx> Stacks { fn for_each( &mut self, range: AllocRange, - mut dcx_builder: DiagnosticCxBuilder<'_, '_, 'tcx>, + mut dcx_builder: DiagnosticCxBuilder<'_, 'tcx>, mut f: impl FnMut( &mut Stack, - &mut DiagnosticCx<'_, '_, '_, 'tcx>, + &mut DiagnosticCx<'_, '_, 'tcx>, &mut FxHashSet, ) -> InterpResult<'tcx>, ) -> InterpResult<'tcx> { @@ -510,7 +502,7 @@ impl Stacks { size: Size, state: &mut GlobalStateInner, kind: MemoryKind, - machine: &MiriMachine<'_, '_>, + machine: &MiriMachine<'_>, ) -> Self { let (base_tag, perm) = match kind { // New unique borrow. This tag is not accessible by the program, @@ -526,12 +518,12 @@ impl Stacks { } #[inline(always)] - pub fn before_memory_read<'tcx, 'mir, 'ecx>( + pub fn before_memory_read<'ecx, 'tcx>( &mut self, alloc_id: AllocId, tag: ProvenanceExtra, range: AllocRange, - machine: &'ecx MiriMachine<'mir, 'tcx>, + machine: &'ecx MiriMachine<'tcx>, ) -> InterpResult<'tcx> where 'tcx: 'ecx, @@ -555,7 +547,7 @@ impl Stacks { alloc_id: AllocId, tag: ProvenanceExtra, range: AllocRange, - machine: &MiriMachine<'_, 'tcx>, + machine: &MiriMachine<'tcx>, ) -> InterpResult<'tcx> { trace!( "write access with tag {:?}: {:?}, size {}", @@ -576,7 +568,7 @@ impl Stacks { alloc_id: AllocId, tag: ProvenanceExtra, size: Size, - machine: &MiriMachine<'_, 'tcx>, + machine: &MiriMachine<'tcx>, ) -> InterpResult<'tcx> { trace!("deallocation with tag {:?}: {:?}, size {}", tag, alloc_id, size.bytes()); let dcx = DiagnosticCxBuilder::dealloc(machine, tag); @@ -590,11 +582,8 @@ impl Stacks { /// Retagging/reborrowing. There is some policy in here, such as which permissions /// to grant for which references, and when to add protectors. -impl<'mir: 'ecx, 'tcx: 'mir, 'ecx> EvalContextPrivExt<'mir, 'tcx, 'ecx> - for crate::MiriInterpCx<'mir, 'tcx> -{ -} -trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx, 'ecx> EvalContextPrivExt<'tcx, 'ecx> for crate::MiriInterpCx<'tcx> {} +trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> { /// Returns the provenance that should be used henceforth. fn sb_reborrow( &mut self, @@ -609,7 +598,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' this.check_ptr_access(place.ptr(), size, CheckInAllocMsg::InboundsTest)?; // It is crucial that this gets called on all code paths, to ensure we track tag creation. - let log_creation = |this: &MiriInterpCx<'mir, 'tcx>, + let log_creation = |this: &MiriInterpCx<'tcx>, loc: Option<(AllocId, Size, ProvenanceExtra)>| // alloc_id, base_offset, orig_tag -> InterpResult<'tcx> { let global = this.machine.borrow_tracker.as_ref().unwrap().borrow(); @@ -861,8 +850,8 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn sb_retag_ptr_value( &mut self, kind: RetagKind, @@ -895,14 +884,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { return visitor.visit_value(place); // The actual visitor. - struct RetagVisitor<'ecx, 'mir, 'tcx> { - ecx: &'ecx mut MiriInterpCx<'mir, 'tcx>, + struct RetagVisitor<'ecx, 'tcx> { + ecx: &'ecx mut MiriInterpCx<'tcx>, kind: RetagKind, retag_cause: RetagCause, retag_fields: RetagFields, in_field: bool, } - impl<'ecx, 'mir, 'tcx> RetagVisitor<'ecx, 'mir, 'tcx> { + impl<'ecx, 'tcx> RetagVisitor<'ecx, 'tcx> { #[inline(always)] // yes this helps in our benchmarks fn retag_ptr_inplace( &mut self, @@ -919,13 +908,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Ok(()) } } - impl<'ecx, 'mir, 'tcx> ValueVisitor<'mir, 'tcx, MiriMachine<'mir, 'tcx>> - for RetagVisitor<'ecx, 'mir, 'tcx> - { + impl<'ecx, 'tcx> ValueVisitor<'tcx, MiriMachine<'tcx>> for RetagVisitor<'ecx, 'tcx> { type V = PlaceTy<'tcx, Provenance>; #[inline(always)] - fn ecx(&self) -> &MiriInterpCx<'mir, 'tcx> { + fn ecx(&self) -> &MiriInterpCx<'tcx> { self.ecx } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index b5bf16d3d366..e1c06b2bd98e 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -35,7 +35,7 @@ impl<'tcx> Tree { size: Size, state: &mut GlobalStateInner, _kind: MemoryKind, - machine: &MiriMachine<'_, 'tcx>, + machine: &MiriMachine<'tcx>, ) -> Self { let tag = state.root_ptr_tag(id, machine); // Fresh tag for the root let span = machine.current_span(); @@ -50,7 +50,7 @@ impl<'tcx> Tree { alloc_id: AllocId, prov: ProvenanceExtra, range: AllocRange, - machine: &MiriMachine<'_, 'tcx>, + machine: &MiriMachine<'tcx>, ) -> InterpResult<'tcx> { trace!( "{} with tag {:?}: {:?}, size {}", @@ -84,7 +84,7 @@ impl<'tcx> Tree { alloc_id: AllocId, prov: ProvenanceExtra, size: Size, - machine: &MiriMachine<'_, 'tcx>, + machine: &MiriMachine<'tcx>, ) -> InterpResult<'tcx> { // TODO: for now we bail out on wildcard pointers. Eventually we should // handle them as much as we can. @@ -109,7 +109,7 @@ impl<'tcx> Tree { /// protector. pub fn release_protector( &mut self, - machine: &MiriMachine<'_, 'tcx>, + machine: &MiriMachine<'tcx>, global: &GlobalState, tag: BorTag, alloc_id: AllocId, // diagnostics @@ -146,7 +146,7 @@ impl<'tcx> NewPermission { pointee: Ty<'tcx>, mutability: Mutability, kind: RetagKind, - cx: &crate::MiriInterpCx<'_, 'tcx>, + cx: &crate::MiriInterpCx<'tcx>, ) -> Option { let ty_is_freeze = pointee.is_freeze(*cx.tcx, cx.param_env()); let ty_is_unpin = pointee.is_unpin(*cx.tcx, cx.param_env()); @@ -170,7 +170,7 @@ impl<'tcx> NewPermission { fn from_unique_ty( ty: Ty<'tcx>, kind: RetagKind, - cx: &crate::MiriInterpCx<'_, 'tcx>, + cx: &crate::MiriInterpCx<'tcx>, zero_size: bool, ) -> Option { let pointee = ty.builtin_deref(true).unwrap(); @@ -190,11 +190,8 @@ impl<'tcx> NewPermission { /// Retagging/reborrowing. /// Policy on which permission to grant to each pointer should be left to /// the implementation of NewPermission. -impl<'mir: 'ecx, 'tcx: 'mir, 'ecx> EvalContextPrivExt<'mir, 'tcx, 'ecx> - for crate::MiriInterpCx<'mir, 'tcx> -{ -} -trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextPrivExt<'tcx> for crate::MiriInterpCx<'tcx> {} +trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Returns the provenance that should be used henceforth. fn tb_reborrow( &mut self, @@ -210,7 +207,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' this.check_ptr_access(place.ptr(), ptr_size, CheckInAllocMsg::InboundsTest)?; // It is crucial that this gets called on all code paths, to ensure we track tag creation. - let log_creation = |this: &MiriInterpCx<'mir, 'tcx>, + let log_creation = |this: &MiriInterpCx<'tcx>, loc: Option<(AllocId, Size, ProvenanceExtra)>| // alloc_id, base_offset, orig_tag -> InterpResult<'tcx> { let global = this.machine.borrow_tracker.as_ref().unwrap().borrow(); @@ -379,8 +376,8 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Retag a pointer. References are passed to `from_ref_ty` and /// raw pointers are never reborrowed. fn tb_retag_ptr_value( @@ -416,13 +413,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { return visitor.visit_value(place); // The actual visitor. - struct RetagVisitor<'ecx, 'mir, 'tcx> { - ecx: &'ecx mut MiriInterpCx<'mir, 'tcx>, + struct RetagVisitor<'ecx, 'tcx> { + ecx: &'ecx mut MiriInterpCx<'tcx>, kind: RetagKind, retag_fields: RetagFields, unique_did: Option, } - impl<'ecx, 'mir, 'tcx> RetagVisitor<'ecx, 'mir, 'tcx> { + impl<'ecx, 'tcx> RetagVisitor<'ecx, 'tcx> { #[inline(always)] // yes this helps in our benchmarks fn retag_ptr_inplace( &mut self, @@ -437,13 +434,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Ok(()) } } - impl<'ecx, 'mir, 'tcx> ValueVisitor<'mir, 'tcx, MiriMachine<'mir, 'tcx>> - for RetagVisitor<'ecx, 'mir, 'tcx> - { + impl<'ecx, 'tcx> ValueVisitor<'tcx, MiriMachine<'tcx>> for RetagVisitor<'ecx, 'tcx> { type V = PlaceTy<'tcx, Provenance>; #[inline(always)] - fn ecx(&self) -> &MiriInterpCx<'mir, 'tcx> { + fn ecx(&self) -> &MiriInterpCx<'tcx> { self.ecx } @@ -608,7 +603,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// I.e. input is what you get from the visitor upon encountering an `adt` that is `Unique`, /// and output can be used by `retag_ptr_inplace`. fn inner_ptr_of_unique<'tcx>( - ecx: &MiriInterpCx<'_, 'tcx>, + ecx: &MiriInterpCx<'tcx>, place: &PlaceTy<'tcx, Provenance>, ) -> InterpResult<'tcx, PlaceTy<'tcx, Provenance>> { // Follows the same layout as `interpret/visitor.rs:walk_value` for `Box` in diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index b96e3beed459..719c262290ef 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -601,8 +601,8 @@ impl MemoryCellClocks { } /// Evaluation context extensions. -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> { /// Perform an atomic read operation at the memory location. fn read_scalar_atomic( &self, @@ -828,7 +828,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { /// with this program point. fn release_clock<'a>(&'a self) -> Option> where - 'mir: 'a, + 'tcx: 'a, { let this = self.eval_context_ref(); Some(this.machine.data_race.as_ref()?.release_clock(&this.machine.threads)) @@ -861,7 +861,7 @@ impl VClockAlloc { /// Create a new data-race detector for newly allocated memory. pub fn new_allocation( global: &GlobalState, - thread_mgr: &ThreadManager<'_, '_>, + thread_mgr: &ThreadManager<'_>, len: Size, kind: MemoryKind, current_span: Span, @@ -944,7 +944,7 @@ impl VClockAlloc { #[inline(never)] fn report_data_race<'tcx>( global: &GlobalState, - thread_mgr: &ThreadManager<'_, '_>, + thread_mgr: &ThreadManager<'_>, mem_clocks: &MemoryCellClocks, access: AccessType, access_size: Size, @@ -1042,7 +1042,7 @@ impl VClockAlloc { access_range: AllocRange, read_type: NaReadType, ty: Option>, - machine: &MiriMachine<'_, '_>, + machine: &MiriMachine<'_>, ) -> InterpResult<'tcx> { let current_span = machine.current_span(); let global = machine.data_race.as_ref().unwrap(); @@ -1085,7 +1085,7 @@ impl VClockAlloc { access_range: AllocRange, write_type: NaWriteType, ty: Option>, - machine: &mut MiriMachine<'_, '_>, + machine: &mut MiriMachine<'_>, ) -> InterpResult<'tcx> { let current_span = machine.current_span(); let global = machine.data_race.as_mut().unwrap(); @@ -1120,8 +1120,8 @@ impl VClockAlloc { } } -impl<'mir, 'tcx: 'mir> EvalContextPrivExt<'mir, 'tcx> for MiriInterpCx<'mir, 'tcx> {} -trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextPrivExt<'tcx> for MiriInterpCx<'tcx> {} +trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { /// Temporarily allow data-races to occur. This should only be used in /// one of these cases: /// - One of the appropriate `validate_atomic` functions will be called to @@ -1130,7 +1130,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { /// cannot be accessed by the interpreted program. /// - Execution of the interpreted program execution has halted. #[inline] - fn allow_data_races_ref(&self, op: impl FnOnce(&MiriInterpCx<'mir, 'tcx>) -> R) -> R { + fn allow_data_races_ref(&self, op: impl FnOnce(&MiriInterpCx<'tcx>) -> R) -> R { let this = self.eval_context_ref(); if let Some(data_race) = &this.machine.data_race { let old = data_race.ongoing_action_data_race_free.replace(true); @@ -1147,10 +1147,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { /// so should only be used for atomic operations or internal state that the program cannot /// access. #[inline] - fn allow_data_races_mut( - &mut self, - op: impl FnOnce(&mut MiriInterpCx<'mir, 'tcx>) -> R, - ) -> R { + fn allow_data_races_mut(&mut self, op: impl FnOnce(&mut MiriInterpCx<'tcx>) -> R) -> R { let this = self.eval_context_mut(); if let Some(data_race) = &this.machine.data_race { let old = data_race.ongoing_action_data_race_free.replace(true); @@ -1523,7 +1520,7 @@ impl GlobalState { #[inline] pub fn thread_created( &mut self, - thread_mgr: &ThreadManager<'_, '_>, + thread_mgr: &ThreadManager<'_>, thread: ThreadId, current_span: Span, ) { @@ -1591,7 +1588,7 @@ impl GlobalState { /// thread (the joinee, the thread that someone waited on) and the current thread (the joiner, /// the thread who was waiting). #[inline] - pub fn thread_joined(&mut self, threads: &ThreadManager<'_, '_>, joinee: ThreadId) { + pub fn thread_joined(&mut self, threads: &ThreadManager<'_>, joinee: ThreadId) { let thread_info = self.thread_info.borrow(); let thread_info = &thread_info[joinee]; @@ -1633,7 +1630,7 @@ impl GlobalState { /// This should be called strictly before any calls to /// `thread_joined`. #[inline] - pub fn thread_terminated(&mut self, thread_mgr: &ThreadManager<'_, '_>) { + pub fn thread_terminated(&mut self, thread_mgr: &ThreadManager<'_>) { let current_thread = thread_mgr.active_thread(); let current_index = self.active_thread_index(thread_mgr); @@ -1656,7 +1653,7 @@ impl GlobalState { /// operation may create. fn maybe_perform_sync_operation<'tcx>( &self, - thread_mgr: &ThreadManager<'_, '_>, + thread_mgr: &ThreadManager<'_>, current_span: Span, op: impl FnOnce(VectorIdx, RefMut<'_, ThreadClockSet>) -> InterpResult<'tcx, bool>, ) -> InterpResult<'tcx> { @@ -1672,11 +1669,7 @@ impl GlobalState { /// Internal utility to identify a thread stored internally /// returns the id and the name for better diagnostics. - fn print_thread_metadata( - &self, - thread_mgr: &ThreadManager<'_, '_>, - vector: VectorIdx, - ) -> String { + fn print_thread_metadata(&self, thread_mgr: &ThreadManager<'_>, vector: VectorIdx) -> String { let thread = self.vector_info.borrow()[vector]; let thread_name = thread_mgr.get_thread_display_name(thread); format!("thread `{thread_name}`") @@ -1686,7 +1679,7 @@ impl GlobalState { /// the moment when that clock snapshot was taken via `release_clock`. /// As this is an acquire operation, the thread timestamp is not /// incremented. - pub fn acquire_clock<'mir, 'tcx>(&self, clock: &VClock, threads: &ThreadManager<'mir, 'tcx>) { + pub fn acquire_clock<'tcx>(&self, clock: &VClock, threads: &ThreadManager<'tcx>) { let thread = threads.active_thread(); let (_, mut clocks) = self.thread_state_mut(thread); clocks.clock.join(clock); @@ -1695,10 +1688,7 @@ impl GlobalState { /// Returns the `release` clock of the current thread. /// Other threads can acquire this clock in the future to establish synchronization /// with this program point. - pub fn release_clock<'mir, 'tcx>( - &self, - threads: &ThreadManager<'mir, 'tcx>, - ) -> Ref<'_, VClock> { + pub fn release_clock<'tcx>(&self, threads: &ThreadManager<'tcx>) -> Ref<'_, VClock> { let thread = threads.active_thread(); let span = threads.active_thread_ref().current_span(); // We increment the clock each time this happens, to ensure no two releases @@ -1741,7 +1731,7 @@ impl GlobalState { #[inline] pub(super) fn active_thread_state( &self, - thread_mgr: &ThreadManager<'_, '_>, + thread_mgr: &ThreadManager<'_>, ) -> (VectorIdx, Ref<'_, ThreadClockSet>) { self.thread_state(thread_mgr.active_thread()) } @@ -1751,7 +1741,7 @@ impl GlobalState { #[inline] pub(super) fn active_thread_state_mut( &self, - thread_mgr: &ThreadManager<'_, '_>, + thread_mgr: &ThreadManager<'_>, ) -> (VectorIdx, RefMut<'_, ThreadClockSet>) { self.thread_state_mut(thread_mgr.active_thread()) } @@ -1759,19 +1749,19 @@ impl GlobalState { /// Return the current thread, should be the same /// as the data-race active thread. #[inline] - fn active_thread_index(&self, thread_mgr: &ThreadManager<'_, '_>) -> VectorIdx { + fn active_thread_index(&self, thread_mgr: &ThreadManager<'_>) -> VectorIdx { let active_thread_id = thread_mgr.active_thread(); self.thread_index(active_thread_id) } // SC ATOMIC STORE rule in the paper. - pub(super) fn sc_write(&self, thread_mgr: &ThreadManager<'_, '_>) { + pub(super) fn sc_write(&self, thread_mgr: &ThreadManager<'_>) { let (index, clocks) = self.active_thread_state(thread_mgr); self.last_sc_write.borrow_mut().set_at_index(&clocks.clock, index); } // SC ATOMIC READ rule in the paper. - pub(super) fn sc_read(&self, thread_mgr: &ThreadManager<'_, '_>) { + pub(super) fn sc_read(&self, thread_mgr: &ThreadManager<'_>) { let (.., mut clocks) = self.active_thread_state_mut(thread_mgr); clocks.read_seqcst.join(&self.last_sc_fence.borrow()); } diff --git a/src/tools/miri/src/concurrency/init_once.rs b/src/tools/miri/src/concurrency/init_once.rs index f1534d3745f9..7f8500159c14 100644 --- a/src/tools/miri/src/concurrency/init_once.rs +++ b/src/tools/miri/src/concurrency/init_once.rs @@ -26,17 +26,14 @@ pub(super) struct InitOnce { clock: VClock, } -impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} +trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Provides the closure with the next InitOnceId. Creates that InitOnce if the closure returns None, /// otherwise returns the value from the closure. #[inline] fn init_once_get_or_create(&mut self, existing: F) -> InterpResult<'tcx, InitOnceId> where - F: FnOnce( - &mut MiriInterpCx<'mir, 'tcx>, - InitOnceId, - ) -> InterpResult<'tcx, Option>, + F: FnOnce(&mut MiriInterpCx<'tcx>, InitOnceId) -> InterpResult<'tcx, Option>, { let this = self.eval_context_mut(); let next_index = this.machine.sync.init_onces.next_index(); @@ -50,8 +47,8 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn init_once_get_or_create_id( &mut self, lock_op: &OpTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index 2ea89050ecd9..dfe4d0d4c2f9 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -160,10 +160,8 @@ pub struct SynchronizationObjects { } // Private extension trait for local helper methods -impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub(super) trait EvalContextExtPriv<'mir, 'tcx: 'mir>: - crate::MiriInterpCxExt<'mir, 'tcx> -{ +impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Lazily initialize the ID of this Miri sync structure. /// ('0' indicates uninit.) #[inline] @@ -203,7 +201,7 @@ pub(super) trait EvalContextExtPriv<'mir, 'tcx: 'mir>: #[inline] fn mutex_get_or_create(&mut self, existing: F) -> InterpResult<'tcx, MutexId> where - F: FnOnce(&mut MiriInterpCx<'mir, 'tcx>, MutexId) -> InterpResult<'tcx, Option>, + F: FnOnce(&mut MiriInterpCx<'tcx>, MutexId) -> InterpResult<'tcx, Option>, { let this = self.eval_context_mut(); let next_index = this.machine.sync.mutexes.next_index(); @@ -224,7 +222,7 @@ pub(super) trait EvalContextExtPriv<'mir, 'tcx: 'mir>: #[inline] fn rwlock_get_or_create(&mut self, existing: F) -> InterpResult<'tcx, RwLockId> where - F: FnOnce(&mut MiriInterpCx<'mir, 'tcx>, RwLockId) -> InterpResult<'tcx, Option>, + F: FnOnce(&mut MiriInterpCx<'tcx>, RwLockId) -> InterpResult<'tcx, Option>, { let this = self.eval_context_mut(); let next_index = this.machine.sync.rwlocks.next_index(); @@ -245,10 +243,7 @@ pub(super) trait EvalContextExtPriv<'mir, 'tcx: 'mir>: #[inline] fn condvar_get_or_create(&mut self, existing: F) -> InterpResult<'tcx, CondvarId> where - F: FnOnce( - &mut MiriInterpCx<'mir, 'tcx>, - CondvarId, - ) -> InterpResult<'tcx, Option>, + F: FnOnce(&mut MiriInterpCx<'tcx>, CondvarId) -> InterpResult<'tcx, Option>, { let this = self.eval_context_mut(); let next_index = this.machine.sync.condvars.next_index(); @@ -288,8 +283,8 @@ pub(super) trait EvalContextExtPriv<'mir, 'tcx: 'mir>: // cases, the function calls are infallible and it is the client's (shim // implementation's) responsibility to detect and deal with erroneous // situations. -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn mutex_get_or_create_id( &mut self, lock_op: &OpTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index c948383d597d..8e8e1182bfff 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -44,17 +44,12 @@ pub enum TlsAllocAction { pub trait UnblockCallback<'tcx>: VisitProvenance { /// Will be invoked when the thread was unblocked the "regular" way, /// i.e. whatever event it was blocking on has happened. - fn unblock<'mir>( - self: Box, - ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, - ) -> InterpResult<'tcx>; + fn unblock(self: Box, ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>) -> InterpResult<'tcx>; /// Will be invoked when the timeout ellapsed without the event the /// thread was blocking on having occurred. - fn timeout<'mir>( - self: Box, - _ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, - ) -> InterpResult<'tcx>; + fn timeout(self: Box, _ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>) + -> InterpResult<'tcx>; } type DynUnblockCallback<'tcx> = Box + 'tcx>; @@ -94,13 +89,13 @@ macro_rules! callback { } impl<$tcx, $($lft),*> UnblockCallback<$tcx> for Callback<$tcx, $($lft),*> { - fn unblock<'mir>(self: Box, $this: &mut MiriInterpCx<'mir, $tcx>) -> InterpResult<$tcx> { + fn unblock(self: Box, $this: &mut MiriInterpCx<$tcx>) -> InterpResult<$tcx> { #[allow(unused_variables)] let Callback { $($name,)* _phantom } = *self; $unblock } - fn timeout<'mir>(self: Box, $this_timeout: &mut MiriInterpCx<'mir, $tcx>) -> InterpResult<$tcx> { + fn timeout(self: Box, $this_timeout: &mut MiriInterpCx<$tcx>) -> InterpResult<$tcx> { #[allow(unused_variables)] let Callback { $($name,)* _phantom } = *self; $timeout @@ -228,20 +223,20 @@ enum ThreadJoinStatus { } /// A thread. -pub struct Thread<'mir, 'tcx> { +pub struct Thread<'tcx> { state: ThreadState<'tcx>, /// Name of the thread. thread_name: Option>, /// The virtual call stack. - stack: Vec>>, + stack: Vec>>, /// The function to call when the stack ran empty, to figure out what to do next. /// Conceptually, this is the interpreter implementation of the things that happen 'after' the /// Rust language entry point for this thread returns (usually implemented by the C or OS runtime). /// (`None` is an error, it means the callback has not been set up yet or is actively running.) - pub(crate) on_stack_empty: Option>, + pub(crate) on_stack_empty: Option>, /// The index of the topmost user-relevant frame in `stack`. This field must contain /// the value produced by `get_top_user_relevant_frame`. @@ -267,10 +262,10 @@ pub struct Thread<'mir, 'tcx> { pub(crate) last_error: Option>, } -pub type StackEmptyCallback<'mir, 'tcx> = - Box) -> InterpResult<'tcx, Poll<()>> + 'tcx>; +pub type StackEmptyCallback<'tcx> = + Box) -> InterpResult<'tcx, Poll<()>> + 'tcx>; -impl<'mir, 'tcx> Thread<'mir, 'tcx> { +impl<'tcx> Thread<'tcx> { /// Get the name of the current thread if it was set. fn thread_name(&self) -> Option<&[u8]> { self.thread_name.as_deref() @@ -326,7 +321,7 @@ impl<'mir, 'tcx> Thread<'mir, 'tcx> { } } -impl<'mir, 'tcx> std::fmt::Debug for Thread<'mir, 'tcx> { +impl<'tcx> std::fmt::Debug for Thread<'tcx> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, @@ -338,8 +333,8 @@ impl<'mir, 'tcx> std::fmt::Debug for Thread<'mir, 'tcx> { } } -impl<'mir, 'tcx> Thread<'mir, 'tcx> { - fn new(name: Option<&str>, on_stack_empty: Option>) -> Self { +impl<'tcx> Thread<'tcx> { + fn new(name: Option<&str>, on_stack_empty: Option>) -> Self { Self { state: ThreadState::Enabled, thread_name: name.map(|name| Vec::from(name.as_bytes())), @@ -353,7 +348,7 @@ impl<'mir, 'tcx> Thread<'mir, 'tcx> { } } -impl VisitProvenance for Thread<'_, '_> { +impl VisitProvenance for Thread<'_> { fn visit_provenance(&self, visit: &mut VisitWith<'_>) { let Thread { panic_payloads: panic_payload, @@ -376,7 +371,7 @@ impl VisitProvenance for Thread<'_, '_> { } } -impl VisitProvenance for Frame<'_, '_, Provenance, FrameExtra<'_>> { +impl VisitProvenance for Frame<'_, Provenance, FrameExtra<'_>> { fn visit_provenance(&self, visit: &mut VisitWith<'_>) { let Frame { return_place, @@ -430,13 +425,13 @@ impl Timeout { /// A set of threads. #[derive(Debug)] -pub struct ThreadManager<'mir, 'tcx> { +pub struct ThreadManager<'tcx> { /// Identifier of the currently active thread. active_thread: ThreadId, /// Threads used in the program. /// /// Note that this vector also contains terminated threads. - threads: IndexVec>, + threads: IndexVec>, /// A mapping from a thread-local static to an allocation id of a thread /// specific allocation. thread_local_alloc_ids: FxHashMap<(DefId, ThreadId), Pointer>, @@ -444,7 +439,7 @@ pub struct ThreadManager<'mir, 'tcx> { yield_active_thread: bool, } -impl VisitProvenance for ThreadManager<'_, '_> { +impl VisitProvenance for ThreadManager<'_> { fn visit_provenance(&self, visit: &mut VisitWith<'_>) { let ThreadManager { threads, @@ -462,7 +457,7 @@ impl VisitProvenance for ThreadManager<'_, '_> { } } -impl<'mir, 'tcx> Default for ThreadManager<'mir, 'tcx> { +impl<'tcx> Default for ThreadManager<'tcx> { fn default() -> Self { let mut threads = IndexVec::new(); // Create the main thread and add it to the list of threads. @@ -476,10 +471,10 @@ impl<'mir, 'tcx> Default for ThreadManager<'mir, 'tcx> { } } -impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> { +impl<'tcx> ThreadManager<'tcx> { pub(crate) fn init( - ecx: &mut MiriInterpCx<'mir, 'tcx>, - on_main_stack_empty: StackEmptyCallback<'mir, 'tcx>, + ecx: &mut MiriInterpCx<'tcx>, + on_main_stack_empty: StackEmptyCallback<'tcx>, ) { ecx.machine.threads.threads[ThreadId::MAIN_THREAD].on_stack_empty = Some(on_main_stack_empty); @@ -505,24 +500,22 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> { } /// Borrow the stack of the active thread. - pub fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>] { + pub fn active_thread_stack(&self) -> &[Frame<'tcx, Provenance, FrameExtra<'tcx>>] { &self.threads[self.active_thread].stack } /// Mutably borrow the stack of the active thread. - fn active_thread_stack_mut( - &mut self, - ) -> &mut Vec>> { + fn active_thread_stack_mut(&mut self) -> &mut Vec>> { &mut self.threads[self.active_thread].stack } pub fn all_stacks( &self, - ) -> impl Iterator>])> { + ) -> impl Iterator>])> { self.threads.iter_enumerated().map(|(id, t)| (id, &t.stack[..])) } /// Create a new thread and returns its id. - fn create_thread(&mut self, on_stack_empty: StackEmptyCallback<'mir, 'tcx>) -> ThreadId { + fn create_thread(&mut self, on_stack_empty: StackEmptyCallback<'tcx>) -> ThreadId { let new_thread_id = ThreadId::new(self.threads.len()); self.threads.push(Thread::new(None, Some(on_stack_empty))); new_thread_id @@ -572,12 +565,12 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> { } /// Get a mutable borrow of the currently active thread. - pub fn active_thread_mut(&mut self) -> &mut Thread<'mir, 'tcx> { + pub fn active_thread_mut(&mut self) -> &mut Thread<'tcx> { &mut self.threads[self.active_thread] } /// Get a shared borrow of the currently active thread. - pub fn active_thread_ref(&self) -> &Thread<'mir, 'tcx> { + pub fn active_thread_ref(&self) -> &Thread<'tcx> { &self.threads[self.active_thread] } @@ -791,8 +784,8 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> { } } -impl<'mir, 'tcx: 'mir> EvalContextPrivExt<'mir, 'tcx> for MiriInterpCx<'mir, 'tcx> {} -trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextPrivExt<'tcx> for MiriInterpCx<'tcx> {} +trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { /// Execute a timeout callback on the callback's thread. #[inline] fn run_timeout_callback(&mut self) -> InterpResult<'tcx> { @@ -848,8 +841,8 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { } // Public interface to thread management. -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Get a thread-specific allocation id for the given thread-local static. /// If needed, allocate a new one. fn get_or_create_thread_local_alloc( @@ -1069,13 +1062,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } #[inline] - fn active_thread_mut(&mut self) -> &mut Thread<'mir, 'tcx> { + fn active_thread_mut(&mut self) -> &mut Thread<'tcx> { let this = self.eval_context_mut(); this.machine.threads.active_thread_mut() } #[inline] - fn active_thread_ref(&self) -> &Thread<'mir, 'tcx> { + fn active_thread_ref(&self) -> &Thread<'tcx> { let this = self.eval_context_ref(); this.machine.threads.active_thread_ref() } @@ -1099,15 +1092,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } #[inline] - fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>] { + fn active_thread_stack<'a>(&'a self) -> &'a [Frame<'tcx, Provenance, FrameExtra<'tcx>>] { let this = self.eval_context_ref(); this.machine.threads.active_thread_stack() } #[inline] - fn active_thread_stack_mut( - &mut self, - ) -> &mut Vec>> { + fn active_thread_stack_mut<'a>( + &'a mut self, + ) -> &'a mut Vec>> { let this = self.eval_context_mut(); this.machine.threads.active_thread_stack_mut() } @@ -1122,7 +1115,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { #[inline] fn get_thread_name<'c>(&'c self, thread: ThreadId) -> Option<&[u8]> where - 'mir: 'c, + 'tcx: 'c, { self.eval_context_ref().machine.threads.get_thread_name(thread) } diff --git a/src/tools/miri/src/concurrency/weak_memory.rs b/src/tools/miri/src/concurrency/weak_memory.rs index 8c71eeb27aa6..7a49f6d34707 100644 --- a/src/tools/miri/src/concurrency/weak_memory.rs +++ b/src/tools/miri/src/concurrency/weak_memory.rs @@ -243,7 +243,7 @@ impl StoreBufferAlloc { } } -impl<'mir, 'tcx: 'mir> StoreBuffer { +impl<'tcx> StoreBuffer { fn new(init: Scalar) -> Self { let mut buffer = VecDeque::new(); buffer.reserve(STORE_BUFFER_LIMIT); @@ -265,7 +265,7 @@ impl<'mir, 'tcx: 'mir> StoreBuffer { fn read_from_last_store( &self, global: &DataRaceState, - thread_mgr: &ThreadManager<'_, '_>, + thread_mgr: &ThreadManager<'_>, is_seqcst: bool, ) { let store_elem = self.buffer.back(); @@ -278,7 +278,7 @@ impl<'mir, 'tcx: 'mir> StoreBuffer { fn buffered_read( &self, global: &DataRaceState, - thread_mgr: &ThreadManager<'_, '_>, + thread_mgr: &ThreadManager<'_>, is_seqcst: bool, rng: &mut (impl rand::Rng + ?Sized), validate: impl FnOnce() -> InterpResult<'tcx>, @@ -309,7 +309,7 @@ impl<'mir, 'tcx: 'mir> StoreBuffer { &mut self, val: Scalar, global: &DataRaceState, - thread_mgr: &ThreadManager<'_, '_>, + thread_mgr: &ThreadManager<'_>, is_seqcst: bool, ) -> InterpResult<'tcx> { let (index, clocks) = global.active_thread_state(thread_mgr); @@ -463,10 +463,8 @@ impl StoreElement { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: - crate::MiriInterpCxExt<'mir, 'tcx> -{ +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn buffered_atomic_rmw( &mut self, new_val: Scalar, diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 468bbb85dddf..d55f21d74efc 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -144,7 +144,7 @@ pub enum DiagLevel { /// be pointing to a problem in the Rust runtime itself, and do not prune it at all. pub fn prune_stacktrace<'tcx>( mut stacktrace: Vec>, - machine: &MiriMachine<'_, 'tcx>, + machine: &MiriMachine<'tcx>, ) -> (Vec>, bool) { match machine.backtrace_style { BacktraceStyle::Off => { @@ -201,8 +201,8 @@ pub fn prune_stacktrace<'tcx>( /// Emit a custom diagnostic without going through the miri-engine machinery. /// /// Returns `Some` if this was regular program termination with a given exit code and a `bool` indicating whether a leak check should happen; `None` otherwise. -pub fn report_error<'tcx, 'mir>( - ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, +pub fn report_error<'tcx>( + ecx: &InterpCx<'tcx, MiriMachine<'tcx>>, e: InterpErrorInfo<'tcx>, ) -> Option<(i64, bool)> { use InterpError::*; @@ -457,8 +457,8 @@ pub fn report_error<'tcx, 'mir>( None } -pub fn report_leaks<'mir, 'tcx>( - ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, +pub fn report_leaks<'tcx>( + ecx: &InterpCx<'tcx, MiriMachine<'tcx>>, leaks: Vec<(AllocId, MemoryKind, Allocation, MiriAllocBytes>)>, ) { let mut any_pruned = false; @@ -504,7 +504,7 @@ pub fn report_msg<'tcx>( helps: Vec<(Option, String)>, stacktrace: &[FrameInfo<'tcx>], thread: Option, - machine: &MiriMachine<'_, 'tcx>, + machine: &MiriMachine<'tcx>, ) { let span = stacktrace.first().map_or(DUMMY_SP, |fi| fi.span); let sess = machine.tcx.sess; @@ -577,7 +577,7 @@ pub fn report_msg<'tcx>( err.emit(); } -impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { +impl<'tcx> MiriMachine<'tcx> { pub fn emit_diagnostic(&self, e: NonHaltingDiagnostic) { use NonHaltingDiagnostic::*; @@ -690,8 +690,8 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emit_diagnostic(&self, e: NonHaltingDiagnostic) { let this = self.eval_context_ref(); this.machine.emit_diagnostic(e); diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 78c092faf909..35f7f43f123f 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -214,7 +214,7 @@ enum MainThreadState<'tcx> { impl<'tcx> MainThreadState<'tcx> { fn on_main_stack_empty( &mut self, - this: &mut MiriInterpCx<'_, 'tcx>, + this: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, Poll<()>> { use MainThreadState::*; match self { @@ -263,12 +263,12 @@ impl<'tcx> MainThreadState<'tcx> { /// Returns a freshly created `InterpCx`. /// Public because this is also used by `priroda`. -pub fn create_ecx<'mir, 'tcx: 'mir>( +pub fn create_ecx<'tcx>( tcx: TyCtxt<'tcx>, entry_id: DefId, entry_type: EntryFnType, config: &MiriConfig, -) -> InterpResult<'tcx, InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>> { +) -> InterpResult<'tcx, InterpCx<'tcx, MiriMachine<'tcx>>> { let param_env = ty::ParamEnv::reveal_all(); let layout_cx = LayoutCx { tcx, param_env }; let mut ecx = diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index bd160380cd52..5c3b8f2d2a05 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -234,8 +234,8 @@ impl ToSoft for f32 { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Checks if the given crate/module exists. fn have_module(&self, path: &[&str]) -> bool { try_resolve_did(*self.eval_context_ref().tcx, path, None).is_some() @@ -573,23 +573,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// Visiting the memory covered by a `MemPlace`, being aware of /// whether we are inside an `UnsafeCell` or not. - struct UnsafeCellVisitor<'ecx, 'mir, 'tcx, F> + struct UnsafeCellVisitor<'ecx, 'tcx, F> where F: FnMut(&MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx>, { - ecx: &'ecx MiriInterpCx<'mir, 'tcx>, + ecx: &'ecx MiriInterpCx<'tcx>, unsafe_cell_action: F, } - impl<'ecx, 'mir, 'tcx: 'mir, F> ValueVisitor<'mir, 'tcx, MiriMachine<'mir, 'tcx>> - for UnsafeCellVisitor<'ecx, 'mir, 'tcx, F> + impl<'ecx, 'tcx, F> ValueVisitor<'tcx, MiriMachine<'tcx>> for UnsafeCellVisitor<'ecx, 'tcx, F> where F: FnMut(&MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx>, { type V = MPlaceTy<'tcx, Provenance>; #[inline(always)] - fn ecx(&self) -> &MiriInterpCx<'mir, 'tcx> { + fn ecx(&self) -> &MiriInterpCx<'tcx> { self.ecx } @@ -920,7 +919,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { slice: &ImmTy<'tcx, Provenance>, ) -> InterpResult<'tcx, &'a [u8]> where - 'mir: 'a, + 'tcx: 'a, { let this = self.eval_context_ref(); let (ptr, len) = slice.to_scalar_pair(); @@ -933,7 +932,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// Read a sequence of bytes until the first null terminator. fn read_c_str<'a>(&'a self, ptr: Pointer>) -> InterpResult<'tcx, &'a [u8]> where - 'mir: 'a, + 'tcx: 'a, { let this = self.eval_context_ref(); let size1 = Size::from_bytes(1); @@ -1176,7 +1175,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_ref(); fn float_to_int_inner<'tcx, F: rustc_apfloat::Float>( - this: &MiriInterpCx<'_, 'tcx>, + this: &MiriInterpCx<'tcx>, src: F, cast_to: TyAndLayout<'tcx>, round: rustc_apfloat::Round, @@ -1299,7 +1298,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } -impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { +impl<'tcx> MiriMachine<'tcx> { /// Get the current span in the topmost function which is workspace-local and not /// `#[track_caller]`. /// This function is backed by a cache, and can be assumed to be very fast. @@ -1321,7 +1320,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { self.stack()[frame_idx].current_span() } - fn stack(&self) -> &[Frame<'mir, 'tcx, Provenance, machine::FrameExtra<'tcx>>] { + fn stack(&self) -> &[Frame<'tcx, Provenance, machine::FrameExtra<'tcx>>] { self.threads.active_thread_stack() } @@ -1330,7 +1329,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { } /// This is the source of truth for the `is_user_relevant` flag in our `FrameExtra`. - pub fn is_user_relevant(&self, frame: &Frame<'mir, 'tcx, Provenance>) -> bool { + pub fn is_user_relevant(&self, frame: &Frame<'tcx, Provenance>) -> bool { let def_id = frame.instance.def_id(); (def_id.is_local() || self.local_crates.contains(&def_id.krate)) && !frame.instance.def.requires_caller_location(self.tcx) diff --git a/src/tools/miri/src/intrinsics/atomic.rs b/src/tools/miri/src/intrinsics/atomic.rs index 0daf59c943ce..17f95df9aa15 100644 --- a/src/tools/miri/src/intrinsics/atomic.rs +++ b/src/tools/miri/src/intrinsics/atomic.rs @@ -11,8 +11,8 @@ pub enum AtomicOp { Min, } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Calls the atomic intrinsic `intrinsic`; the `atomic_` prefix has already been removed. /// Returns `Ok(true)` if the intrinsic was handled. fn emulate_atomic_intrinsic( @@ -120,8 +120,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } -impl<'mir, 'tcx: 'mir> EvalContextPrivExt<'mir, 'tcx> for MiriInterpCx<'mir, 'tcx> {} -trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextPrivExt<'tcx> for MiriInterpCx<'tcx> {} +trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> { fn atomic_load( &mut self, args: &[OpTy<'tcx, Provenance>], diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index 973a0c84a882..e39b78d3816f 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -18,8 +18,8 @@ use atomic::EvalContextExt as _; use helpers::{check_arg_count, ToHost, ToSoft}; use simd::EvalContextExt as _; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn call_intrinsic( &mut self, instance: ty::Instance<'tcx>, diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs index 67a2d565fa2f..ed0c30e2a11a 100644 --- a/src/tools/miri/src/intrinsics/simd.rs +++ b/src/tools/miri/src/intrinsics/simd.rs @@ -15,8 +15,8 @@ pub(crate) enum MinMax { Max, } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Calls the simd intrinsic `intrinsic`; the `simd_` prefix has already been removed. /// Returns `Ok(true)` if the intrinsic was handled. fn emulate_simd_intrinsic( diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index e09fd2122f8c..fc1a655c1232 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -373,7 +373,7 @@ pub struct PrimitiveLayouts<'tcx> { pub const_raw_ptr: TyAndLayout<'tcx>, // *const () } -impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> { +impl<'tcx> PrimitiveLayouts<'tcx> { fn new(layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result> { let tcx = layout_cx.tcx; let mut_raw_ptr = Ty::new_mut_ptr(tcx, tcx.types.unit); @@ -425,7 +425,7 @@ impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> { /// /// If you add anything here that stores machine values, remember to update /// `visit_all_machine_values`! -pub struct MiriMachine<'mir, 'tcx> { +pub struct MiriMachine<'tcx> { // We carry a copy of the global `TyCtxt` for convenience, so methods taking just `&Evaluator` have `tcx` access. pub tcx: TyCtxt<'tcx>, @@ -471,7 +471,7 @@ pub struct MiriMachine<'mir, 'tcx> { pub(crate) clock: Clock, /// The set of threads. - pub(crate) threads: ThreadManager<'mir, 'tcx>, + pub(crate) threads: ThreadManager<'tcx>, /// The state of the primitive synchronization objects. pub(crate) sync: SynchronizationObjects, @@ -576,7 +576,7 @@ pub struct MiriMachine<'mir, 'tcx> { pub(crate) symbolic_alignment: RefCell>, } -impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { +impl<'tcx> MiriMachine<'tcx> { pub(crate) fn new(config: &MiriConfig, layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Self { let tcx = layout_cx.tcx; let local_crates = helpers::get_local_crates(tcx); @@ -706,9 +706,9 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { } pub(crate) fn late_init( - this: &mut MiriInterpCx<'mir, 'tcx>, + this: &mut MiriInterpCx<'tcx>, config: &MiriConfig, - on_main_stack_empty: StackEmptyCallback<'mir, 'tcx>, + on_main_stack_empty: StackEmptyCallback<'tcx>, ) -> InterpResult<'tcx> { EnvVars::init(this, config)?; MiriMachine::init_extern_statics(this)?; @@ -717,7 +717,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { } pub(crate) fn add_extern_static( - this: &mut MiriInterpCx<'mir, 'tcx>, + this: &mut MiriInterpCx<'tcx>, name: &str, ptr: Pointer>, ) { @@ -765,7 +765,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { } } -impl VisitProvenance for MiriMachine<'_, '_> { +impl VisitProvenance for MiriMachine<'_> { fn visit_provenance(&self, visit: &mut VisitWith<'_>) { #[rustfmt::skip] let MiriMachine { @@ -837,26 +837,26 @@ impl VisitProvenance for MiriMachine<'_, '_> { } /// A rustc InterpCx for Miri. -pub type MiriInterpCx<'mir, 'tcx> = InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>; +pub type MiriInterpCx<'tcx> = InterpCx<'tcx, MiriMachine<'tcx>>; /// A little trait that's useful to be inherited by extension traits. -pub trait MiriInterpCxExt<'mir, 'tcx> { - fn eval_context_ref<'a>(&'a self) -> &'a MiriInterpCx<'mir, 'tcx>; - fn eval_context_mut<'a>(&'a mut self) -> &'a mut MiriInterpCx<'mir, 'tcx>; +pub trait MiriInterpCxExt<'tcx> { + fn eval_context_ref<'a>(&'a self) -> &'a MiriInterpCx<'tcx>; + fn eval_context_mut<'a>(&'a mut self) -> &'a mut MiriInterpCx<'tcx>; } -impl<'mir, 'tcx> MiriInterpCxExt<'mir, 'tcx> for MiriInterpCx<'mir, 'tcx> { +impl<'tcx> MiriInterpCxExt<'tcx> for MiriInterpCx<'tcx> { #[inline(always)] - fn eval_context_ref(&self) -> &MiriInterpCx<'mir, 'tcx> { + fn eval_context_ref(&self) -> &MiriInterpCx<'tcx> { self } #[inline(always)] - fn eval_context_mut(&mut self) -> &mut MiriInterpCx<'mir, 'tcx> { + fn eval_context_mut(&mut self) -> &mut MiriInterpCx<'tcx> { self } } /// Machine hook implementations. -impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { +impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { type MemoryKind = MiriMemoryKind; type ExtraFnVal = DynSym; @@ -875,13 +875,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { const PANIC_ON_ALLOC_FAIL: bool = false; #[inline(always)] - fn enforce_alignment(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool { + fn enforce_alignment(ecx: &MiriInterpCx<'tcx>) -> bool { ecx.machine.check_alignment != AlignmentCheck::None } #[inline(always)] fn alignment_check( - ecx: &MiriInterpCx<'mir, 'tcx>, + ecx: &MiriInterpCx<'tcx>, alloc_id: AllocId, alloc_align: Align, alloc_kind: AllocKind, @@ -926,30 +926,30 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { } #[inline(always)] - fn enforce_validity(ecx: &MiriInterpCx<'mir, 'tcx>, _layout: TyAndLayout<'tcx>) -> bool { + fn enforce_validity(ecx: &MiriInterpCx<'tcx>, _layout: TyAndLayout<'tcx>) -> bool { ecx.machine.validate } #[inline(always)] - fn enforce_abi(_ecx: &MiriInterpCx<'mir, 'tcx>) -> bool { + fn enforce_abi(_ecx: &MiriInterpCx<'tcx>) -> bool { true } #[inline(always)] - fn ignore_optional_overflow_checks(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool { + fn ignore_optional_overflow_checks(ecx: &MiriInterpCx<'tcx>) -> bool { !ecx.tcx.sess.overflow_checks() } #[inline(always)] fn find_mir_or_eval_fn( - ecx: &mut MiriInterpCx<'mir, 'tcx>, + ecx: &mut MiriInterpCx<'tcx>, instance: ty::Instance<'tcx>, abi: Abi, args: &[FnArg<'tcx, Provenance>], dest: &MPlaceTy<'tcx, Provenance>, ret: Option, unwind: mir::UnwindAction, - ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> { + ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> { // For foreign items, try to see if we can emulate them. if ecx.tcx.is_foreign_item(instance.def_id()) { // An external function call that does not have a MIR body. We either find MIR elsewhere @@ -969,7 +969,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { #[inline(always)] fn call_extra_fn( - ecx: &mut MiriInterpCx<'mir, 'tcx>, + ecx: &mut MiriInterpCx<'tcx>, fn_val: DynSym, abi: Abi, args: &[FnArg<'tcx, Provenance>], @@ -983,7 +983,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { #[inline(always)] fn call_intrinsic( - ecx: &mut MiriInterpCx<'mir, 'tcx>, + ecx: &mut MiriInterpCx<'tcx>, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, Provenance>], dest: &MPlaceTy<'tcx, Provenance>, @@ -995,19 +995,19 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { #[inline(always)] fn assert_panic( - ecx: &mut MiriInterpCx<'mir, 'tcx>, + ecx: &mut MiriInterpCx<'tcx>, msg: &mir::AssertMessage<'tcx>, unwind: mir::UnwindAction, ) -> InterpResult<'tcx> { ecx.assert_panic(msg, unwind) } - fn panic_nounwind(ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx> { + fn panic_nounwind(ecx: &mut InterpCx<'tcx, Self>, msg: &str) -> InterpResult<'tcx> { ecx.start_panic_nounwind(msg) } fn unwind_terminate( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, reason: mir::UnwindTerminateReason, ) -> InterpResult<'tcx> { // Call the lang item. @@ -1025,7 +1025,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { #[inline(always)] fn binary_ptr_op( - ecx: &MiriInterpCx<'mir, 'tcx>, + ecx: &MiriInterpCx<'tcx>, bin_op: mir::BinOp, left: &ImmTy<'tcx, Provenance>, right: &ImmTy<'tcx, Provenance>, @@ -1038,21 +1038,21 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { F1: rustc_apfloat::Float + rustc_apfloat::FloatConvert, F2: rustc_apfloat::Float, >( - ecx: &InterpCx<'mir, 'tcx, Self>, + ecx: &InterpCx<'tcx, Self>, inputs: &[F1], ) -> F2 { ecx.generate_nan(inputs) } fn thread_local_static_pointer( - ecx: &mut MiriInterpCx<'mir, 'tcx>, + ecx: &mut MiriInterpCx<'tcx>, def_id: DefId, ) -> InterpResult<'tcx, Pointer> { ecx.get_or_create_thread_local_alloc(def_id) } fn extern_static_pointer( - ecx: &MiriInterpCx<'mir, 'tcx>, + ecx: &MiriInterpCx<'tcx>, def_id: DefId, ) -> InterpResult<'tcx, Pointer> { let link_name = ecx.item_link_name(def_id); @@ -1087,7 +1087,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { } fn adjust_allocation<'b>( - ecx: &MiriInterpCx<'mir, 'tcx>, + ecx: &MiriInterpCx<'tcx>, id: AllocId, alloc: Cow<'b, Allocation>, kind: Option, @@ -1152,7 +1152,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { } fn adjust_alloc_root_pointer( - ecx: &MiriInterpCx<'mir, 'tcx>, + ecx: &MiriInterpCx<'tcx>, ptr: Pointer, kind: Option, ) -> InterpResult<'tcx, Pointer> { @@ -1183,7 +1183,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { /// Called on `usize as ptr` casts. #[inline(always)] fn ptr_from_addr_cast( - ecx: &MiriInterpCx<'mir, 'tcx>, + ecx: &MiriInterpCx<'tcx>, addr: u64, ) -> InterpResult<'tcx, Pointer>> { ecx.ptr_from_addr_cast(addr) @@ -1193,7 +1193,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { /// (Actually computing the resulting `usize` doesn't need machine help, /// that's just `Scalar::try_to_int`.) fn expose_ptr( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, ptr: Pointer, ) -> InterpResult<'tcx> { match ptr.provenance { @@ -1215,7 +1215,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { /// (i.e., we'll never turn the data returned here back into a `Pointer` that might be /// stored in machine state). fn ptr_get_alloc( - ecx: &MiriInterpCx<'mir, 'tcx>, + ecx: &MiriInterpCx<'tcx>, ptr: Pointer, ) -> Option<(AllocId, Size, Self::ProvenanceExtra)> { let rel = ecx.ptr_get_alloc(ptr); @@ -1312,7 +1312,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { #[inline(always)] fn retag_ptr_value( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, kind: mir::RetagKind, val: &ImmTy<'tcx, Provenance>, ) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> { @@ -1325,7 +1325,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { #[inline(always)] fn retag_place_contents( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, kind: mir::RetagKind, place: &PlaceTy<'tcx, Provenance>, ) -> InterpResult<'tcx> { @@ -1336,7 +1336,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { } fn protect_in_place_function_argument( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, place: &MPlaceTy<'tcx, Provenance>, ) -> InterpResult<'tcx> { // If we have a borrow tracker, we also have it set up protection so that all reads *and @@ -1358,9 +1358,9 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { #[inline(always)] fn init_frame_extra( - ecx: &mut InterpCx<'mir, 'tcx, Self>, - frame: Frame<'mir, 'tcx, Provenance>, - ) -> InterpResult<'tcx, Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>> { + ecx: &mut InterpCx<'tcx, Self>, + frame: Frame<'tcx, Provenance>, + ) -> InterpResult<'tcx, Frame<'tcx, Provenance, FrameExtra<'tcx>>> { // Start recording our event before doing anything else let timing = if let Some(profiler) = ecx.machine.profiler.as_ref() { let fn_name = frame.instance.to_string(); @@ -1390,18 +1390,18 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { } fn stack<'a>( - ecx: &'a InterpCx<'mir, 'tcx, Self>, - ) -> &'a [Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>] { + ecx: &'a InterpCx<'tcx, Self>, + ) -> &'a [Frame<'tcx, Self::Provenance, Self::FrameExtra>] { ecx.active_thread_stack() } fn stack_mut<'a>( - ecx: &'a mut InterpCx<'mir, 'tcx, Self>, - ) -> &'a mut Vec> { + ecx: &'a mut InterpCx<'tcx, Self>, + ) -> &'a mut Vec> { ecx.active_thread_stack_mut() } - fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { + fn before_terminator(ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> { ecx.machine.basic_block_count += 1u64; // a u64 that is only incremented by 1 will "never" overflow ecx.machine.since_gc += 1; // Possibly report our progress. @@ -1432,7 +1432,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { } #[inline(always)] - fn after_stack_push(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { + fn after_stack_push(ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> { if ecx.frame().extra.is_user_relevant { // We just pushed a local frame, so we know that the topmost local frame is the topmost // frame. If we push a non-local frame, there's no need to do anything. @@ -1443,8 +1443,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { } fn before_stack_pop( - ecx: &InterpCx<'mir, 'tcx, Self>, - frame: &Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>, + ecx: &InterpCx<'tcx, Self>, + frame: &Frame<'tcx, Self::Provenance, Self::FrameExtra>, ) -> InterpResult<'tcx> { // We want this *before* the return value copy, because the return place itself is protected // until we do `end_call` here. @@ -1460,8 +1460,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { #[inline(always)] fn after_stack_pop( - ecx: &mut InterpCx<'mir, 'tcx, Self>, - frame: Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>, + ecx: &mut InterpCx<'tcx, Self>, + frame: Frame<'tcx, Provenance, FrameExtra<'tcx>>, unwinding: bool, ) -> InterpResult<'tcx, StackPopJump> { if frame.extra.is_user_relevant { @@ -1490,7 +1490,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { } fn after_local_allocated( - ecx: &mut InterpCx<'mir, 'tcx, Self>, + ecx: &mut InterpCx<'tcx, Self>, local: mir::Local, mplace: &MPlaceTy<'tcx, Provenance>, ) -> InterpResult<'tcx> { @@ -1504,7 +1504,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { } fn eval_mir_constant( - ecx: &InterpCx<'mir, 'tcx, Self>, + ecx: &InterpCx<'tcx, Self>, val: mir::Const<'tcx>, span: Span, layout: Option>, @@ -1512,7 +1512,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { ) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>> where F: Fn( - &InterpCx<'mir, 'tcx, Self>, + &InterpCx<'tcx, Self>, mir::Const<'tcx>, Span, Option>, diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs index 7a008266dbc8..c04f12c339e0 100644 --- a/src/tools/miri/src/operator.rs +++ b/src/tools/miri/src/operator.rs @@ -7,8 +7,8 @@ use rustc_target::abi::Size; use crate::*; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn binary_ptr_op( &self, bin_op: mir::BinOp, diff --git a/src/tools/miri/src/provenance_gc.rs b/src/tools/miri/src/provenance_gc.rs index 5cc14e25ebdf..03b6cfdce7bc 100644 --- a/src/tools/miri/src/provenance_gc.rs +++ b/src/tools/miri/src/provenance_gc.rs @@ -144,7 +144,7 @@ impl VisitProvenance for Allocation, MiriAllocBytes> } } -impl VisitProvenance for crate::MiriInterpCx<'_, '_> { +impl VisitProvenance for crate::MiriInterpCx<'_> { fn visit_provenance(&self, visit: &mut VisitWith<'_>) { // Visit the contents of the allocations and the IDs themselves, to account for all // live allocation IDs and all provenance in the allocation bytes, even if they are leaked. @@ -162,19 +162,19 @@ impl VisitProvenance for crate::MiriInterpCx<'_, '_> { } } -pub struct LiveAllocs<'a, 'mir, 'tcx> { +pub struct LiveAllocs<'a, 'tcx> { collected: FxHashSet, - ecx: &'a MiriInterpCx<'mir, 'tcx>, + ecx: &'a MiriInterpCx<'tcx>, } -impl LiveAllocs<'_, '_, '_> { +impl LiveAllocs<'_, '_> { pub fn is_live(&self, id: AllocId) -> bool { self.collected.contains(&id) || self.ecx.is_alloc_live(id) } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> { fn run_provenance_gc(&mut self) { // We collect all tags from various parts of the interpreter, but also let this = self.eval_context_mut(); diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index ca672bdc611f..bbe4bdd8450c 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -17,8 +17,8 @@ pub(super) fn check_alloc_request<'tcx>(size: u64, align: u64) -> InterpResult<' Ok(()) } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Returns the alignment that `malloc` would guarantee for requests of the given size. fn malloc_align(&self, size: u64) -> Align { let this = self.eval_context_ref(); @@ -67,7 +67,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// Emulates calling the internal __rust_* allocator functions fn emulate_allocator( &mut self, - default: impl FnOnce(&mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx>, + default: impl FnOnce(&mut MiriInterpCx<'tcx>) -> InterpResult<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { let this = self.eval_context_mut(); diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index 294ad50c33f2..6ec65a16b8a4 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -5,8 +5,8 @@ use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{hygiene, BytePos, Loc, Symbol}; use rustc_target::{abi::Size, spec::abi::Abi}; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn handle_miri_backtrace_size( &mut self, abi: Abi, diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index 695d1138756c..7ad395cccb79 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -24,8 +24,8 @@ impl VisitProvenance for EnvVars<'_> { } impl<'tcx> EnvVars<'tcx> { - pub(crate) fn init<'mir>( - ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, + pub(crate) fn init( + ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>, config: &MiriConfig, ) -> InterpResult<'tcx> { // Initialize the `env_vars` map. @@ -58,9 +58,7 @@ impl<'tcx> EnvVars<'tcx> { Ok(()) } - pub(crate) fn cleanup<'mir>( - ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, - ) -> InterpResult<'tcx> { + pub(crate) fn cleanup(ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>) -> InterpResult<'tcx> { let this = ecx.eval_context_mut(); match this.machine.env_vars { EnvVars::Unix(_) => UnixEnvVars::cleanup(this), @@ -98,8 +96,8 @@ impl<'tcx> EnvVars<'tcx> { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Try to get an environment variable from the interpreted program's environment. This is /// useful for implementing shims which are documented to read from the environment. fn get_env_var(&mut self, name: &OsStr) -> InterpResult<'tcx, Option> { diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs index 390c29c9db7d..9330ac0b4dd8 100644 --- a/src/tools/miri/src/shims/extern_static.rs +++ b/src/tools/miri/src/shims/extern_static.rs @@ -2,9 +2,9 @@ use crate::*; -impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { +impl<'tcx> MiriMachine<'tcx> { fn alloc_extern_static( - this: &mut MiriInterpCx<'mir, 'tcx>, + this: &mut MiriInterpCx<'tcx>, name: &str, val: ImmTy<'tcx, Provenance>, ) -> InterpResult<'tcx> { @@ -19,7 +19,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { /// symbol is not supported, and triggering fallback code which ends up calling /// some other shim that we do support). fn null_ptr_extern_statics( - this: &mut MiriInterpCx<'mir, 'tcx>, + this: &mut MiriInterpCx<'tcx>, names: &[&str], ) -> InterpResult<'tcx> { for name in names { @@ -31,7 +31,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { /// Extern statics that are initialized with function pointers to the symbols of the same name. fn weak_symbol_extern_statics( - this: &mut MiriInterpCx<'mir, 'tcx>, + this: &mut MiriInterpCx<'tcx>, names: &[&str], ) -> InterpResult<'tcx> { for name in names { @@ -45,7 +45,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { } /// Sets up the "extern statics" for this machine. - pub fn init_extern_statics(this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> { + pub fn init_extern_statics(this: &mut MiriInterpCx<'tcx>) -> InterpResult<'tcx> { // "__rust_no_alloc_shim_is_unstable" let val = ImmTy::from_int(0, this.machine.layouts.u8); // always 0, value does not matter Self::alloc_extern_static(this, "__rust_no_alloc_shim_is_unstable", val)?; diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index eccccb4a4497..6dfd9866cae9 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -28,8 +28,8 @@ impl DynSym { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Emulates calling a foreign item, failing if the item is not supported. /// This function will handle `goto_block` if needed. /// Returns Ok(None) if the foreign item was completely handled @@ -44,7 +44,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { dest: &MPlaceTy<'tcx, Provenance>, ret: Option, unwind: mir::UnwindAction, - ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> { + ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> { let this = self.eval_context_mut(); let tcx = this.tcx.tcx; @@ -137,7 +137,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn lookup_exported_symbol( &mut self, link_name: Symbol, - ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> { + ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> { let this = self.eval_context_mut(); let tcx = this.tcx.tcx; @@ -202,8 +202,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } -impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} +trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, @@ -455,7 +455,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Rust allocation "__rust_alloc" | "miri_alloc" => { - let default = |this: &mut MiriInterpCx<'mir, 'tcx>| { + let default = |this: &mut MiriInterpCx<'tcx>| { // Only call `check_shim` when `#[global_allocator]` isn't used. When that // macro is used, we act like no shim exists, so that the exported function can run. let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?; @@ -514,7 +514,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { }); } "__rust_dealloc" | "miri_dealloc" => { - let default = |this: &mut MiriInterpCx<'mir, 'tcx>| { + let default = |this: &mut MiriInterpCx<'tcx>| { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. let [ptr, old_size, align] = diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs index f9b8563b4b04..cc5cc75332aa 100644 --- a/src/tools/miri/src/shims/native_lib.rs +++ b/src/tools/miri/src/shims/native_lib.rs @@ -8,8 +8,8 @@ use rustc_target::abi::{Abi, HasDataLayout}; use crate::*; -impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} +trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Call native host function and return the output as an immediate. fn call_native_with_args<'a>( &mut self, @@ -122,8 +122,8 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Call the native host function, with supplied arguments. /// Needs to convert all the arguments from their Miri representations to /// a native form (through `libffi` call). diff --git a/src/tools/miri/src/shims/os_str.rs b/src/tools/miri/src/shims/os_str.rs index 5fcea9ced691..c00e4384bab4 100644 --- a/src/tools/miri/src/shims/os_str.rs +++ b/src/tools/miri/src/shims/os_str.rs @@ -30,8 +30,8 @@ pub fn bytes_to_os_str<'tcx>(bytes: &[u8]) -> InterpResult<'tcx, &OsStr> { Ok(OsStr::new(s)) } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Helper function to read an OsString from a null-terminated sequence of bytes, which is what /// the Unix APIs usually handle. fn read_os_str_from_c_str<'a>( @@ -40,7 +40,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, &'a OsStr> where 'tcx: 'a, - 'mir: 'a, { let this = self.eval_context_ref(); let bytes = this.read_c_str(ptr)?; @@ -55,7 +54,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, OsString> where 'tcx: 'a, - 'mir: 'a, { #[cfg(windows)] pub fn u16vec_to_osstring<'tcx>(u16_vec: Vec) -> InterpResult<'tcx, OsString> { @@ -183,7 +181,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, Cow<'a, Path>> where 'tcx: 'a, - 'mir: 'a, { let this = self.eval_context_ref(); let os_str = this.read_os_str_from_c_str(ptr)?; diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs index e0e5396a455f..8aed6d4f463f 100644 --- a/src/tools/miri/src/shims/panic.rs +++ b/src/tools/miri/src/shims/panic.rs @@ -41,8 +41,8 @@ impl VisitProvenance for CatchUnwindData<'_> { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Handles the special `miri_start_unwind` intrinsic, which is called /// by libpanic_unwind to delegate the actual unwinding process to Miri. fn handle_miri_start_unwind(&mut self, payload: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> { diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs index 5c43563fac42..9fb7a735c30b 100644 --- a/src/tools/miri/src/shims/time.rs +++ b/src/tools/miri/src/shims/time.rs @@ -14,8 +14,8 @@ pub fn system_time_to_duration<'tcx>(time: &SystemTime) -> InterpResult<'tcx, Du .map_err(|_| err_unsup_format!("times before the Unix epoch are not supported").into()) } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn clock_gettime( &mut self, clk_id_op: &OpTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs index 3dc85cc70be8..fa52b036ce94 100644 --- a/src/tools/miri/src/shims/tls.rs +++ b/src/tools/miri/src/shims/tls.rs @@ -235,7 +235,7 @@ enum TlsDtorsStatePriv<'tcx> { impl<'tcx> TlsDtorsState<'tcx> { pub fn on_stack_empty( &mut self, - this: &mut MiriInterpCx<'_, 'tcx>, + this: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, Poll<()>> { use TlsDtorsStatePriv::*; let new_state = 'new_state: { @@ -293,8 +293,8 @@ impl<'tcx> TlsDtorsState<'tcx> { } } -impl<'mir, 'tcx: 'mir> EvalContextPrivExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextPrivExt<'tcx> for crate::MiriInterpCx<'tcx> {} +trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Schedule TLS destructors for Windows. /// On windows, TLS destructors are managed by std. fn lookup_windows_tls_dtors(&mut self) -> InterpResult<'tcx, Vec>> { diff --git a/src/tools/miri/src/shims/unix/android/foreign_items.rs b/src/tools/miri/src/shims/unix/android/foreign_items.rs index 590a5672f156..8a6e025ee18f 100644 --- a/src/tools/miri/src/shims/unix/android/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs @@ -7,8 +7,8 @@ pub fn is_dyn_sym(_name: &str) -> bool { false } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs index 6fcfb6939153..26096910aa19 100644 --- a/src/tools/miri/src/shims/unix/env.rs +++ b/src/tools/miri/src/shims/unix/env.rs @@ -31,8 +31,8 @@ impl VisitProvenance for UnixEnvVars<'_> { } impl<'tcx> UnixEnvVars<'tcx> { - pub(crate) fn new<'mir>( - ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, + pub(crate) fn new( + ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>, env_vars: FxHashMap, ) -> InterpResult<'tcx, Self> { // Allocate memory for all these env vars. @@ -51,9 +51,7 @@ impl<'tcx> UnixEnvVars<'tcx> { Ok(UnixEnvVars { map: env_vars_machine, environ }) } - pub(crate) fn cleanup<'mir>( - ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, - ) -> InterpResult<'tcx> { + pub(crate) fn cleanup(ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>) -> InterpResult<'tcx> { // Deallocate individual env vars. let env_vars = mem::take(&mut ecx.machine.env_vars.unix_mut().map); for (_name, ptr) in env_vars { @@ -71,9 +69,9 @@ impl<'tcx> UnixEnvVars<'tcx> { self.environ.ptr() } - fn get_ptr<'mir>( + fn get_ptr( &self, - ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, + ecx: &InterpCx<'tcx, MiriMachine<'tcx>>, name: &OsStr, ) -> InterpResult<'tcx, Option>>> { // We don't care about the value as we have the `map` to keep track of everything, @@ -92,9 +90,9 @@ impl<'tcx> UnixEnvVars<'tcx> { /// Implementation detail for [`InterpCx::get_env_var`]. This basically does `getenv`, complete /// with the reads of the environment, but returns an [`OsString`] instead of a pointer. - pub(crate) fn get<'mir>( + pub(crate) fn get( &self, - ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, + ecx: &InterpCx<'tcx, MiriMachine<'tcx>>, name: &OsStr, ) -> InterpResult<'tcx, Option> { let var_ptr = self.get_ptr(ecx, name)?; @@ -107,8 +105,8 @@ impl<'tcx> UnixEnvVars<'tcx> { } } -fn alloc_env_var<'mir, 'tcx>( - ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, +fn alloc_env_var<'tcx>( + ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>, name: &OsStr, value: &OsStr, ) -> InterpResult<'tcx, Pointer>> { @@ -119,8 +117,8 @@ fn alloc_env_var<'mir, 'tcx>( } /// Allocates an `environ` block with the given list of pointers. -fn alloc_environ_block<'mir, 'tcx>( - ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, +fn alloc_environ_block<'tcx>( + ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>, mut vars: Vec>>, ) -> InterpResult<'tcx, Pointer>> { // Add trailing null. @@ -139,8 +137,8 @@ fn alloc_environ_block<'mir, 'tcx>( Ok(vars_place.ptr()) } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn getenv( &mut self, name_op: &OpTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs index 8159960f8268..5fdd77a0cbdb 100644 --- a/src/tools/miri/src/shims/unix/fd.rs +++ b/src/tools/miri/src/shims/unix/fd.rs @@ -21,7 +21,7 @@ pub trait FileDescription: std::fmt::Debug + Any { &mut self, _communicate_allowed: bool, _bytes: &mut [u8], - _ecx: &mut MiriInterpCx<'_, 'tcx>, + _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result> { throw_unsup_format!("cannot read from {}", self.name()); } @@ -31,7 +31,7 @@ pub trait FileDescription: std::fmt::Debug + Any { &mut self, _communicate_allowed: bool, _bytes: &[u8], - _ecx: &mut MiriInterpCx<'_, 'tcx>, + _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result> { throw_unsup_format!("cannot write to {}", self.name()); } @@ -81,7 +81,7 @@ impl FileDescription for io::Stdin { &mut self, communicate_allowed: bool, bytes: &mut [u8], - _ecx: &mut MiriInterpCx<'_, 'tcx>, + _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result> { if !communicate_allowed { // We want isolation mode to be deterministic, so we have to disallow all reads, even stdin. @@ -104,7 +104,7 @@ impl FileDescription for io::Stdout { &mut self, _communicate_allowed: bool, bytes: &[u8], - _ecx: &mut MiriInterpCx<'_, 'tcx>, + _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result> { // We allow writing to stderr even with isolation enabled. let result = Write::write(self, bytes); @@ -132,7 +132,7 @@ impl FileDescription for io::Stderr { &mut self, _communicate_allowed: bool, bytes: &[u8], - _ecx: &mut MiriInterpCx<'_, 'tcx>, + _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result> { // We allow writing to stderr even with isolation enabled. // No need to flush, stderr is not buffered. @@ -157,7 +157,7 @@ impl FileDescription for NullOutput { &mut self, _communicate_allowed: bool, bytes: &[u8], - _ecx: &mut MiriInterpCx<'_, 'tcx>, + _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result> { // We just don't write anything, but report to the user that we did. Ok(Ok(bytes.len())) @@ -271,8 +271,8 @@ impl FdTable { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn fcntl(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index e75df88876b5..052715e239f2 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -37,8 +37,8 @@ pub fn is_dyn_sym(name: &str, target_os: &str) -> bool { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, @@ -326,7 +326,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let name = this.read_scalar(name)?.to_i32()?; // FIXME: Which of these are POSIX, and which are GNU/Linux? // At least the names seem to all also exist on macOS. - let sysconfs: &[(&str, fn(&MiriInterpCx<'_, '_>) -> Scalar)] = &[ + let sysconfs: &[(&str, fn(&MiriInterpCx<'_>) -> Scalar)] = &[ ("_SC_PAGESIZE", |this| Scalar::from_int(this.machine.page_size, this.pointer_size())), ("_SC_NPROCESSORS_CONF", |this| Scalar::from_int(this.machine.num_cpus, this.pointer_size())), ("_SC_NPROCESSORS_ONLN", |this| Scalar::from_int(this.machine.num_cpus, this.pointer_size())), diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs index 8a7f7e9d1fd8..30eb88151e4b 100644 --- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs @@ -8,8 +8,8 @@ pub fn is_dyn_sym(_name: &str) -> bool { false } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 5b0c1b2bafe7..8e3d547b0750 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -33,7 +33,7 @@ impl FileDescription for FileHandle { &mut self, communicate_allowed: bool, bytes: &mut [u8], - _ecx: &mut MiriInterpCx<'_, 'tcx>, + _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result> { assert!(communicate_allowed, "isolation should have prevented even opening a file"); Ok(self.file.read(bytes)) @@ -43,7 +43,7 @@ impl FileDescription for FileHandle { &mut self, communicate_allowed: bool, bytes: &[u8], - _ecx: &mut MiriInterpCx<'_, 'tcx>, + _ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result> { assert!(communicate_allowed, "isolation should have prevented even opening a file"); Ok(self.file.write(bytes)) @@ -86,8 +86,8 @@ impl FileDescription for FileHandle { } } -impl<'mir, 'tcx: 'mir> EvalContextExtPrivate<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -trait EvalContextExtPrivate<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExtPrivate<'tcx> for crate::MiriInterpCx<'tcx> {} +trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> { fn macos_stat_write_buf( &mut self, metadata: FileMetadata, @@ -254,8 +254,8 @@ fn maybe_sync_file( } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn open(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> { if args.len() < 2 { throw_ub_format!( @@ -1540,7 +1540,7 @@ struct FileMetadata { impl FileMetadata { fn from_path<'tcx>( - ecx: &mut MiriInterpCx<'_, 'tcx>, + ecx: &mut MiriInterpCx<'tcx>, path: &Path, follow_symlink: bool, ) -> InterpResult<'tcx, Option> { @@ -1551,7 +1551,7 @@ impl FileMetadata { } fn from_fd<'tcx>( - ecx: &mut MiriInterpCx<'_, 'tcx>, + ecx: &mut MiriInterpCx<'tcx>, fd: i32, ) -> InterpResult<'tcx, Option> { let Some(file_descriptor) = ecx.machine.fds.get(fd) else { @@ -1573,7 +1573,7 @@ impl FileMetadata { } fn from_meta<'tcx>( - ecx: &mut MiriInterpCx<'_, 'tcx>, + ecx: &mut MiriInterpCx<'tcx>, metadata: Result, ) -> InterpResult<'tcx, Option> { let metadata = match metadata { diff --git a/src/tools/miri/src/shims/unix/linux/epoll.rs b/src/tools/miri/src/shims/unix/linux/epoll.rs index 48a0ba019760..50868e60e951 100644 --- a/src/tools/miri/src/shims/unix/linux/epoll.rs +++ b/src/tools/miri/src/shims/unix/linux/epoll.rs @@ -44,8 +44,8 @@ impl FileDescription for Epoll { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// This function returns a file descriptor referring to the new `Epoll` instance. This file /// descriptor is used for all subsequent calls to the epoll interface. If the `flags` argument /// is 0, then this function is the same as `epoll_create()`. diff --git a/src/tools/miri/src/shims/unix/linux/eventfd.rs b/src/tools/miri/src/shims/unix/linux/eventfd.rs index f31c2bb84aee..1447e498fd7d 100644 --- a/src/tools/miri/src/shims/unix/linux/eventfd.rs +++ b/src/tools/miri/src/shims/unix/linux/eventfd.rs @@ -51,7 +51,7 @@ impl FileDescription for Event { &mut self, _communicate_allowed: bool, bytes: &[u8], - ecx: &mut MiriInterpCx<'_, 'tcx>, + ecx: &mut MiriInterpCx<'tcx>, ) -> InterpResult<'tcx, io::Result> { let bytes: [u8; 8] = bytes.try_into().unwrap(); // FIXME fail gracefully when this has the wrong size // Convert from target endianness to host endianness. @@ -66,8 +66,8 @@ impl FileDescription for Event { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// This function creates an `Event` that is used as an event wait/notify mechanism by /// user-space applications, and by the kernel to notify user-space applications of events. /// The `Event` contains an `u64` counter maintained by the kernel. The counter is initialized diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index b2666101ff29..7d0c8be1eaa0 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -14,8 +14,8 @@ pub fn is_dyn_sym(name: &str) -> bool { matches!(name, "statx") } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, diff --git a/src/tools/miri/src/shims/unix/linux/mem.rs b/src/tools/miri/src/shims/unix/linux/mem.rs index 3948216f7297..5f5d2b0c739d 100644 --- a/src/tools/miri/src/shims/unix/linux/mem.rs +++ b/src/tools/miri/src/shims/unix/linux/mem.rs @@ -4,8 +4,8 @@ use crate::*; use rustc_target::abi::Size; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn mremap( &mut self, old_address: &OpTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/shims/unix/linux/sync.rs b/src/tools/miri/src/shims/unix/linux/sync.rs index 2c7c4dd65cef..de83a358db92 100644 --- a/src/tools/miri/src/shims/unix/linux/sync.rs +++ b/src/tools/miri/src/shims/unix/linux/sync.rs @@ -5,7 +5,7 @@ use crate::*; /// Implementation of the SYS_futex syscall. /// `args` is the arguments *after* the syscall number. pub fn futex<'tcx>( - this: &mut MiriInterpCx<'_, 'tcx>, + this: &mut MiriInterpCx<'tcx>, args: &[OpTy<'tcx, Provenance>], dest: &MPlaceTy<'tcx, Provenance>, ) -> InterpResult<'tcx> { diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index 7c489ec4e3c8..a1e9ccec676e 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -8,8 +8,8 @@ pub fn is_dyn_sym(_name: &str) -> bool { false } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, diff --git a/src/tools/miri/src/shims/unix/mem.rs b/src/tools/miri/src/shims/unix/mem.rs index 89d04bb737ef..4d727c0b1804 100644 --- a/src/tools/miri/src/shims/unix/mem.rs +++ b/src/tools/miri/src/shims/unix/mem.rs @@ -17,8 +17,8 @@ use crate::*; use rustc_target::abi::Size; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn mmap( &mut self, addr: &OpTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/shims/unix/socket.rs b/src/tools/miri/src/shims/unix/socket.rs index 11fd83f57e67..a0fa3bcee342 100644 --- a/src/tools/miri/src/shims/unix/socket.rs +++ b/src/tools/miri/src/shims/unix/socket.rs @@ -24,8 +24,8 @@ impl FileDescription for SocketPair { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Currently this function this function is a stub. Eventually we need to /// properly implement an FD type for sockets and have this function create /// two sockets and associated FDs such that writing to one will produce diff --git a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs index d852b3537aa2..93427b05d2d8 100644 --- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs @@ -8,8 +8,8 @@ pub fn is_dyn_sym(name: &str) -> bool { matches!(name, "pthread_setname_np") } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index b2864269b2ee..304c1386370c 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -10,17 +10,15 @@ use crate::*; // - kind: i32 #[inline] -fn mutexattr_kind_offset<'mir, 'tcx: 'mir>( - ecx: &MiriInterpCx<'mir, 'tcx>, -) -> InterpResult<'tcx, u64> { +fn mutexattr_kind_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> { Ok(match &*ecx.tcx.sess.target.os { "linux" | "illumos" | "solaris" | "macos" => 0, os => throw_unsup_format!("`pthread_mutexattr` is not supported on {os}"), }) } -fn mutexattr_get_kind<'mir, 'tcx: 'mir>( - ecx: &MiriInterpCx<'mir, 'tcx>, +fn mutexattr_get_kind<'tcx>( + ecx: &MiriInterpCx<'tcx>, attr_op: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, i32> { ecx.deref_pointer_and_read( @@ -32,8 +30,8 @@ fn mutexattr_get_kind<'mir, 'tcx: 'mir>( .to_i32() } -fn mutexattr_set_kind<'mir, 'tcx: 'mir>( - ecx: &mut MiriInterpCx<'mir, 'tcx>, +fn mutexattr_set_kind<'tcx>( + ecx: &mut MiriInterpCx<'tcx>, attr_op: &OpTy<'tcx, Provenance>, kind: i32, ) -> InterpResult<'tcx, ()> { @@ -53,17 +51,11 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>( /// in `pthread_mutexattr_settype` function. const PTHREAD_MUTEX_NORMAL_FLAG: i32 = 0x8000000; -fn is_mutex_kind_default<'mir, 'tcx: 'mir>( - ecx: &MiriInterpCx<'mir, 'tcx>, - kind: i32, -) -> InterpResult<'tcx, bool> { +fn is_mutex_kind_default<'tcx>(ecx: &MiriInterpCx<'tcx>, kind: i32) -> InterpResult<'tcx, bool> { Ok(kind == ecx.eval_libc_i32("PTHREAD_MUTEX_DEFAULT")) } -fn is_mutex_kind_normal<'mir, 'tcx: 'mir>( - ecx: &MiriInterpCx<'mir, 'tcx>, - kind: i32, -) -> InterpResult<'tcx, bool> { +fn is_mutex_kind_normal<'tcx>(ecx: &MiriInterpCx<'tcx>, kind: i32) -> InterpResult<'tcx, bool> { let mutex_normal_kind = ecx.eval_libc_i32("PTHREAD_MUTEX_NORMAL"); Ok(kind == (mutex_normal_kind | PTHREAD_MUTEX_NORMAL_FLAG)) } @@ -73,7 +65,7 @@ fn is_mutex_kind_normal<'mir, 'tcx: 'mir>( // - id: u32 // - kind: i32 -fn mutex_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx, u64> { +fn mutex_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> { let offset = match &*ecx.tcx.sess.target.os { "linux" | "illumos" | "solaris" => 0, // macOS stores a signature in the first bytes, so we have to move to offset 4. @@ -99,7 +91,7 @@ fn mutex_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> InterpRe Ok(offset) } -fn mutex_kind_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 { +fn mutex_kind_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> u64 { // These offsets are picked for compatibility with Linux's static initializer // macros, e.g. PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP.) let offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 }; @@ -123,8 +115,8 @@ fn mutex_kind_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 { offset } -fn mutex_get_id<'mir, 'tcx: 'mir>( - ecx: &mut MiriInterpCx<'mir, 'tcx>, +fn mutex_get_id<'tcx>( + ecx: &mut MiriInterpCx<'tcx>, mutex_op: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, MutexId> { ecx.mutex_get_or_create_id( @@ -134,8 +126,8 @@ fn mutex_get_id<'mir, 'tcx: 'mir>( ) } -fn mutex_reset_id<'mir, 'tcx: 'mir>( - ecx: &mut MiriInterpCx<'mir, 'tcx>, +fn mutex_reset_id<'tcx>( + ecx: &mut MiriInterpCx<'tcx>, mutex_op: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, ()> { ecx.deref_pointer_and_write( @@ -147,8 +139,8 @@ fn mutex_reset_id<'mir, 'tcx: 'mir>( ) } -fn mutex_get_kind<'mir, 'tcx: 'mir>( - ecx: &MiriInterpCx<'mir, 'tcx>, +fn mutex_get_kind<'tcx>( + ecx: &MiriInterpCx<'tcx>, mutex_op: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, i32> { ecx.deref_pointer_and_read( @@ -160,8 +152,8 @@ fn mutex_get_kind<'mir, 'tcx: 'mir>( .to_i32() } -fn mutex_set_kind<'mir, 'tcx: 'mir>( - ecx: &mut MiriInterpCx<'mir, 'tcx>, +fn mutex_set_kind<'tcx>( + ecx: &mut MiriInterpCx<'tcx>, mutex_op: &OpTy<'tcx, Provenance>, kind: i32, ) -> InterpResult<'tcx, ()> { @@ -178,7 +170,7 @@ fn mutex_set_kind<'mir, 'tcx: 'mir>( // We ignore the platform layout and store our own fields: // - id: u32 -fn rwlock_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx, u64> { +fn rwlock_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> { let offset = match &*ecx.tcx.sess.target.os { "linux" | "illumos" | "solaris" => 0, // macOS stores a signature in the first bytes, so we have to move to offset 4. @@ -204,8 +196,8 @@ fn rwlock_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> InterpR Ok(offset) } -fn rwlock_get_id<'mir, 'tcx: 'mir>( - ecx: &mut MiriInterpCx<'mir, 'tcx>, +fn rwlock_get_id<'tcx>( + ecx: &mut MiriInterpCx<'tcx>, rwlock_op: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, RwLockId> { ecx.rwlock_get_or_create_id( @@ -220,9 +212,7 @@ fn rwlock_get_id<'mir, 'tcx: 'mir>( // - clock: i32 #[inline] -fn condattr_clock_offset<'mir, 'tcx: 'mir>( - ecx: &MiriInterpCx<'mir, 'tcx>, -) -> InterpResult<'tcx, u64> { +fn condattr_clock_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> { Ok(match &*ecx.tcx.sess.target.os { "linux" | "illumos" | "solaris" => 0, // macOS does not have a clock attribute. @@ -230,8 +220,8 @@ fn condattr_clock_offset<'mir, 'tcx: 'mir>( }) } -fn condattr_get_clock_id<'mir, 'tcx: 'mir>( - ecx: &MiriInterpCx<'mir, 'tcx>, +fn condattr_get_clock_id<'tcx>( + ecx: &MiriInterpCx<'tcx>, attr_op: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, i32> { ecx.deref_pointer_and_read( @@ -243,8 +233,8 @@ fn condattr_get_clock_id<'mir, 'tcx: 'mir>( .to_i32() } -fn condattr_set_clock_id<'mir, 'tcx: 'mir>( - ecx: &mut MiriInterpCx<'mir, 'tcx>, +fn condattr_set_clock_id<'tcx>( + ecx: &mut MiriInterpCx<'tcx>, attr_op: &OpTy<'tcx, Provenance>, clock_id: i32, ) -> InterpResult<'tcx, ()> { @@ -262,7 +252,7 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>( // - id: u32 // - clock: i32 -fn cond_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx, u64> { +fn cond_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> { let offset = match &*ecx.tcx.sess.target.os { "linux" | "illumos" | "solaris" => 0, // macOS stores a signature in the first bytes, so we have to move to offset 4. @@ -289,7 +279,7 @@ fn cond_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> InterpRes } /// Determines whether this clock represents the real-time clock, CLOCK_REALTIME. -fn is_cond_clock_realtime<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>, clock_id: i32) -> bool { +fn is_cond_clock_realtime<'tcx>(ecx: &MiriInterpCx<'tcx>, clock_id: i32) -> bool { // To ensure compatibility with PTHREAD_COND_INITIALIZER on all platforms, // we can't just compare with CLOCK_REALTIME: on Solarish, PTHREAD_COND_INITIALIZER // makes the clock 0 but CLOCK_REALTIME is 3. @@ -298,7 +288,7 @@ fn is_cond_clock_realtime<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>, cloc || (clock_id == 0 && clock_id != ecx.eval_libc_i32("CLOCK_MONOTONIC")) } -fn cond_clock_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 { +fn cond_clock_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> u64 { // macOS doesn't have a clock attribute, but to keep the code uniform we store // a clock ID in the pthread_cond_t anyway. There's enough space. let offset = 8; @@ -321,8 +311,8 @@ fn cond_clock_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 { offset } -fn cond_get_id<'mir, 'tcx: 'mir>( - ecx: &mut MiriInterpCx<'mir, 'tcx>, +fn cond_get_id<'tcx>( + ecx: &mut MiriInterpCx<'tcx>, cond_op: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, CondvarId> { ecx.condvar_get_or_create_id( @@ -332,8 +322,8 @@ fn cond_get_id<'mir, 'tcx: 'mir>( ) } -fn cond_reset_id<'mir, 'tcx: 'mir>( - ecx: &mut MiriInterpCx<'mir, 'tcx>, +fn cond_reset_id<'tcx>( + ecx: &mut MiriInterpCx<'tcx>, cond_op: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, ()> { ecx.deref_pointer_and_write( @@ -345,8 +335,8 @@ fn cond_reset_id<'mir, 'tcx: 'mir>( ) } -fn cond_get_clock_id<'mir, 'tcx: 'mir>( - ecx: &MiriInterpCx<'mir, 'tcx>, +fn cond_get_clock_id<'tcx>( + ecx: &MiriInterpCx<'tcx>, cond_op: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, i32> { ecx.deref_pointer_and_read( @@ -358,8 +348,8 @@ fn cond_get_clock_id<'mir, 'tcx: 'mir>( .to_i32() } -fn cond_set_clock_id<'mir, 'tcx: 'mir>( - ecx: &mut MiriInterpCx<'mir, 'tcx>, +fn cond_set_clock_id<'tcx>( + ecx: &mut MiriInterpCx<'tcx>, cond_op: &OpTy<'tcx, Provenance>, clock_id: i32, ) -> InterpResult<'tcx, ()> { @@ -372,8 +362,8 @@ fn cond_set_clock_id<'mir, 'tcx: 'mir>( ) } -impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn pthread_mutexattr_init( &mut self, attr_op: &OpTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/shims/unix/thread.rs b/src/tools/miri/src/shims/unix/thread.rs index f8787ad90e0c..323b5c1992eb 100644 --- a/src/tools/miri/src/shims/unix/thread.rs +++ b/src/tools/miri/src/shims/unix/thread.rs @@ -2,8 +2,8 @@ use crate::*; use rustc_middle::ty::layout::LayoutOf; use rustc_target::spec::abi::Abi; -impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn pthread_create( &mut self, thread: &OpTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/shims/wasi/foreign_items.rs b/src/tools/miri/src/shims/wasi/foreign_items.rs index 774a5e720254..b81b35bd963e 100644 --- a/src/tools/miri/src/shims/wasi/foreign_items.rs +++ b/src/tools/miri/src/shims/wasi/foreign_items.rs @@ -8,8 +8,8 @@ pub fn is_dyn_sym(_name: &str) -> bool { false } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, diff --git a/src/tools/miri/src/shims/windows/env.rs b/src/tools/miri/src/shims/windows/env.rs index 0e52959b762e..488a05366d23 100644 --- a/src/tools/miri/src/shims/windows/env.rs +++ b/src/tools/miri/src/shims/windows/env.rs @@ -20,8 +20,8 @@ impl VisitProvenance for WindowsEnvVars { } impl WindowsEnvVars { - pub(crate) fn new<'mir, 'tcx>( - _ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, + pub(crate) fn new<'tcx>( + _ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>, env_vars: FxHashMap, ) -> InterpResult<'tcx, Self> { Ok(Self { map: env_vars }) @@ -33,8 +33,8 @@ impl WindowsEnvVars { } } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { #[allow(non_snake_case)] fn GetEnvironmentVariableW( &mut self, diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 462c7ffcdccf..a60c2a337cfc 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -76,8 +76,8 @@ fn win_absolute<'tcx>(path: &Path) -> InterpResult<'tcx, io::Result> { Ok(path::absolute(bytes_to_os_str(&result)?)) } -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, diff --git a/src/tools/miri/src/shims/windows/handle.rs b/src/tools/miri/src/shims/windows/handle.rs index d9ae1b22409d..3e274a5b8028 100644 --- a/src/tools/miri/src/shims/windows/handle.rs +++ b/src/tools/miri/src/shims/windows/handle.rs @@ -145,10 +145,10 @@ impl Handle { } } -impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} #[allow(non_snake_case)] -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn invalid_handle(&mut self, function_name: &str) -> InterpResult<'tcx, !> { throw_machine_stop!(TerminationInfo::Abort(format!( "invalid handle passed to `{function_name}`" diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index e4307c33bb40..d5fe15b401bc 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -5,8 +5,8 @@ use rustc_target::abi::Size; use crate::concurrency::init_once::InitOnceStatus; use crate::*; -impl<'mir, 'tcx> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} +trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Windows sync primitives are pointer sized. // We only use the first 4 bytes for the id. @@ -44,9 +44,9 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } -impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} #[allow(non_snake_case)] -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn InitOnceBeginInitialize( &mut self, init_once_op: &OpTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/shims/windows/thread.rs b/src/tools/miri/src/shims/windows/thread.rs index 047f52f50be2..a9ef03d14ae4 100644 --- a/src/tools/miri/src/shims/windows/thread.rs +++ b/src/tools/miri/src/shims/windows/thread.rs @@ -4,10 +4,10 @@ use rustc_target::spec::abi::Abi; use crate::*; use shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle}; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} #[allow(non_snake_case)] -pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { +pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn CreateThread( &mut self, security_op: &OpTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/shims/x86/aesni.rs b/src/tools/miri/src/shims/x86/aesni.rs index 3a66c4315062..e7164d665113 100644 --- a/src/tools/miri/src/shims/x86/aesni.rs +++ b/src/tools/miri/src/shims/x86/aesni.rs @@ -5,10 +5,8 @@ use rustc_target::spec::abi::Abi; use crate::*; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: - crate::MiriInterpCxExt<'mir, 'tcx> -{ +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_aesni_intrinsic( &mut self, link_name: Symbol, @@ -134,7 +132,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: // Performs an AES round (given by `f`) on each 128-bit word of // `state` with the corresponding 128-bit key of `key`. fn aes_round<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, state: &OpTy<'tcx, Provenance>, key: &OpTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs index b1c61c8b3b2b..1a912f6ff5d7 100644 --- a/src/tools/miri/src/shims/x86/avx.rs +++ b/src/tools/miri/src/shims/x86/avx.rs @@ -12,10 +12,8 @@ use super::{ }; use crate::*; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: - crate::MiriInterpCxExt<'mir, 'tcx> -{ +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_avx_intrinsic( &mut self, link_name: Symbol, diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index e0bd2298ab8d..9b50da79edd2 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -10,10 +10,8 @@ use super::{ }; use crate::*; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: - crate::MiriInterpCxExt<'mir, 'tcx> -{ +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_avx2_intrinsic( &mut self, link_name: Symbol, diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 04ad979cf5d5..b5951e9e895b 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -20,10 +20,8 @@ mod sse3; mod sse41; mod ssse3; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: - crate::MiriInterpCxExt<'mir, 'tcx> -{ +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_intrinsic( &mut self, link_name: Symbol, @@ -200,7 +198,7 @@ impl FloatBinOp { /// Convert from the `imm` argument used to specify the comparison /// operation in intrinsics such as `llvm.x86.sse.cmp.ss`. fn cmp_from_imm<'tcx>( - this: &crate::MiriInterpCx<'_, 'tcx>, + this: &crate::MiriInterpCx<'tcx>, imm: i8, intrinsic: Symbol, ) -> InterpResult<'tcx, Self> { @@ -244,7 +242,7 @@ impl FloatBinOp { /// Performs `which` scalar operation on `left` and `right` and returns /// the result. fn bin_op_float<'tcx, F: rustc_apfloat::Float>( - this: &crate::MiriInterpCx<'_, 'tcx>, + this: &crate::MiriInterpCx<'tcx>, which: FloatBinOp, left: &ImmTy<'tcx, Provenance>, right: &ImmTy<'tcx, Provenance>, @@ -306,7 +304,7 @@ fn bin_op_float<'tcx, F: rustc_apfloat::Float>( /// Performs `which` operation on the first component of `left` and `right` /// and copies the other components from `left`. The result is stored in `dest`. fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, which: FloatBinOp, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, @@ -337,7 +335,7 @@ fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>( /// Performs `which` operation on each component of `left` and /// `right`, storing the result is stored in `dest`. fn bin_op_simd_float_all<'tcx, F: rustc_apfloat::Float>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, which: FloatBinOp, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, @@ -384,7 +382,7 @@ enum FloatUnaryOp { /// Performs `which` scalar operation on `op` and returns the result. #[allow(clippy::arithmetic_side_effects)] // floating point operations without side effects fn unary_op_f32<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, which: FloatUnaryOp, op: &ImmTy<'tcx, Provenance>, ) -> InterpResult<'tcx, Scalar> { @@ -418,7 +416,7 @@ fn unary_op_f32<'tcx>( /// Disturbes a floating-point result by a relative error on the order of (-2^scale, 2^scale). #[allow(clippy::arithmetic_side_effects)] // floating point arithmetic cannot panic fn apply_random_float_error( - this: &mut crate::MiriInterpCx<'_, '_>, + this: &mut crate::MiriInterpCx<'_>, val: F, err_scale: i32, ) -> F { @@ -435,7 +433,7 @@ fn apply_random_float_error( /// Performs `which` operation on the first component of `op` and copies /// the other components. The result is stored in `dest`. fn unary_op_ss<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, which: FloatUnaryOp, op: &OpTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>, @@ -458,7 +456,7 @@ fn unary_op_ss<'tcx>( /// Performs `which` operation on each component of `op`, storing the /// result is stored in `dest`. fn unary_op_ps<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, which: FloatUnaryOp, op: &OpTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>, @@ -495,7 +493,7 @@ enum ShiftOp { /// For arithmetic right-shifts, when right is larger than BITS - 1, the sign /// bit is copied to all bits. fn shift_simd_by_scalar<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, which: ShiftOp, @@ -551,7 +549,7 @@ fn shift_simd_by_scalar<'tcx>( /// For arithmetic right-shifts, when right is larger than BITS - 1, the sign /// bit is copied to all bits. fn shift_simd_by_simd<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, which: ShiftOp, @@ -603,7 +601,7 @@ fn shift_simd_by_simd<'tcx>( /// Takes a 128-bit vector, transmutes it to `[u64; 2]` and extracts /// the first value. fn extract_first_u64<'tcx>( - this: &crate::MiriInterpCx<'_, 'tcx>, + this: &crate::MiriInterpCx<'tcx>, op: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, u64> { // Transmute vector to `[u64; 2]` @@ -617,7 +615,7 @@ fn extract_first_u64<'tcx>( // Rounds the first element of `right` according to `rounding` // and copies the remaining elements from `left`. fn round_first<'tcx, F: rustc_apfloat::Float>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, rounding: &OpTy<'tcx, Provenance>, @@ -648,7 +646,7 @@ fn round_first<'tcx, F: rustc_apfloat::Float>( // Rounds all elements of `op` according to `rounding`. fn round_all<'tcx, F: rustc_apfloat::Float>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, op: &OpTy<'tcx, Provenance>, rounding: &OpTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>, @@ -700,7 +698,7 @@ fn rounding_from_imm<'tcx>(rounding: i32) -> InterpResult<'tcx, rustc_apfloat::R /// If `op` has more elements than `dest`, extra elements are ignored. If `op` /// has less elements than `dest`, the rest is filled with zeros. fn convert_float_to_int<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, op: &OpTy<'tcx, Provenance>, rnd: rustc_apfloat::Round, dest: &MPlaceTy<'tcx, Provenance>, @@ -735,7 +733,7 @@ fn convert_float_to_int<'tcx>( /// In case of overflow (when the operand is the minimum value), the operation /// will wrap around. fn int_abs<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, op: &OpTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>, ) -> InterpResult<'tcx, ()> { @@ -768,7 +766,7 @@ fn int_abs<'tcx>( /// * The third element is the `op` vector split into chunks, i.e, it's /// type is `[[T; M]; N]` where `T` is the element type of `op`. fn split_simd_to_128bit_chunks<'tcx, P: Projectable<'tcx, Provenance>>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, op: &P, ) -> InterpResult<'tcx, (u64, u64, P)> { let simd_layout = op.layout(); @@ -801,7 +799,7 @@ fn split_simd_to_128bit_chunks<'tcx, P: Projectable<'tcx, Provenance>>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn horizontal_bin_op<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, which: mir::BinOp, saturating: bool, left: &OpTy<'tcx, Provenance>, @@ -854,7 +852,7 @@ fn horizontal_bin_op<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit blocks of `left` and `right`). fn conditional_dot_product<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, imm: &OpTy<'tcx, Provenance>, @@ -912,7 +910,7 @@ fn conditional_dot_product<'tcx>( /// The first is true when all the bits of `op & mask` are zero. /// The second is true when `(op & mask) == mask` fn test_bits_masked<'tcx>( - this: &crate::MiriInterpCx<'_, 'tcx>, + this: &crate::MiriInterpCx<'tcx>, op: &OpTy<'tcx, Provenance>, mask: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, (bool, bool)> { @@ -943,7 +941,7 @@ fn test_bits_masked<'tcx>( /// The first is true when the highest bit of each element of `op & mask` is zero. /// The second is true when the highest bit of each element of `!op & mask` is zero. fn test_high_bits_masked<'tcx>( - this: &crate::MiriInterpCx<'_, 'tcx>, + this: &crate::MiriInterpCx<'tcx>, op: &OpTy<'tcx, Provenance>, mask: &OpTy<'tcx, Provenance>, ) -> InterpResult<'tcx, (bool, bool)> { @@ -974,7 +972,7 @@ fn test_high_bits_masked<'tcx>( /// Conditionally loads from `ptr` according the high bit of each /// element of `mask`. `ptr` does not need to be aligned. fn mask_load<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, ptr: &OpTy<'tcx, Provenance>, mask: &OpTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>, @@ -1007,7 +1005,7 @@ fn mask_load<'tcx>( /// Conditionally stores into `ptr` according the high bit of each /// element of `mask`. `ptr` does not need to be aligned. fn mask_store<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, ptr: &OpTy<'tcx, Provenance>, mask: &OpTy<'tcx, Provenance>, value: &OpTy<'tcx, Provenance>, @@ -1047,7 +1045,7 @@ fn mask_store<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn mpsadbw<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, imm: &OpTy<'tcx, Provenance>, @@ -1104,7 +1102,7 @@ fn mpsadbw<'tcx>( /// /// fn pmulhrsw<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>, @@ -1143,7 +1141,7 @@ fn pmulhrsw<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn pack_generic<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>, @@ -1188,7 +1186,7 @@ fn pack_generic<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn packsswb<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>, @@ -1207,7 +1205,7 @@ fn packsswb<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn packuswb<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>, @@ -1226,7 +1224,7 @@ fn packuswb<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn packssdw<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>, @@ -1245,7 +1243,7 @@ fn packssdw<'tcx>( /// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// 128-bit chunks of `left` and `right`). fn packusdw<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>, @@ -1262,7 +1260,7 @@ fn packusdw<'tcx>( /// is written to the corresponding output element. /// In other words, multiplies `left` with `right.signum()`. fn psign<'tcx>( - this: &mut crate::MiriInterpCx<'_, 'tcx>, + this: &mut crate::MiriInterpCx<'tcx>, left: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>, diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs index 3636fb2f3fbf..16c070818200 100644 --- a/src/tools/miri/src/shims/x86/sse.rs +++ b/src/tools/miri/src/shims/x86/sse.rs @@ -9,10 +9,8 @@ use super::{ }; use crate::*; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: - crate::MiriInterpCxExt<'mir, 'tcx> -{ +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse_intrinsic( &mut self, link_name: Symbol, diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 54d1e0c803bb..f8b512e7981c 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -8,10 +8,8 @@ use super::{ }; use crate::*; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: - crate::MiriInterpCxExt<'mir, 'tcx> -{ +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse2_intrinsic( &mut self, link_name: Symbol, diff --git a/src/tools/miri/src/shims/x86/sse3.rs b/src/tools/miri/src/shims/x86/sse3.rs index fa1dd07e90b4..58d27ef8f721 100644 --- a/src/tools/miri/src/shims/x86/sse3.rs +++ b/src/tools/miri/src/shims/x86/sse3.rs @@ -5,10 +5,8 @@ use rustc_target::spec::abi::Abi; use super::horizontal_bin_op; use crate::*; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: - crate::MiriInterpCxExt<'mir, 'tcx> -{ +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse3_intrinsic( &mut self, link_name: Symbol, diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs index cd82108678da..79f885ed0948 100644 --- a/src/tools/miri/src/shims/x86/sse41.rs +++ b/src/tools/miri/src/shims/x86/sse41.rs @@ -4,10 +4,8 @@ use rustc_target::spec::abi::Abi; use super::{conditional_dot_product, mpsadbw, packusdw, round_all, round_first, test_bits_masked}; use crate::*; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: - crate::MiriInterpCxExt<'mir, 'tcx> -{ +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse41_intrinsic( &mut self, link_name: Symbol, diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs index ec625da68c27..2bb9a8dec690 100644 --- a/src/tools/miri/src/shims/x86/ssse3.rs +++ b/src/tools/miri/src/shims/x86/ssse3.rs @@ -5,10 +5,8 @@ use rustc_target::spec::abi::Abi; use super::{horizontal_bin_op, int_abs, pmulhrsw, psign}; use crate::*; -impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} -pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: - crate::MiriInterpCxExt<'mir, 'tcx> -{ +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_ssse3_intrinsic( &mut self, link_name: Symbol, diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs index 46b0a5438025..d03d1936e086 100644 --- a/src/tools/opt-dist/src/tests.rs +++ b/src/tools/opt-dist/src/tests.rs @@ -59,26 +59,17 @@ pub fn run_tests(env: &Environment) -> anyhow::Result<()> { .join(format!("llvm-config{}", executable_extension())); assert!(llvm_config.is_file()); - let config_content = format!( - r#"profile = "user" -change-id = 115898 + let rustc = format!("build.rustc={}", rustc_path.to_string().replace('\\', "/")); + let cargo = format!("build.cargo={}", cargo_path.to_string().replace('\\', "/")); + let llvm_config = + format!("target.{host_triple}.llvm-config={}", llvm_config.to_string().replace('\\', "/")); -[build] -rustc = "{rustc}" -cargo = "{cargo}" - -[target.{host_triple}] -llvm-config = "{llvm_config}" -"#, - rustc = rustc_path.to_string().replace('\\', "/"), - cargo = cargo_path.to_string().replace('\\', "/"), - llvm_config = llvm_config.to_string().replace('\\', "/") - ); - log::info!("Using following `config.toml` for running tests:\n{config_content}"); + log::info!("Set the following configurations for running tests:"); + log::info!("\t{rustc}"); + log::info!("\t{cargo}"); + log::info!("\t{llvm_config}"); // Simulate a stage 0 compiler with the extracted optimized dist artifacts. - std::fs::write("config.toml", config_content)?; - let x_py = env.checkout_path().join("x.py"); let mut args = vec![ env.python_binary(), @@ -97,6 +88,12 @@ llvm-config = "{llvm_config}" "tests/run-pass-valgrind", "tests/ui", "tests/crashes", + "--set", + &rustc, + "--set", + &cargo, + "--set", + &llvm_config, ]; for test_path in env.skipped_tests() { args.extend(["--skip", test_path]); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs index 1fba2e2e4d34..f4564c94bb59 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs @@ -12,9 +12,6 @@ use std::sync::OnceLock; use rustc_hash::FxHashMap; -/// Ignored attribute namespaces used by tools. -pub const TOOL_MODULES: &[&str] = &["rustfmt", "clippy"]; - pub struct BuiltinAttribute { pub name: &'static str, pub template: AttributeTemplate, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs index 82f89393add6..c6d9ba6cfe45 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs @@ -17,7 +17,7 @@ use syntax::{ self, ArrayExprKind, AstChildren, BlockExpr, HasArgList, HasAttrs, HasLoopBody, HasName, RangeItem, SlicePatComponents, }, - AstNode, AstPtr, SyntaxNodePtr, + AstNode, AstPtr, AstToken as _, SyntaxNodePtr, }; use triomphe::Arc; @@ -1577,7 +1577,13 @@ impl ExprCollector<'_> { }); }); let template = f.template(); - let fmt_snippet = template.as_ref().map(ToString::to_string); + let fmt_snippet = template.as_ref().and_then(|it| match it { + ast::Expr::Literal(literal) => match literal.kind() { + ast::LiteralKind::String(s) => Some(s.text().to_owned()), + _ => None, + }, + _ => None, + }); let mut mappings = vec![]; let fmt = match template.and_then(|it| self.expand_macros_to_string(it)) { Some((s, is_direct_literal)) => format_args::parse( diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs index 4c8a54f7c8c7..e8b26d537345 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs @@ -150,7 +150,7 @@ fn desugar_builtin_format_args() { fn main() { let are = "are"; let count = 10; - builtin#format_args("hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", last = "!"); + builtin#format_args("\u{1b}hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", last = "!"); } "#, ); @@ -161,7 +161,7 @@ fn main() { let count = 10; builtin#lang(Arguments::new_v1_formatted)( &[ - "hello ", " ", " friends, we ", " ", "", + "\u{1b}hello ", " ", " friends, we ", " ", "", ], &[ builtin#lang(Argument::new_display)( diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs index 985c6387ba0b..f483efa85179 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/body/tests/block.rs @@ -528,3 +528,65 @@ fn f() {$0 "#]], ) } + +#[test] +fn resolve_extern_prelude_in_block() { + check_at( + r#" +//- /main.rs crate:main deps:core +fn main() { + mod f { + use core::S; + $0 + } +} + +//- /core.rs crate:core +pub struct S; + "#, + expect![[r#" + block scope + f: t + + block scope::f + S: ti vi + + crate + main: v + "#]], + ) +} + +#[test] +fn shadow_extern_prelude_in_block() { + check_at( + r#" +//- /main.rs crate:main deps:core +fn main() { + mod core { pub struct S; } + { + fn inner() {} // forces a block def map + use core::S; // should resolve to the local one + $0 + } +} + +//- /core.rs crate:core +pub const S; + "#, + expect![[r#" + block scope + S: ti vi + inner: v + + block scope + core: t + + block scope::core + S: t v + + crate + main: v + "#]], + ) +} diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index 4e57845a694d..d9495d36c0d9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs @@ -14,7 +14,7 @@ use crate::{ nameres::DefMap, path::{ModPath, PathKind}, visibility::{Visibility, VisibilityExplicitness}, - CrateRootModuleId, ModuleDefId, ModuleId, + ImportPathConfig, ModuleDefId, ModuleId, }; /// Find a path that can be used to refer to a certain item. This can depend on @@ -23,29 +23,12 @@ pub fn find_path( db: &dyn DefDatabase, item: ItemInNs, from: ModuleId, - prefer_no_std: bool, - prefer_prelude: bool, + prefix_kind: PrefixKind, + ignore_local_imports: bool, + cfg: ImportPathConfig, ) -> Option { let _p = tracing::span!(tracing::Level::INFO, "find_path").entered(); - find_path_inner(FindPathCtx { db, prefixed: None, prefer_no_std, prefer_prelude }, item, from) -} - -/// Find a path that can be used to refer to a certain item. This can depend on -/// *from where* you're referring to the item, hence the `from` parameter. -pub fn find_path_prefixed( - db: &dyn DefDatabase, - item: ItemInNs, - from: ModuleId, - prefix_kind: PrefixKind, - prefer_no_std: bool, - prefer_prelude: bool, -) -> Option { - let _p = tracing::span!(tracing::Level::INFO, "find_path_prefixed").entered(); - find_path_inner( - FindPathCtx { db, prefixed: Some(prefix_kind), prefer_no_std, prefer_prelude }, - item, - from, - ) + find_path_inner(FindPathCtx { db, prefix: prefix_kind, cfg, ignore_local_imports }, item, from) } #[derive(Copy, Clone, Debug)] @@ -70,7 +53,7 @@ pub enum PrefixKind { /// This is the same as plain, just that paths will start with `self` prepended if the path /// starts with an identifier that is not a crate. BySelf, - /// Causes paths to ignore imports in the local module. + /// Causes paths to not use a self, super or crate prefix. Plain, /// Causes paths to start with `crate` where applicable, effectively forcing paths to be absolute. ByCrate, @@ -78,48 +61,46 @@ pub enum PrefixKind { impl PrefixKind { #[inline] - fn prefix(self) -> PathKind { + fn path_kind(self) -> PathKind { match self { PrefixKind::BySelf => PathKind::Super(0), PrefixKind::Plain => PathKind::Plain, PrefixKind::ByCrate => PathKind::Crate, } } - - #[inline] - fn is_absolute(&self) -> bool { - self == &PrefixKind::ByCrate - } } #[derive(Copy, Clone)] struct FindPathCtx<'db> { db: &'db dyn DefDatabase, - prefixed: Option, - prefer_no_std: bool, - prefer_prelude: bool, + prefix: PrefixKind, + cfg: ImportPathConfig, + ignore_local_imports: bool, } /// Attempts to find a path to refer to the given `item` visible from the `from` ModuleId fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Option { // - if the item is a builtin, it's in scope if let ItemInNs::Types(ModuleDefId::BuiltinType(builtin)) = item { - return Some(ModPath::from_segments(PathKind::Plain, Some(builtin.as_name()))); + return Some(ModPath::from_segments(PathKind::Plain, iter::once(builtin.as_name()))); } let def_map = from.def_map(ctx.db); - let crate_root = def_map.crate_root(); + let crate_root = from.derive_crate_root(); // - if the item is a module, jump straight to module search if let ItemInNs::Types(ModuleDefId::ModuleId(module_id)) = item { let mut visited_modules = FxHashSet::default(); return find_path_for_module( FindPathCtx { - prefer_no_std: ctx.prefer_no_std || ctx.db.crate_supports_no_std(crate_root.krate), + cfg: ImportPathConfig { + prefer_no_std: ctx.cfg.prefer_no_std + || ctx.db.crate_supports_no_std(crate_root.krate), + ..ctx.cfg + }, ..ctx }, &def_map, &mut visited_modules, - crate_root, from, module_id, MAX_PATH_LEN, @@ -127,11 +108,20 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti .map(|(item, _)| item); } - // - if the item is already in scope, return the name under which it is - let scope_name = find_in_scope(ctx.db, &def_map, from, item); - if ctx.prefixed.is_none() { + let prefix = if item.module(ctx.db).is_some_and(|it| it.is_within_block()) { + PrefixKind::Plain + } else { + ctx.prefix + }; + let may_be_in_scope = match prefix { + PrefixKind::Plain | PrefixKind::BySelf => true, + PrefixKind::ByCrate => from.is_crate_root(), + }; + if may_be_in_scope { + // - if the item is already in scope, return the name under which it is + let scope_name = find_in_scope(ctx.db, &def_map, from, item, ctx.ignore_local_imports); if let Some(scope_name) = scope_name { - return Some(ModPath::from_segments(PathKind::Plain, Some(scope_name))); + return Some(ModPath::from_segments(prefix.path_kind(), iter::once(scope_name))); } } @@ -159,16 +149,18 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti calculate_best_path( FindPathCtx { - prefer_no_std: ctx.prefer_no_std || ctx.db.crate_supports_no_std(crate_root.krate), + cfg: ImportPathConfig { + prefer_no_std: ctx.cfg.prefer_no_std + || ctx.db.crate_supports_no_std(crate_root.krate), + ..ctx.cfg + }, ..ctx }, &def_map, &mut visited_modules, - crate_root, MAX_PATH_LEN, item, from, - scope_name, ) .map(|(item, _)| item) } @@ -178,7 +170,6 @@ fn find_path_for_module( ctx: FindPathCtx<'_>, def_map: &DefMap, visited_modules: &mut FxHashSet, - crate_root: CrateRootModuleId, from: ModuleId, module_id: ModuleId, max_len: usize, @@ -187,38 +178,25 @@ fn find_path_for_module( return None; } - // Base cases: - // - if the item is already in scope, return the name under which it is - let scope_name = find_in_scope(ctx.db, def_map, from, ItemInNs::Types(module_id.into())); - if ctx.prefixed.is_none() { - if let Some(scope_name) = scope_name { - return Some((ModPath::from_segments(PathKind::Plain, Some(scope_name)), Stable)); - } - } - + let is_crate_root = module_id.as_crate_root(); // - if the item is the crate root, return `crate` - if module_id == crate_root { + if is_crate_root.is_some_and(|it| it == from.derive_crate_root()) { return Some((ModPath::from_segments(PathKind::Crate, None), Stable)); } - // - if relative paths are fine, check if we are searching for a parent - if ctx.prefixed.filter(PrefixKind::is_absolute).is_none() { - if let modpath @ Some(_) = find_self_super(def_map, module_id, from) { - return modpath.zip(Some(Stable)); - } - } - + let root_def_map = from.derive_crate_root().def_map(ctx.db); // - if the item is the crate root of a dependency crate, return the name from the extern prelude - let root_def_map = crate_root.def_map(ctx.db); - for (name, (def_id, _extern_crate)) in root_def_map.extern_prelude() { - if module_id == def_id { - let name = scope_name.unwrap_or_else(|| name.clone()); - + if let Some(crate_root) = is_crate_root { + // rev here so we prefer looking at renamed extern decls first + for (name, (def_id, _extern_crate)) in root_def_map.extern_prelude().rev() { + if crate_root != def_id { + continue; + } let name_already_occupied_in_type_ns = def_map .with_ancestor_maps(ctx.db, from.local_id, &mut |def_map, local_id| { def_map[local_id] .scope - .type_(&name) + .type_(name) .filter(|&(id, _)| id != ModuleDefId::ModuleId(def_id.into())) }) .is_some(); @@ -228,24 +206,51 @@ fn find_path_for_module( } else { PathKind::Plain }; - return Some((ModPath::from_segments(kind, Some(name)), Stable)); + return Some((ModPath::from_segments(kind, iter::once(name.clone())), Stable)); + } + } + let prefix = if module_id.is_within_block() { PrefixKind::Plain } else { ctx.prefix }; + let may_be_in_scope = match prefix { + PrefixKind::Plain | PrefixKind::BySelf => true, + PrefixKind::ByCrate => from.is_crate_root(), + }; + if may_be_in_scope { + let scope_name = find_in_scope( + ctx.db, + def_map, + from, + ItemInNs::Types(module_id.into()), + ctx.ignore_local_imports, + ); + if let Some(scope_name) = scope_name { + // - if the item is already in scope, return the name under which it is + return Some(( + ModPath::from_segments(prefix.path_kind(), iter::once(scope_name)), + Stable, + )); } } - if let value @ Some(_) = + // - if the module can be referenced as self, super or crate, do that + if let Some(mod_path) = is_kw_kind_relative_to_from(def_map, module_id, from) { + if ctx.prefix != PrefixKind::ByCrate || mod_path.kind == PathKind::Crate { + return Some((mod_path, Stable)); + } + } + + // - if the module is in the prelude, return it by that path + if let Some(mod_path) = find_in_prelude(ctx.db, &root_def_map, def_map, ItemInNs::Types(module_id.into()), from) { - return value.zip(Some(Stable)); + return Some((mod_path, Stable)); } calculate_best_path( ctx, def_map, visited_modules, - crate_root, max_len, ItemInNs::Types(module_id.into()), from, - scope_name, ) } @@ -255,9 +260,13 @@ fn find_in_scope( def_map: &DefMap, from: ModuleId, item: ItemInNs, + ignore_local_imports: bool, ) -> Option { + // FIXME: We could have multiple applicable names here, but we currently only return the first def_map.with_ancestor_maps(db, from.local_id, &mut |def_map, local_id| { - def_map[local_id].scope.names_of(item, |name, _, _| Some(name.clone())) + def_map[local_id].scope.names_of(item, |name, _, declared| { + (declared || !ignore_local_imports).then(|| name.clone()) + }) }) } @@ -292,21 +301,32 @@ fn find_in_prelude( }); if found_and_same_def.unwrap_or(true) { - Some(ModPath::from_segments(PathKind::Plain, Some(name.clone()))) + Some(ModPath::from_segments(PathKind::Plain, iter::once(name.clone()))) } else { None } } -fn find_self_super(def_map: &DefMap, item: ModuleId, from: ModuleId) -> Option { +fn is_kw_kind_relative_to_from( + def_map: &DefMap, + item: ModuleId, + from: ModuleId, +) -> Option { + if item.krate != from.krate || item.is_within_block() || from.is_within_block() { + return None; + } + let item = item.local_id; + let from = from.local_id; if item == from { // - if the item is the module we're in, use `self` Some(ModPath::from_segments(PathKind::Super(0), None)) - } else if let Some(parent_id) = def_map[from.local_id].parent { - // - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly) - let parent_id = def_map.module_id(parent_id); + } else if let Some(parent_id) = def_map[from].parent { if item == parent_id { - Some(ModPath::from_segments(PathKind::Super(1), None)) + // - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly) + Some(ModPath::from_segments( + if parent_id == DefMap::ROOT { PathKind::Crate } else { PathKind::Super(1) }, + None, + )) } else { None } @@ -320,11 +340,9 @@ fn calculate_best_path( ctx: FindPathCtx<'_>, def_map: &DefMap, visited_modules: &mut FxHashSet, - crate_root: CrateRootModuleId, max_len: usize, item: ItemInNs, from: ModuleId, - scope_name: Option, ) -> Option<(ModPath, Stability)> { if max_len <= 1 { return None; @@ -346,14 +364,12 @@ fn calculate_best_path( // dependency in this case. for (module_id, name) in find_local_import_locations(ctx.db, item, from) { if !visited_modules.insert(module_id) { - cov_mark::hit!(recursive_imports); continue; } if let Some(mut path) = find_path_for_module( ctx, def_map, visited_modules, - crate_root, from, module_id, best_path_len - 1, @@ -361,9 +377,7 @@ fn calculate_best_path( path.0.push_segment(name); let new_path = match best_path.take() { - Some(best_path) => { - select_best_path(best_path, path, ctx.prefer_no_std, ctx.prefer_prelude) - } + Some(best_path) => select_best_path(best_path, path, ctx.cfg), None => path, }; best_path_len = new_path.0.len(); @@ -390,7 +404,6 @@ fn calculate_best_path( ctx, def_map, visited_modules, - crate_root, from, info.container, max_len - 1, @@ -406,31 +419,14 @@ fn calculate_best_path( ); let new_path_with_stab = match best_path.take() { - Some(best_path) => select_best_path( - best_path, - path_with_stab, - ctx.prefer_no_std, - ctx.prefer_prelude, - ), + Some(best_path) => select_best_path(best_path, path_with_stab, ctx.cfg), None => path_with_stab, }; update_best_path(&mut best_path, new_path_with_stab); } } } - let mut prefixed = ctx.prefixed; - if let Some(module) = item.module(ctx.db) { - if module.containing_block().is_some() && ctx.prefixed.is_some() { - cov_mark::hit!(prefixed_in_block_expression); - prefixed = Some(PrefixKind::Plain); - } - } - match prefixed.map(PrefixKind::prefix) { - Some(prefix) => best_path.or_else(|| { - scope_name.map(|scope_name| (ModPath::from_segments(prefix, Some(scope_name)), Stable)) - }), - None => best_path, - } + best_path } /// Select the best (most relevant) path between two paths. @@ -439,8 +435,7 @@ fn calculate_best_path( fn select_best_path( old_path @ (_, old_stability): (ModPath, Stability), new_path @ (_, new_stability): (ModPath, Stability), - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> (ModPath, Stability) { match (old_stability, new_stability) { (Stable, Unstable) => return old_path, @@ -454,7 +449,7 @@ fn select_best_path( let (old_path, _) = &old; let new_has_prelude = new_path.segments().iter().any(|seg| seg == &known::prelude); let old_has_prelude = old_path.segments().iter().any(|seg| seg == &known::prelude); - match (new_has_prelude, old_has_prelude, prefer_prelude) { + match (new_has_prelude, old_has_prelude, cfg.prefer_prelude) { (true, false, true) | (false, true, false) => new, (true, false, false) | (false, true, true) => old, // no prelude difference in the paths, so pick the shorter one @@ -475,7 +470,7 @@ fn select_best_path( match (old_path.0.segments().first(), new_path.0.segments().first()) { (Some(old), Some(new)) if STD_CRATES.contains(old) && STD_CRATES.contains(new) => { - let rank = match prefer_no_std { + let rank = match cfg.prefer_no_std { false => |name: &Name| match name { name if name == &known::core => 0, name if name == &known::alloc => 1, @@ -535,7 +530,6 @@ fn find_local_import_locations( if !seen.insert(module) { continue; // already processed this module } - let ext_def_map; let data = if module.krate == from.krate { if module.block.is_some() { @@ -571,7 +565,7 @@ fn find_local_import_locations( // what the user wants; and if this module can import // the item and we're a submodule of it, so can we. // Also this keeps the cached data smaller. - if is_pub_or_explicit || declared { + if declared || is_pub_or_explicit { locations.push((module, name.clone())); } } @@ -590,7 +584,10 @@ fn find_local_import_locations( #[cfg(test)] mod tests { + use expect_test::{expect, Expect}; use hir_expand::db::ExpandDatabase; + use itertools::Itertools; + use stdx::format_to; use syntax::ast::AstNode; use test_fixture::WithFixture; @@ -602,12 +599,7 @@ mod tests { /// item the `path` refers to returns that same path when called from the /// module the cursor is in. #[track_caller] - fn check_found_path_( - ra_fixture: &str, - path: &str, - prefix_kind: Option, - prefer_prelude: bool, - ) { + fn check_found_path_(ra_fixture: &str, path: &str, prefer_prelude: bool, expect: Expect) { let (db, pos) = TestDB::with_position(ra_fixture); let module = db.module_at_position(pos); let parsed_path_file = @@ -628,43 +620,47 @@ mod tests { crate::item_scope::BuiltinShadowMode::Module, None, ) - .0 + .0; + let resolved = resolved .take_types() - .expect("path does not resolve to a type"); + .map(ItemInNs::Types) + .or_else(|| resolved.take_values().map(ItemInNs::Values)) + .expect("path does not resolve to a type or value"); - let found_path = find_path_inner( - FindPathCtx { prefer_no_std: false, db: &db, prefixed: prefix_kind, prefer_prelude }, - ItemInNs::Types(resolved), - module, - ); - assert_eq!(found_path, Some(mod_path), "on kind: {prefix_kind:?}"); + let mut res = String::new(); + for (prefix, ignore_local_imports) in + [PrefixKind::Plain, PrefixKind::ByCrate, PrefixKind::BySelf] + .into_iter() + .cartesian_product([false, true]) + { + let found_path = find_path_inner( + FindPathCtx { + db: &db, + prefix, + cfg: ImportPathConfig { prefer_no_std: false, prefer_prelude }, + ignore_local_imports, + }, + resolved, + module, + ); + format_to!( + res, + "{:7}(imports {}): {}\n", + format!("{:?}", prefix), + if ignore_local_imports { '✖' } else { '✔' }, + found_path + .map_or_else(|| "".to_owned(), |it| it.display(&db).to_string()), + ); + } + expect.assert_eq(&res); } - #[track_caller] - fn check_found_path( - ra_fixture: &str, - unprefixed: &str, - prefixed: &str, - absolute: &str, - self_prefixed: &str, - ) { - check_found_path_(ra_fixture, unprefixed, None, false); - check_found_path_(ra_fixture, prefixed, Some(PrefixKind::Plain), false); - check_found_path_(ra_fixture, absolute, Some(PrefixKind::ByCrate), false); - check_found_path_(ra_fixture, self_prefixed, Some(PrefixKind::BySelf), false); + fn check_found_path(ra_fixture: &str, path: &str, expect: Expect) { + check_found_path_(ra_fixture, path, false, expect); } - fn check_found_path_prelude( - ra_fixture: &str, - unprefixed: &str, - prefixed: &str, - absolute: &str, - self_prefixed: &str, - ) { - check_found_path_(ra_fixture, unprefixed, None, true); - check_found_path_(ra_fixture, prefixed, Some(PrefixKind::Plain), true); - check_found_path_(ra_fixture, absolute, Some(PrefixKind::ByCrate), true); - check_found_path_(ra_fixture, self_prefixed, Some(PrefixKind::BySelf), true); + fn check_found_path_prelude(ra_fixture: &str, path: &str, expect: Expect) { + check_found_path_(ra_fixture, path, true, expect); } #[test] @@ -675,9 +671,14 @@ struct S; $0 "#, "S", - "S", - "crate::S", - "self::S", + expect![[r#" + Plain (imports ✔): S + Plain (imports ✖): S + ByCrate(imports ✔): crate::S + ByCrate(imports ✖): crate::S + BySelf (imports ✔): self::S + BySelf (imports ✖): self::S + "#]], ); } @@ -689,9 +690,14 @@ enum E { A } $0 "#, "E::A", - "E::A", - "crate::E::A", - "self::E::A", + expect![[r#" + Plain (imports ✔): E::A + Plain (imports ✖): E::A + ByCrate(imports ✔): crate::E::A + ByCrate(imports ✖): crate::E::A + BySelf (imports ✔): self::E::A + BySelf (imports ✖): self::E::A + "#]], ); } @@ -705,9 +711,14 @@ mod foo { $0 "#, "foo::S", - "foo::S", - "crate::foo::S", - "self::foo::S", + expect![[r#" + Plain (imports ✔): foo::S + Plain (imports ✖): foo::S + ByCrate(imports ✔): crate::foo::S + ByCrate(imports ✖): crate::foo::S + BySelf (imports ✔): self::foo::S + BySelf (imports ✖): self::foo::S + "#]], ); } @@ -724,9 +735,14 @@ struct S; $0 "#, "super::S", - "super::S", - "crate::foo::S", - "super::S", + expect![[r#" + Plain (imports ✔): super::S + Plain (imports ✖): super::S + ByCrate(imports ✔): crate::foo::S + ByCrate(imports ✖): crate::foo::S + BySelf (imports ✔): super::S + BySelf (imports ✖): super::S + "#]], ); } @@ -740,9 +756,14 @@ mod foo; $0 "#, "self", - "self", - "crate::foo", - "self", + expect![[r#" + Plain (imports ✔): self + Plain (imports ✖): self + ByCrate(imports ✔): crate::foo + ByCrate(imports ✖): crate::foo + BySelf (imports ✔): self + BySelf (imports ✖): self + "#]], ); } @@ -756,9 +777,14 @@ mod foo; $0 "#, "crate", - "crate", - "crate", - "crate", + expect![[r#" + Plain (imports ✔): crate + Plain (imports ✖): crate + ByCrate(imports ✔): crate + ByCrate(imports ✖): crate + BySelf (imports ✔): crate + BySelf (imports ✖): crate + "#]], ); } @@ -773,9 +799,14 @@ struct S; $0 "#, "crate::S", - "crate::S", - "crate::S", - "crate::S", + expect![[r#" + Plain (imports ✔): crate::S + Plain (imports ✖): crate::S + ByCrate(imports ✔): crate::S + ByCrate(imports ✖): crate::S + BySelf (imports ✔): crate::S + BySelf (imports ✖): crate::S + "#]], ); } @@ -789,9 +820,14 @@ $0 pub struct S; "#, "std::S", - "std::S", - "std::S", - "std::S", + expect![[r#" + Plain (imports ✔): std::S + Plain (imports ✖): std::S + ByCrate(imports ✔): std::S + ByCrate(imports ✖): std::S + BySelf (imports ✔): std::S + BySelf (imports ✖): std::S + "#]], ); } @@ -806,9 +842,14 @@ $0 pub struct S; "#, "std_renamed::S", - "std_renamed::S", - "std_renamed::S", - "std_renamed::S", + expect![[r#" + Plain (imports ✔): std_renamed::S + Plain (imports ✖): std_renamed::S + ByCrate(imports ✔): std_renamed::S + ByCrate(imports ✖): std_renamed::S + BySelf (imports ✔): std_renamed::S + BySelf (imports ✖): std_renamed::S + "#]], ); } @@ -831,10 +872,15 @@ pub mod ast { } } "#, - "ast::ModuleItem", - "syntax::ast::ModuleItem", - "syntax::ast::ModuleItem", "syntax::ast::ModuleItem", + expect![[r#" + Plain (imports ✔): ast::ModuleItem + Plain (imports ✖): syntax::ast::ModuleItem + ByCrate(imports ✔): crate::ast::ModuleItem + ByCrate(imports ✖): syntax::ast::ModuleItem + BySelf (imports ✔): self::ast::ModuleItem + BySelf (imports ✖): syntax::ast::ModuleItem + "#]], ); check_found_path( @@ -850,9 +896,14 @@ pub mod ast { } "#, "syntax::ast::ModuleItem", - "syntax::ast::ModuleItem", - "syntax::ast::ModuleItem", - "syntax::ast::ModuleItem", + expect![[r#" + Plain (imports ✔): syntax::ast::ModuleItem + Plain (imports ✖): syntax::ast::ModuleItem + ByCrate(imports ✔): syntax::ast::ModuleItem + ByCrate(imports ✖): syntax::ast::ModuleItem + BySelf (imports ✔): syntax::ast::ModuleItem + BySelf (imports ✖): syntax::ast::ModuleItem + "#]], ); } @@ -867,9 +918,14 @@ mod bar { $0 "#, "bar::S", - "bar::S", - "crate::bar::S", - "self::bar::S", + expect![[r#" + Plain (imports ✔): bar::S + Plain (imports ✖): bar::S + ByCrate(imports ✔): crate::bar::S + ByCrate(imports ✖): crate::bar::S + BySelf (imports ✔): self::bar::S + BySelf (imports ✖): self::bar::S + "#]], ); } @@ -884,9 +940,14 @@ mod bar { $0 "#, "bar::U", - "bar::U", - "crate::bar::U", - "self::bar::U", + expect![[r#" + Plain (imports ✔): bar::U + Plain (imports ✖): bar::U + ByCrate(imports ✔): crate::bar::U + ByCrate(imports ✖): crate::bar::U + BySelf (imports ✔): self::bar::U + BySelf (imports ✖): self::bar::U + "#]], ); } @@ -902,9 +963,14 @@ pub use core::S; pub struct S; "#, "std::S", - "std::S", - "std::S", - "std::S", + expect![[r#" + Plain (imports ✔): std::S + Plain (imports ✖): std::S + ByCrate(imports ✔): std::S + ByCrate(imports ✖): std::S + BySelf (imports ✔): std::S + BySelf (imports ✖): std::S + "#]], ); } @@ -922,9 +988,14 @@ pub mod prelude { } "#, "S", - "S", - "S", - "S", + expect![[r#" + Plain (imports ✔): S + Plain (imports ✖): S + ByCrate(imports ✔): S + ByCrate(imports ✖): S + BySelf (imports ✔): S + BySelf (imports ✖): S + "#]], ); } @@ -943,9 +1014,14 @@ pub mod prelude { } "#, "std::prelude::rust_2018::S", - "std::prelude::rust_2018::S", - "std::prelude::rust_2018::S", - "std::prelude::rust_2018::S", + expect![[r#" + Plain (imports ✔): std::prelude::rust_2018::S + Plain (imports ✖): std::prelude::rust_2018::S + ByCrate(imports ✔): std::prelude::rust_2018::S + ByCrate(imports ✖): std::prelude::rust_2018::S + BySelf (imports ✔): std::prelude::rust_2018::S + BySelf (imports ✖): std::prelude::rust_2018::S + "#]], ); } @@ -964,9 +1040,14 @@ pub mod prelude { } "#, "S", - "S", - "S", - "S", + expect![[r#" + Plain (imports ✔): S + Plain (imports ✖): S + ByCrate(imports ✔): crate::S + ByCrate(imports ✖): S + BySelf (imports ✔): self::S + BySelf (imports ✖): S + "#]], ); } @@ -983,8 +1064,30 @@ pub mod prelude { } } "#; - check_found_path(code, "None", "None", "None", "None"); - check_found_path(code, "Some", "Some", "Some", "Some"); + check_found_path( + code, + "None", + expect![[r#" + Plain (imports ✔): None + Plain (imports ✖): None + ByCrate(imports ✔): None + ByCrate(imports ✖): None + BySelf (imports ✔): None + BySelf (imports ✖): None + "#]], + ); + check_found_path( + code, + "Some", + expect![[r#" + Plain (imports ✔): Some + Plain (imports ✖): Some + ByCrate(imports ✔): Some + ByCrate(imports ✖): Some + BySelf (imports ✔): Some + BySelf (imports ✖): Some + "#]], + ); } #[test] @@ -1002,9 +1105,14 @@ pub mod bar { pub struct S; } pub use crate::foo::bar::S; "#, "baz::S", - "baz::S", - "crate::baz::S", - "self::baz::S", + expect![[r#" + Plain (imports ✔): baz::S + Plain (imports ✖): baz::S + ByCrate(imports ✔): crate::baz::S + ByCrate(imports ✖): crate::baz::S + BySelf (imports ✔): self::baz::S + BySelf (imports ✖): self::baz::S + "#]], ); } @@ -1022,9 +1130,14 @@ $0 "#, // crate::S would be shorter, but using private imports seems wrong "crate::bar::S", - "crate::bar::S", - "crate::bar::S", - "crate::bar::S", + expect![[r#" + Plain (imports ✔): crate::bar::S + Plain (imports ✖): crate::bar::S + ByCrate(imports ✔): crate::bar::S + ByCrate(imports ✖): crate::bar::S + BySelf (imports ✔): crate::bar::S + BySelf (imports ✖): crate::bar::S + "#]], ); } @@ -1041,9 +1154,14 @@ pub(crate) use bar::S; $0 "#, "crate::S", - "crate::S", - "crate::S", - "crate::S", + expect![[r#" + Plain (imports ✔): crate::S + Plain (imports ✖): crate::S + ByCrate(imports ✔): crate::S + ByCrate(imports ✖): crate::S + BySelf (imports ✔): crate::S + BySelf (imports ✖): crate::S + "#]], ); } @@ -1063,9 +1181,14 @@ pub mod bar { $0 "#, "super::S", - "super::S", - "crate::bar::S", - "super::S", + expect![[r#" + Plain (imports ✔): super::S + Plain (imports ✖): super::S + ByCrate(imports ✔): crate::bar::S + ByCrate(imports ✖): crate::bar::S + BySelf (imports ✔): super::S + BySelf (imports ✖): super::S + "#]], ); } @@ -1086,9 +1209,14 @@ pub struct S; pub use super::foo; "#, "crate::foo::S", - "crate::foo::S", - "crate::foo::S", - "crate::foo::S", + expect![[r#" + Plain (imports ✔): crate::foo::S + Plain (imports ✖): crate::foo::S + ByCrate(imports ✔): crate::foo::S + ByCrate(imports ✖): crate::foo::S + BySelf (imports ✔): crate::foo::S + BySelf (imports ✖): crate::foo::S + "#]], ); } @@ -1110,9 +1238,14 @@ pub mod sync { } "#, "std::sync::Arc", - "std::sync::Arc", - "std::sync::Arc", - "std::sync::Arc", + expect![[r#" + Plain (imports ✔): std::sync::Arc + Plain (imports ✖): std::sync::Arc + ByCrate(imports ✔): std::sync::Arc + ByCrate(imports ✖): std::sync::Arc + BySelf (imports ✔): std::sync::Arc + BySelf (imports ✖): std::sync::Arc + "#]], ); } @@ -1138,9 +1271,14 @@ pub mod fmt { } "#, "core::fmt::Error", - "core::fmt::Error", - "core::fmt::Error", - "core::fmt::Error", + expect![[r#" + Plain (imports ✔): core::fmt::Error + Plain (imports ✖): core::fmt::Error + ByCrate(imports ✔): core::fmt::Error + ByCrate(imports ✖): core::fmt::Error + BySelf (imports ✔): core::fmt::Error + BySelf (imports ✖): core::fmt::Error + "#]], ); // Should also work (on a best-effort basis) if `no_std` is conditional. @@ -1164,9 +1302,14 @@ pub mod fmt { } "#, "core::fmt::Error", - "core::fmt::Error", - "core::fmt::Error", - "core::fmt::Error", + expect![[r#" + Plain (imports ✔): core::fmt::Error + Plain (imports ✖): core::fmt::Error + ByCrate(imports ✔): core::fmt::Error + ByCrate(imports ✖): core::fmt::Error + BySelf (imports ✔): core::fmt::Error + BySelf (imports ✖): core::fmt::Error + "#]], ); } @@ -1194,9 +1337,14 @@ pub mod sync { } "#, "alloc::sync::Arc", - "alloc::sync::Arc", - "alloc::sync::Arc", - "alloc::sync::Arc", + expect![[r#" + Plain (imports ✔): alloc::sync::Arc + Plain (imports ✖): alloc::sync::Arc + ByCrate(imports ✔): alloc::sync::Arc + ByCrate(imports ✖): alloc::sync::Arc + BySelf (imports ✔): alloc::sync::Arc + BySelf (imports ✖): alloc::sync::Arc + "#]], ); } @@ -1216,9 +1364,14 @@ pub mod sync { pub struct Arc; "#, "megaalloc::Arc", - "megaalloc::Arc", - "megaalloc::Arc", - "megaalloc::Arc", + expect![[r#" + Plain (imports ✔): megaalloc::Arc + Plain (imports ✖): megaalloc::Arc + ByCrate(imports ✔): megaalloc::Arc + ByCrate(imports ✖): megaalloc::Arc + BySelf (imports ✔): megaalloc::Arc + BySelf (imports ✖): megaalloc::Arc + "#]], ); } @@ -1231,8 +1384,30 @@ pub mod primitive { pub use u8; } "#; - check_found_path(code, "u8", "u8", "u8", "u8"); - check_found_path(code, "u16", "u16", "u16", "u16"); + check_found_path( + code, + "u8", + expect![[r#" + Plain (imports ✔): u8 + Plain (imports ✖): u8 + ByCrate(imports ✔): u8 + ByCrate(imports ✖): u8 + BySelf (imports ✔): u8 + BySelf (imports ✖): u8 + "#]], + ); + check_found_path( + code, + "u16", + expect![[r#" + Plain (imports ✔): u16 + Plain (imports ✖): u16 + ByCrate(imports ✔): u16 + ByCrate(imports ✖): u16 + BySelf (imports ✔): u16 + BySelf (imports ✖): u16 + "#]], + ); } #[test] @@ -1245,9 +1420,14 @@ fn main() { } "#, "Inner", - "Inner", - "Inner", - "Inner", + expect![[r#" + Plain (imports ✔): Inner + Plain (imports ✖): Inner + ByCrate(imports ✔): Inner + ByCrate(imports ✖): Inner + BySelf (imports ✔): Inner + BySelf (imports ✖): Inner + "#]], ); } @@ -1263,20 +1443,24 @@ fn main() { } "#, "Struct", - "Struct", - "Struct", - "Struct", + expect![[r#" + Plain (imports ✔): Struct + Plain (imports ✖): Struct + ByCrate(imports ✔): Struct + ByCrate(imports ✖): Struct + BySelf (imports ✔): Struct + BySelf (imports ✖): Struct + "#]], ); } #[test] fn inner_items_from_inner_module() { - cov_mark::check!(prefixed_in_block_expression); check_found_path( r#" fn main() { mod module { - struct Struct {} + pub struct Struct {} } { $0 @@ -1284,9 +1468,14 @@ fn main() { } "#, "module::Struct", - "module::Struct", - "module::Struct", - "module::Struct", + expect![[r#" + Plain (imports ✔): module::Struct + Plain (imports ✖): module::Struct + ByCrate(imports ✔): module::Struct + ByCrate(imports ✖): module::Struct + BySelf (imports ✔): module::Struct + BySelf (imports ✖): module::Struct + "#]], ); } @@ -1303,11 +1492,15 @@ fn main() { $0 } "#, - // FIXME: these could use fewer/better prefixes "module::CompleteMe", - "crate::module::CompleteMe", - "crate::module::CompleteMe", - "crate::module::CompleteMe", + expect![[r#" + Plain (imports ✔): module::CompleteMe + Plain (imports ✖): module::CompleteMe + ByCrate(imports ✔): crate::module::CompleteMe + ByCrate(imports ✖): crate::module::CompleteMe + BySelf (imports ✔): self::module::CompleteMe + BySelf (imports ✖): self::module::CompleteMe + "#]], ) } @@ -1328,9 +1521,14 @@ mod bar { } "#, "crate::baz::Foo", - "crate::baz::Foo", - "crate::baz::Foo", - "crate::baz::Foo", + expect![[r#" + Plain (imports ✔): crate::baz::Foo + Plain (imports ✖): crate::baz::Foo + ByCrate(imports ✔): crate::baz::Foo + ByCrate(imports ✖): crate::baz::Foo + BySelf (imports ✔): crate::baz::Foo + BySelf (imports ✖): crate::baz::Foo + "#]], ) } @@ -1350,15 +1548,19 @@ mod bar { } "#, "crate::baz::Foo", - "crate::baz::Foo", - "crate::baz::Foo", - "crate::baz::Foo", + expect![[r#" + Plain (imports ✔): crate::baz::Foo + Plain (imports ✖): crate::baz::Foo + ByCrate(imports ✔): crate::baz::Foo + ByCrate(imports ✖): crate::baz::Foo + BySelf (imports ✔): crate::baz::Foo + BySelf (imports ✖): crate::baz::Foo + "#]], ) } #[test] fn recursive_pub_mod_reexport() { - cov_mark::check!(recursive_imports); check_found_path( r#" fn main() { @@ -1378,9 +1580,14 @@ pub mod name { } "#, "name::AsName", - "name::AsName", - "crate::name::AsName", - "self::name::AsName", + expect![[r#" + Plain (imports ✔): name::AsName + Plain (imports ✖): name::AsName + ByCrate(imports ✔): crate::name::AsName + ByCrate(imports ✖): crate::name::AsName + BySelf (imports ✔): self::name::AsName + BySelf (imports ✖): self::name::AsName + "#]], ); } @@ -1393,9 +1600,14 @@ $0 //- /dep.rs crate:dep "#, "dep", - "dep", - "dep", - "dep", + expect![[r#" + Plain (imports ✔): dep + Plain (imports ✖): dep + ByCrate(imports ✔): dep + ByCrate(imports ✖): dep + BySelf (imports ✔): dep + BySelf (imports ✖): dep + "#]], ); check_found_path( @@ -1408,9 +1620,14 @@ fn f() { //- /dep.rs crate:dep "#, "dep", - "dep", - "dep", - "dep", + expect![[r#" + Plain (imports ✔): dep + Plain (imports ✖): dep + ByCrate(imports ✔): dep + ByCrate(imports ✖): dep + BySelf (imports ✔): dep + BySelf (imports ✖): dep + "#]], ); } @@ -1432,9 +1649,14 @@ pub mod prelude { } "#, "None", - "None", - "None", - "None", + expect![[r#" + Plain (imports ✔): None + Plain (imports ✖): None + ByCrate(imports ✔): None + ByCrate(imports ✖): None + BySelf (imports ✔): None + BySelf (imports ✖): None + "#]], ); } @@ -1450,9 +1672,14 @@ pub extern crate std as std_renamed; pub struct S; "#, "intermediate::std_renamed::S", - "intermediate::std_renamed::S", - "intermediate::std_renamed::S", - "intermediate::std_renamed::S", + expect![[r#" + Plain (imports ✔): intermediate::std_renamed::S + Plain (imports ✖): intermediate::std_renamed::S + ByCrate(imports ✔): intermediate::std_renamed::S + ByCrate(imports ✖): intermediate::std_renamed::S + BySelf (imports ✔): intermediate::std_renamed::S + BySelf (imports ✖): intermediate::std_renamed::S + "#]], ); } @@ -1470,9 +1697,14 @@ pub extern crate std as longer; pub struct S; "#, "intermediate::longer::S", - "intermediate::longer::S", - "intermediate::longer::S", - "intermediate::longer::S", + expect![[r#" + Plain (imports ✔): intermediate::longer::S + Plain (imports ✖): intermediate::longer::S + ByCrate(imports ✔): intermediate::longer::S + ByCrate(imports ✖): intermediate::longer::S + BySelf (imports ✔): intermediate::longer::S + BySelf (imports ✖): intermediate::longer::S + "#]], ); } @@ -1493,9 +1725,14 @@ pub mod ops { } "#, "std::ops::Deref", - "std::ops::Deref", - "std::ops::Deref", - "std::ops::Deref", + expect![[r#" + Plain (imports ✔): std::ops::Deref + Plain (imports ✖): std::ops::Deref + ByCrate(imports ✔): std::ops::Deref + ByCrate(imports ✖): std::ops::Deref + BySelf (imports ✔): std::ops::Deref + BySelf (imports ✖): std::ops::Deref + "#]], ); } @@ -1518,9 +1755,14 @@ pub mod error { } "#, "std::error::Error", - "std::error::Error", - "std::error::Error", - "std::error::Error", + expect![[r#" + Plain (imports ✔): std::error::Error + Plain (imports ✖): std::error::Error + ByCrate(imports ✔): std::error::Error + ByCrate(imports ✖): std::error::Error + BySelf (imports ✔): std::error::Error + BySelf (imports ✖): std::error::Error + "#]], ); } @@ -1541,16 +1783,26 @@ pub mod foo { check_found_path( ra_fixture, "krate::foo::Foo", - "krate::foo::Foo", - "krate::foo::Foo", - "krate::foo::Foo", + expect![[r#" + Plain (imports ✔): krate::foo::Foo + Plain (imports ✖): krate::foo::Foo + ByCrate(imports ✔): krate::foo::Foo + ByCrate(imports ✖): krate::foo::Foo + BySelf (imports ✔): krate::foo::Foo + BySelf (imports ✖): krate::foo::Foo + "#]], ); check_found_path_prelude( ra_fixture, "krate::prelude::Foo", - "krate::prelude::Foo", - "krate::prelude::Foo", - "krate::prelude::Foo", + expect![[r#" + Plain (imports ✔): krate::prelude::Foo + Plain (imports ✖): krate::prelude::Foo + ByCrate(imports ✔): krate::prelude::Foo + ByCrate(imports ✖): krate::prelude::Foo + BySelf (imports ✔): krate::prelude::Foo + BySelf (imports ✖): krate::prelude::Foo + "#]], ); } @@ -1582,9 +1834,40 @@ pub mod prelude { } "#, "petgraph::graph::NodeIndex", - "petgraph::graph::NodeIndex", - "petgraph::graph::NodeIndex", - "petgraph::graph::NodeIndex", + expect![[r#" + Plain (imports ✔): petgraph::graph::NodeIndex + Plain (imports ✖): petgraph::graph::NodeIndex + ByCrate(imports ✔): petgraph::graph::NodeIndex + ByCrate(imports ✖): petgraph::graph::NodeIndex + BySelf (imports ✔): petgraph::graph::NodeIndex + BySelf (imports ✖): petgraph::graph::NodeIndex + "#]], + ); + } + + #[test] + fn regression_17271() { + check_found_path( + r#" +//- /lib.rs crate:main +mod foo; + +//- /foo.rs +mod bar; + +pub fn b() {$0} +//- /foo/bar.rs +pub fn c() {} +"#, + "bar::c", + expect![[r#" + Plain (imports ✔): bar::c + Plain (imports ✖): bar::c + ByCrate(imports ✔): crate::foo::bar::c + ByCrate(imports ✖): crate::foo::bar::c + BySelf (imports ✔): self::bar::c + BySelf (imports ✖): self::bar::c + "#]], ); } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs index b097a721c758..de0fa982c86a 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs @@ -175,7 +175,13 @@ pub(crate) fn parse( mut synth: impl FnMut(Name) -> ExprId, mut record_usage: impl FnMut(Name, Option), ) -> FormatArgs { - let text = s.text_without_quotes(); + let Ok(text) = s.value() else { + return FormatArgs { + template: Default::default(), + arguments: args.finish(), + orphans: vec![], + }; + }; let str_style = match s.quote_offsets() { Some(offsets) => { let raw = usize::from(offsets.quotes.0.len()) - 1; @@ -186,7 +192,7 @@ pub(crate) fn parse( }; let mut parser = - parse::Parser::new(text, str_style, fmt_snippet, false, parse::ParseMode::Format); + parse::Parser::new(&text, str_style, fmt_snippet, false, parse::ParseMode::Format); let mut pieces = Vec::new(); while let Some(piece) = parser.next() { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs index faa1eed15a45..6e40293dbf8e 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs @@ -1,13 +1,12 @@ //! A map of all publicly exported items in a crate. -use std::{fmt, hash::BuildHasherDefault}; +use std::fmt; use base_db::CrateId; use fst::{raw::IndexedValue, Automaton, Streamer}; use hir_expand::name::Name; -use indexmap::IndexMap; use itertools::Itertools; -use rustc_hash::{FxHashSet, FxHasher}; +use rustc_hash::FxHashSet; use smallvec::SmallVec; use stdx::{format_to, TupleExt}; use triomphe::Arc; @@ -17,7 +16,7 @@ use crate::{ item_scope::{ImportOrExternCrate, ItemInNs}, nameres::DefMap, visibility::Visibility, - AssocItemId, ModuleDefId, ModuleId, TraitId, + AssocItemId, FxIndexMap, ModuleDefId, ModuleId, TraitId, }; /// Item import details stored in the `ImportMap`. @@ -58,7 +57,6 @@ enum IsTraitAssocItem { No, } -type FxIndexMap = IndexMap>; type ImportMapIndex = FxIndexMap, IsTraitAssocItem)>; impl ImportMap { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs index 54cd57110ea8..9c7dfa05b0e4 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs @@ -295,7 +295,7 @@ impl ItemScope { pub(crate) fn names_of( &self, item: ItemInNs, - mut cb: impl FnMut(&Name, Visibility, bool) -> Option, + mut cb: impl FnMut(&Name, Visibility, /*declared*/ bool) -> Option, ) -> Option { match item { ItemInNs::Macros(def) => self diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index 88d4572196cd..682d169adb11 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -106,6 +106,18 @@ use crate::{ }, }; +type FxIndexMap = + indexmap::IndexMap>; +/// A wrapper around two booleans, [`ImportPathConfig::prefer_no_std`] and [`ImportPathConfig::prefer_prelude`]. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)] +pub struct ImportPathConfig { + /// If true, prefer to unconditionally use imports of the `core` and `alloc` crate + /// over the std. + pub prefer_no_std: bool, + /// If true, prefer import paths containing a prelude module. + pub prefer_prelude: bool, +} + #[derive(Debug)] pub struct ItemLoc { pub container: ModuleId, @@ -455,6 +467,26 @@ impl ModuleId { pub fn is_block_module(self) -> bool { self.block.is_some() && self.local_id == DefMap::ROOT } + + pub fn is_within_block(self) -> bool { + self.block.is_some() + } + + pub fn as_crate_root(&self) -> Option { + if self.local_id == DefMap::ROOT && self.block.is_none() { + Some(CrateRootModuleId { krate: self.krate }) + } else { + None + } + } + + pub fn derive_crate_root(&self) -> CrateRootModuleId { + CrateRootModuleId { krate: self.krate } + } + + fn is_crate_root(&self) -> bool { + self.local_id == DefMap::ROOT && self.block.is_none() + } } impl PartialEq for ModuleId { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index a528c4cc6972..a3eab22fc49c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -81,9 +81,17 @@ use crate::{ per_ns::PerNs, visibility::{Visibility, VisibilityExplicitness}, AstId, BlockId, BlockLoc, CrateRootModuleId, EnumId, EnumVariantId, ExternCrateId, FunctionId, - LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId, + FxIndexMap, LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId, }; +const PREDEFINED_TOOLS: &[SmolStr] = &[ + SmolStr::new_static("clippy"), + SmolStr::new_static("rustfmt"), + SmolStr::new_static("diagnostic"), + SmolStr::new_static("miri"), + SmolStr::new_static("rust_analyzer"), +]; + /// Contains the results of (early) name resolution. /// /// A `DefMap` stores the module tree and the definitions that are in scope in every module after @@ -129,7 +137,7 @@ pub struct DefMap { #[derive(Clone, Debug, PartialEq, Eq)] struct DefMapCrateData { /// The extern prelude which contains all root modules of external crates that are in scope. - extern_prelude: FxHashMap)>, + extern_prelude: FxIndexMap)>, /// Side table for resolving derive helpers. exported_derives: FxHashMap>, @@ -155,12 +163,12 @@ struct DefMapCrateData { impl DefMapCrateData { fn new(edition: Edition) -> Self { Self { - extern_prelude: FxHashMap::default(), + extern_prelude: FxIndexMap::default(), exported_derives: FxHashMap::default(), fn_proc_macro_mapping: FxHashMap::default(), proc_macro_loading_error: None, registered_attrs: Vec::new(), - registered_tools: Vec::new(), + registered_tools: PREDEFINED_TOOLS.into(), unstable_features: FxHashSet::default(), rustc_coherence_is_core: false, no_core: false, @@ -578,7 +586,8 @@ impl DefMap { pub(crate) fn extern_prelude( &self, - ) -> impl Iterator))> + '_ { + ) -> impl DoubleEndedIterator))> + '_ + { self.data.extern_prelude.iter().map(|(name, &def)| (name, def)) } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs index eb7f4c05ae21..3cb0666edf9c 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs @@ -10,7 +10,7 @@ use syntax::{ast, SmolStr}; use triomphe::Arc; use crate::{ - attr::builtin::{find_builtin_attr_idx, TOOL_MODULES}, + attr::builtin::find_builtin_attr_idx, db::DefDatabase, item_scope::BuiltinShadowMode, nameres::path_resolution::ResolveMode, @@ -82,8 +82,7 @@ impl DefMap { let name = name.to_smol_str(); let pred = |n: &_| *n == name; - let registered = self.data.registered_tools.iter().map(SmolStr::as_str); - let is_tool = TOOL_MODULES.iter().copied().chain(registered).any(pred); + let is_tool = self.data.registered_tools.iter().map(SmolStr::as_str).any(pred); // FIXME: tool modules can be shadowed by actual modules if is_tool { return true; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs index 262bc538b941..587997c47361 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs @@ -395,6 +395,8 @@ impl DefCollector<'_> { .cfg() .map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false)); if is_cfg_enabled { + self.inject_prelude(); + ModCollector { def_collector: self, macro_depth: 0, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs index ee29b89f3d3b..d621f3a360a9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs @@ -221,7 +221,7 @@ impl DefMap { None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; tracing::debug!("resolving {:?} in crate root (+ extern prelude)", segment); - self.resolve_name_in_crate_root_or_extern_prelude(db, segment) + self.resolve_name_in_crate_root_or_extern_prelude(db, original_module, segment) } PathKind::Plain => { let (_, segment) = match segments.next() { @@ -470,9 +470,9 @@ impl DefMap { }; let extern_prelude = || { - if self.block.is_some() { - // Don't resolve extern prelude in block `DefMap`s, defer it to the crate def map so - // that blocks can properly shadow them + if self.block.is_some() && module == DefMap::ROOT { + // Don't resolve extern prelude in pseudo-modules of blocks, because + // they might been shadowed by local names. return PerNs::none(); } self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| { @@ -505,6 +505,7 @@ impl DefMap { fn resolve_name_in_crate_root_or_extern_prelude( &self, db: &dyn DefDatabase, + module: LocalModuleId, name: &Name, ) -> PerNs { let from_crate_root = match self.block { @@ -515,8 +516,8 @@ impl DefMap { None => self[Self::ROOT].scope.get(name), }; let from_extern_prelude = || { - if self.block.is_some() { - // Don't resolve extern prelude in block `DefMap`s. + if self.block.is_some() && module == DefMap::ROOT { + // Don't resolve extern prelude in pseudo-module of a block. return PerNs::none(); } self.data.extern_prelude.get(name).copied().map_or( diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 1602b173858d..9794963203bc 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -1,12 +1,11 @@ //! Name resolution façade. -use std::{fmt, hash::BuildHasherDefault, iter, mem}; +use std::{fmt, iter, mem}; use base_db::CrateId; use hir_expand::{ name::{name, Name}, MacroDefId, }; -use indexmap::IndexMap; use intern::Interned; use rustc_hash::FxHashSet; use smallvec::{smallvec, SmallVec}; @@ -27,10 +26,10 @@ use crate::{ type_ref::LifetimeRef, visibility::{RawVisibility, Visibility}, AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, - ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, - ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId, - MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, - TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId, + ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule, + ImplId, ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, + MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, + TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId, }; #[derive(Debug, Clone)] @@ -957,7 +956,6 @@ fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option)> { Some((res, import)) } -type FxIndexMap = IndexMap>; #[derive(Default)] struct ScopeNames { map: FxIndexMap>, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index c010f5d22b68..5a9621bb69a4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs @@ -13,7 +13,7 @@ use either::Either; use hir_def::{ data::adt::VariantData, db::DefDatabase, - find_path, + find_path::{self, PrefixKind}, generics::{TypeOrConstParamData, TypeParamProvenance}, item_scope::ItemInNs, lang_item::{LangItem, LangItemTarget}, @@ -21,7 +21,8 @@ use hir_def::{ path::{Path, PathKind}, type_ref::{TraitBoundModifier, TypeBound, TypeRef}, visibility::Visibility, - HasModule, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, ModuleId, TraitId, + HasModule, ImportPathConfig, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, ModuleId, + TraitId, }; use hir_expand::name::Name; use intern::{Internable, Interned}; @@ -999,8 +1000,9 @@ impl HirDisplay for Ty { db.upcast(), ItemInNs::Types((*def_id).into()), module_id, + PrefixKind::Plain, false, - true, + ImportPathConfig { prefer_no_std: false, prefer_prelude: true }, ) { write!(f, "{}", path.display(f.db.upcast()))?; } else { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index 38076fce8f8f..4c12786362f0 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -933,8 +933,24 @@ impl InferenceContext<'_> { let prev_ret_coercion = mem::replace(&mut self.return_coercion, Some(CoerceMany::new(ret_ty.clone()))); + // FIXME: We should handle async blocks like we handle closures + let expected = &Expectation::has_type(ret_ty); let (_, inner_ty) = self.with_breakable_ctx(BreakableKind::Border, None, None, |this| { - this.infer_block(tgt_expr, *id, statements, *tail, None, &Expectation::has_type(ret_ty)) + let ty = this.infer_block(tgt_expr, *id, statements, *tail, None, expected); + if let Some(target) = expected.only_has_type(&mut this.table) { + match this.coerce(Some(tgt_expr), &ty, &target) { + Ok(res) => res, + Err(_) => { + this.result.type_mismatches.insert( + tgt_expr.into(), + TypeMismatch { expected: target.clone(), actual: ty.clone() }, + ); + target + } + } + } else { + ty + } }); self.diverges = prev_diverges; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs index b68fefc5150b..36e3a458898d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs @@ -797,19 +797,22 @@ impl<'a> InferenceTable<'a> { }) .build(); - let projection = { - let b = TyBuilder::subst_for_def(self.db, fn_once_trait, None); - if b.remaining() != 2 { - return None; - } - let fn_once_subst = b.push(ty.clone()).push(arg_ty).build(); + let b = TyBuilder::trait_ref(self.db, fn_once_trait); + if b.remaining() != 2 { + return None; + } + let mut trait_ref = b.push(ty.clone()).push(arg_ty).build(); - TyBuilder::assoc_type_projection(self.db, output_assoc_type, Some(fn_once_subst)) - .build() + let projection = { + TyBuilder::assoc_type_projection( + self.db, + output_assoc_type, + Some(trait_ref.substitution.clone()), + ) + .build() }; let trait_env = self.trait_env.env.clone(); - let mut trait_ref = projection.trait_ref(self.db); let obligation = InEnvironment { goal: trait_ref.clone().cast(Interner), environment: trait_env.clone(), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs index 6c1eccb75e63..392bda51b528 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs @@ -1,7 +1,7 @@ use chalk_ir::{AdtId, TyKind}; use either::Either; use hir_def::db::DefDatabase; -use project_model::target_data_layout::RustcDataLayoutConfig; +use project_model::{target_data_layout::RustcDataLayoutConfig, Sysroot}; use rustc_hash::FxHashMap; use test_fixture::WithFixture; use triomphe::Arc; @@ -17,7 +17,7 @@ mod closure; fn current_machine_data_layout() -> String { project_model::target_data_layout::get( - RustcDataLayoutConfig::Rustc(None), + RustcDataLayoutConfig::Rustc(&Sysroot::empty()), None, &FxHashMap::default(), ) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 1727cec9893b..26a839f0e9fa 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -570,6 +570,10 @@ impl CallableSig { } } + pub fn abi(&self) -> FnAbi { + self.abi + } + pub fn params(&self) -> &[Ty] { &self.params_and_return[0..self.params_and_return.len() - 1] } @@ -892,20 +896,16 @@ where Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(Interner, kinds) } } -pub fn callable_sig_from_fnonce( - mut self_ty: &Ty, - env: Arc, +pub fn callable_sig_from_fn_trait( + self_ty: &Ty, + trait_env: Arc, db: &dyn HirDatabase, -) -> Option { - if let Some((ty, _, _)) = self_ty.as_reference() { - // This will happen when it implements fn or fn mut, since we add a autoborrow adjustment - self_ty = ty; - } - let krate = env.krate; +) -> Option<(FnTrait, CallableSig)> { + let krate = trait_env.krate; let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?; let output_assoc_type = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; - let mut table = InferenceTable::new(db, env); + let mut table = InferenceTable::new(db, trait_env.clone()); let b = TyBuilder::trait_ref(db, fn_once_trait); if b.remaining() != 2 { return None; @@ -915,23 +915,56 @@ pub fn callable_sig_from_fnonce( // - Self: FnOnce // - >::Output == ?ret_ty let args_ty = table.new_type_var(); - let trait_ref = b.push(self_ty.clone()).push(args_ty.clone()).build(); + let mut trait_ref = b.push(self_ty.clone()).push(args_ty.clone()).build(); let projection = TyBuilder::assoc_type_projection( db, output_assoc_type, Some(trait_ref.substitution.clone()), ) .build(); - table.register_obligation(trait_ref.cast(Interner)); - let ret_ty = table.normalize_projection_ty(projection); - let ret_ty = table.resolve_completely(ret_ty); - let args_ty = table.resolve_completely(args_ty); + let block = trait_env.block; + let trait_env = trait_env.env.clone(); + let obligation = + InEnvironment { goal: trait_ref.clone().cast(Interner), environment: trait_env.clone() }; + let canonical = table.canonicalize(obligation.clone()); + if db.trait_solve(krate, block, canonical.cast(Interner)).is_some() { + table.register_obligation(obligation.goal); + let return_ty = table.normalize_projection_ty(projection); + for fn_x in [FnTrait::Fn, FnTrait::FnMut, FnTrait::FnOnce] { + let fn_x_trait = fn_x.get_id(db, krate)?; + trait_ref.trait_id = to_chalk_trait_id(fn_x_trait); + let obligation: chalk_ir::InEnvironment> = InEnvironment { + goal: trait_ref.clone().cast(Interner), + environment: trait_env.clone(), + }; + let canonical = table.canonicalize(obligation.clone()); + if db.trait_solve(krate, block, canonical.cast(Interner)).is_some() { + let ret_ty = table.resolve_completely(return_ty); + let args_ty = table.resolve_completely(args_ty); + let params = args_ty + .as_tuple()? + .iter(Interner) + .map(|it| it.assert_ty_ref(Interner)) + .cloned() + .collect(); - let params = - args_ty.as_tuple()?.iter(Interner).map(|it| it.assert_ty_ref(Interner)).cloned().collect(); - - Some(CallableSig::from_params_and_return(params, ret_ty, false, Safety::Safe, FnAbi::RustCall)) + return Some(( + fn_x, + CallableSig::from_params_and_return( + params, + ret_ty, + false, + Safety::Safe, + FnAbi::RustCall, + ), + )); + } + } + unreachable!("It should at least implement FnOnce at this point"); + } else { + None + } } struct PlaceholderCollector<'db> { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index 930bc7df5e01..02f2cd761599 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -1,5 +1,6 @@ //! Trait solving using Chalk. +use core::fmt; use std::env::var; use chalk_ir::{fold::TypeFoldable, DebruijnIndex, GoalData}; @@ -209,7 +210,25 @@ pub enum FnTrait { Fn, } +impl fmt::Display for FnTrait { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + FnTrait::FnOnce => write!(f, "FnOnce"), + FnTrait::FnMut => write!(f, "FnMut"), + FnTrait::Fn => write!(f, "Fn"), + } + } +} + impl FnTrait { + pub const fn function_name(&self) -> &'static str { + match self { + FnTrait::FnOnce => "call_once", + FnTrait::FnMut => "call_mut", + FnTrait::Fn => "call", + } + } + const fn lang_item(self) -> LangItem { match self { FnTrait::FnOnce => LangItem::FnOnce, diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 85f33a10fcb2..777be711a5e6 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -35,7 +35,7 @@ pub mod term_search; mod display; -use std::{iter, mem::discriminant, ops::ControlFlow}; +use std::{mem::discriminant, ops::ControlFlow}; use arrayvec::ArrayVec; use base_db::{CrateDisplayName, CrateId, CrateOrigin, FileId}; @@ -52,7 +52,6 @@ use hir_def::{ path::ImportAlias, per_ns::PerNs, resolver::{HasResolver, Resolver}, - src::HasSource as _, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, MacroExpander, @@ -69,7 +68,7 @@ use hir_ty::{ diagnostics::BodyValidationDiagnostic, error_lifetime, known_const_to_ast, layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding}, - method_resolution::{self, TyFingerprint}, + method_resolution::{self}, mir::{interpret_mir, MutBorrowKind}, primitive::UintTy, traits::FnTrait, @@ -100,6 +99,7 @@ pub use crate::{ VisibleTraits, }, }; +pub use hir_ty::method_resolution::TyFingerprint; // Be careful with these re-exports. // @@ -123,6 +123,7 @@ pub use { per_ns::Namespace, type_ref::{Mutability, TypeRef}, visibility::Visibility, + ImportPathConfig, // FIXME: This is here since some queries take it as input that are used // outside of hir. {AdtId, MacroId, ModuleDefId}, @@ -141,7 +142,7 @@ pub use { display::{ClosureStyle, HirDisplay, HirDisplayError, HirWrite}, layout::LayoutError, mir::{MirEvalError, MirLowerError}, - PointerCast, Safety, + FnAbi, PointerCast, Safety, }, // FIXME: Properly encapsulate mir hir_ty::{mir, Interner as ChalkTyInterner}, @@ -789,40 +790,32 @@ impl Module { /// Finds a path that can be used to refer to the given item from within /// this module, if possible. - pub fn find_use_path( + pub fn find_path( self, db: &dyn DefDatabase, item: impl Into, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Option { hir_def::find_path::find_path( db, item.into().into(), self.into(), - prefer_no_std, - prefer_prelude, + PrefixKind::Plain, + false, + cfg, ) } /// Finds a path that can be used to refer to the given item from within /// this module, if possible. This is used for returning import paths for use-statements. - pub fn find_use_path_prefixed( + pub fn find_use_path( self, db: &dyn DefDatabase, item: impl Into, prefix_kind: PrefixKind, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Option { - hir_def::find_path::find_path_prefixed( - db, - item.into().into(), - self.into(), - prefix_kind, - prefer_no_std, - prefer_prelude, - ) + hir_def::find_path::find_path(db, item.into().into(), self.into(), prefix_kind, true, cfg) } } @@ -1965,7 +1958,7 @@ impl Function { .enumerate() .map(|(idx, ty)| { let ty = Type { env: environment.clone(), ty: ty.clone() }; - Param { func: self, ty, idx } + Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } }) .collect() } @@ -1991,7 +1984,7 @@ impl Function { .skip(skip) .map(|(idx, ty)| { let ty = Type { env: environment.clone(), ty: ty.clone() }; - Param { func: self, ty, idx } + Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } }) .collect() } @@ -2037,7 +2030,7 @@ impl Function { .skip(skip) .map(|(idx, ty)| { let ty = Type { env: environment.clone(), ty: ty.clone() }; - Param { func: self, ty, idx } + Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } }) .collect() } @@ -2167,17 +2160,24 @@ impl From for Access { #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct Param { - func: Function, + func: Callee, /// The index in parameter list, including self parameter. idx: usize, ty: Type, } impl Param { - pub fn parent_fn(&self) -> Function { - self.func + pub fn parent_fn(&self) -> Option { + match self.func { + Callee::Def(CallableDefId::FunctionId(f)) => Some(f.into()), + _ => None, + } } + // pub fn parent_closure(&self) -> Option { + // self.func.as_ref().right().cloned() + // } + pub fn index(&self) -> usize { self.idx } @@ -2191,7 +2191,11 @@ impl Param { } pub fn as_local(&self, db: &dyn HirDatabase) -> Option { - let parent = DefWithBodyId::FunctionId(self.func.into()); + let parent = match self.func { + Callee::Def(CallableDefId::FunctionId(it)) => DefWithBodyId::FunctionId(it), + Callee::Closure(closure, _) => db.lookup_intern_closure(closure.into()).0, + _ => return None, + }; let body = db.body(parent); if let Some(self_param) = body.self_param.filter(|_| self.idx == 0) { Some(Local { parent, binding_id: self_param }) @@ -2205,18 +2209,45 @@ impl Param { } pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option { - self.source(db).and_then(|p| p.value.pat()) + self.source(db).and_then(|p| p.value.right()?.pat()) } - pub fn source(&self, db: &dyn HirDatabase) -> Option> { - let InFile { file_id, value } = self.func.source(db)?; - let params = value.param_list()?; - if params.self_param().is_some() { - params.params().nth(self.idx.checked_sub(params.self_param().is_some() as usize)?) - } else { - params.params().nth(self.idx) + pub fn source( + &self, + db: &dyn HirDatabase, + ) -> Option>> { + match self.func { + Callee::Def(CallableDefId::FunctionId(func)) => { + let InFile { file_id, value } = Function { id: func }.source(db)?; + let params = value.param_list()?; + if let Some(self_param) = params.self_param() { + if let Some(idx) = self.idx.checked_sub(1) { + params.params().nth(idx).map(Either::Right) + } else { + Some(Either::Left(self_param)) + } + } else { + params.params().nth(self.idx).map(Either::Right) + } + .map(|value| InFile { file_id, value }) + } + Callee::Closure(closure, _) => { + let InternedClosure(owner, expr_id) = db.lookup_intern_closure(closure.into()); + let (_, source_map) = db.body_with_source_map(owner); + let ast @ InFile { file_id, value } = source_map.expr_syntax(expr_id).ok()?; + let root = db.parse_or_expand(file_id); + match value.to_node(&root) { + ast::Expr::ClosureExpr(it) => it + .param_list()? + .params() + .nth(self.idx) + .map(Either::Right) + .map(|value| InFile { file_id: ast.file_id, value }), + _ => None, + } + } + _ => None, } - .map(|value| InFile { file_id, value }) } } @@ -3372,34 +3403,21 @@ impl BuiltinAttr { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct ToolModule { - krate: Option, + krate: CrateId, idx: u32, } impl ToolModule { - // FIXME: consider crates\hir_def\src\nameres\attr_resolution.rs? pub(crate) fn by_name(db: &dyn HirDatabase, krate: Crate, name: &str) -> Option { - if let builtin @ Some(_) = Self::builtin(name) { - return builtin; - } + let krate = krate.id; let idx = - db.crate_def_map(krate.id).registered_tools().iter().position(|it| it == name)? as u32; - Some(ToolModule { krate: Some(krate.id), idx }) - } - - fn builtin(name: &str) -> Option { - hir_def::attr::builtin::TOOL_MODULES - .iter() - .position(|&tool| tool == name) - .map(|idx| ToolModule { krate: None, idx: idx as u32 }) + db.crate_def_map(krate).registered_tools().iter().position(|it| it == name)? as u32; + Some(ToolModule { krate, idx }) } pub fn name(&self, db: &dyn HirDatabase) -> SmolStr { // FIXME: Return a `Name` here - match self.krate { - Some(krate) => db.crate_def_map(krate).registered_tools()[self.idx as usize].clone(), - None => SmolStr::new(hir_def::attr::builtin::TOOL_MODULES[self.idx as usize]), - } + db.crate_def_map(self.krate).registered_tools()[self.idx as usize].clone() } } @@ -4292,27 +4310,37 @@ impl Type { } pub fn as_callable(&self, db: &dyn HirDatabase) -> Option { - let mut the_ty = &self.ty; let callee = match self.ty.kind(Interner) { - TyKind::Ref(_, _, ty) if ty.as_closure().is_some() => { - the_ty = ty; - Callee::Closure(ty.as_closure().unwrap()) - } - TyKind::Closure(id, _) => Callee::Closure(*id), + TyKind::Closure(id, subst) => Callee::Closure(*id, subst.clone()), TyKind::Function(_) => Callee::FnPtr, TyKind::FnDef(..) => Callee::Def(self.ty.callable_def(db)?), - _ => { - let sig = hir_ty::callable_sig_from_fnonce(&self.ty, self.env.clone(), db)?; + kind => { + // This will happen when it implements fn or fn mut, since we add an autoborrow adjustment + let (ty, kind) = if let TyKind::Ref(_, _, ty) = kind { + (ty, ty.kind(Interner)) + } else { + (&self.ty, kind) + }; + if let TyKind::Closure(closure, subst) = kind { + let sig = ty.callable_sig(db)?; + return Some(Callable { + ty: self.clone(), + sig, + callee: Callee::Closure(*closure, subst.clone()), + is_bound_method: false, + }); + } + let (fn_trait, sig) = hir_ty::callable_sig_from_fn_trait(ty, self.env.clone(), db)?; return Some(Callable { ty: self.clone(), sig, - callee: Callee::Other, + callee: Callee::FnImpl(fn_trait), is_bound_method: false, }); } }; - let sig = the_ty.callable_sig(db)?; + let sig = self.ty.callable_sig(db)?; Some(Callable { ty: self.clone(), sig, callee, is_bound_method: false }) } @@ -4929,37 +4957,39 @@ pub struct Callable { sig: CallableSig, callee: Callee, /// Whether this is a method that was called with method call syntax. - pub(crate) is_bound_method: bool, + is_bound_method: bool, } -#[derive(Debug)] +#[derive(Clone, PartialEq, Eq, Hash, Debug)] enum Callee { Def(CallableDefId), - Closure(ClosureId), + Closure(ClosureId, Substitution), FnPtr, - Other, + FnImpl(FnTrait), } pub enum CallableKind { Function(Function), TupleStruct(Struct), TupleEnumVariant(Variant), - Closure, + Closure(Closure), FnPtr, - /// Some other type that implements `FnOnce`. - Other, + FnImpl(FnTrait), } impl Callable { pub fn kind(&self) -> CallableKind { - use Callee::*; match self.callee { - Def(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()), - Def(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()), - Def(CallableDefId::EnumVariantId(it)) => CallableKind::TupleEnumVariant(it.into()), - Closure(_) => CallableKind::Closure, - FnPtr => CallableKind::FnPtr, - Other => CallableKind::Other, + Callee::Def(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()), + Callee::Def(CallableDefId::StructId(it)) => CallableKind::TupleStruct(it.into()), + Callee::Def(CallableDefId::EnumVariantId(it)) => { + CallableKind::TupleEnumVariant(it.into()) + } + Callee::Closure(id, ref subst) => { + CallableKind::Closure(Closure { id, subst: subst.clone() }) + } + Callee::FnPtr => CallableKind::FnPtr, + Callee::FnImpl(fn_) => CallableKind::FnImpl(fn_), } } pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<(SelfParam, Type)> { @@ -4973,43 +5003,15 @@ impl Callable { pub fn n_params(&self) -> usize { self.sig.params().len() - if self.is_bound_method { 1 } else { 0 } } - pub fn params( - &self, - db: &dyn HirDatabase, - ) -> Vec<(Option>, Type)> { - let types = self - .sig + pub fn params(&self) -> Vec { + self.sig .params() .iter() + .enumerate() .skip(if self.is_bound_method { 1 } else { 0 }) - .map(|ty| self.ty.derived(ty.clone())); - let map_param = |it: ast::Param| it.pat().map(Either::Right); - let patterns = match self.callee { - Callee::Def(CallableDefId::FunctionId(func)) => { - let src = func.lookup(db.upcast()).source(db.upcast()); - src.value.param_list().map(|param_list| { - param_list - .self_param() - .map(|it| Some(Either::Left(it))) - .filter(|_| !self.is_bound_method) - .into_iter() - .chain(param_list.params().map(map_param)) - }) - } - Callee::Closure(closure_id) => match closure_source(db, closure_id) { - Some(src) => src.param_list().map(|param_list| { - param_list - .self_param() - .map(|it| Some(Either::Left(it))) - .filter(|_| !self.is_bound_method) - .into_iter() - .chain(param_list.params().map(map_param)) - }), - None => None, - }, - _ => None, - }; - patterns.into_iter().flatten().chain(iter::repeat(None)).zip(types).collect() + .map(|(idx, ty)| (idx, self.ty.derived(ty.clone()))) + .map(|(idx, ty)| Param { func: self.callee.clone(), idx, ty }) + .collect() } pub fn return_type(&self) -> Type { self.ty.derived(self.sig.ret().clone()) @@ -5017,17 +5019,9 @@ impl Callable { pub fn sig(&self) -> &CallableSig { &self.sig } -} -fn closure_source(db: &dyn HirDatabase, closure: ClosureId) -> Option { - let InternedClosure(owner, expr_id) = db.lookup_intern_closure(closure.into()); - let (_, source_map) = db.body_with_source_map(owner); - let ast = source_map.expr_syntax(expr_id).ok()?; - let root = ast.file_syntax(db.upcast()); - let expr = ast.value.to_node(&root); - match expr { - ast::Expr::ClosureExpr(it) => Some(it), - _ => None, + pub fn ty(&self) -> &Type { + &self.ty } } diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs index 057b03baef07..d22958406420 100644 --- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs +++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs @@ -307,7 +307,8 @@ impl SourceAnalyzer { db: &dyn HirDatabase, call: &ast::Expr, ) -> Option { - self.type_of_expr(db, &call.clone())?.0.as_callable(db) + let (orig, adjusted) = self.type_of_expr(db, &call.clone())?; + adjusted.unwrap_or(orig).as_callable(db) } pub(crate) fn resolve_field( diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs index 9f56a1ee55d3..8173427cd907 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs @@ -1,6 +1,6 @@ //! Type tree for term search -use hir_def::find_path::PrefixKind; +use hir_def::ImportPathConfig; use hir_expand::mod_path::ModPath; use hir_ty::{ db::HirDatabase, @@ -17,42 +17,20 @@ use crate::{ fn mod_item_path( sema_scope: &SemanticsScope<'_>, def: &ModuleDef, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Option { let db = sema_scope.db; - // Account for locals shadowing items from module - let name_hit_count = def.name(db).map(|def_name| { - let mut name_hit_count = 0; - sema_scope.process_all_names(&mut |name, _| { - if name == def_name { - name_hit_count += 1; - } - }); - name_hit_count - }); - let m = sema_scope.module(); - match name_hit_count { - Some(0..=1) | None => m.find_use_path(db.upcast(), *def, prefer_no_std, prefer_prelude), - Some(_) => m.find_use_path_prefixed( - db.upcast(), - *def, - PrefixKind::ByCrate, - prefer_no_std, - prefer_prelude, - ), - } + m.find_path(db.upcast(), *def, cfg) } /// Helper function to get path to `ModuleDef` as string fn mod_item_path_str( sema_scope: &SemanticsScope<'_>, def: &ModuleDef, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Result { - let path = mod_item_path(sema_scope, def, prefer_no_std, prefer_prelude); + let path = mod_item_path(sema_scope, def, cfg); path.map(|it| it.display(sema_scope.db.upcast()).to_string()) .ok_or(DisplaySourceCodeError::PathNotFound) } @@ -61,8 +39,7 @@ fn mod_item_path_str( fn type_path( sema_scope: &SemanticsScope<'_>, ty: &Type, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Result { let db = sema_scope.db; let m = sema_scope.module(); @@ -71,9 +48,7 @@ fn type_path( Some(adt) => { let ty_name = ty.display_source_code(db, m.id, true)?; - let mut path = - mod_item_path(sema_scope, &ModuleDef::Adt(adt), prefer_no_std, prefer_prelude) - .unwrap(); + let mut path = mod_item_path(sema_scope, &ModuleDef::Adt(adt), cfg).unwrap(); path.pop_segment(); let path = path.display(db.upcast()).to_string(); let res = match path.is_empty() { @@ -158,11 +133,10 @@ impl Expr { &self, sema_scope: &SemanticsScope<'_>, many_formatter: &mut dyn FnMut(&Type) -> String, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Result { let db = sema_scope.db; - let mod_item_path_str = |s, def| mod_item_path_str(s, def, prefer_no_std, prefer_prelude); + let mod_item_path_str = |s, def| mod_item_path_str(s, def, cfg); match self { Expr::Const(it) => mod_item_path_str(sema_scope, &ModuleDef::Const(*it)), Expr::Static(it) => mod_item_path_str(sema_scope, &ModuleDef::Static(*it)), @@ -172,9 +146,7 @@ impl Expr { Expr::Function { func, params, .. } => { let args = params .iter() - .map(|f| { - f.gen_source_code(sema_scope, many_formatter, prefer_no_std, prefer_prelude) - }) + .map(|f| f.gen_source_code(sema_scope, many_formatter, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -188,14 +160,10 @@ impl Expr { crate::AssocItemContainer::Impl(imp) => { let self_ty = imp.self_ty(db); // Should it be guaranteed that `mod_item_path` always exists? - match self_ty.as_adt().and_then(|adt| { - mod_item_path( - sema_scope, - &adt.into(), - prefer_no_std, - prefer_prelude, - ) - }) { + match self_ty + .as_adt() + .and_then(|adt| mod_item_path(sema_scope, &adt.into(), cfg)) + { Some(path) => path.display(sema_scope.db.upcast()).to_string(), None => self_ty.display(db).to_string(), } @@ -217,17 +185,10 @@ impl Expr { let func_name = func.name(db).display(db.upcast()).to_string(); let self_param = func.self_param(db).unwrap(); - let target_str = target.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude, - )?; + let target_str = target.gen_source_code(sema_scope, many_formatter, cfg)?; let args = params .iter() - .map(|f| { - f.gen_source_code(sema_scope, many_formatter, prefer_no_std, prefer_prelude) - }) + .map(|f| f.gen_source_code(sema_scope, many_formatter, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -259,7 +220,7 @@ impl Expr { false => { let generics = generics .iter() - .map(|it| type_path(sema_scope, it, prefer_no_std, prefer_prelude)) + .map(|it| type_path(sema_scope, it, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -270,14 +231,7 @@ impl Expr { StructKind::Tuple => { let args = params .iter() - .map(|f| { - f.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude, - ) - }) + .map(|f| f.gen_source_code(sema_scope, many_formatter, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -292,12 +246,7 @@ impl Expr { let tmp = format!( "{}: {}", f.name(db).display(db.upcast()), - a.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude - )? + a.gen_source_code(sema_scope, many_formatter, cfg)? ); Ok(tmp) }) @@ -318,14 +267,7 @@ impl Expr { StructKind::Tuple => { let args = params .iter() - .map(|a| { - a.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude, - ) - }) + .map(|a| a.gen_source_code(sema_scope, many_formatter, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -340,12 +282,7 @@ impl Expr { let tmp = format!( "{}: {}", f.name(db).display(db.upcast()), - a.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude - )? + a.gen_source_code(sema_scope, many_formatter, cfg)? ); Ok(tmp) }) @@ -359,7 +296,7 @@ impl Expr { false => { let generics = generics .iter() - .map(|it| type_path(sema_scope, it, prefer_no_std, prefer_prelude)) + .map(|it| type_path(sema_scope, it, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -374,9 +311,7 @@ impl Expr { Expr::Tuple { params, .. } => { let args = params .iter() - .map(|a| { - a.gen_source_code(sema_scope, many_formatter, prefer_no_std, prefer_prelude) - }) + .map(|a| a.gen_source_code(sema_scope, many_formatter, cfg)) .collect::, DisplaySourceCodeError>>()? .into_iter() .join(", "); @@ -388,12 +323,7 @@ impl Expr { return Ok(many_formatter(&expr.ty(db))); } - let strukt = expr.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude, - )?; + let strukt = expr.gen_source_code(sema_scope, many_formatter, cfg)?; let field = field.name(db).display(db.upcast()).to_string(); Ok(format!("{strukt}.{field}")) } @@ -402,12 +332,7 @@ impl Expr { return Ok(many_formatter(&expr.ty(db))); } - let inner = expr.gen_source_code( - sema_scope, - many_formatter, - prefer_no_std, - prefer_prelude, - )?; + let inner = expr.gen_source_code(sema_scope, many_formatter, cfg)?; Ok(format!("&{inner}")) } Expr::Many(ty) => Ok(many_formatter(ty)), diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 5ef374506ecc..22a4674fd46c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -1,7 +1,7 @@ use std::iter::{self, Peekable}; use either::Either; -use hir::{Adt, Crate, HasAttrs, HasSource, ModuleDef, Semantics}; +use hir::{Adt, Crate, HasAttrs, HasSource, ImportPathConfig, ModuleDef, Semantics}; use ide_db::RootDatabase; use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast}; use itertools::Itertools; @@ -71,6 +71,11 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .filter(|pat| !matches!(pat, Pat::WildcardPat(_))) .collect(); + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + let module = ctx.sema.scope(expr.syntax())?.module(); let (mut missing_pats, is_non_exhaustive, has_hidden_variants): ( Peekable>>, @@ -88,13 +93,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) .into_iter() .filter_map(|variant| { Some(( - build_pat( - ctx.db(), - module, - variant, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - )?, + build_pat(ctx.db(), module, variant, cfg)?, variant.should_be_hidden(ctx.db(), module.krate()), )) }) @@ -145,15 +144,9 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let is_hidden = variants .iter() .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); - let patterns = variants.into_iter().filter_map(|variant| { - build_pat( - ctx.db(), - module, - variant, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) - }); + let patterns = variants + .into_iter() + .filter_map(|variant| build_pat(ctx.db(), module, variant, cfg)); (ast::Pat::from(make::tuple_pat(patterns)), is_hidden) }) @@ -184,15 +177,9 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) let is_hidden = variants .iter() .any(|variant| variant.should_be_hidden(ctx.db(), module.krate())); - let patterns = variants.into_iter().filter_map(|variant| { - build_pat( - ctx.db(), - module, - variant, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) - }); + let patterns = variants + .into_iter() + .filter_map(|variant| build_pat(ctx.db(), module, variant, cfg)); (ast::Pat::from(make::slice_pat(patterns)), is_hidden) }) .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat)); @@ -457,18 +444,11 @@ fn build_pat( db: &RootDatabase, module: hir::Module, var: ExtendedVariant, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Option { match var { ExtendedVariant::Variant(var) => { - let path = mod_path_to_ast(&module.find_use_path( - db, - ModuleDef::from(var), - prefer_no_std, - prefer_prelude, - )?); - + let path = mod_path_to_ast(&module.find_path(db, ModuleDef::from(var), cfg)?); // FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though Some(match var.source(db)?.value.kind() { ast::StructKind::Tuple(field_list) => { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs index b90bccb48ede..3bd003a267a2 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs @@ -1,6 +1,6 @@ use std::cmp::Reverse; -use hir::{db::HirDatabase, Module}; +use hir::{db::HirDatabase, ImportPathConfig, Module}; use ide_db::{ helpers::mod_path_to_ast, imports::{ @@ -90,14 +90,14 @@ use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel}; // # pub mod std { pub mod collections { pub struct HashMap { } } } // ``` pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + let (import_assets, syntax_under_caret) = find_importable_node(ctx)?; let mut proposed_imports: Vec<_> = import_assets - .search_for_imports( - &ctx.sema, - ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_no_std, - ) + .search_for_imports(&ctx.sema, cfg, ctx.config.insert_use.prefix_kind) .collect(); if proposed_imports.is_empty() { return None; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs index fd3a0506ab67..71436e658047 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs @@ -1,4 +1,4 @@ -use hir::ModuleDef; +use hir::{ImportPathConfig, ModuleDef}; use ide_db::{ assists::{AssistId, AssistKind}, defs::Definition, @@ -326,6 +326,11 @@ fn augment_references_with_imports( ) -> Vec { let mut visited_modules = FxHashSet::default(); + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + references .into_iter() .filter_map(|FileReference { range, name, .. }| { @@ -341,12 +346,11 @@ fn augment_references_with_imports( let import_scope = ImportScope::find_insert_use_container(name.syntax(), &ctx.sema); let path = ref_module - .find_use_path_prefixed( + .find_use_path( ctx.sema.db, ModuleDef::Module(*target_module), ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + cfg, ) .map(|mod_path| { make::path_concat(mod_path_to_ast(&mod_path), make::path_from_text("Bool")) @@ -1521,7 +1525,7 @@ mod foo { } "#, r#" -use crate::foo::Bool; +use foo::Bool; fn main() { use foo::FOO; @@ -1602,7 +1606,7 @@ pub mod bar { "#, r#" //- /main.rs -use crate::foo::bar::Bool; +use foo::bar::Bool; mod foo; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs index d649f13d6ee3..be433c333385 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs @@ -1,3 +1,4 @@ +use hir::ImportPathConfig; use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast, traits::resolve_target_trait}; use syntax::ast::{self, AstNode, HasName}; @@ -43,19 +44,18 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) - return None; } + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + let src_type_path = { let src_type_path = src_type.syntax().descendants().find_map(ast::Path::cast)?; let src_type_def = match ctx.sema.resolve_path(&src_type_path) { Some(hir::PathResolution::Def(module_def)) => module_def, _ => return None, }; - - mod_path_to_ast(&module.find_use_path( - ctx.db(), - src_type_def, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - )?) + mod_path_to_ast(&module.find_path(ctx.db(), src_type_def, cfg)?) }; let dest_type = match &ast_trait { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs index 41366658a74b..241fc3b7a379 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs @@ -1,5 +1,5 @@ use either::Either; -use hir::ModuleDef; +use hir::{ImportPathConfig, ModuleDef}; use ide_db::{ assists::{AssistId, AssistKind}, defs::Definition, @@ -183,6 +183,11 @@ fn augment_references_with_imports( ) -> Vec<(ast::NameLike, Option<(ImportScope, ast::Path)>)> { let mut visited_modules = FxHashSet::default(); + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + references .iter() .filter_map(|FileReference { name, .. }| { @@ -201,12 +206,11 @@ fn augment_references_with_imports( let import_scope = ImportScope::find_insert_use_container(new_name.syntax(), &ctx.sema); let path = ref_module - .find_use_path_prefixed( + .find_use_path( ctx.sema.db, ModuleDef::Module(*target_module), ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + cfg, ) .map(|mod_path| { make::path_concat( @@ -811,7 +815,7 @@ pub mod bar { "#, r#" //- /main.rs -use crate::foo::bar::BarResult; +use foo::bar::BarResult; mod foo; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs index c1a3f9302650..9adbdd220c2b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_struct_binding.rs @@ -1,4 +1,4 @@ -use hir::HasVisibility; +use hir::{HasVisibility, ImportPathConfig}; use ide_db::{ assists::{AssistId, AssistKind}, defs::Definition, @@ -87,15 +87,15 @@ fn collect_data(ident_pat: ast::IdentPat, ctx: &AssistContext<'_>) -> Option) -> Op FamousDefs(&ctx.sema, module.krate()).core_ops_ControlFlow(); if let Some(control_flow_enum) = control_flow_enum { - let mod_path = module.find_use_path_prefixed( + let mod_path = module.find_use_path( ctx.sema.db, ModuleDef::from(control_flow_enum), ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ); if let Some(mod_path) = mod_path { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs index 81a639e0b9f3..3c6d73b62e73 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs @@ -1,7 +1,7 @@ use std::iter; use either::Either; -use hir::{Module, ModuleDef, Name, Variant}; +use hir::{ImportPathConfig, Module, ModuleDef, Name, Variant}; use ide_db::{ defs::Definition, helpers::mod_path_to_ast, @@ -386,12 +386,14 @@ fn process_references( let segment = builder.make_mut(segment); let scope_node = builder.make_syntax_mut(scope_node); if !visited_modules.contains(&module) { - let mod_path = module.find_use_path_prefixed( + let mod_path = module.find_use_path( ctx.sema.db, *enum_module_def, ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ); if let Some(mut mod_path) = mod_path { mod_path.pop_segment(); @@ -881,7 +883,7 @@ fn another_fn() { r#"use my_mod::my_other_mod::MyField; mod my_mod { - use self::my_other_mod::MyField; + use my_other_mod::MyField; fn another_fn() { let m = my_other_mod::MyEnum::MyField(MyField(1, 1)); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs index 473c699b595c..9a441fc5ebcd 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs @@ -1,6 +1,6 @@ use std::fmt::Display; -use hir::{ModPath, ModuleDef}; +use hir::{ImportPathConfig, ModPath, ModuleDef}; use ide_db::{famous_defs::FamousDefs, RootDatabase}; use syntax::{ ast::{self, HasName}, @@ -58,11 +58,13 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( let module = ctx.sema.to_def(&strukt)?.module(ctx.db()); let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate())?; - let trait_path = module.find_use_path( + let trait_path = module.find_path( ctx.db(), ModuleDef::Trait(trait_), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, )?; let field_type = field.ty()?; @@ -103,11 +105,13 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() let module = ctx.sema.to_def(&strukt)?.module(ctx.db()); let trait_ = deref_type_to_generate.to_trait(&ctx.sema, module.krate())?; - let trait_path = module.find_use_path( + let trait_path = module.find_path( ctx.db(), ModuleDef::Trait(trait_), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, )?; let field_type = field.ty()?; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs index 22c75cd5eefc..52007e0e297b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_new.rs @@ -1,3 +1,4 @@ +use hir::ImportPathConfig; use ide_db::{ imports::import_assets::item_for_path_search, use_trivial_constructor::use_trivial_constructor, }; @@ -58,11 +59,13 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option let item_in_ns = hir::ItemInNs::from(hir::ModuleDef::from(ty.as_adt()?)); - let type_path = current_module.find_use_path( + let type_path = current_module.find_path( ctx.sema.db, item_for_path_search(ctx.sema.db, item_in_ns)?, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, )?; let expr = use_trivial_constructor( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs index ff65aac82e07..5d1140d57ac9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs @@ -1,4 +1,7 @@ -use hir::{db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, ItemInNs, ModuleDef}; +use hir::{ + db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, ImportPathConfig, ItemInNs, + ModuleDef, +}; use ide_db::assists::{AssistId, AssistKind}; use syntax::{ast, AstNode}; @@ -44,11 +47,13 @@ pub(crate) fn qualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) -> let current_module = ctx.sema.scope(call.syntax())?.module(); let target_module_def = ModuleDef::from(resolved_call); let item_in_ns = ItemInNs::from(target_module_def); - let receiver_path = current_module.find_use_path( + let receiver_path = current_module.find_path( ctx.sema.db, item_for_path_search(ctx.sema.db, item_in_ns)?, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, )?; let qualify_candidate = QualifyCandidate::ImplMethod(ctx.sema.db, call, resolved_call); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs index 63a09ce2e976..978b719c30a0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs @@ -1,6 +1,6 @@ use std::iter; -use hir::AsAssocItem; +use hir::{AsAssocItem, ImportPathConfig}; use ide_db::RootDatabase; use ide_db::{ helpers::mod_path_to_ast, @@ -37,9 +37,13 @@ use crate::{ // ``` pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { let (import_assets, syntax_under_caret) = find_importable_node(ctx)?; - let mut proposed_imports: Vec<_> = import_assets - .search_for_relative_paths(&ctx.sema, ctx.config.prefer_no_std, ctx.config.prefer_prelude) - .collect(); + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + + let mut proposed_imports: Vec<_> = + import_assets.search_for_relative_paths(&ctx.sema, cfg).collect(); if proposed_imports.is_empty() { return None; } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs index 0f0f13bbc80b..b653f3b6650e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_imports.rs @@ -776,6 +776,40 @@ mod z { ); } + #[test] + fn remove_unused_fixes_nested_self() { + check_assist( + remove_unused_imports, + r#" +mod inner { + pub struct X(); + pub struct Y(); +} + +mod z { + use super::inner::{self, X}$0; + + fn f() { + let y = inner::Y(); + } +} +"#, + r#"mod inner { + pub struct X(); + pub struct Y(); +} + +mod z { + use super::inner::{self}; + + fn f() { + let y = inner::Y(); + } +} +"#, + ); + } + #[test] fn dont_remove_used_glob() { check_assist_not_applicable( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 3420d906dea5..e792debaa517 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -1,4 +1,4 @@ -use hir::{InFile, MacroFileIdExt, ModuleDef}; +use hir::{ImportPathConfig, InFile, MacroFileIdExt, ModuleDef}; use ide_db::{helpers::mod_path_to_ast, imports::import_assets::NameToImport, items_locator}; use itertools::Itertools; use syntax::{ @@ -83,11 +83,13 @@ pub(crate) fn replace_derive_with_manual_impl( }) .flat_map(|trait_| { current_module - .find_use_path( + .find_path( ctx.sema.db, hir::ModuleDef::Trait(trait_), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) .as_ref() .map(mod_path_to_ast) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs index 7f3b0d758839..37ea5123a71e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs @@ -114,10 +114,10 @@ pub(crate) fn replace_with_eager_method(acc: &mut Assists, ctx: &AssistContext<' let callable = ctx.sema.resolve_method_call_as_callable(&call)?; let (_, receiver_ty) = callable.receiver_param(ctx.sema.db)?; let n_params = callable.n_params() + 1; - let params = callable.params(ctx.sema.db); + let params = callable.params(); // FIXME: Check that the arg is of the form `() -> T` - if !params.first()?.1.impls_fnonce(ctx.sema.db) { + if !params.first()?.ty().impls_fnonce(ctx.sema.db) { return None; } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs index ba1c25fa5a74..188165e77645 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs @@ -1,4 +1,4 @@ -use hir::AsAssocItem; +use hir::{AsAssocItem, ImportPathConfig}; use ide_db::{ helpers::mod_path_to_ast, imports::insert_use::{insert_use, ImportScope}, @@ -63,12 +63,14 @@ pub(crate) fn replace_qualified_name_with_use( ); let path_to_qualifier = starts_with_name_ref .then(|| { - ctx.sema.scope(path.syntax())?.module().find_use_path_prefixed( + ctx.sema.scope(path.syntax())?.module().find_use_path( ctx.sema.db, module, ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) }) .flatten(); diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs index d0c6ae21988d..ffd1508ccbdc 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/term_search.rs @@ -1,5 +1,8 @@ //! Term search assist -use hir::term_search::{TermSearchConfig, TermSearchCtx}; +use hir::{ + term_search::{TermSearchConfig, TermSearchCtx}, + ImportPathConfig, +}; use ide_db::{ assists::{AssistId, AssistKind, GroupLabel}, famous_defs::FamousDefs, @@ -50,8 +53,10 @@ pub(crate) fn term_search(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< path.gen_source_code( &scope, &mut formatter, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) .ok() }) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs index 1859825b3d65..23a06404f301 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils/suggest_name.rs @@ -253,11 +253,8 @@ fn from_param(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option pat, - _ => return None, - }; + let param = func.params().into_iter().nth(idx)?; + let pat = param.source(sema.db)?.value.right()?.pat()?; let name = var_name_from_pat(&pat)?; normalize(&name.to_string()) } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs index 1ea7220960d2..11ffc8bc4414 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs @@ -24,7 +24,7 @@ pub(crate) mod vis; use std::iter; -use hir::{known, HasAttrs, ScopeDef, Variant}; +use hir::{known, HasAttrs, ImportPathConfig, ScopeDef, Variant}; use ide_db::{imports::import_assets::LocatedImport, RootDatabase, SymbolKind}; use syntax::{ast, SmolStr}; @@ -633,11 +633,13 @@ fn enum_variants_with_paths( } for variant in variants { - if let Some(path) = ctx.module.find_use_path( + if let Some(path) = ctx.module.find_path( ctx.db, hir::ModuleDef::from(variant), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) { // Variants with trivial paths are already added by the existing completion logic, // so we should avoid adding these twice diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs index 1e31d65fddfe..ddb1aeb3711d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs @@ -1,6 +1,6 @@ //! Completion of names from the current scope in expression position. -use hir::ScopeDef; +use hir::{ImportPathConfig, ScopeDef}; use syntax::ast; use crate::{ @@ -171,11 +171,13 @@ pub(crate) fn complete_expr_path( hir::Adt::Struct(strukt) => { let path = ctx .module - .find_use_path( + .find_path( ctx.db, hir::ModuleDef::from(strukt), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) .filter(|it| it.len() > 1); @@ -194,11 +196,13 @@ pub(crate) fn complete_expr_path( hir::Adt::Union(un) => { let path = ctx .module - .find_use_path( + .find_path( ctx.db, hir::ModuleDef::from(un), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) .filter(|it| it.len() > 1); diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs index bf6747d71b7a..d5a4e9ecdcc1 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs @@ -1,5 +1,5 @@ //! See [`import_on_the_fly`]. -use hir::{ItemInNs, ModuleDef}; +use hir::{ImportPathConfig, ItemInNs, ModuleDef}; use ide_db::imports::{ import_assets::{ImportAssets, LocatedImport}, insert_use::ImportScope, @@ -257,13 +257,13 @@ fn import_on_the_fly( }; let user_input_lowercased = potential_import_name.to_lowercase(); + let import_cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + import_assets - .search_for_imports( - &ctx.sema, - ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) + .search_for_imports(&ctx.sema, import_cfg, ctx.config.insert_use.prefix_kind) .filter(ns_filter) .filter(|import| { let original_item = &import.original_item; @@ -308,13 +308,13 @@ fn import_on_the_fly_pat_( }; let user_input_lowercased = potential_import_name.to_lowercase(); + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + import_assets - .search_for_imports( - &ctx.sema, - ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) + .search_for_imports(&ctx.sema, cfg, ctx.config.insert_use.prefix_kind) .filter(ns_filter) .filter(|import| { let original_item = &import.original_item; @@ -355,13 +355,13 @@ fn import_on_the_fly_method( let user_input_lowercased = potential_import_name.to_lowercase(); + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + import_assets - .search_for_imports( - &ctx.sema, - ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) + .search_for_imports(&ctx.sema, cfg, ctx.config.insert_use.prefix_kind) .filter(|import| { !ctx.is_item_hidden(&import.item_to_import) && !ctx.is_item_hidden(&import.original_item) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs index c6e243b31a79..a230edd39b6d 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs @@ -2,7 +2,7 @@ mod format_like; -use hir::ItemInNs; +use hir::{ImportPathConfig, ItemInNs}; use ide_db::{ documentation::{Documentation, HasDocs}, imports::insert_use::ImportScope, @@ -60,15 +60,17 @@ pub(crate) fn complete_postfix( None => return, }; + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + if let Some(drop_trait) = ctx.famous_defs().core_ops_Drop() { if receiver_ty.impls_trait(ctx.db, drop_trait, &[]) { if let Some(drop_fn) = ctx.famous_defs().core_mem_drop() { - if let Some(path) = ctx.module.find_use_path( - ctx.db, - ItemInNs::Values(drop_fn.into()), - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) { + if let Some(path) = + ctx.module.find_path(ctx.db, ItemInNs::Values(drop_fn.into()), cfg) + { cov_mark::hit!(postfix_drop_completion); let mut item = postfix_snippet( "drop", diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs index d89cfc8b6cb8..a83fa28b8758 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs @@ -12,6 +12,7 @@ mod snippet; #[cfg(test)] mod tests; +use hir::ImportPathConfig; use ide_db::{ base_db::FilePosition, helpers::mod_path_to_ast, @@ -251,6 +252,11 @@ pub fn resolve_completion_edits( let new_ast = scope.clone_for_update(); let mut import_insert = TextEdit::builder(); + let cfg = ImportPathConfig { + prefer_no_std: config.prefer_no_std, + prefer_prelude: config.prefer_prelude, + }; + imports.into_iter().for_each(|(full_import_path, imported_name)| { let items_with_name = items_locator::items_with_name( &sema, @@ -260,13 +266,7 @@ pub fn resolve_completion_edits( ); let import = items_with_name .filter_map(|candidate| { - current_module.find_use_path_prefixed( - db, - candidate, - config.insert_use.prefix_kind, - config.prefer_no_std, - config.prefer_prelude, - ) + current_module.find_use_path(db, candidate, config.insert_use.prefix_kind, cfg) }) .find(|mod_path| mod_path.display(db).to_string() == full_import_path); if let Some(import_path) = import { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index 7fa31e2757db..8f563790737e 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs @@ -10,7 +10,7 @@ pub(crate) mod type_alias; pub(crate) mod union_literal; pub(crate) mod variant; -use hir::{AsAssocItem, HasAttrs, HirDisplay, ModuleDef, ScopeDef, Type}; +use hir::{AsAssocItem, HasAttrs, HirDisplay, ImportPathConfig, ModuleDef, ScopeDef, Type}; use ide_db::{ documentation::{Documentation, HasDocs}, helpers::item_name, @@ -295,14 +295,12 @@ pub(crate) fn render_expr( .unwrap_or_else(|| String::from("...")) }; - let label = expr - .gen_source_code( - &ctx.scope, - &mut label_formatter, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) - .ok()?; + let cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + + let label = expr.gen_source_code(&ctx.scope, &mut label_formatter, cfg).ok()?; let source_range = match ctx.original_token.parent() { Some(node) => match node.ancestors().find_map(ast::Path::cast) { @@ -314,16 +312,8 @@ pub(crate) fn render_expr( let mut item = CompletionItem::new(CompletionItemKind::Expression, source_range, label); - let snippet = format!( - "{}$0", - expr.gen_source_code( - &ctx.scope, - &mut snippet_formatter, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude - ) - .ok()? - ); + let snippet = + format!("{}$0", expr.gen_source_code(&ctx.scope, &mut snippet_formatter, cfg).ok()?); let edit = TextEdit::replace(source_range, snippet); item.snippet_edit(ctx.config.snippet_cap?, edit); item.documentation(Documentation::new(String::from("Autogenerated expression by term search"))); @@ -333,12 +323,7 @@ pub(crate) fn render_expr( }); for trait_ in expr.traits_used(ctx.db) { let trait_item = hir::ItemInNs::from(hir::ModuleDef::from(trait_)); - let Some(path) = ctx.module.find_use_path( - ctx.db, - trait_item, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, - ) else { + let Some(path) = ctx.module.find_path(ctx.db, trait_item, cfg) else { continue; }; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs index 7d710f1e1308..07836040b487 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/snippet.rs @@ -100,6 +100,7 @@ // } // ---- +use hir::ImportPathConfig; use ide_db::imports::import_assets::LocatedImport; use itertools::Itertools; use syntax::{ast, AstNode, GreenNode, SyntaxNode}; @@ -168,18 +169,22 @@ impl Snippet { } fn import_edits(ctx: &CompletionContext<'_>, requires: &[GreenNode]) -> Option> { + let import_cfg = ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }; + let resolve = |import: &GreenNode| { let path = ast::Path::cast(SyntaxNode::new_root(import.clone()))?; let item = match ctx.scope.speculative_resolve(&path)? { hir::PathResolution::Def(def) => def.into(), _ => return None, }; - let path = ctx.module.find_use_path_prefixed( + let path = ctx.module.find_use_path( ctx.db, item, ctx.config.insert_use.prefix_kind, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + import_cfg, )?; Some((path.len() > 1).then(|| LocatedImport::new(path.clone(), item, item))) }; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs index 70e0aa4e9a91..c1a67315b75c 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests.rs @@ -66,11 +66,10 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig { enable_self_on_the_fly: true, enable_private_editable: false, enable_term_search: true, + term_search_fuel: 200, full_function_signatures: false, callable: Some(CallableSnippets::FillArguments), snippet_cap: SnippetCap::new(true), - prefer_no_std: false, - prefer_prelude: true, insert_use: InsertUseConfig { granularity: ImportGranularity::Crate, prefix_kind: PrefixKind::Plain, @@ -78,9 +77,10 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig { group: true, skip_glob_imports: true, }, + prefer_no_std: false, + prefer_prelude: true, snippets: Vec::new(), limit: None, - term_search_fuel: 200, }; pub(crate) fn completion_list(ra_fixture: &str) -> String { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs index d2227d23cd77..abffa73c3b4c 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs @@ -472,6 +472,47 @@ fn main() { ); } +#[test] +fn trait_completions_handle_associated_types() { + let fixture = r#" +//- /foo.rs crate:foo +pub trait NotInScope { + fn not_in_scope(&self); +} + +pub trait Wrapper { + type Inner: NotInScope; + fn inner(&self) -> Self::Inner; +} + +//- /main.rs crate:main deps:foo +use foo::Wrapper; + +fn completion(whatever: T) { + whatever.inner().$0 +} +"#; + + check( + fixture, + expect![[r#" + me not_in_scope() (use foo::NotInScope) fn(&self) + "#]], + ); + + check_edit( + "not_in_scope", + fixture, + r#" +use foo::{NotInScope, Wrapper}; + +fn completion(whatever: T) { + whatever.inner().not_in_scope()$0 +} +"#, + ); +} + #[test] fn trait_method_fuzzy_completion_aware_of_unit_type() { let fixture = r#" diff --git a/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs b/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs index 5780b5a5bb93..98d2e8175461 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/active_parameter.rs @@ -1,7 +1,7 @@ //! This module provides functionality for querying callable information about a token. use either::Either; -use hir::{Semantics, Type}; +use hir::{InFile, Semantics, Type}; use parser::T; use syntax::{ ast::{self, HasArgList, HasName}, @@ -13,7 +13,7 @@ use crate::RootDatabase; #[derive(Debug)] pub struct ActiveParameter { pub ty: Type, - pub pat: Option>, + pub src: Option>>, } impl ActiveParameter { @@ -22,18 +22,18 @@ impl ActiveParameter { let (signature, active_parameter) = callable_for_token(sema, token)?; let idx = active_parameter?; - let mut params = signature.params(sema.db); + let mut params = signature.params(); if idx >= params.len() { cov_mark::hit!(too_many_arguments); return None; } - let (pat, ty) = params.swap_remove(idx); - Some(ActiveParameter { ty, pat }) + let param = params.swap_remove(idx); + Some(ActiveParameter { ty: param.ty().clone(), src: param.source(sema.db) }) } pub fn ident(&self) -> Option { - self.pat.as_ref().and_then(|param| match param { - Either::Right(ast::Pat::IdentPat(ident)) => ident.name(), + self.src.as_ref().and_then(|param| match param.value.as_ref().right()?.pat()? { + ast::Pat::IdentPat(ident) => ident.name(), _ => None, }) } @@ -60,10 +60,7 @@ pub fn callable_for_node( token: &SyntaxToken, ) -> Option<(hir::Callable, Option)> { let callable = match calling_node { - ast::CallableExpr::Call(call) => { - let expr = call.expr()?; - sema.type_of_expr(&expr)?.adjusted().as_callable(sema.db) - } + ast::CallableExpr::Call(call) => sema.resolve_expr_as_callable(&call.expr()?), ast::CallableExpr::MethodCall(call) => sema.resolve_method_call_as_callable(call), }?; let active_param = calling_node.arg_list().map(|arg_list| { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs index 766bfcf4d094..4caecb3f2fe1 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs @@ -1,9 +1,9 @@ //! Look up accessible paths for items. use hir::{ - db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasCrate, ItemInNs, - ModPath, Module, ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, - SemanticsScope, Trait, Type, + db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasCrate, ImportPathConfig, + ItemInNs, ModPath, Module, ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, + SemanticsScope, Trait, TyFingerprint, Type, }; use itertools::{EitherOrBoth, Itertools}; use rustc_hash::{FxHashMap, FxHashSet}; @@ -205,24 +205,22 @@ impl ImportAssets { pub fn search_for_imports( &self, sema: &Semantics<'_, RootDatabase>, + cfg: ImportPathConfig, prefix_kind: PrefixKind, - prefer_no_std: bool, - prefer_prelude: bool, ) -> impl Iterator { let _p = tracing::span!(tracing::Level::INFO, "ImportAssets::search_for_imports").entered(); - self.search_for(sema, Some(prefix_kind), prefer_no_std, prefer_prelude) + self.search_for(sema, Some(prefix_kind), cfg) } /// This may return non-absolute paths if a part of the returned path is already imported into scope. pub fn search_for_relative_paths( &self, sema: &Semantics<'_, RootDatabase>, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> impl Iterator { let _p = tracing::span!(tracing::Level::INFO, "ImportAssets::search_for_relative_paths") .entered(); - self.search_for(sema, None, prefer_no_std, prefer_prelude) + self.search_for(sema, None, cfg) } /// Requires imports to by prefix instead of fuzzily. @@ -259,8 +257,7 @@ impl ImportAssets { &self, sema: &Semantics<'_, RootDatabase>, prefixed: Option, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> impl Iterator { let _p = tracing::span!(tracing::Level::INFO, "ImportAssets::search_for").entered(); @@ -277,8 +274,7 @@ impl ImportAssets { item_for_path_search(sema.db, item)?, &self.module_with_candidate, prefixed, - prefer_no_std, - prefer_prelude, + cfg, ) .filter(|path| path.len() > 1) }; @@ -549,6 +545,15 @@ fn trait_applicable_items( let Some(receiver) = trait_candidate.receiver_ty.fingerprint_for_trait_impl() else { return false; }; + + // in order to handle implied bounds through an associated type, keep any + // method receiver that matches `TyFingerprint::Unnameable`. this receiver + // won't be in `TraitImpls` anyways, as `TraitImpls` only contains actual + // implementations. + if matches!(receiver, TyFingerprint::Unnameable) { + return true; + } + let definitions_exist_in_trait_crate = db .trait_impls_in_crate(defining_crate_for_trait.into()) .has_impls_for_trait_and_self_ty(candidate_trait_id, receiver); @@ -634,19 +639,12 @@ fn get_mod_path( item_to_search: ItemInNs, module_with_candidate: &Module, prefixed: Option, - prefer_no_std: bool, - prefer_prelude: bool, + cfg: ImportPathConfig, ) -> Option { if let Some(prefix_kind) = prefixed { - module_with_candidate.find_use_path_prefixed( - db, - item_to_search, - prefix_kind, - prefer_no_std, - prefer_prelude, - ) + module_with_candidate.find_use_path(db, item_to_search, prefix_kind, cfg) } else { - module_with_candidate.find_use_path(db, item_to_search, prefer_no_std, prefer_prelude) + module_with_candidate.find_path(db, item_to_search, cfg) } } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs index 7e1811b4cacb..7c11dd3e2a4e 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs @@ -2,7 +2,7 @@ use crate::helpers::mod_path_to_ast; use either::Either; -use hir::{AsAssocItem, HirDisplay, ModuleDef, SemanticsScope}; +use hir::{AsAssocItem, HirDisplay, ImportPathConfig, ModuleDef, SemanticsScope}; use itertools::Itertools; use rustc_hash::FxHashMap; use syntax::{ @@ -308,11 +308,12 @@ impl Ctx<'_> { parent.segment()?.name_ref()?, ) .and_then(|trait_ref| { - let found_path = self.target_module.find_use_path( + let cfg = + ImportPathConfig { prefer_no_std: false, prefer_prelude: true }; + let found_path = self.target_module.find_path( self.source_scope.db.upcast(), hir::ModuleDef::Trait(trait_ref), - false, - true, + cfg, )?; match make::ty_path(mod_path_to_ast(&found_path)) { ast::Type::PathType(path_ty) => Some(path_ty), @@ -347,12 +348,9 @@ impl Ctx<'_> { } } - let found_path = self.target_module.find_use_path( - self.source_scope.db.upcast(), - def, - false, - true, - )?; + let cfg = ImportPathConfig { prefer_no_std: false, prefer_prelude: true }; + let found_path = + self.target_module.find_path(self.source_scope.db.upcast(), def, cfg)?; let res = mod_path_to_ast(&found_path).clone_for_update(); if let Some(args) = path.segment().and_then(|it| it.generic_arg_list()) { if let Some(segment) = res.segment() { @@ -385,11 +383,11 @@ impl Ctx<'_> { if let Some(adt) = ty.as_adt() { if let ast::Type::PathType(path_ty) = &ast_ty { - let found_path = self.target_module.find_use_path( + let cfg = ImportPathConfig { prefer_no_std: false, prefer_prelude: true }; + let found_path = self.target_module.find_path( self.source_scope.db.upcast(), ModuleDef::from(adt), - false, - true, + cfg, )?; if let Some(qual) = mod_path_to_ast(&found_path).qualifier() { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs index 8302b015ddaf..92478ef480d6 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string.rs @@ -41,6 +41,7 @@ pub enum FormatSpecifier { Escape, } +// FIXME: Remove this, we can use rustc_format_parse instead pub fn lex_format_specifiers( string: &ast::String, mut callback: &mut dyn FnMut(TextRange, FormatSpecifier), diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs index b3dde977b1c4..132b93df10ab 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs @@ -1,7 +1,7 @@ //! This diagnostic provides an assist for creating a struct definition from a JSON //! example. -use hir::{PathResolution, Semantics}; +use hir::{ImportPathConfig, PathResolution, Semantics}; use ide_db::{ base_db::{FileId, FileRange}, helpers::mod_path_to_ast, @@ -142,14 +142,19 @@ pub(crate) fn json_in_items( ImportScope::Block(it) => ImportScope::Block(scb.make_mut(it)), }; let current_module = semantics_scope.module(); + + let cfg = ImportPathConfig { + prefer_no_std: config.prefer_no_std, + prefer_prelude: config.prefer_prelude, + }; + if !scope_has("Serialize") { if let Some(PathResolution::Def(it)) = serialize_resolved { - if let Some(it) = current_module.find_use_path_prefixed( + if let Some(it) = current_module.find_use_path( sema.db, it, config.insert_use.prefix_kind, - config.prefer_no_std, - config.prefer_prelude, + cfg, ) { insert_use(&scope, mod_path_to_ast(&it), &config.insert_use); } @@ -157,12 +162,11 @@ pub(crate) fn json_in_items( } if !scope_has("Deserialize") { if let Some(PathResolution::Def(it)) = deserialize_resolved { - if let Some(it) = current_module.find_use_path_prefixed( + if let Some(it) = current_module.find_use_path( sema.db, it, config.insert_use.prefix_kind, - config.prefer_no_std, - config.prefer_prelude, + cfg, ) { insert_use(&scope, mod_path_to_ast(&it), &config.insert_use); } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs index f92ba576d3ab..9eff84b89879 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -1,7 +1,7 @@ use either::Either; use hir::{ db::{ExpandDatabase, HirDatabase}, - known, AssocItem, HirDisplay, HirFileIdExt, InFile, Type, + known, AssocItem, HirDisplay, HirFileIdExt, ImportPathConfig, InFile, Type, }; use ide_db::{ assists::Assist, famous_defs::FamousDefs, imports::import_assets::item_for_path_search, @@ -122,11 +122,13 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option Option { let item_in_ns = hir::ItemInNs::from(hir::ModuleDef::from(ty.as_adt()?)); - let type_path = current_module?.find_use_path( + let type_path = current_module?.find_path( ctx.sema.db, item_for_path_search(ctx.sema.db, item_in_ns)?, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, )?; use_trivial_constructor( diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs index 656d79dc7324..9651ce6106b7 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/typed_hole.rs @@ -1,7 +1,7 @@ use hir::{ db::ExpandDatabase, term_search::{term_search, TermSearchConfig, TermSearchCtx}, - ClosureStyle, HirDisplay, + ClosureStyle, HirDisplay, ImportPathConfig, }; use ide_db::{ assists::{Assist, AssistId, AssistKind, GroupLabel}, @@ -59,8 +59,10 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option path.gen_source_code( &scope, &mut formatter, - ctx.config.prefer_no_std, - ctx.config.prefer_prelude, + ImportPathConfig { + prefer_no_std: ctx.config.prefer_no_std, + prefer_prelude: ctx.config.prefer_prelude, + }, ) .ok() }) @@ -368,6 +370,7 @@ fn main() { ); } + // FIXME #[test] fn local_shadow_fn() { check_fixes_unordered( @@ -385,7 +388,7 @@ fn f() { r#" fn f() { let f: i32 = 0; - crate::f() + f() }"#, ], ); diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs index cfda1c692aea..cf7e7e08bc52 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs @@ -6,7 +6,7 @@ use crate::{ resolving::{ResolvedPattern, ResolvedRule, UfcsCallInfo}, SsrMatches, }; -use hir::Semantics; +use hir::{ImportPathConfig, Semantics}; use ide_db::{base_db::FileRange, FxHashMap}; use std::{cell::Cell, iter::Peekable}; use syntax::{ @@ -663,10 +663,10 @@ impl Match { .module(); for (path, resolved_path) in &template.resolved_paths { if let hir::PathResolution::Def(module_def) = resolved_path.resolution { - let mod_path = - module.find_use_path(sema.db, module_def, false, true).ok_or_else(|| { - match_error!("Failed to render template path `{}` at match location") - })?; + let cfg = ImportPathConfig { prefer_no_std: false, prefer_prelude: true }; + let mod_path = module.find_path(sema.db, module_def, cfg).ok_or_else(|| { + match_error!("Failed to render template path `{}` at match location") + })?; self.rendered_template_paths.insert(path.clone(), mod_path); } } diff --git a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs index 458b852e2a1e..654a1cd31647 100644 --- a/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs +++ b/src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs @@ -109,12 +109,12 @@ pub(crate) fn outgoing_calls( let expr = call.expr()?; let callable = sema.type_of_expr(&expr)?.original.as_callable(db)?; match callable.kind() { - hir::CallableKind::Function(it) => { - let range = expr.syntax().text_range(); - it.try_to_nav(db).zip(Some(range)) - } + hir::CallableKind::Function(it) => it.try_to_nav(db), + hir::CallableKind::TupleEnumVariant(it) => it.try_to_nav(db), + hir::CallableKind::TupleStruct(it) => it.try_to_nav(db), _ => None, } + .zip(Some(expr.syntax().text_range())) } ast::CallableExpr::MethodCall(expr) => { let range = expr.name_ref()?.syntax().text_range(); diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs index 8d765dfc91b4..f42613637b25 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs @@ -487,19 +487,23 @@ fn get_doc_base_urls( let system_doc = sysroot .map(|sysroot| format!("file:///{sysroot}/share/doc/rust/html/")) .and_then(|it| Url::parse(&it).ok()); + let krate = def.krate(db); + let channel = krate + .and_then(|krate| db.toolchain_channel(krate.into())) + .unwrap_or(ReleaseChannel::Nightly) + .as_str(); // special case base url of `BuiltinType` to core // https://github.com/rust-lang/rust-analyzer/issues/12250 if let Definition::BuiltinType(..) = def { - let web_link = Url::parse("https://doc.rust-lang.org/nightly/core/").ok(); + let web_link = Url::parse(&format!("https://doc.rust-lang.org/{channel}/core/")).ok(); let system_link = system_doc.and_then(|it| it.join("core/").ok()); return (web_link, system_link); }; - let Some(krate) = def.krate(db) else { return Default::default() }; + let Some(krate) = krate else { return Default::default() }; let Some(display_name) = krate.display_name(db) else { return Default::default() }; let crate_data = &db.crate_graph()[krate.into()]; - let channel = db.toolchain_channel(krate.into()).unwrap_or(ReleaseChannel::Nightly).as_str(); let (web_base, local_base) = match &crate_data.origin { // std and co do not specify `html_root_url` any longer so we gotta handwrite this ourself. diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs index 0cb8c485b2f2..3311bb48ad65 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs @@ -1120,4 +1120,30 @@ fn test() { "#, ); } + + #[test] + fn type_hints_async_block() { + check_types( + r#" +//- minicore: future +async fn main() { + let _x = async { 8_i32 }; + //^^ impl Future +}"#, + ); + } + + #[test] + fn type_hints_async_block_with_tail_return_exp() { + check_types( + r#" +//- minicore: future +async fn main() { + let _x = async { + //^^ impl Future + return 8_i32; + }; +}"#, + ); + } } diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs index 96e845b2f323..fb50c49a3ae8 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs @@ -24,34 +24,29 @@ pub(super) fn hints( let (callable, arg_list) = get_callable(sema, &expr)?; let hints = callable - .params(sema.db) + .params() .into_iter() .zip(arg_list.args()) - .filter_map(|((param, _ty), arg)| { + .filter_map(|(p, arg)| { // Only annotate hints for expressions that exist in the original file let range = sema.original_range_opt(arg.syntax())?; - let (param_name, name_syntax) = match param.as_ref()? { + let source = p.source(sema.db)?; + let (param_name, name_syntax) = match source.value.as_ref() { Either::Left(pat) => (pat.name()?, pat.name()), - Either::Right(pat) => match pat { + Either::Right(param) => match param.pat()? { ast::Pat::IdentPat(it) => (it.name()?, it.name()), _ => return None, }, }; + // make sure the file is cached so we can map out of macros + sema.parse_or_expand(source.file_id); Some((name_syntax, param_name, arg, range)) }) .filter(|(_, param_name, arg, _)| { !should_hide_param_name_hint(sema, &callable, ¶m_name.text(), arg) }) .map(|(param, param_name, _, FileRange { range, .. })| { - let mut linked_location = None; - if let Some(name) = param { - if let hir::CallableKind::Function(f) = callable.kind() { - // assert the file is cached so we can map out of macros - if sema.source(f).is_some() { - linked_location = sema.original_range_opt(name.syntax()); - } - } - } + let linked_location = param.and_then(|name| sema.original_range_opt(name.syntax())); let colon = if config.render_colons { ":" } else { "" }; let label = diff --git a/src/tools/rust-analyzer/crates/ide/src/runnables.rs b/src/tools/rust-analyzer/crates/ide/src/runnables.rs index 64ffa5910176..2feea09840fa 100644 --- a/src/tools/rust-analyzer/crates/ide/src/runnables.rs +++ b/src/tools/rust-analyzer/crates/ide/src/runnables.rs @@ -79,7 +79,7 @@ impl RunnableKind { impl Runnable { // test package::module::testname - pub fn label(&self, target: Option) -> String { + pub fn label(&self, target: Option<&str>) -> String { match &self.kind { RunnableKind::Test { test_id, .. } => format!("test {test_id}"), RunnableKind::TestMod { path } => format!("test-mod {path}"), diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index b2eb5a5fff1e..378a38892c7d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -201,7 +201,21 @@ fn signature_help_for_call( variant.name(db).display(db) ); } - hir::CallableKind::Closure | hir::CallableKind::FnPtr | hir::CallableKind::Other => (), + hir::CallableKind::Closure(closure) => { + let fn_trait = closure.fn_trait(db); + format_to!(res.signature, "impl {fn_trait}") + } + hir::CallableKind::FnPtr => format_to!(res.signature, "fn"), + hir::CallableKind::FnImpl(fn_trait) => match callable.ty().as_adt() { + // FIXME: Render docs of the concrete trait impl function + Some(adt) => format_to!( + res.signature, + "<{} as {fn_trait}>::{}", + adt.name(db).display(db), + fn_trait.function_name() + ), + None => format_to!(res.signature, "impl {fn_trait}"), + }, } res.signature.push('('); @@ -210,12 +224,15 @@ fn signature_help_for_call( format_to!(res.signature, "{}", self_param.display(db)) } let mut buf = String::new(); - for (idx, (pat, ty)) in callable.params(db).into_iter().enumerate() { + for (idx, p) in callable.params().into_iter().enumerate() { buf.clear(); - if let Some(pat) = pat { - match pat { - Either::Left(_self) => format_to!(buf, "self: "), - Either::Right(pat) => format_to!(buf, "{}: ", pat), + if let Some(param) = p.source(sema.db) { + match param.value { + Either::Right(param) => match param.pat() { + Some(pat) => format_to!(buf, "{}: ", pat), + None => format_to!(buf, "?: "), + }, + Either::Left(_) => format_to!(buf, "self: "), } } // APITs (argument position `impl Trait`s) are inferred as {unknown} as the user is @@ -223,9 +240,9 @@ fn signature_help_for_call( // In that case, fall back to render definitions of the respective parameters. // This is overly conservative: we do not substitute known type vars // (see FIXME in tests::impl_trait) and falling back on any unknowns. - match (ty.contains_unknown(), fn_params.as_deref()) { + match (p.ty().contains_unknown(), fn_params.as_deref()) { (true, Some(fn_params)) => format_to!(buf, "{}", fn_params[idx].ty().display(db)), - _ => format_to!(buf, "{}", ty.display(db)), + _ => format_to!(buf, "{}", p.ty().display(db)), } res.push_call_param(&buf); } @@ -242,9 +259,9 @@ fn signature_help_for_call( render(func.ret_type(db)) } hir::CallableKind::Function(_) - | hir::CallableKind::Closure + | hir::CallableKind::Closure(_) | hir::CallableKind::FnPtr - | hir::CallableKind::Other => render(callable.return_type()), + | hir::CallableKind::FnImpl(_) => render(callable.return_type()), hir::CallableKind::TupleStruct(_) | hir::CallableKind::TupleEnumVariant(_) => {} } Some(res) @@ -1345,15 +1362,43 @@ fn test() { S.foo($0); } r#" struct S; fn foo(s: S) -> i32 { 92 } +fn main() { + let _move = S; + (|s| {{_move}; foo(s)})($0) +} + "#, + expect![[r#" + impl FnOnce(s: S) -> i32 + ^^^^ + "#]], + ); + check( + r#" +struct S; +fn foo(s: S) -> i32 { 92 } fn main() { (|s| foo(s))($0) } "#, expect![[r#" - (s: S) -> i32 - ^^^^ + impl Fn(s: S) -> i32 + ^^^^ "#]], - ) + ); + check( + r#" +struct S; +fn foo(s: S) -> i32 { 92 } +fn main() { + let mut mutate = 0; + (|s| { mutate = 1; foo(s) })($0) +} + "#, + expect![[r#" + impl FnMut(s: S) -> i32 + ^^^^ + "#]], + ); } #[test] @@ -1383,12 +1428,81 @@ fn main(f: fn(i32, f64) -> char) { } "#, expect![[r#" - (i32, f64) -> char - --- ^^^ + fn(i32, f64) -> char + --- ^^^ "#]], ) } + #[test] + fn call_info_for_fn_impl() { + check( + r#" +struct S; +impl core::ops::FnOnce<(i32, f64)> for S { + type Output = char; +} +impl core::ops::FnMut<(i32, f64)> for S {} +impl core::ops::Fn<(i32, f64)> for S {} +fn main() { + S($0); +} + "#, + expect![[r#" + ::call(i32, f64) -> char + ^^^ --- + "#]], + ); + check( + r#" +struct S; +impl core::ops::FnOnce<(i32, f64)> for S { + type Output = char; +} +impl core::ops::FnMut<(i32, f64)> for S {} +impl core::ops::Fn<(i32, f64)> for S {} +fn main() { + S(1, $0); +} + "#, + expect![[r#" + ::call(i32, f64) -> char + --- ^^^ + "#]], + ); + check( + r#" +struct S; +impl core::ops::FnOnce<(i32, f64)> for S { + type Output = char; +} +impl core::ops::FnOnce<(char, char)> for S { + type Output = f64; +} +fn main() { + S($0); +} + "#, + expect![""], + ); + check( + r#" +struct S; +impl core::ops::FnOnce<(i32, f64)> for S { + type Output = char; +} +impl core::ops::FnOnce<(char, char)> for S { + type Output = f64; +} +fn main() { + // FIXME: The ide layer loses the calling info here so we get an ambiguous trait solve result + S(0i32, $0); +} + "#, + expect![""], + ); + } + #[test] fn call_info_for_unclosed_call() { check( @@ -1794,19 +1908,19 @@ fn f i32>(f: F) { } "#, expect![[r#" - (u8, u16) -> i32 - ^^ --- + impl FnOnce(u8, u16) -> i32 + ^^ --- "#]], ); check( r#" -fn f &T>(f: F) { +fn f &T>(f: F) { f($0) } "#, expect![[r#" - (&T, u16) -> &T - ^^ --- + impl FnMut(&T, u16) -> &T + ^^ --- "#]], ); } @@ -1826,7 +1940,7 @@ fn take( } "#, expect![[r#" - () -> i32 + impl Fn() -> i32 "#]], ); } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs index 0439e509d21d..2f387968c96a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs @@ -9,8 +9,9 @@ pub(super) fn highlight_escape_string( string: &T, start: TextSize, ) { + let text = string.text(); string.escaped_char_ranges(&mut |piece_range, char| { - if string.text()[piece_range.start().into()..].starts_with('\\') { + if text[piece_range.start().into()..].starts_with('\\') { let highlight = match char { Ok(_) => HlTag::EscapeSequence, Err(_) => HlTag::InvalidEscapeSequence, @@ -33,17 +34,15 @@ pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char, start: } let text = char.text(); - if !text.starts_with('\'') || !text.ends_with('\'') { + let Some(text) = text + .strip_prefix('\'') + .and_then(|it| it.strip_suffix('\'')) + .filter(|it| it.starts_with('\\')) + else { return; - } + }; - let text = &text[1..text.len() - 1]; - if !text.starts_with('\\') { - return; - } - - let range = - TextRange::new(start + TextSize::from(1), start + TextSize::from(text.len() as u32 + 1)); + let range = TextRange::at(start + TextSize::from(1), TextSize::from(text.len() as u32)); stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None }) } @@ -54,16 +53,14 @@ pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte, start: } let text = byte.text(); - if !text.starts_with("b'") || !text.ends_with('\'') { + let Some(text) = text + .strip_prefix("b'") + .and_then(|it| it.strip_suffix('\'')) + .filter(|it| it.starts_with('\\')) + else { return; - } + }; - let text = &text[2..text.len() - 1]; - if !text.starts_with('\\') { - return; - } - - let range = - TextRange::new(start + TextSize::from(2), start + TextSize::from(text.len() as u32 + 2)); + let range = TextRange::at(start + TextSize::from(2), TextSize::from(text.len() as u32)); stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None }) } diff --git a/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs b/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs index 8e1f7fdcded7..d2f423590e2c 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs @@ -65,7 +65,7 @@ impl WorkspaceBuildScripts { allowed_features: &FxHashSet, manifest_path: &ManifestPath, toolchain: Option<&Version>, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> io::Result { const RUST_1_75: Version = Version::new(1, 75, 0); let mut cmd = match config.run_build_script_command.as_deref() { @@ -75,7 +75,7 @@ impl WorkspaceBuildScripts { cmd } _ => { - let mut cmd = Sysroot::tool(sysroot, Tool::Cargo); + let mut cmd = sysroot.tool(Tool::Cargo); cmd.args(["check", "--quiet", "--workspace", "--message-format=json"]); cmd.args(&config.extra_args); @@ -149,7 +149,7 @@ impl WorkspaceBuildScripts { workspace: &CargoWorkspace, progress: &dyn Fn(String), toolchain: Option<&Version>, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> io::Result { let current_dir = match &config.invocation_location { InvocationLocation::Root(root) if config.run_build_script_command.is_some() => { @@ -195,7 +195,7 @@ impl WorkspaceBuildScripts { // This is not gonna be used anyways, so just construct a dummy here &ManifestPath::try_from(workspace_root.clone()).unwrap(), None, - None, + &Sysroot::empty(), )?; // NB: Cargo.toml could have been modified between `cargo metadata` and // `cargo check`. We shouldn't assume that package ids we see here are @@ -412,7 +412,7 @@ impl WorkspaceBuildScripts { rustc: &CargoWorkspace, current_dir: &AbsPath, extra_env: &FxHashMap, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> Self { let mut bs = WorkspaceBuildScripts::default(); for p in rustc.packages() { @@ -420,7 +420,7 @@ impl WorkspaceBuildScripts { } let res = (|| { let target_libdir = (|| { - let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo); + let mut cargo_config = sysroot.tool(Tool::Cargo); cargo_config.envs(extra_env); cargo_config .current_dir(current_dir) @@ -429,7 +429,7 @@ impl WorkspaceBuildScripts { if let Ok(it) = utf8_stdout(cargo_config) { return Ok(it); } - let mut cmd = Sysroot::tool(sysroot, Tool::Rustc); + let mut cmd = sysroot.tool(Tool::Rustc); cmd.envs(extra_env); cmd.args(["--print", "target-libdir"]); utf8_stdout(cmd) diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index 9955f2687c91..632ba1cacf21 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -258,12 +258,12 @@ impl CargoWorkspace { cargo_toml: &ManifestPath, current_dir: &AbsPath, config: &CargoConfig, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, progress: &dyn Fn(String), ) -> anyhow::Result { let targets = find_list_of_build_targets(config, cargo_toml, sysroot); - let cargo = Sysroot::tool(sysroot, Tool::Cargo); + let cargo = sysroot.tool(Tool::Cargo); let mut meta = MetadataCommand::new(); meta.cargo_path(cargo.get_program()); cargo.get_envs().for_each(|(var, val)| _ = meta.env(var, val.unwrap_or_default())); @@ -536,7 +536,7 @@ impl CargoWorkspace { fn find_list_of_build_targets( config: &CargoConfig, cargo_toml: &ManifestPath, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> Vec { if let Some(target) = &config.target { return [target.into()].to_vec(); @@ -553,9 +553,9 @@ fn find_list_of_build_targets( fn rustc_discover_host_triple( cargo_toml: &ManifestPath, extra_env: &FxHashMap, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> Option { - let mut rustc = Sysroot::tool(sysroot, Tool::Rustc); + let mut rustc = sysroot.tool(Tool::Rustc); rustc.envs(extra_env); rustc.current_dir(cargo_toml.parent()).arg("-vV"); tracing::debug!("Discovering host platform by {:?}", rustc); @@ -581,9 +581,9 @@ fn rustc_discover_host_triple( fn cargo_config_build_target( cargo_toml: &ManifestPath, extra_env: &FxHashMap, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> Vec { - let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo); + let mut cargo_config = sysroot.tool(Tool::Cargo); cargo_config.envs(extra_env); cargo_config .current_dir(cargo_toml.parent()) diff --git a/src/tools/rust-analyzer/crates/project-model/src/env.rs b/src/tools/rust-analyzer/crates/project-model/src/env.rs index 5520cdaff6b0..88fb10a68c61 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/env.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/env.rs @@ -62,9 +62,9 @@ pub(crate) fn inject_rustc_tool_env(env: &mut Env, cargo_name: &str, kind: Targe pub(crate) fn cargo_config_env( manifest: &ManifestPath, extra_env: &FxHashMap, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, ) -> FxHashMap { - let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo); + let mut cargo_config = sysroot.tool(Tool::Cargo); cargo_config.envs(extra_env); cargo_config .current_dir(manifest.parent()) diff --git a/src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs b/src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs index 4f69b2b96f0c..26499308ce96 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/rustc_cfg.rs @@ -10,10 +10,10 @@ use crate::{cfg::CfgFlag, utf8_stdout, ManifestPath, Sysroot}; pub(crate) enum RustcCfgConfig<'a> { /// Use `rustc --print cfg`, either from with the binary from the sysroot or by discovering via /// [`toolchain::rustc`]. - Rustc(Option<&'a Sysroot>), + Rustc(&'a Sysroot), /// Use `cargo --print cfg`, either from with the binary from the sysroot or by discovering via /// [`toolchain::cargo`]. - Cargo(Option<&'a Sysroot>, &'a ManifestPath), + Cargo(&'a Sysroot, &'a ManifestPath), } pub(crate) fn get( @@ -65,7 +65,7 @@ fn get_rust_cfgs( ) -> anyhow::Result { let sysroot = match config { RustcCfgConfig::Cargo(sysroot, cargo_toml) => { - let mut cmd = Sysroot::tool(sysroot, Tool::Cargo); + let mut cmd = sysroot.tool(Tool::Cargo); cmd.envs(extra_env); cmd.current_dir(cargo_toml.parent()) @@ -86,7 +86,7 @@ fn get_rust_cfgs( RustcCfgConfig::Rustc(sysroot) => sysroot, }; - let mut cmd = Sysroot::tool(sysroot, Tool::Rustc); + let mut cmd = sysroot.tool(Tool::Rustc); cmd.envs(extra_env); cmd.args(["--print", "cfg", "-O"]); if let Some(target) = target { diff --git a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs index e6bbe6ede8a0..653e7157bcb3 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs @@ -4,7 +4,7 @@ //! but we can't process `.rlib` and need source code instead. The source code //! is typically installed with `rustup component add rust-src` command. -use std::{env, fs, ops, process::Command, sync::Arc}; +use std::{env, fs, ops, process::Command}; use anyhow::{format_err, Result}; use base_db::CrateName; @@ -16,30 +16,19 @@ use toolchain::{probe_for_binary, Tool}; use crate::{utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath}; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Sysroot { - root: AbsPathBuf, - src_root: Option>>, + root: Option, + src_root: Option, mode: SysrootMode, -} - -impl Eq for Sysroot {} -impl PartialEq for Sysroot { - fn eq(&self, other: &Self) -> bool { - self.root == other.root - && self.mode == other.mode - && match (&self.src_root, &other.src_root) { - (Some(Ok(this)), Some(Ok(other))) => this == other, - (None, None) | (Some(Err(_)), Some(Err(_))) => true, - _ => false, - } - } + error: Option, } #[derive(Debug, Clone, Eq, PartialEq)] pub(crate) enum SysrootMode { Workspace(CargoWorkspace), Stitched(Stitched), + Empty, } #[derive(Debug, Clone, Eq, PartialEq)] @@ -89,70 +78,40 @@ pub(crate) struct SysrootCrateData { } impl Sysroot { + pub const fn empty() -> Sysroot { + Sysroot { root: None, src_root: None, mode: SysrootMode::Empty, error: None } + } + /// Returns sysroot "root" directory, where `bin/`, `etc/`, `lib/`, `libexec/` /// subfolder live, like: /// `$HOME/.rustup/toolchains/nightly-2022-07-23-x86_64-unknown-linux-gnu` - pub fn root(&self) -> &AbsPath { - &self.root + pub fn root(&self) -> Option<&AbsPath> { + self.root.as_deref() } /// Returns the sysroot "source" directory, where stdlib sources are located, like: /// `$HOME/.rustup/toolchains/nightly-2022-07-23-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library` pub fn src_root(&self) -> Option<&AbsPath> { - self.src_root.as_ref()?.as_deref().ok() + self.src_root.as_deref() } pub fn is_empty(&self) -> bool { match &self.mode { SysrootMode::Workspace(ws) => ws.packages().next().is_none(), SysrootMode::Stitched(stitched) => stitched.crates.is_empty(), + SysrootMode::Empty => true, } } - pub fn loading_warning(&self) -> Option { - let src_root = match &self.src_root { - None => return Some(format!("sysroot at `{}` has no library sources", self.root)), - Some(Ok(src_root)) => src_root, - Some(Err(e)) => return Some(e.to_string()), - }; - let has_core = match &self.mode { - SysrootMode::Workspace(ws) => ws.packages().any(|p| ws[p].name == "core"), - SysrootMode::Stitched(stitched) => stitched.by_name("core").is_some(), - }; - if !has_core { - let var_note = if env::var_os("RUST_SRC_PATH").is_some() { - " (`RUST_SRC_PATH` might be incorrect, try unsetting it)" - } else { - " try running `rustup component add rust-src` to possible fix this" - }; - Some(format!("could not find libcore in loaded sysroot at `{}`{var_note}", src_root,)) - } else { - None - } - } - - pub fn check_has_core(&self) -> Result<(), String> { - let Some(Ok(src_root)) = &self.src_root else { return Ok(()) }; - let has_core = match &self.mode { - SysrootMode::Workspace(ws) => ws.packages().any(|p| ws[p].name == "core"), - SysrootMode::Stitched(stitched) => stitched.by_name("core").is_some(), - }; - if !has_core { - let var_note = if env::var_os("RUST_SRC_PATH").is_some() { - " (`RUST_SRC_PATH` might be incorrect, try unsetting it)" - } else { - " try running `rustup component add rust-src` to possible fix this" - }; - Err(format!("could not find libcore in loaded sysroot at `{}`{var_note}", src_root,)) - } else { - Ok(()) - } + pub fn error(&self) -> Option<&str> { + self.error.as_deref() } pub fn num_packages(&self) -> usize { match &self.mode { SysrootMode::Workspace(ws) => ws.packages().count(), SysrootMode::Stitched(c) => c.crates().count(), + SysrootMode::Empty => 0, } } @@ -168,63 +127,50 @@ impl Sysroot { dir: &AbsPath, extra_env: &FxHashMap, metadata: bool, - ) -> Result { - tracing::debug!("discovering sysroot for {dir}"); - let sysroot_dir = discover_sysroot_dir(dir, extra_env)?; - let sysroot_src_dir = - discover_sysroot_src_dir_or_add_component(&sysroot_dir, dir, extra_env); - Ok(Sysroot::load(sysroot_dir, Some(sysroot_src_dir), metadata)) - } - - pub fn discover_no_source( - dir: &AbsPath, - extra_env: &FxHashMap, - ) -> Result { - tracing::debug!("discovering sysroot for {dir}"); - let sysroot_dir = discover_sysroot_dir(dir, extra_env)?; - let sysroot_src_dir = - discover_sysroot_src_dir_or_add_component(&sysroot_dir, dir, extra_env); - Ok(Sysroot::load(sysroot_dir, Some(sysroot_src_dir), false)) + ) -> Sysroot { + let sysroot_dir = discover_sysroot_dir(dir, extra_env); + let sysroot_src_dir = sysroot_dir.as_ref().ok().map(|sysroot_dir| { + discover_sysroot_src_dir_or_add_component(sysroot_dir, dir, extra_env) + }); + Sysroot::load_core_check(Some(sysroot_dir), sysroot_src_dir, metadata) } pub fn discover_with_src_override( current_dir: &AbsPath, extra_env: &FxHashMap, - src: AbsPathBuf, + sysroot_src_dir: AbsPathBuf, metadata: bool, - ) -> Result { - tracing::debug!("discovering sysroot for {current_dir}"); - let sysroot_dir = discover_sysroot_dir(current_dir, extra_env)?; - Ok(Sysroot::load(sysroot_dir, Some(Ok(src)), metadata)) + ) -> Sysroot { + let sysroot_dir = discover_sysroot_dir(current_dir, extra_env); + Sysroot::load_core_check(Some(sysroot_dir), Some(Ok(sysroot_src_dir)), metadata) + } + + pub fn discover_sysroot_src_dir(sysroot_dir: AbsPathBuf, metadata: bool) -> Sysroot { + let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir) + .ok_or_else(|| format_err!("can't find standard library sources in {sysroot_dir}")); + Sysroot::load_core_check(Some(Ok(sysroot_dir)), Some(sysroot_src_dir), metadata) } pub fn discover_rustc_src(&self) -> Option { - get_rustc_src(&self.root) - } - - pub fn with_sysroot_dir(sysroot_dir: AbsPathBuf, metadata: bool) -> Result { - let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir).ok_or_else(|| { - format_err!("can't load standard library from sysroot path {sysroot_dir}") - }); - Ok(Sysroot::load(sysroot_dir, Some(sysroot_src_dir), metadata)) + get_rustc_src(self.root()?) } /// Returns a command to run a tool preferring the cargo proxies if the sysroot exists. - pub fn tool(sysroot: Option<&Self>, tool: Tool) -> Command { - match sysroot { - Some(sysroot) => { + pub fn tool(&self, tool: Tool) -> Command { + match self.root() { + Some(root) => { // special case rustc, we can look that up directly in the sysroot's bin folder // as it should never invoke another cargo binary if let Tool::Rustc = tool { if let Some(path) = - probe_for_binary(sysroot.root.join("bin").join(Tool::Rustc.name()).into()) + probe_for_binary(root.join("bin").join(Tool::Rustc.name()).into()) { return Command::new(path); } } let mut cmd = Command::new(tool.prefer_proxy()); - cmd.env("RUSTUP_TOOLCHAIN", AsRef::::as_ref(&sysroot.root)); + cmd.env("RUSTUP_TOOLCHAIN", AsRef::::as_ref(root)); cmd } _ => Command::new(tool.path()), @@ -232,35 +178,89 @@ impl Sysroot { } pub fn discover_proc_macro_srv(&self) -> anyhow::Result { + let Some(root) = self.root() else { + return Err(anyhow::format_err!("no sysroot",)); + }; ["libexec", "lib"] .into_iter() - .map(|segment| self.root().join(segment).join("rust-analyzer-proc-macro-srv")) + .map(|segment| root.join(segment).join("rust-analyzer-proc-macro-srv")) .find_map(|server_path| probe_for_binary(server_path.into())) .map(AbsPathBuf::assert) .ok_or_else(|| { - anyhow::format_err!("cannot find proc-macro server in sysroot `{}`", self.root()) + anyhow::format_err!("cannot find proc-macro server in sysroot `{}`", root) }) } pub fn load( - sysroot_dir: AbsPathBuf, + sysroot_dir: Option, + sysroot_src_dir: Option, + metadata: bool, + ) -> Sysroot { + Self::load_core_check(sysroot_dir.map(Ok), sysroot_src_dir.map(Ok), metadata) + } + + fn load_core_check( + sysroot_dir: Option>, sysroot_src_dir: Option>, metadata: bool, ) -> Sysroot { + let mut sysroot = Self::load_(sysroot_dir, sysroot_src_dir, metadata); + if sysroot.error.is_none() { + if let Some(src_root) = &sysroot.src_root { + let has_core = match &sysroot.mode { + SysrootMode::Workspace(ws) => ws.packages().any(|p| ws[p].name == "core"), + SysrootMode::Stitched(stitched) => stitched.by_name("core").is_some(), + SysrootMode::Empty => true, + }; + if !has_core { + let var_note = if env::var_os("RUST_SRC_PATH").is_some() { + " (env var `RUST_SRC_PATH` is set and may be incorrect, try unsetting it)" + } else { + ", try running `rustup component add rust-src` to possibly fix this" + }; + sysroot.error = Some(format!( + "sysroot at `{}` is missing a `core` library{var_note}", + src_root, + )); + } + } + } + sysroot + } + + fn load_( + sysroot_dir: Option>, + sysroot_src_dir: Option>, + metadata: bool, + ) -> Sysroot { + let sysroot_dir = match sysroot_dir { + Some(Ok(sysroot_dir)) => Some(sysroot_dir), + Some(Err(e)) => { + return Sysroot { + root: None, + src_root: None, + mode: SysrootMode::Empty, + error: Some(e.to_string()), + } + } + None => None, + }; let sysroot_src_dir = match sysroot_src_dir { Some(Ok(sysroot_src_dir)) => sysroot_src_dir, Some(Err(e)) => { return Sysroot { root: sysroot_dir, - src_root: Some(Err(Arc::new(e))), - mode: SysrootMode::Stitched(Stitched { crates: Arena::default() }), + src_root: None, + mode: SysrootMode::Empty, + error: Some(e.to_string()), } } None => { return Sysroot { root: sysroot_dir, src_root: None, - mode: SysrootMode::Stitched(Stitched { crates: Arena::default() }), + mode: SysrootMode::Empty, + error: None, } } }; @@ -284,7 +284,7 @@ impl Sysroot { &sysroot_cargo_toml, ¤t_dir, &cargo_config, - None, + &Sysroot::empty(), &|_| (), ) .map_err(|e| { @@ -368,8 +368,9 @@ impl Sysroot { let cargo_workspace = CargoWorkspace::new(res, sysroot_cargo_toml); Some(Sysroot { root: sysroot_dir.clone(), - src_root: Some(Ok(sysroot_src_dir.clone())), + src_root: Some(sysroot_src_dir.clone()), mode: SysrootMode::Workspace(cargo_workspace), + error: None, }) })(); if let Some(sysroot) = sysroot { @@ -420,8 +421,9 @@ impl Sysroot { } Sysroot { root: sysroot_dir, - src_root: Some(Ok(sysroot_src_dir)), + src_root: Some(sysroot_src_dir), mode: SysrootMode::Stitched(stitched), + error: None, } } } diff --git a/src/tools/rust-analyzer/crates/project-model/src/target_data_layout.rs b/src/tools/rust-analyzer/crates/project-model/src/target_data_layout.rs index 4e810a0232ea..8a8a2d32558b 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/target_data_layout.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/target_data_layout.rs @@ -9,10 +9,10 @@ use crate::{utf8_stdout, ManifestPath, Sysroot}; pub enum RustcDataLayoutConfig<'a> { /// Use `rustc --print target-spec-json`, either from with the binary from the sysroot or by discovering via /// [`toolchain::rustc`]. - Rustc(Option<&'a Sysroot>), + Rustc(&'a Sysroot), /// Use `cargo --print target-spec-json`, either from with the binary from the sysroot or by discovering via /// [`toolchain::cargo`]. - Cargo(Option<&'a Sysroot>, &'a ManifestPath), + Cargo(&'a Sysroot, &'a ManifestPath), } pub fn get( @@ -28,7 +28,7 @@ pub fn get( }; let sysroot = match config { RustcDataLayoutConfig::Cargo(sysroot, cargo_toml) => { - let mut cmd = Sysroot::tool(sysroot, Tool::Cargo); + let mut cmd = sysroot.tool(Tool::Cargo); cmd.envs(extra_env); cmd.current_dir(cargo_toml.parent()) .args([ diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs index 3d5a934fc92e..a6730863d6b2 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs @@ -34,7 +34,7 @@ fn load_cargo_with_overrides( cargo_config_extra_env: Default::default(), }, cfg_overrides, - sysroot: Err(None), + sysroot: Sysroot::empty(), rustc_cfg: Vec::new(), toolchain: None, target_layout: Err("target_data_layout not loaded".into()), @@ -57,7 +57,7 @@ fn load_cargo_with_fake_sysroot( rustc: Err(None), cargo_config_extra_env: Default::default(), }, - sysroot: Ok(get_fake_sysroot()), + sysroot: get_fake_sysroot(), rustc_cfg: Vec::new(), cfg_overrides: Default::default(), toolchain: None, @@ -77,7 +77,7 @@ fn load_cargo_with_fake_sysroot( fn load_rust_project(file: &str) -> (CrateGraph, ProcMacroPaths) { let data = get_test_json_file(file); let project = rooted_project_json(data); - let sysroot = Ok(get_fake_sysroot()); + let sysroot = get_fake_sysroot(); let project_workspace = ProjectWorkspace { kind: ProjectWorkspaceKind::Json(project), sysroot, @@ -144,7 +144,7 @@ fn get_fake_sysroot() -> Sysroot { // fake sysroot, so we give them both the same path: let sysroot_dir = AbsPathBuf::assert(sysroot_path); let sysroot_src_dir = sysroot_dir.clone(); - Sysroot::load(sysroot_dir, Some(Ok(sysroot_src_dir)), false) + Sysroot::load(Some(sysroot_dir), Some(sysroot_src_dir), false) } fn rooted_project_json(data: ProjectJsonData) -> ProjectJson { @@ -281,12 +281,11 @@ fn smoke_test_real_sysroot_cargo() { let manifest_path = ManifestPath::try_from(AbsPathBuf::try_from(meta.workspace_root.clone()).unwrap()).unwrap(); let cargo_workspace = CargoWorkspace::new(meta, manifest_path); - let sysroot = Ok(Sysroot::discover( + let sysroot = Sysroot::discover( AbsPath::assert(Utf8Path::new(env!("CARGO_MANIFEST_DIR"))), &Default::default(), true, - ) - .unwrap()); + ); let project_workspace = ProjectWorkspace { kind: ProjectWorkspaceKind::Cargo { diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 85621444e339..0d2174073a2a 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -48,7 +48,7 @@ pub struct PackageRoot { pub struct ProjectWorkspace { pub kind: ProjectWorkspaceKind, /// The sysroot loaded for this workspace. - pub sysroot: Result>, + pub sysroot: Sysroot, /// Holds cfg flags for the current target. We get those by running /// `rustc --print cfg`. // FIXME: make this a per-crate map, as, eg, build.rs might have a @@ -112,7 +112,7 @@ impl fmt::Debug for ProjectWorkspace { .debug_struct("Cargo") .field("root", &cargo.workspace_root().file_name()) .field("n_packages", &cargo.packages().len()) - .field("sysroot", &sysroot.is_ok()) + .field("n_sysroot_crates", &sysroot.num_packages()) .field( "n_rustc_compiler_crates", &rustc.as_ref().map(|a| a.as_ref()).map_or(0, |(rc, _)| rc.packages().len()), @@ -125,11 +125,9 @@ impl fmt::Debug for ProjectWorkspace { .finish(), ProjectWorkspaceKind::Json(project) => { let mut debug_struct = f.debug_struct("Json"); - debug_struct.field("n_crates", &project.n_crates()); - if let Ok(sysroot) = sysroot { - debug_struct.field("n_sysroot_crates", &sysroot.num_packages()); - } debug_struct + .field("n_crates", &project.n_crates()) + .field("n_sysroot_crates", &sysroot.num_packages()) .field("n_rustc_cfg", &rustc_cfg.len()) .field("toolchain", &toolchain) .field("data_layout", &target_layout) @@ -144,7 +142,7 @@ impl fmt::Debug for ProjectWorkspace { .debug_struct("DetachedFiles") .field("file", &file) .field("cargo_script", &cargo_script.is_some()) - .field("sysroot", &sysroot.is_ok()) + .field("n_sysroot_crates", &sysroot.num_packages()) .field("cargo_script", &cargo_script.is_some()) .field("n_rustc_cfg", &rustc_cfg.len()) .field("toolchain", &toolchain) @@ -158,7 +156,7 @@ impl fmt::Debug for ProjectWorkspace { fn get_toolchain_version( current_dir: &AbsPath, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, tool: Tool, extra_env: &FxHashMap, prefix: &str, @@ -213,41 +211,37 @@ impl ProjectWorkspace { } ProjectManifest::CargoToml(cargo_toml) => { let sysroot = match (&config.sysroot, &config.sysroot_src) { - (Some(RustLibSource::Path(path)), None) => { - Sysroot::with_sysroot_dir(path.clone(), config.sysroot_query_metadata).map_err(|e| { - Some(format!("Failed to find sysroot at {path}:{e}")) - }) - } - (Some(RustLibSource::Discover), None) => { - Sysroot::discover(cargo_toml.parent(), &config.extra_env, config.sysroot_query_metadata).map_err(|e| { - Some(format!("Failed to find sysroot for Cargo.toml file {cargo_toml}. Is rust-src installed? {e}")) - }) - } - (Some(RustLibSource::Path(sysroot)), Some(sysroot_src)) => { - Ok(Sysroot::load(sysroot.clone(), Some(Ok(sysroot_src.clone())), config.sysroot_query_metadata)) - } + (Some(RustLibSource::Discover), None) => Sysroot::discover( + cargo_toml.parent(), + &config.extra_env, + config.sysroot_query_metadata, + ), (Some(RustLibSource::Discover), Some(sysroot_src)) => { Sysroot::discover_with_src_override( cargo_toml.parent(), &config.extra_env, - sysroot_src.clone(), config.sysroot_query_metadata, - ).map_err(|e| { - Some(format!("Failed to find sysroot for Cargo.toml file {cargo_toml}. Is rust-src installed? {e}")) - }) + sysroot_src.clone(), + config.sysroot_query_metadata, + ) } - (None, _) => Err(None), + (Some(RustLibSource::Path(path)), None) => Sysroot::discover_sysroot_src_dir( + path.clone(), + config.sysroot_query_metadata, + ), + (Some(RustLibSource::Path(sysroot)), Some(sysroot_src)) => Sysroot::load( + Some(sysroot.clone()), + Some(sysroot_src.clone()), + config.sysroot_query_metadata, + ), + (None, _) => Sysroot::empty(), }; - let sysroot_ref = sysroot.as_ref().ok(); - - if let Ok(sysroot) = &sysroot { - tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = %sysroot.root(), "Using sysroot"); - } + tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = ?sysroot.root(), "Using sysroot"); let rustc_dir = match &config.rustc_source { Some(RustLibSource::Path(path)) => ManifestPath::try_from(path.clone()) .map_err(|p| Some(format!("rustc source path is not absolute: {p}"))), Some(RustLibSource::Discover) => { - sysroot_ref.and_then(Sysroot::discover_rustc_src).ok_or_else(|| { + sysroot.discover_rustc_src().ok_or_else(|| { Some("Failed to discover rustc source for sysroot.".to_owned()) }) } @@ -263,7 +257,7 @@ impl ProjectWorkspace { features: crate::CargoFeatures::default(), ..config.clone() }, - sysroot_ref, + &sysroot, progress, ) { Ok(meta) => { @@ -272,7 +266,7 @@ impl ProjectWorkspace { &workspace, cargo_toml.parent(), &config.extra_env, - sysroot_ref + &sysroot ); Ok(Box::new((workspace, buildscripts))) } @@ -290,7 +284,7 @@ impl ProjectWorkspace { let toolchain = get_toolchain_version( cargo_toml.parent(), - sysroot_ref, + &sysroot, Tool::Cargo, &config.extra_env, "cargo ", @@ -298,12 +292,12 @@ impl ProjectWorkspace { let rustc_cfg = rustc_cfg::get( config.target.as_deref(), &config.extra_env, - RustcCfgConfig::Cargo(sysroot_ref, cargo_toml), + RustcCfgConfig::Cargo(&sysroot, cargo_toml), ); let cfg_overrides = config.cfg_overrides.clone(); let data_layout = target_data_layout::get( - RustcDataLayoutConfig::Cargo(sysroot_ref, cargo_toml), + RustcDataLayoutConfig::Cargo(&sysroot, cargo_toml), config.target.as_deref(), &config.extra_env, ); @@ -315,7 +309,7 @@ impl ProjectWorkspace { cargo_toml, cargo_toml.parent(), config, - sysroot_ref, + &sysroot, progress, ) .with_context(|| { @@ -326,7 +320,7 @@ impl ProjectWorkspace { let cargo = CargoWorkspace::new(meta, cargo_toml.clone()); let cargo_config_extra_env = - cargo_config_env(cargo_toml, &config.extra_env, sysroot_ref); + cargo_config_env(cargo_toml, &config.extra_env, &sysroot); ProjectWorkspace { kind: ProjectWorkspaceKind::Cargo { cargo, @@ -354,32 +348,13 @@ impl ProjectWorkspace { extra_env: &FxHashMap, cfg_overrides: &CfgOverrides, ) -> ProjectWorkspace { - let sysroot = match (project_json.sysroot.clone(), project_json.sysroot_src.clone()) { - (Some(sysroot), Some(sysroot_src)) => { - Ok(Sysroot::load(sysroot, Some(Ok(sysroot_src)), false)) - } - (Some(sysroot), None) => { - // assume sysroot is structured like rustup's and guess `sysroot_src` - let sysroot_src = - sysroot.join("lib").join("rustlib").join("src").join("rust").join("library"); - Ok(Sysroot::load(sysroot, Some(Ok(sysroot_src)), false)) - } - (None, Some(sysroot_src)) => { - // assume sysroot is structured like rustup's and guess `sysroot` - let mut sysroot = sysroot_src.clone(); - for _ in 0..5 { - sysroot.pop(); - } - Ok(Sysroot::load(sysroot, Some(Ok(sysroot_src)), false)) - } - (None, None) => Err(None), - }; - let sysroot_ref = sysroot.as_ref().ok(); - let cfg_config = RustcCfgConfig::Rustc(sysroot_ref); - let data_layout_config = RustcDataLayoutConfig::Rustc(sysroot_ref); + let sysroot = + Sysroot::load(project_json.sysroot.clone(), project_json.sysroot_src.clone(), false); + let cfg_config = RustcCfgConfig::Rustc(&sysroot); + let data_layout_config = RustcDataLayoutConfig::Rustc(&sysroot); let toolchain = match get_toolchain_version( project_json.path(), - sysroot_ref, + &sysroot, Tool::Rustc, extra_env, "rustc ", @@ -410,24 +385,16 @@ impl ProjectWorkspace { let dir = detached_file.parent(); let sysroot = match &config.sysroot { Some(RustLibSource::Path(path)) => { - Sysroot::with_sysroot_dir(path.clone(), config.sysroot_query_metadata) - .map_err(|e| Some(format!("Failed to find sysroot at {path}:{e}"))) + Sysroot::discover_sysroot_src_dir(path.clone(), config.sysroot_query_metadata) } - Some(RustLibSource::Discover) => Sysroot::discover( - dir, - &config.extra_env, - config.sysroot_query_metadata, - ) - .map_err(|e| { - Some(format!("Failed to find sysroot for {dir}. Is rust-src installed? {e}")) - }), - None => Err(None), + Some(RustLibSource::Discover) => { + Sysroot::discover(dir, &config.extra_env, config.sysroot_query_metadata) + } + None => Sysroot::empty(), }; - let sysroot_ref = sysroot.as_ref().ok(); let toolchain = - match get_toolchain_version(dir, sysroot_ref, Tool::Rustc, &config.extra_env, "rustc ") - { + match get_toolchain_version(dir, &sysroot, Tool::Rustc, &config.extra_env, "rustc ") { Ok(it) => it, Err(e) => { tracing::error!("{e}"); @@ -435,25 +402,24 @@ impl ProjectWorkspace { } }; - let rustc_cfg = rustc_cfg::get(None, &config.extra_env, RustcCfgConfig::Rustc(sysroot_ref)); + let rustc_cfg = rustc_cfg::get(None, &config.extra_env, RustcCfgConfig::Rustc(&sysroot)); let data_layout = target_data_layout::get( - RustcDataLayoutConfig::Rustc(sysroot_ref), + RustcDataLayoutConfig::Rustc(&sysroot), None, &config.extra_env, ); let cargo_script = - CargoWorkspace::fetch_metadata(detached_file, dir, config, sysroot_ref, &|_| ()) - .ok() - .map(|ws| { + CargoWorkspace::fetch_metadata(detached_file, dir, config, &sysroot, &|_| ()).ok().map( + |ws| { ( CargoWorkspace::new(ws, detached_file.clone()), WorkspaceBuildScripts::default(), ) - }); + }, + ); - let cargo_config_extra_env = - cargo_config_env(detached_file, &config.extra_env, sysroot_ref); + let cargo_config_extra_env = cargo_config_env(detached_file, &config.extra_env, &sysroot); Ok(ProjectWorkspace { kind: ProjectWorkspaceKind::DetachedFile { file: detached_file.to_owned(), @@ -489,7 +455,7 @@ impl ProjectWorkspace { cargo, progress, self.toolchain.as_ref(), - self.sysroot.as_ref().ok(), + &self.sysroot, ) .with_context(|| { format!("Failed to run build scripts for {}", cargo.workspace_root()) @@ -562,17 +528,7 @@ impl ProjectWorkspace { } pub fn find_sysroot_proc_macro_srv(&self) -> anyhow::Result { - match &self.sysroot { - Ok(sysroot) => sysroot.discover_proc_macro_srv(), - Err(None) => Err(anyhow::format_err!( - "cannot find proc-macro server, the workspace `{}` is missing a sysroot", - self.manifest_or_root() - )), - Err(Some(e)) => Err(anyhow::format_err!( - "cannot find proc-macro server, the workspace `{}` is missing a sysroot: {e}", - self.manifest_or_root() - )), - } + self.sysroot.discover_proc_macro_srv() } /// Returns the roots for the current `ProjectWorkspace` @@ -580,39 +536,37 @@ impl ProjectWorkspace { /// the root is a member of the current workspace pub fn to_roots(&self) -> Vec { let mk_sysroot = || { - self.sysroot.as_ref().into_iter().flat_map(move |sysroot: &Sysroot| { - let mut r = match sysroot.mode() { - SysrootMode::Workspace(ws) => ws - .packages() - .filter_map(|pkg| { - if ws[pkg].is_local { - // the local ones are included in the main `PackageRoot`` below - return None; - } - let pkg_root = ws[pkg].manifest.parent().to_path_buf(); + let mut r = match self.sysroot.mode() { + SysrootMode::Workspace(ws) => ws + .packages() + .filter_map(|pkg| { + if ws[pkg].is_local { + // the local ones are included in the main `PackageRoot`` below + return None; + } + let pkg_root = ws[pkg].manifest.parent().to_path_buf(); - let include = vec![pkg_root.clone()]; + let include = vec![pkg_root.clone()]; - let exclude = vec![ - pkg_root.join(".git"), - pkg_root.join("target"), - pkg_root.join("tests"), - pkg_root.join("examples"), - pkg_root.join("benches"), - ]; - Some(PackageRoot { is_local: false, include, exclude }) - }) - .collect(), - SysrootMode::Stitched(_) => vec![], - }; + let exclude = vec![ + pkg_root.join(".git"), + pkg_root.join("target"), + pkg_root.join("tests"), + pkg_root.join("examples"), + pkg_root.join("benches"), + ]; + Some(PackageRoot { is_local: false, include, exclude }) + }) + .collect(), + SysrootMode::Stitched(_) | SysrootMode::Empty => vec![], + }; - r.push(PackageRoot { - is_local: false, - include: sysroot.src_root().map(|it| it.to_path_buf()).into_iter().collect(), - exclude: Vec::new(), - }); - r - }) + r.push(PackageRoot { + is_local: false, + include: self.sysroot.src_root().map(|it| it.to_path_buf()).into_iter().collect(), + exclude: Vec::new(), + }); + r }; match &self.kind { ProjectWorkspaceKind::Json(project) => project @@ -731,19 +685,15 @@ impl ProjectWorkspace { } pub fn n_packages(&self) -> usize { + let sysroot_package_len = self.sysroot.num_packages(); match &self.kind { - ProjectWorkspaceKind::Json(project) => { - let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages()); - sysroot_package_len + project.n_crates() - } + ProjectWorkspaceKind::Json(project) => sysroot_package_len + project.n_crates(), ProjectWorkspaceKind::Cargo { cargo, rustc, .. } => { let rustc_package_len = rustc.as_ref().map(|a| a.as_ref()).map_or(0, |(it, _)| it.packages().len()); - let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages()); cargo.packages().len() + sysroot_package_len + rustc_package_len } ProjectWorkspaceKind::DetachedFile { cargo: cargo_script, .. } => { - let sysroot_package_len = self.sysroot.as_ref().map_or(0, |it| it.num_packages()); sysroot_package_len + cargo_script.as_ref().map_or(1, |(cargo, _)| cargo.packages().len()) } @@ -764,7 +714,7 @@ impl ProjectWorkspace { rustc_cfg.clone(), load, project, - sysroot.as_ref().ok(), + sysroot, extra_env, cfg_overrides, ), @@ -780,7 +730,7 @@ impl ProjectWorkspace { load, rustc.as_ref().map(|a| a.as_ref()).ok(), cargo, - sysroot.as_ref().ok(), + sysroot, rustc_cfg.clone(), cfg_overrides, build_scripts, @@ -793,7 +743,7 @@ impl ProjectWorkspace { &mut |path| load(path), None, cargo, - sysroot.as_ref().ok(), + sysroot, rustc_cfg.clone(), cfg_overrides, build_scripts, @@ -803,7 +753,7 @@ impl ProjectWorkspace { rustc_cfg.clone(), load, file, - sysroot.as_ref().ok(), + sysroot, cfg_overrides, ) }, @@ -811,9 +761,7 @@ impl ProjectWorkspace { ), }; - if matches!(sysroot.as_ref().map(|it| it.mode()), Ok(SysrootMode::Stitched(_))) - && crate_graph.patch_cfg_if() - { + if matches!(sysroot.mode(), SysrootMode::Stitched(_)) && crate_graph.patch_cfg_if() { tracing::debug!("Patched std to depend on cfg-if") } else { tracing::debug!("Did not patch std to depend on cfg-if") @@ -892,15 +840,14 @@ fn project_json_to_crate_graph( rustc_cfg: Vec, load: FileLoader<'_>, project: &ProjectJson, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, extra_env: &FxHashMap, override_cfg: &CfgOverrides, ) -> (CrateGraph, ProcMacroPaths) { let mut res = (CrateGraph::default(), ProcMacroPaths::default()); let (crate_graph, proc_macros) = &mut res; - let sysroot_deps = sysroot - .as_ref() - .map(|sysroot| sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load)); + let (public_deps, libproc_macro) = + sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load); let r_a_cfg_flag = CfgFlag::Atom("rust_analyzer".to_owned()); let mut cfg_cache: FxHashMap<&str, Vec> = FxHashMap::default(); @@ -978,11 +925,9 @@ fn project_json_to_crate_graph( for (from_idx, krate) in project.crates() { if let Some(&from) = idx_to_crate_id.get(&from_idx) { - if let Some((public_deps, libproc_macro)) = &sysroot_deps { - public_deps.add_to_crate_graph(crate_graph, from); - if let Some(proc_macro) = libproc_macro { - add_proc_macro_dep(crate_graph, from, *proc_macro, krate.is_proc_macro); - } + public_deps.add_to_crate_graph(crate_graph, from); + if let Some(proc_macro) = libproc_macro { + add_proc_macro_dep(crate_graph, from, proc_macro, krate.is_proc_macro); } for dep in &krate.deps { @@ -999,7 +944,7 @@ fn cargo_to_crate_graph( load: FileLoader<'_>, rustc: Option<&(CargoWorkspace, WorkspaceBuildScripts)>, cargo: &CargoWorkspace, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, rustc_cfg: Vec, override_cfg: &CfgOverrides, build_scripts: &WorkspaceBuildScripts, @@ -1008,10 +953,8 @@ fn cargo_to_crate_graph( let mut res = (CrateGraph::default(), ProcMacroPaths::default()); let crate_graph = &mut res.0; let proc_macros = &mut res.1; - let (public_deps, libproc_macro) = match sysroot { - Some(sysroot) => sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load), - None => (SysrootPublicDeps::default(), None), - }; + let (public_deps, libproc_macro) = + sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load); let cfg_options = CfgOptions::from_iter(rustc_cfg); @@ -1188,15 +1131,13 @@ fn detached_file_to_crate_graph( rustc_cfg: Vec, load: FileLoader<'_>, detached_file: &ManifestPath, - sysroot: Option<&Sysroot>, + sysroot: &Sysroot, override_cfg: &CfgOverrides, ) -> (CrateGraph, ProcMacroPaths) { let _p = tracing::span!(tracing::Level::INFO, "detached_file_to_crate_graph").entered(); let mut crate_graph = CrateGraph::default(); - let (public_deps, _libproc_macro) = match sysroot { - Some(sysroot) => sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load), - None => (SysrootPublicDeps::default(), None), - }; + let (public_deps, _libproc_macro) = + sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load); let mut cfg_options = CfgOptions::from_iter(rustc_cfg); cfg_options.insert_atom("test".into()); @@ -1431,7 +1372,7 @@ fn sysroot_to_crate_graph( load, None, cargo, - None, + &Sysroot::empty(), rustc_cfg, &CfgOverrides { global: CfgDiff::new( @@ -1554,6 +1495,7 @@ fn sysroot_to_crate_graph( stitched.proc_macro().and_then(|it| sysroot_crates.get(&it).copied()); (public_deps, libproc_macro) } + SysrootMode::Empty => (SysrootPublicDeps { deps: vec![] }, None), } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index 5208aa9bf08c..bded41932c03 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -8,7 +8,8 @@ use std::{ use hir::{ db::{DefDatabase, ExpandDatabase, HirDatabase}, - Adt, AssocItem, Crate, DefWithBody, HasSource, HirDisplay, HirFileIdExt, ModuleDef, Name, + Adt, AssocItem, Crate, DefWithBody, HasSource, HirDisplay, HirFileIdExt, ImportPathConfig, + ModuleDef, Name, }; use hir_def::{ body::{BodySourceMap, SyntheticSyntax}, @@ -438,8 +439,13 @@ impl flags::AnalysisStats { let mut formatter = |_: &hir::Type| todo.clone(); let mut syntax_hit_found = false; for term in found_terms { - let generated = - term.gen_source_code(&scope, &mut formatter, false, true).unwrap(); + let generated = term + .gen_source_code( + &scope, + &mut formatter, + ImportPathConfig { prefer_no_std: false, prefer_prelude: true }, + ) + .unwrap(); syntax_hit_found |= trim(&original_text) == trim(&generated); // Validate if type-checks diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs index 85f964b1dd93..e9a4db7a2b0d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -69,11 +69,9 @@ impl Tester { let cargo_config = CargoConfig { sysroot: Some(RustLibSource::Discover), ..Default::default() }; - let sysroot = - Ok(Sysroot::discover(tmp_file.parent().unwrap(), &cargo_config.extra_env, false) - .unwrap()); + let sysroot = Sysroot::discover(tmp_file.parent().unwrap(), &cargo_config.extra_env, false); let data_layout = target_data_layout::get( - RustcDataLayoutConfig::Rustc(sysroot.as_ref().ok()), + RustcDataLayoutConfig::Rustc(&sysroot), None, &cargo_config.extra_env, ); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 6c332ae1cb2f..a8d1e72aed9f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -1031,6 +1031,8 @@ impl Config { && completion_item_edit_resolve(&self.caps), enable_self_on_the_fly: self.completion_autoself_enable(source_root).to_owned(), enable_private_editable: self.completion_privateEditable_enable(source_root).to_owned(), + enable_term_search: self.completion_termSearch_enable(source_root).to_owned(), + term_search_fuel: self.completion_termSearch_fuel(source_root).to_owned() as u64, full_function_signatures: self .completion_fullFunctionSignatures_enable(source_root) .to_owned(), @@ -1039,8 +1041,6 @@ impl Config { CallableCompletionDef::AddParentheses => Some(CallableSnippets::AddParentheses), CallableCompletionDef::None => None, }, - insert_use: self.insert_use_config(source_root), - prefer_no_std: self.imports_preferNoStd(source_root).to_owned(), snippet_cap: SnippetCap::new(try_or_def!( self.caps .text_document @@ -1051,11 +1051,11 @@ impl Config { .as_ref()? .snippet_support? )), + insert_use: self.insert_use_config(source_root), + prefer_no_std: self.imports_preferNoStd(source_root).to_owned(), + prefer_prelude: self.imports_preferPrelude(source_root).to_owned(), snippets: self.snippets.clone().to_vec(), limit: self.completion_limit(source_root).to_owned(), - enable_term_search: self.completion_termSearch_enable(source_root).to_owned(), - term_search_fuel: self.completion_termSearch_fuel(source_root).to_owned() as u64, - prefer_prelude: self.imports_preferPrelude(source_root).to_owned(), } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index f64e66183d1b..79b87ecd58ff 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -87,6 +87,7 @@ pub(crate) struct GlobalState { pub(crate) flycheck_sender: Sender, pub(crate) flycheck_receiver: Receiver, pub(crate) last_flycheck_error: Option, + pub(crate) diagnostics_received: bool, // Test explorer pub(crate) test_run_session: Option>, @@ -224,6 +225,7 @@ impl GlobalState { flycheck_sender, flycheck_receiver, last_flycheck_error: None, + diagnostics_received: false, test_run_session: None, test_run_sender, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 5ee0456c15df..1e24bf3aae3b 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -860,6 +860,11 @@ pub(crate) fn handle_runnables( if cmd == "run" && spec.target_kind != TargetKind::Bin { continue; } + let cwd = if cmd != "test" || spec.target_kind == TargetKind::Bin { + spec.workspace_root.clone() + } else { + spec.cargo_toml.parent().to_path_buf() + }; let mut cargo_args = vec![cmd.to_owned(), "--package".to_owned(), spec.package.clone()]; let all_targets = cmd != "run" && !is_crate_no_std; @@ -876,6 +881,7 @@ pub(crate) fn handle_runnables( kind: lsp_ext::RunnableKind::Cargo, args: lsp_ext::CargoRunnable { workspace_root: Some(spec.workspace_root.clone().into()), + cwd: Some(cwd.into()), override_cargo: config.override_cargo.clone(), cargo_args, cargo_extra_args: config.cargo_extra_args.clone(), @@ -893,6 +899,7 @@ pub(crate) fn handle_runnables( kind: lsp_ext::RunnableKind::Cargo, args: lsp_ext::CargoRunnable { workspace_root: None, + cwd: None, override_cargo: config.override_cargo, cargo_args: vec!["check".to_owned(), "--workspace".to_owned()], cargo_extra_args: config.cargo_extra_args, @@ -1783,18 +1790,18 @@ pub(crate) fn handle_open_docs( let ws_and_sysroot = snap.workspaces.iter().find_map(|ws| match &ws.kind { ProjectWorkspaceKind::Cargo { cargo, .. } | ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _)), .. } => { - Some((cargo, ws.sysroot.as_ref().ok())) + Some((cargo, &ws.sysroot)) } ProjectWorkspaceKind::Json { .. } => None, ProjectWorkspaceKind::DetachedFile { .. } => None, }); let (cargo, sysroot) = match ws_and_sysroot { - Some((ws, sysroot)) => (Some(ws), sysroot), + Some((ws, sysroot)) => (Some(ws), Some(sysroot)), _ => (None, None), }; - let sysroot = sysroot.map(|p| p.root().as_str()); + let sysroot = sysroot.and_then(|p| p.root()).map(|it| it.as_str()); let target_dir = cargo.map(|cargo| cargo.target_directory()).map(|p| p.as_str()); let Ok(remote_urls) = snap.analysis.external_docs(position, target_dir, sysroot) else { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs index cc83d6246bf5..5d617780b6df 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs @@ -139,6 +139,7 @@ fn integrated_completion_benchmark() { enable_self_on_the_fly: true, enable_private_editable: true, enable_term_search: true, + term_search_fuel: 200, full_function_signatures: false, callable: Some(CallableSnippets::FillArguments), snippet_cap: SnippetCap::new(true), @@ -149,11 +150,10 @@ fn integrated_completion_benchmark() { group: true, skip_glob_imports: true, }, - snippets: Vec::new(), prefer_no_std: false, prefer_prelude: true, + snippets: Vec::new(), limit: None, - term_search_fuel: 200, }; let position = FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() }; @@ -184,6 +184,7 @@ fn integrated_completion_benchmark() { enable_self_on_the_fly: true, enable_private_editable: true, enable_term_search: true, + term_search_fuel: 200, full_function_signatures: false, callable: Some(CallableSnippets::FillArguments), snippet_cap: SnippetCap::new(true), @@ -194,11 +195,10 @@ fn integrated_completion_benchmark() { group: true, skip_glob_imports: true, }, - snippets: Vec::new(), prefer_no_std: false, prefer_prelude: true, + snippets: Vec::new(), limit: None, - term_search_fuel: 200, }; let position = FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() }; @@ -227,6 +227,7 @@ fn integrated_completion_benchmark() { enable_self_on_the_fly: true, enable_private_editable: true, enable_term_search: true, + term_search_fuel: 200, full_function_signatures: false, callable: Some(CallableSnippets::FillArguments), snippet_cap: SnippetCap::new(true), @@ -237,11 +238,10 @@ fn integrated_completion_benchmark() { group: true, skip_glob_imports: true, }, - snippets: Vec::new(), prefer_no_std: false, prefer_prelude: true, + snippets: Vec::new(), limit: None, - term_search_fuel: 200, }; let position = FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() }; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs index 2cf9b53f7c8d..aa75633ac356 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs @@ -441,6 +441,8 @@ pub struct CargoRunnable { pub override_cargo: Option, #[serde(skip_serializing_if = "Option::is_none")] pub workspace_root: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub cwd: Option, // command, --package and --lib stuff pub cargo_args: Vec, // user-specified additional cargo args, like `--release`. @@ -500,7 +502,6 @@ pub struct ServerStatusParams { pub health: Health, pub quiescent: bool, pub message: Option, - pub workspace_info: Option, } #[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 03daccc99c45..86368c9eea87 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -1360,10 +1360,14 @@ pub(crate) fn runnable( let config = snap.config.runnables(); let spec = CargoTargetSpec::for_file(snap, runnable.nav.file_id)?; let workspace_root = spec.as_ref().map(|it| it.workspace_root.clone()); - let target = spec.as_ref().map(|s| s.target.clone()); + let cwd = match runnable.kind { + ide::RunnableKind::Bin { .. } => workspace_root.clone().map(|it| it.into()), + _ => spec.as_ref().map(|it| it.cargo_toml.parent().into()), + }; + let target = spec.as_ref().map(|s| s.target.as_str()); + let label = runnable.label(target); let (cargo_args, executable_args) = CargoTargetSpec::runnable_args(snap, spec, &runnable.kind, &runnable.cfg); - let label = runnable.label(target); let location = location_link(snap, None, runnable.nav)?; Ok(lsp_ext::Runnable { @@ -1372,6 +1376,7 @@ pub(crate) fn runnable( kind: lsp_ext::RunnableKind::Cargo, args: lsp_ext::CargoRunnable { workspace_root: workspace_root.map(|it| it.into()), + cwd, override_cargo: config.override_cargo, cargo_args, cargo_extra_args: config.cargo_extra_args, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index 5435be3dc272..7acd302867c3 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -804,6 +804,10 @@ impl GlobalState { fn handle_flycheck_msg(&mut self, message: flycheck::Message) { match message { flycheck::Message::AddDiagnostic { id, workspace_root, diagnostic } => { + if !self.diagnostics_received { + self.diagnostics.clear_check(id); + self.diagnostics_received = true; + } let snap = self.snapshot(); let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( &self.config.diagnostics_map(), @@ -832,7 +836,7 @@ impl GlobalState { flycheck::Message::Progress { id, progress } => { let (state, message) = match progress { flycheck::Progress::DidStart => { - self.diagnostics.clear_check(id); + self.diagnostics_received = false; (Progress::Begin, None) } flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)), @@ -848,6 +852,9 @@ impl GlobalState { flycheck::Progress::DidFinish(result) => { self.last_flycheck_error = result.err().map(|err| format!("cargo check failed to start: {err}")); + if !self.diagnostics_received { + self.diagnostics.clear_check(id); + } (Progress::End, None) } }; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index fd14efa1da56..627be7e951ad 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -103,7 +103,6 @@ impl GlobalState { health: lsp_ext::Health::Ok, quiescent: self.is_quiescent(), message: None, - workspace_info: None, }; let mut message = String::new(); @@ -164,53 +163,37 @@ impl GlobalState { let proc_macro_clients = self.proc_macro_clients.iter().map(Some).chain(iter::repeat_with(|| None)); - let mut workspace_info = "Loaded workspaces:\n".to_owned(); for (ws, proc_macro_client) in self.workspaces.iter().zip(proc_macro_clients) { - format_to!(workspace_info, "- `{}`\n", ws.manifest_or_root()); - format_to!(workspace_info, " - sysroot:"); - - match ws.sysroot.as_ref() { - Err(None) => format_to!(workspace_info, " None"), - Err(Some(e)) => { - status.health |= lsp_ext::Health::Warning; - format_to!(workspace_info, " {e}"); - } - Ok(s) => { - format_to!(workspace_info, " `{}`", s.root().to_string()); - if let Some(err) = s - .check_has_core() - .err() - .inspect(|_| status.health |= lsp_ext::Health::Warning) - { - format_to!(workspace_info, " ({err})"); - } - if let Some(src_root) = s.src_root() { - format_to!( - workspace_info, - "\n - sysroot source: `{}`", - src_root - ); - } - format_to!(workspace_info, "\n"); - } - } - - if let ProjectWorkspaceKind::Cargo { rustc: Err(Some(e)), .. } = &ws.kind { + if let Some(err) = ws.sysroot.error() { status.health |= lsp_ext::Health::Warning; - format_to!(workspace_info, " - rustc workspace: {e}\n"); + format_to!( + message, + "Workspace `{}` has sysroot errors: ", + ws.manifest_or_root() + ); + message.push_str(err); + message.push_str("\n\n"); + } + if let ProjectWorkspaceKind::Cargo { rustc: Err(Some(err)), .. } = &ws.kind { + status.health |= lsp_ext::Health::Warning; + format_to!( + message, + "Failed loading rustc_private crates for workspace `{}`: ", + ws.manifest_or_root() + ); + message.push_str(err); + message.push_str("\n\n"); }; - if let Some(proc_macro_client) = proc_macro_client { - format_to!(workspace_info, " - proc-macro server: "); - match proc_macro_client { - Ok(it) => format_to!(workspace_info, "`{}`\n", it.path()), - Err(e) => { - status.health |= lsp_ext::Health::Warning; - format_to!(workspace_info, "{e}\n") - } - } + if let Some(Err(err)) = proc_macro_client { + status.health |= lsp_ext::Health::Warning; + format_to!( + message, + "Failed spawning proc-macro server for workspace `{}`: {err}", + ws.manifest_or_root() + ); + message.push_str("\n\n"); } } - status.workspace_info = Some(workspace_info); } if !message.is_empty() { @@ -534,8 +517,8 @@ impl GlobalState { .map(|(a, b)| (a.clone(), b.clone())) .chain( ws.sysroot - .as_ref() - .map(|it| ("RUSTUP_TOOLCHAIN".to_owned(), it.root().to_string())), + .root() + .map(|it| ("RUSTUP_TOOLCHAIN".to_owned(), it.to_string())), ) .collect(), @@ -719,7 +702,7 @@ impl GlobalState { } ProjectWorkspaceKind::DetachedFile { .. } => return None, }, - ws.sysroot.as_ref().ok().map(|sysroot| sysroot.root().to_owned()), + ws.sysroot.root().map(ToOwned::to_owned), )) }) .map(|(id, (root, manifest_path), sysroot_root)| { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/crate_graph.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/crate_graph.rs index 59b229cd0645..66481d3d7f5e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/crate_graph.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/crate_graph.rs @@ -21,7 +21,7 @@ fn load_cargo_with_fake_sysroot(file: &str) -> ProjectWorkspace { rustc: Err(None), cargo_config_extra_env: Default::default(), }, - sysroot: Ok(get_fake_sysroot()), + sysroot: get_fake_sysroot(), rustc_cfg: Vec::new(), cfg_overrides: Default::default(), toolchain: None, @@ -69,7 +69,7 @@ fn get_fake_sysroot() -> Sysroot { // fake sysroot, so we give them both the same path: let sysroot_dir = AbsPathBuf::assert_utf8(sysroot_path); let sysroot_src_dir = sysroot_dir.clone(); - Sysroot::load(sysroot_dir, Some(Ok(sysroot_src_dir)), false) + Sysroot::load(Some(sysroot_dir), Some(sysroot_src_dir), false) } #[test] diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs index 5a1397bbb0e7..43a830501058 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs @@ -260,6 +260,7 @@ fn main() {} "executableArgs": ["test_eggs", "--exact", "--show-output"], "cargoExtraArgs": [], "overrideCargo": null, + "cwd": server.path().join("foo"), "workspaceRoot": server.path().join("foo") }, "kind": "cargo", @@ -279,6 +280,7 @@ fn main() {} { "args": { "overrideCargo": null, + "cwd": server.path().join("foo"), "workspaceRoot": server.path().join("foo"), "cargoArgs": [ "test", @@ -325,6 +327,7 @@ fn main() {} "executableArgs": [], "cargoExtraArgs": [], "overrideCargo": null, + "cwd": server.path().join("foo"), "workspaceRoot": server.path().join("foo") }, "kind": "cargo", @@ -336,6 +339,7 @@ fn main() {} "executableArgs": [], "cargoExtraArgs": [], "overrideCargo": null, + "cwd": server.path().join("foo"), "workspaceRoot": server.path().join("foo") }, "kind": "cargo", @@ -415,6 +419,7 @@ mod tests { "args": { "overrideCargo": null, "workspaceRoot": server.path().join(runnable), + "cwd": server.path().join(runnable), "cargoArgs": [ "test", "--package", @@ -432,6 +437,94 @@ mod tests { } } +// The main fn in packages should be run from the workspace root +#[test] +fn test_runnables_cwd() { + if skip_slow_tests() { + return; + } + + let server = Project::with_fixture( + r#" +//- /foo/Cargo.toml +[workspace] +members = ["mainpkg", "otherpkg"] + +//- /foo/mainpkg/Cargo.toml +[package] +name = "mainpkg" +version = "0.1.0" + +//- /foo/mainpkg/src/main.rs +fn main() {} + +//- /foo/otherpkg/Cargo.toml +[package] +name = "otherpkg" +version = "0.1.0" + +//- /foo/otherpkg/src/lib.rs +#[test] +fn otherpkg() {} +"#, + ) + .root("foo") + .server() + .wait_until_workspace_is_loaded(); + + server.request::( + RunnablesParams { text_document: server.doc_id("foo/mainpkg/src/main.rs"), position: None }, + json!([ + "{...}", + { + "label": "cargo test -p mainpkg --all-targets", + "kind": "cargo", + "args": { + "overrideCargo": null, + "workspaceRoot": server.path().join("foo"), + "cwd": server.path().join("foo"), + "cargoArgs": [ + "test", + "--package", + "mainpkg", + "--all-targets" + ], + "cargoExtraArgs": [], + "executableArgs": [] + }, + }, + "{...}", + "{...}" + ]), + ); + + server.request::( + RunnablesParams { text_document: server.doc_id("foo/otherpkg/src/lib.rs"), position: None }, + json!([ + "{...}", + { + "label": "cargo test -p otherpkg --all-targets", + "kind": "cargo", + "args": { + "overrideCargo": null, + "workspaceRoot": server.path().join("foo"), + "cwd": server.path().join("foo").join("otherpkg"), + "cargoArgs": [ + "test", + "--package", + "otherpkg", + "--all-targets" + ], + "cargoExtraArgs": [], + "executableArgs": [] + }, + }, + "{...}", + "{...}" + ]), + ); +} + #[test] fn test_format_document() { if skip_slow_tests() { @@ -1059,11 +1152,11 @@ fn resolve_proc_macro() { return; } - let sysroot = project_model::Sysroot::discover_no_source( + let sysroot = project_model::Sysroot::discover( &AbsPathBuf::assert_utf8(std::env::current_dir().unwrap()), &Default::default(), - ) - .unwrap(); + false, + ); let proc_macro_server_path = sysroot.discover_proc_macro_srv().unwrap(); diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs index c3d6f50e6b08..b0fbe7101c11 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs @@ -378,9 +378,26 @@ impl ast::UseTreeList { /// Remove the unnecessary braces in current `UseTreeList` pub fn remove_unnecessary_braces(mut self) { + // Returns true iff there is a single subtree and it is not the self keyword. The braces in + // `use x::{self};` are necessary and so we should not remove them. + let has_single_subtree_that_is_not_self = |u: &ast::UseTreeList| { + if let Some((single_subtree,)) = u.use_trees().collect_tuple() { + // We have a single subtree, check whether it is self. + + let is_self = single_subtree.path().as_ref().map_or(false, |path| { + path.segment().and_then(|seg| seg.self_token()).is_some() + && path.qualifier().is_none() + }); + + !is_self + } else { + // Not a single subtree + false + } + }; + let remove_brace_in_use_tree_list = |u: &ast::UseTreeList| { - let use_tree_count = u.use_trees().count(); - if use_tree_count == 1 { + if has_single_subtree_that_is_not_self(u) { if let Some(a) = u.l_curly_token() { ted::remove(a) } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs index 16599881d643..1ce548f8fc70 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs @@ -8,6 +8,7 @@ use std::{ use rustc_lexer::unescape::{ unescape_byte, unescape_char, unescape_mixed, unescape_unicode, EscapeError, MixedUnit, Mode, }; +use stdx::always; use crate::{ ast::{self, AstToken}, @@ -181,25 +182,25 @@ pub trait IsString: AstToken { self.quote_offsets().map(|it| it.quotes.1) } fn escaped_char_ranges(&self, cb: &mut dyn FnMut(TextRange, Result)) { - let text_range_no_quotes = match self.text_range_between_quotes() { - Some(it) => it, - None => return, - }; + let Some(text_range_no_quotes) = self.text_range_between_quotes() else { return }; let start = self.syntax().text_range().start(); let text = &self.text()[text_range_no_quotes - start]; let offset = text_range_no_quotes.start() - start; unescape_unicode(text, Self::MODE, &mut |range, unescaped_char| { - let text_range = - TextRange::new(range.start.try_into().unwrap(), range.end.try_into().unwrap()); - cb(text_range + offset, unescaped_char); + if let Some((s, e)) = range.start.try_into().ok().zip(range.end.try_into().ok()) { + cb(TextRange::new(s, e) + offset, unescaped_char); + } }); } fn map_range_up(&self, range: TextRange) -> Option { let contents_range = self.text_range_between_quotes()?; - assert!(TextRange::up_to(contents_range.len()).contains_range(range)); - Some(range + contents_range.start()) + if always!(TextRange::up_to(contents_range.len()).contains_range(range)) { + Some(range + contents_range.start()) + } else { + None + } } } diff --git a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md index 46c1ccb79bf9..1c91e856e72e 100644 --- a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md +++ b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md @@ -1,5 +1,5 @@ $DIR/diagnostics.rs:107:21 + --> $DIR/diagnostics.rs:99:21 | LL | let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example); | ^^^^^^^^^^ @@ -35,13 +35,13 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls - --> $DIR/diagnostics.rs:110:21 + --> $DIR/diagnostics.rs:102:21 | LL | let _diag = dcx.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:110:21 + --> $DIR/diagnostics.rs:102:21 | LL | let _diag = dcx.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 043c7c166540..4f50837d5fe4 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -603,7 +603,6 @@ struct LintAttributeOnSessionDiag {} #[derive(LintDiagnostic)] #[lint(no_crate_example, code = E0123)] //~^ ERROR `#[lint(...)]` is not a valid attribute -//~| ERROR `#[lint(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified //~| ERROR cannot find attribute `lint` in this scope struct LintAttributeOnLintDiag {} diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 1266430e2f77..e36c6852d3b2 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -378,14 +378,6 @@ error: `#[lint(...)]` is not a valid attribute LL | #[lint(no_crate_example, code = E0123)] | ^ -error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:604:1 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:604:1 | @@ -395,19 +387,19 @@ LL | #[lint(no_crate_example, code = E0123)] = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]` error: specified multiple times - --> $DIR/diagnostic-derive.rs:614:53 + --> $DIR/diagnostic-derive.rs:613:53 | LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:614:39 + --> $DIR/diagnostic-derive.rs:613:39 | LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] | ^^^^ error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:623:24 + --> $DIR/diagnostic-derive.rs:622:24 | LL | suggestion: (Span, usize), | ^^^^^ @@ -415,7 +407,7 @@ LL | suggestion: (Span, usize), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:631:17 + --> $DIR/diagnostic-derive.rs:630:17 | LL | suggestion: (Span,), | ^^^^^^^ @@ -423,13 +415,13 @@ LL | suggestion: (Span,), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:638:5 + --> $DIR/diagnostic-derive.rs:637:5 | LL | #[suggestion(no_crate_suggestion)] | ^ error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:645:1 + --> $DIR/diagnostic-derive.rs:644:1 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^ @@ -437,7 +429,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:648:1 + --> $DIR/diagnostic-derive.rs:647:1 | LL | #[multipart_suggestion()] | ^ @@ -445,7 +437,7 @@ LL | #[multipart_suggestion()] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:652:5 + --> $DIR/diagnostic-derive.rs:651:5 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^ @@ -453,7 +445,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)] = help: consider creating a `Subdiagnostic` instead error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:660:1 + --> $DIR/diagnostic-derive.rs:659:1 | LL | #[suggestion(no_crate_suggestion, code = "...")] | ^ @@ -461,7 +453,7 @@ LL | #[suggestion(no_crate_suggestion, code = "...")] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:669:1 + --> $DIR/diagnostic-derive.rs:668:1 | LL | #[label] | ^ @@ -469,61 +461,61 @@ LL | #[label] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:703:5 + --> $DIR/diagnostic-derive.rs:702:5 | LL | #[subdiagnostic(bad)] | ^ error: `#[subdiagnostic = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:711:5 + --> $DIR/diagnostic-derive.rs:710:5 | LL | #[subdiagnostic = "bad"] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:719:5 + --> $DIR/diagnostic-derive.rs:718:5 | LL | #[subdiagnostic(bad, bad)] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:727:5 + --> $DIR/diagnostic-derive.rs:726:5 | LL | #[subdiagnostic("bad")] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:735:5 + --> $DIR/diagnostic-derive.rs:734:5 | LL | #[subdiagnostic(eager)] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:743:5 + --> $DIR/diagnostic-derive.rs:742:5 | LL | #[subdiagnostic(eager)] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:764:5 + --> $DIR/diagnostic-derive.rs:763:5 | LL | #[subdiagnostic(eager)] | ^ error: expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:795:23 + --> $DIR/diagnostic-derive.rs:794:23 | LL | #[suggestion(code())] | ^ error: `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:803:23 + --> $DIR/diagnostic-derive.rs:802:23 | LL | #[suggestion(code(foo))] | ^^^ error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:827:5 + --> $DIR/diagnostic-derive.rs:826:5 | LL | #[suggestion(no_crate_suggestion, code = "")] | ^ @@ -539,13 +531,13 @@ LL | #[diag = "E0123"] | ^ maybe a missing crate `core`? error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/diagnostic-derive.rs:803:23 + --> $DIR/diagnostic-derive.rs:802:23 | LL | #[suggestion(code(foo))] | ^^^ maybe a missing crate `core`? error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/diagnostic-derive.rs:812:25 + --> $DIR/diagnostic-derive.rs:811:25 | LL | #[suggestion(code = 3)] | ^ maybe a missing crate `core`? @@ -587,19 +579,19 @@ LL | #[lint(no_crate_example, code = E0123)] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:645:3 + --> $DIR/diagnostic-derive.rs:644:3 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:648:3 + --> $DIR/diagnostic-derive.rs:647:3 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:652:7 + --> $DIR/diagnostic-derive.rs:651:7 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ @@ -611,7 +603,7 @@ LL | #[diag(nonsense, code = E0123)] | ^^^^^^^^ not found in `crate::fluent_generated` error[E0425]: cannot find value `__code_34` in this scope - --> $DIR/diagnostic-derive.rs:809:10 + --> $DIR/diagnostic-derive.rs:808:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ not found in this scope @@ -632,7 +624,7 @@ note: required by a bound in `Diag::<'a, G>::arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 86 previous errors +error: aborting due to 85 previous errors Some errors have detailed explanations: E0277, E0425, E0433. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/borrowck/issue-64453.stderr b/tests/ui/borrowck/issue-64453.stderr index 0e4a8d42f6e8..e671817633be 100644 --- a/tests/ui/borrowck/issue-64453.stderr +++ b/tests/ui/borrowck/issue-64453.stderr @@ -14,7 +14,7 @@ LL | static settings_dir: String = format!(""); | ^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0507]: cannot move out of static item `settings_dir` diff --git a/tests/ui/c-variadic/variadic-ffi-no-fixed-args.rs b/tests/ui/c-variadic/variadic-ffi-no-fixed-args.rs index 588c15a18297..b8841e88c4f4 100644 --- a/tests/ui/c-variadic/variadic-ffi-no-fixed-args.rs +++ b/tests/ui/c-variadic/variadic-ffi-no-fixed-args.rs @@ -1,6 +1,9 @@ +//@ build-pass + +// Supported since C23 +// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2975.pdf extern "C" { fn foo(...); -//~^ ERROR C-variadic function must be declared with at least one named argument } fn main() {} diff --git a/tests/ui/c-variadic/variadic-ffi-no-fixed-args.stderr b/tests/ui/c-variadic/variadic-ffi-no-fixed-args.stderr deleted file mode 100644 index e268ef3fa681..000000000000 --- a/tests/ui/c-variadic/variadic-ffi-no-fixed-args.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-no-fixed-args.rs:2:12 - | -LL | fn foo(...); - | ^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr index 8c1bf5a11607..b3d0046fc178 100644 --- a/tests/ui/check-cfg/mix.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -251,7 +251,7 @@ warning: unexpected `cfg` condition value: `zebra` LL | cfg!(target_feature = "zebra"); | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, and `bmi2` and 188 more + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, and `bulk-memory` and 186 more = note: see for more information about checking conditional configuration warning: 27 warnings emitted diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index c13446bb9f89..0c50ec1abba9 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -165,7 +165,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_feature = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` diff --git a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.rs b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.rs index 840eda0513f8..a0e8e614d8ee 100644 --- a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.rs +++ b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.rs @@ -2,8 +2,7 @@ //@ edition:2021 const PATTERN_REF: &str = "Hello World"; -const NUMBER: i32 = 30; -const NUMBER_POINTER: *const i32 = &NUMBER; +const NUMBER_POINTER: *const i32 = 30 as *const i32; pub fn edge_case_ref(event: &str) { let _ = || { @@ -26,8 +25,7 @@ pub fn edge_case_str(event: String) { pub fn edge_case_raw_ptr(event: *const i32) { let _ = || { match event { - NUMBER_POINTER => (), //~WARN behave unpredictably - //~| previously accepted + NUMBER_POINTER => (), _ => (), }; }; diff --git a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.stderr b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.stderr deleted file mode 100644 index 8a2aaade6650..000000000000 --- a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.stderr +++ /dev/null @@ -1,23 +0,0 @@ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/match-edge-cases_1.rs:29:13 - | -LL | NUMBER_POINTER => (), - | ^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -warning: 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/match-edge-cases_1.rs:29:13 - | -LL | NUMBER_POINTER => (), - | ^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - diff --git a/tests/ui/codegen/mono-impossible-drop.rs b/tests/ui/codegen/mono-impossible-drop.rs new file mode 100644 index 000000000000..dec013cfe54b --- /dev/null +++ b/tests/ui/codegen/mono-impossible-drop.rs @@ -0,0 +1,18 @@ +//@ compile-flags: -Clink-dead-code=on --crate-type=lib +//@ build-pass + +#![feature(trivial_bounds)] +#![allow(trivial_bounds)] + +// Make sure we don't monomorphize the drop impl for `Baz`, since it has predicates +// that don't hold under a reveal-all param env. + +trait Foo { + type Assoc; +} + +struct Bar; + +struct Baz(::Assoc) +where + Bar: Foo; diff --git a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs new file mode 100644 index 000000000000..89d0b74d4030 --- /dev/null +++ b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs @@ -0,0 +1,12 @@ +//! This test used to ICE (#119381), because relating the `u8` and `i8` generic +//! const with the array length of the `Self` type was succeeding under the +//! assumption that an error had already been reported. + +#![feature(with_negative_coherence)] +trait Trait {} +impl Trait for [(); N] {} +//~^ ERROR: mismatched types +impl Trait for [(); N] {} +//~^ ERROR: mismatched types + +fn main() {} diff --git a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr new file mode 100644 index 000000000000..d19502546602 --- /dev/null +++ b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/generic_const_type_mismatch.rs:7:34 + | +LL | impl Trait for [(); N] {} + | ^ expected `usize`, found `u8` + +error[E0308]: mismatched types + --> $DIR/generic_const_type_mismatch.rs:9:34 + | +LL | impl Trait for [(); N] {} + | ^ expected `usize`, found `i8` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/bad-subst-const-kind.rs b/tests/ui/const-generics/bad-subst-const-kind.rs index ca5522a2ddf3..88f98a54b6e6 100644 --- a/tests/ui/const-generics/bad-subst-const-kind.rs +++ b/tests/ui/const-generics/bad-subst-const-kind.rs @@ -11,4 +11,4 @@ impl Q for [u8; N] { } pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() } -//~^ ERROR: the constant `13` is not of type `u64` +//~^ ERROR: `[u8; 13]: Q` is not satisfied diff --git a/tests/ui/const-generics/bad-subst-const-kind.stderr b/tests/ui/const-generics/bad-subst-const-kind.stderr index c04a05573bed..6cf9fa743b34 100644 --- a/tests/ui/const-generics/bad-subst-const-kind.stderr +++ b/tests/ui/const-generics/bad-subst-const-kind.stderr @@ -1,16 +1,10 @@ -error: the constant `13` is not of type `u64` +error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied --> $DIR/bad-subst-const-kind.rs:13:24 | LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() } - | ^^^^^^^^ expected `u64`, found `usize` + | ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]` | -note: required for `[u8; 13]` to implement `Q` - --> $DIR/bad-subst-const-kind.rs:8:20 - | -LL | impl Q for [u8; N] { - | ------------ ^ ^^^^^^^ - | | - | unsatisfied trait bound introduced here + = help: the trait `Q` is implemented for `[u8; N]` error[E0308]: mismatched types --> $DIR/bad-subst-const-kind.rs:8:31 @@ -20,4 +14,5 @@ LL | impl Q for [u8; N] { error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs b/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs index 6b0d9e047dbc..285f9dee6c27 100644 --- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs +++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs @@ -10,7 +10,7 @@ impl Q for [u8; N] {} //~| ERROR mismatched types pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {} -//~^ ERROR the constant `13` is not of type `u64` +//~^ ERROR `[u8; 13]: Q` is not satisfied //~| ERROR mismatched types pub fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr index bb6d650b7ab2..a63a56dd6753 100644 --- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr +++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr @@ -7,19 +7,13 @@ LL | const ASSOC: usize; LL | impl Q for [u8; N] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `ASSOC` in implementation -error: the constant `13` is not of type `u64` +error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied --> $DIR/type_mismatch.rs:12:26 | LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {} - | ^^^^^^^^ expected `u64`, found `usize` + | ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]` | -note: required for `[u8; 13]` to implement `Q` - --> $DIR/type_mismatch.rs:8:20 - | -LL | impl Q for [u8; N] {} - | ------------ ^ ^^^^^^^ - | | - | unsatisfied trait bound introduced here + = help: the trait `Q` is implemented for `[u8; N]` error[E0308]: mismatched types --> $DIR/type_mismatch.rs:12:20 @@ -37,5 +31,5 @@ LL | impl Q for [u8; N] {} error: aborting due to 4 previous errors -Some errors have detailed explanations: E0046, E0308. +Some errors have detailed explanations: E0046, E0277, E0308. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/const-generics/issues/issue-105821.rs b/tests/ui/const-generics/issues/issue-105821.rs index a0a98103b2cd..282cbe9249d9 100644 --- a/tests/ui/const-generics/issues/issue-105821.rs +++ b/tests/ui/const-generics/issues/issue-105821.rs @@ -1,4 +1,10 @@ -//@ check-pass +//@ failure-status: 101 +//@ known-bug: unknown +//@ normalize-stderr-test "note: .*\n\n" -> "" +//@ normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> "" +//@ normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr-test "delayed at .*" -> "" +//@ rustc-env:RUST_BACKTRACE=0 #![allow(incomplete_features)] #![feature(adt_const_params, generic_const_exprs)] diff --git a/tests/ui/const-generics/issues/issue-105821.stderr b/tests/ui/const-generics/issues/issue-105821.stderr new file mode 100644 index 000000000000..1f0fc0f33ce4 --- /dev/null +++ b/tests/ui/const-generics/issues/issue-105821.stderr @@ -0,0 +1,8 @@ +error: internal compiler error: compiler/rustc_borrowck/src/universal_regions.rs:LL:CC: cannot convert `'{erased}` to a region vid + +query stack during panic: +#0 [mir_borrowck] borrow-checking `::R` +#1 [analysis] running analysis passes on this crate +end of query stack +error: aborting due to 1 previous error + diff --git a/tests/ui/consts/const-eval/format.rs b/tests/ui/consts/const-eval/format.rs index 5bdb2bf19543..b12df824a337 100644 --- a/tests/ui/consts/const-eval/format.rs +++ b/tests/ui/consts/const-eval/format.rs @@ -1,13 +1,13 @@ const fn failure() { panic!("{:?}", 0); //~^ ERROR cannot call non-const formatting macro in constant functions - //~| ERROR cannot call non-const fn `Arguments::<'_>::new_v1` in constant functions + //~| ERROR cannot call non-const fn `Arguments::<'_>::new_v1::<1, 1>` in constant functions } const fn print() { println!("{:?}", 0); //~^ ERROR cannot call non-const formatting macro in constant functions - //~| ERROR cannot call non-const fn `Arguments::<'_>::new_v1` in constant functions + //~| ERROR cannot call non-const fn `Arguments::<'_>::new_v1::<2, 1>` in constant functions //~| ERROR cannot call non-const fn `_print` in constant functions } diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr index 434b07443044..ce3f9f2190e5 100644 --- a/tests/ui/consts/const-eval/format.stderr +++ b/tests/ui/consts/const-eval/format.stderr @@ -7,7 +7,7 @@ LL | panic!("{:?}", 0); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0015]: cannot call non-const fn `Arguments::<'_>::new_v1` in constant functions +error[E0015]: cannot call non-const fn `Arguments::<'_>::new_v1::<1, 1>` in constant functions --> $DIR/format.rs:2:5 | LL | panic!("{:?}", 0); @@ -25,7 +25,7 @@ LL | println!("{:?}", 0); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0015]: cannot call non-const fn `Arguments::<'_>::new_v1` in constant functions +error[E0015]: cannot call non-const fn `Arguments::<'_>::new_v1::<2, 1>` in constant functions --> $DIR/format.rs:8:5 | LL | println!("{:?}", 0); diff --git a/tests/ui/consts/const_in_pattern/accept_structural.rs b/tests/ui/consts/const_in_pattern/accept_structural.rs index 31d3b6e73312..78d92abd88b4 100644 --- a/tests/ui/consts/const_in_pattern/accept_structural.rs +++ b/tests/ui/consts/const_in_pattern/accept_structural.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(non_local_definitions)] -#![warn(indirect_structural_match)] // This test is checking our logic for structural match checking by enumerating // the different kinds of const expressions. This test is collecting cases where diff --git a/tests/ui/consts/const_in_pattern/cross-crate-fail.rs b/tests/ui/consts/const_in_pattern/cross-crate-fail.rs index d8df2847c440..163a47f43336 100644 --- a/tests/ui/consts/const_in_pattern/cross-crate-fail.rs +++ b/tests/ui/consts/const_in_pattern/cross-crate-fail.rs @@ -1,7 +1,5 @@ //@ aux-build:consts.rs -#![warn(indirect_structural_match)] - extern crate consts; struct Defaulted; diff --git a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr index 067f2b6e6747..e0f97a9abd21 100644 --- a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr +++ b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr @@ -1,5 +1,5 @@ error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cross-crate-fail.rs:13:9 + --> $DIR/cross-crate-fail.rs:11:9 | LL | consts::SOME => panic!(), | ^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | consts::SOME => panic!(), = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cross-crate-fail.rs:20:9 + --> $DIR/cross-crate-fail.rs:18:9 | LL | ::SOME => panic!(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/const_in_pattern/cross-crate-pass.rs b/tests/ui/consts/const_in_pattern/cross-crate-pass.rs index c18a30b3495b..2a121a23dfc8 100644 --- a/tests/ui/consts/const_in_pattern/cross-crate-pass.rs +++ b/tests/ui/consts/const_in_pattern/cross-crate-pass.rs @@ -1,8 +1,6 @@ //@ run-pass //@ aux-build:consts.rs -#![warn(indirect_structural_match)] - extern crate consts; use consts::CustomEq; diff --git a/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs b/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs index 605f4e760cd2..2e7061e7c4b4 100644 --- a/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs +++ b/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs @@ -1,7 +1,5 @@ //@ run-pass -#![warn(indirect_structural_match)] - struct CustomEq; impl Eq for CustomEq {} diff --git a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.rs b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.rs index 6285427f59cb..e7c6101a3e06 100644 --- a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.rs +++ b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.rs @@ -1,4 +1,3 @@ -#![deny(pointer_structural_match)] #![allow(dead_code)] const C: *const u8 = &0; @@ -8,7 +7,6 @@ const C_INNER: (*const u8, u8) = (C, 0); fn foo(x: *const u8) { match x { C => {} //~ERROR: behave unpredictably - //~| previously accepted _ => {} } } @@ -16,7 +14,6 @@ fn foo(x: *const u8) { fn foo2(x: *const u8) { match (x, 1) { C_INNER => {} //~ERROR: behave unpredictably - //~| previously accepted _ => {} } } @@ -28,13 +25,11 @@ const STR: *const str = "abcd"; fn main() { match D { D => {} //~ERROR: behave unpredictably - //~| previously accepted _ => {} } match STR { STR => {} //~ERROR: behave unpredictably - //~| previously accepted _ => {} } } diff --git a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr index bc1015c17342..aa208341c131 100644 --- a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr +++ b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr @@ -1,103 +1,26 @@ error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:10:9 + --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:9:9 | LL | C => {} | ^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9 - | -LL | #![deny(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:18:9 + --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:16:9 | LL | C_INNER => {} | ^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:30:9 + --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:27:9 | LL | D => {} | ^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:36:9 + --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:32:9 | LL | STR => {} | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 error: aborting due to 4 previous errors -Future incompatibility report: Future breakage diagnostic: -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:10:9 - | -LL | C => {} - | ^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9 - | -LL | #![deny(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:18:9 - | -LL | C_INNER => {} - | ^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9 - | -LL | #![deny(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:30:9 - | -LL | D => {} - | ^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9 - | -LL | #![deny(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:36:9 - | -LL | STR => {} - | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9 - | -LL | #![deny(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - diff --git a/tests/ui/consts/const_in_pattern/issue-44333.rs b/tests/ui/consts/const_in_pattern/issue-44333.rs index 9adf02cbfcef..8a70aae1d509 100644 --- a/tests/ui/consts/const_in_pattern/issue-44333.rs +++ b/tests/ui/consts/const_in_pattern/issue-44333.rs @@ -1,7 +1,3 @@ -//@ run-pass - -#![warn(pointer_structural_match)] - type Func = fn(usize, usize) -> usize; fn foo(a: usize, b: usize) -> usize { a + b } @@ -16,10 +12,8 @@ const BAR: Func = bar; fn main() { match test(std::env::consts::ARCH.len()) { - FOO => println!("foo"), //~ WARN behave unpredictably - //~^ WARN will become a hard error - BAR => println!("bar"), //~ WARN behave unpredictably - //~^ WARN will become a hard error + FOO => println!("foo"), //~ ERROR behave unpredictably + BAR => println!("bar"), //~ ERROR behave unpredictably _ => unreachable!(), } } diff --git a/tests/ui/consts/const_in_pattern/issue-44333.stderr b/tests/ui/consts/const_in_pattern/issue-44333.stderr index f5931f0cad08..d377bfd95f9c 100644 --- a/tests/ui/consts/const_in_pattern/issue-44333.stderr +++ b/tests/ui/consts/const_in_pattern/issue-44333.stderr @@ -1,55 +1,14 @@ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-44333.rs:19:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/issue-44333.rs:15:9 | LL | FOO => println!("foo"), | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-44333.rs:3:9 - | -LL | #![warn(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-44333.rs:21:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/issue-44333.rs:16:9 | LL | BAR => println!("bar"), | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: 2 warnings emitted - -Future incompatibility report: Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-44333.rs:19:9 - | -LL | FOO => println!("foo"), - | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-44333.rs:3:9 - | -LL | #![warn(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-44333.rs:21:9 - | -LL | BAR => println!("bar"), - | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-44333.rs:3:9 - | -LL | #![warn(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs index 141d87d9b703..cf013c1a7906 100644 --- a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs +++ b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.rs @@ -1,5 +1,3 @@ -#![warn(indirect_structural_match)] - struct NoEq; enum Foo { diff --git a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr index b29f959de972..7766c6ce683d 100644 --- a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr +++ b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr @@ -1,5 +1,5 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq)]` - --> $DIR/no-eq-branch-fail.rs:21:9 + --> $DIR/no-eq-branch-fail.rs:19:9 | LL | BAR_BAZ => panic!(), | ^^^^^^^ diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.rs b/tests/ui/consts/const_in_pattern/reject_non_structural.rs index a9b0aa5507e3..e3dcecec960a 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.rs +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.rs @@ -11,8 +11,6 @@ // See also RFC 1445 #![feature(type_ascription)] -#![warn(indirect_structural_match)] -//~^ NOTE lint level is defined here #[derive(Copy, Clone, Debug)] struct NoPartialEq; @@ -96,9 +94,7 @@ fn main() { const ADDR_OF: &OND = &Some(NoDerive); match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; - //~^ WARN must be annotated with `#[derive(PartialEq)]` + //~^ ERROR must be annotated with `#[derive(PartialEq)]` //~| NOTE the traits must be derived //~| NOTE StructuralPartialEq.html for details - //~| WARN previously accepted by the compiler but is being phased out - //~| NOTE for more information, see } diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr index 2c7aaf89aa78..c068db42e4d9 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr @@ -1,5 +1,5 @@ error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:42:36 + --> $DIR/reject_non_structural.rs:40:36 | LL | match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), }; | ^^^^ @@ -8,7 +8,7 @@ LL | match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops" = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:48:28 + --> $DIR/reject_non_structural.rs:46:28 | LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; | ^^^^^ @@ -17,7 +17,7 @@ LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:55:27 + --> $DIR/reject_non_structural.rs:53:27 | LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), }; | ^^^^^^^^ @@ -26,7 +26,7 @@ LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops") = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:61:36 + --> $DIR/reject_non_structural.rs:59:36 | LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; | ^^^^^ @@ -35,7 +35,7 @@ LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoop = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:67:28 + --> $DIR/reject_non_structural.rs:65:28 | LL | match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; | ^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => p = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:73:36 + --> $DIR/reject_non_structural.rs:71:36 | LL | match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), }; | ^^^^^ @@ -53,7 +53,7 @@ LL | match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoop = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:79:33 + --> $DIR/reject_non_structural.rs:77:33 | LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; | ^^^^^^ @@ -62,7 +62,7 @@ LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:86:28 + --> $DIR/reject_non_structural.rs:84:28 | LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; | ^^^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => p = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:92:28 + --> $DIR/reject_non_structural.rs:90:28 | LL | match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; | ^^^^^ @@ -79,38 +79,14 @@ LL | match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:98:29 +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` + --> $DIR/reject_non_structural.rs:96:29 | LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; | ^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/reject_non_structural.rs:14:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 9 previous errors; 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/reject_non_structural.rs:98:29 - | -LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; - | ^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/reject_non_structural.rs:14:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 10 previous errors diff --git a/tests/crashes/121858.rs b/tests/ui/consts/eval_type_mismatch.rs similarity index 53% rename from tests/crashes/121858.rs rename to tests/ui/consts/eval_type_mismatch.rs index 7d5bae37f846..3d821ab538ec 100644 --- a/tests/crashes/121858.rs +++ b/tests/ui/consts/eval_type_mismatch.rs @@ -1,14 +1,17 @@ -//@ known-bug: #121858 #![feature(generic_const_exprs)] +#![allow(incomplete_features)] struct Outer(); impl Outer +//~^ ERROR: `A` is not of type `i64` +//~| ERROR: mismatched types where [(); A + (B * 2)]:, { - fn o() -> Union {} + fn o() {} } fn main() { Outer::<1, 1>::o(); + //~^ ERROR: no function or associated item named `o` found } diff --git a/tests/ui/consts/eval_type_mismatch.stderr b/tests/ui/consts/eval_type_mismatch.stderr new file mode 100644 index 000000000000..38d6e33d4067 --- /dev/null +++ b/tests/ui/consts/eval_type_mismatch.stderr @@ -0,0 +1,34 @@ +error: the constant `A` is not of type `i64` + --> $DIR/eval_type_mismatch.rs:5:38 + | +LL | impl Outer + | ^^^^^^^^^^^ expected `i64`, found `usize` + | +note: required by a bound in `Outer` + --> $DIR/eval_type_mismatch.rs:4:14 + | +LL | struct Outer(); + | ^^^^^^^^^^^^ required by this bound in `Outer` + +error[E0599]: no function or associated item named `o` found for struct `Outer<1, 1>` in the current scope + --> $DIR/eval_type_mismatch.rs:15:20 + | +LL | struct Outer(); + | ------------------------------------------ function or associated item `o` not found for this struct +... +LL | Outer::<1, 1>::o(); + | ^ function or associated item not found in `Outer<1, 1>` + | + = note: the function or associated item was found for + - `Outer` + +error[E0308]: mismatched types + --> $DIR/eval_type_mismatch.rs:5:44 + | +LL | impl Outer + | ^ expected `i64`, found `usize` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0599. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/issue-16538.stderr b/tests/ui/consts/issue-16538.stderr index 3981b4ada491..c4f5364b4d78 100644 --- a/tests/ui/consts/issue-16538.stderr +++ b/tests/ui/consts/issue-16538.stderr @@ -5,7 +5,7 @@ LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block --> $DIR/issue-16538.rs:11:22 diff --git a/tests/ui/consts/issue-32829-2.stderr b/tests/ui/consts/issue-32829-2.stderr index 0fec3581873e..bd0b8c15b558 100644 --- a/tests/ui/consts/issue-32829-2.stderr +++ b/tests/ui/consts/issue-32829-2.stderr @@ -13,7 +13,7 @@ LL | invalid(); | ^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error[E0015]: cannot call non-const fn `invalid` in statics --> $DIR/issue-32829-2.rs:54:9 @@ -22,7 +22,7 @@ LL | invalid(); | ^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 3 previous errors diff --git a/tests/ui/consts/issue-89088.rs b/tests/ui/consts/issue-89088.rs index d0782963dfc8..02a786e74651 100644 --- a/tests/ui/consts/issue-89088.rs +++ b/tests/ui/consts/issue-89088.rs @@ -1,8 +1,5 @@ // Regression test for the ICE described in #89088. -//@ check-pass - -#![allow(indirect_structural_match)] use std::borrow::Cow; const FOO: &A = &A::Field(Cow::Borrowed("foo")); @@ -16,7 +13,7 @@ fn main() { let var = A::Field(Cow::Borrowed("bar")); match &var { - FOO => todo!(), + FOO => todo!(), //~ERROR derive(PartialEq) _ => todo!() } } diff --git a/tests/ui/consts/issue-89088.stderr b/tests/ui/consts/issue-89088.stderr index 7cb85d5279d0..362c63a2a456 100644 --- a/tests/ui/consts/issue-89088.stderr +++ b/tests/ui/consts/issue-89088.stderr @@ -1,12 +1,11 @@ -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `Cow<'_, str>` in a pattern, `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-89088.rs:19:9 +error: to use a constant of type `Cow<'_, str>` in a pattern, `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]` + --> $DIR/issue-89088.rs:16:9 | LL | FOO => todo!(), | ^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details +error: aborting due to 1 previous error + diff --git a/tests/ui/consts/mir_check_nonconst.stderr b/tests/ui/consts/mir_check_nonconst.stderr index ea6a8b8ee4a5..95d64622ad7a 100644 --- a/tests/ui/consts/mir_check_nonconst.stderr +++ b/tests/ui/consts/mir_check_nonconst.stderr @@ -5,7 +5,7 @@ LL | static foo: Foo = bar(); | ^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/equality.rs b/tests/ui/impl-trait/equality.rs index 828b5aac896b..952f81f19784 100644 --- a/tests/ui/impl-trait/equality.rs +++ b/tests/ui/impl-trait/equality.rs @@ -22,7 +22,7 @@ fn sum_to(n: u32) -> impl Foo { 0 } else { n + sum_to(n - 1) - //~^ ERROR cannot add `impl Foo` to `u32` + //~^ ERROR cannot satisfy `>::Output == i32` } } @@ -32,12 +32,15 @@ trait Leak: Sized { } impl Leak for T { default type T = (); - default fn leak(self) -> Self::T { panic!() } + default fn leak(self) -> Self::T { + panic!() + } } impl Leak for i32 { type T = i32; - fn leak(self) -> i32 { self } + fn leak(self) -> i32 { + self + } } -fn main() { -} +fn main() {} diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index 69f4cbbbf429..c9ba1a5ba32d 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr @@ -22,20 +22,13 @@ help: change the type of the numeric literal from `u32` to `i32` LL | 0_i32 | ~~~ -error[E0277]: cannot add `impl Foo` to `u32` +error[E0284]: type annotations needed: cannot satisfy `>::Output == i32` --> $DIR/equality.rs:24:11 | LL | n + sum_to(n - 1) - | ^ no implementation for `u32 + impl Foo` - | - = help: the trait `Add` is not implemented for `u32` - = help: the following other types implement trait `Add`: - <&'a u32 as Add> - <&u32 as Add<&u32>> - > - + | ^ cannot satisfy `>::Output == i32` error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0284, E0308. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr index 1f9a2a5e9d60..f7c708a1dfae 100644 --- a/tests/ui/impl-trait/nested_impl_trait.stderr +++ b/tests/ui/impl-trait/nested_impl_trait.stderr @@ -46,19 +46,23 @@ error[E0277]: the trait bound `impl Into: Into` is not satisfie --> $DIR/nested_impl_trait.rs:6:46 | LL | fn bad_in_ret_position(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Into`, which is required by `impl Into: Into` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into` | - = help: the trait `Into` is implemented for `T` - = note: required for `impl Into` to implement `Into` +help: consider further restricting this bound + | +LL | fn bad_in_ret_position(x: impl Into + std::fmt::Debug) -> impl Into { x } + | +++++++++++++++++ error[E0277]: the trait bound `impl Into: Into` is not satisfied --> $DIR/nested_impl_trait.rs:19:34 | LL | fn bad(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Into`, which is required by `impl Into: Into` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into` | - = help: the trait `Into` is implemented for `T` - = note: required for `impl Into` to implement `Into` +help: consider further restricting this bound + | +LL | fn bad(x: impl Into + std::fmt::Debug) -> impl Into { x } + | +++++++++++++++++ error: aborting due to 7 previous errors diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs index aab10be2de27..7874a21f3aec 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs @@ -11,7 +11,7 @@ impl PartialEq<(Bar, i32)> for Bar { } fn foo() -> Foo { - //~^ ERROR can't compare `Bar` with `(Foo, i32)` + //~^ ERROR overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>` Bar } diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr index bc810c0f88f3..2d4707f8a279 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr @@ -1,15 +1,9 @@ -error[E0277]: can't compare `Bar` with `(Foo, i32)` +error[E0275]: overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>` --> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13 | LL | fn foo() -> Foo { - | ^^^ no implementation for `Bar == (Foo, i32)` -LL | -LL | Bar - | --- return type was inferred to be `Bar` here - | - = help: the trait `PartialEq<(Foo, i32)>` is not implemented for `Bar` - = help: the trait `PartialEq<(Bar, i32)>` is implemented for `Bar` + | ^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/impl-trait/unsize_adt.rs b/tests/ui/impl-trait/unsize_adt.rs new file mode 100644 index 000000000000..fce5094bd404 --- /dev/null +++ b/tests/ui/impl-trait/unsize_adt.rs @@ -0,0 +1,14 @@ +//! Test that we do not allow unsizing `Foo<[Opaque; N]>` to `Foo<[Concrete]>`. + +struct Foo(T); + +fn hello() -> Foo<[impl Sized; 2]> { + if false { + let x = hello(); + let _: &Foo<[i32]> = &x; + //~^ ERROR: mismatched types + } + todo!() +} + +fn main() {} diff --git a/tests/ui/impl-trait/unsize_adt.stderr b/tests/ui/impl-trait/unsize_adt.stderr new file mode 100644 index 000000000000..2b93b4a571b1 --- /dev/null +++ b/tests/ui/impl-trait/unsize_adt.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/unsize_adt.rs:8:30 + | +LL | fn hello() -> Foo<[impl Sized; 2]> { + | ---------- the found opaque type +... +LL | let _: &Foo<[i32]> = &x; + | ----------- ^^ expected `&Foo<[i32]>`, found `&Foo<[impl Sized; 2]>` + | | + | expected due to this + | + = note: expected reference `&Foo<[i32]>` + found reference `&Foo<[impl Sized; 2]>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/unsize_slice.rs b/tests/ui/impl-trait/unsize_slice.rs new file mode 100644 index 000000000000..ec0f16265640 --- /dev/null +++ b/tests/ui/impl-trait/unsize_slice.rs @@ -0,0 +1,12 @@ +//! Test that we do not allow unsizing `[Opaque; N]` to `[Concrete]`. + +fn hello() -> [impl Sized; 2] { + if false { + let x = hello(); + let _: &[i32] = &x; + //~^ ERROR: mismatched types + } + todo!() +} + +fn main() {} diff --git a/tests/ui/impl-trait/unsize_slice.stderr b/tests/ui/impl-trait/unsize_slice.stderr new file mode 100644 index 000000000000..6a7fdb46163b --- /dev/null +++ b/tests/ui/impl-trait/unsize_slice.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/unsize_slice.rs:6:25 + | +LL | fn hello() -> [impl Sized; 2] { + | ---------- the found opaque type +... +LL | let _: &[i32] = &x; + | ------ ^^ expected `&[i32]`, found `&[impl Sized; 2]` + | | + | expected due to this + | + = note: expected reference `&[i32]` + found reference `&[impl Sized; 2]` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/unsize_tuple.rs b/tests/ui/impl-trait/unsize_tuple.rs new file mode 100644 index 000000000000..630b8fd430f1 --- /dev/null +++ b/tests/ui/impl-trait/unsize_tuple.rs @@ -0,0 +1,14 @@ +//! Test that we do not allow unsizing `([Opaque; N],)` to `([Concrete],)`. + +#![feature(unsized_tuple_coercion)] + +fn hello() -> ([impl Sized; 2],) { + if false { + let x = hello(); + let _: &([i32],) = &x; + //~^ ERROR: mismatched types + } + todo!() +} + +fn main() {} diff --git a/tests/ui/impl-trait/unsize_tuple.stderr b/tests/ui/impl-trait/unsize_tuple.stderr new file mode 100644 index 000000000000..8d3cf15887c0 --- /dev/null +++ b/tests/ui/impl-trait/unsize_tuple.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/unsize_tuple.rs:8:28 + | +LL | fn hello() -> ([impl Sized; 2],) { + | ---------- the found opaque type +... +LL | let _: &([i32],) = &x; + | --------- ^^ expected `&([i32],)`, found `&([impl Sized; 2],)` + | | + | expected due to this + | + = note: expected reference `&([i32],)` + found reference `&([impl Sized; 2],)` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-25901.stderr b/tests/ui/issues/issue-25901.stderr index 5c19abffa029..3fedfd964170 100644 --- a/tests/ui/issues/issue-25901.stderr +++ b/tests/ui/issues/issue-25901.stderr @@ -16,7 +16,7 @@ note: impl defined here, but it is not `const` LL | impl Deref for A { | ^^^^^^^^^^^^^^^^ = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` help: add `#![feature(const_trait_impl)]` to the crate attributes to enable | LL + #![feature(const_trait_impl)] diff --git a/tests/ui/issues/issue-33992.rs b/tests/ui/issues/issue-33992.rs index 177ff234bb29..495751436e12 100644 --- a/tests/ui/issues/issue-33992.rs +++ b/tests/ui/issues/issue-33992.rs @@ -5,9 +5,6 @@ #![feature(linkage)] -#[linkage = "common"] -pub static mut TEST1: u32 = 0u32; - #[linkage = "external"] pub static TEST2: bool = true; diff --git a/tests/ui/issues/issue-7364.stderr b/tests/ui/issues/issue-7364.stderr index 3bf59a6d7114..d5b6dde1f10e 100644 --- a/tests/ui/issues/issue-7364.stderr +++ b/tests/ui/issues/issue-7364.stderr @@ -18,7 +18,7 @@ LL | static boxed: Box> = Box::new(RefCell::new(0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 2 previous errors diff --git a/tests/ui/linkage-attr/linkage-attr-mutable-static.rs b/tests/ui/linkage-attr/linkage-attr-mutable-static.rs new file mode 100644 index 000000000000..a7109c6d930b --- /dev/null +++ b/tests/ui/linkage-attr/linkage-attr-mutable-static.rs @@ -0,0 +1,15 @@ +//! The symbols are resolved by the linker. It doesn't make sense to change +//! them at runtime, so deny mutable statics with #[linkage]. + +#![feature(linkage)] + +fn main() { + extern "C" { + #[linkage = "weak"] //~ ERROR mutable statics are not allowed with `#[linkage]` + static mut ABC: *const u8; + } + + unsafe { + assert_eq!(ABC as usize, 0); + } +} diff --git a/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr b/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr new file mode 100644 index 000000000000..4db41b623938 --- /dev/null +++ b/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr @@ -0,0 +1,10 @@ +error: mutable statics are not allowed with `#[linkage]` + --> $DIR/linkage-attr-mutable-static.rs:8:9 + | +LL | #[linkage = "weak"] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: making the static mutable would allow changing which symbol the static references rather than make the target of the symbol mutable + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/suspicious-double-ref-op.rs b/tests/ui/lint/suspicious-double-ref-op.rs index bc8c23c7b895..5aeb81dbd65a 100644 --- a/tests/ui/lint/suspicious-double-ref-op.rs +++ b/tests/ui/lint/suspicious-double-ref-op.rs @@ -1,4 +1,3 @@ -#![feature(lazy_cell)] #![deny(suspicious_double_ref_op, noop_method_call)] use std::borrow::Borrow; diff --git a/tests/ui/lint/suspicious-double-ref-op.stderr b/tests/ui/lint/suspicious-double-ref-op.stderr index f5a71d40fc13..c956843c5078 100644 --- a/tests/ui/lint/suspicious-double-ref-op.stderr +++ b/tests/ui/lint/suspicious-double-ref-op.stderr @@ -1,29 +1,29 @@ error: using `.clone()` on a double reference, which returns `&Vec` instead of cloning the inner type - --> $DIR/suspicious-double-ref-op.rs:15:23 + --> $DIR/suspicious-double-ref-op.rs:14:23 | LL | let z: &Vec<_> = y.clone(); | ^^^^^^^^ | note: the lint level is defined here - --> $DIR/suspicious-double-ref-op.rs:2:9 + --> $DIR/suspicious-double-ref-op.rs:1:9 | LL | #![deny(suspicious_double_ref_op, noop_method_call)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: using `.clone()` on a double reference, which returns `&CloneType` instead of cloning the inner type - --> $DIR/suspicious-double-ref-op.rs:33:63 + --> $DIR/suspicious-double-ref-op.rs:32:63 | LL | let clone_type_ref_clone: &CloneType = clone_type_ref.clone(); | ^^^^^^^^ error: using `.deref()` on a double reference, which returns `&PlainType` instead of dereferencing the inner type - --> $DIR/suspicious-double-ref-op.rs:37:63 + --> $DIR/suspicious-double-ref-op.rs:36:63 | LL | let non_deref_type_deref: &PlainType = non_deref_type.deref(); | ^^^^^^^^ error: using `.clone()` on a double reference, which returns `&str` instead of cloning the inner type - --> $DIR/suspicious-double-ref-op.rs:41:44 + --> $DIR/suspicious-double-ref-op.rs:40:44 | LL | let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // could use `*x` instead | ^^^^^^^^ diff --git a/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.rs b/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.rs new file mode 100644 index 000000000000..fc2c15ee8c66 --- /dev/null +++ b/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.rs @@ -0,0 +1,16 @@ +// Fix for . + +fn separate_arms() { + let mut x = None; + match x { + None => { + x = Some(0); + } + Some(right) => { + consume(right); + //~^ ERROR cannot find function `consume` in this scope + } + } +} + +fn main() {} diff --git a/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.stderr b/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.stderr new file mode 100644 index 000000000000..40d8301c24e5 --- /dev/null +++ b/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find function `consume` in this scope + --> $DIR/suggest-method-on-call-for-ambig-receiver.rs:10:13 + | +LL | consume(right); + | ^^^^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/mir/dyn_metadata_sroa.rs b/tests/ui/mir/dyn_metadata_sroa.rs new file mode 100644 index 000000000000..1a00c0f0a3e3 --- /dev/null +++ b/tests/ui/mir/dyn_metadata_sroa.rs @@ -0,0 +1,19 @@ +//@ run-pass +//@ compile-flags: -Zmir-opt-level=5 -Zvalidate-mir + +#![feature(ptr_metadata)] + +// Regression for , +// which failed because of SRoA would project into `DynMetadata`. + +trait Foo {} + +struct Bar; + +impl Foo for Bar {} + +fn main() { + let a: *mut dyn Foo = &mut Bar; + + let _d = a.to_raw_parts().0 as usize; +} diff --git a/tests/ui/nll/issue-55511.rs b/tests/ui/nll/issue-55511.rs index 7dfa9c7bcdff..78ca89b624a9 100644 --- a/tests/ui/nll/issue-55511.rs +++ b/tests/ui/nll/issue-55511.rs @@ -1,4 +1,3 @@ -#![warn(indirect_structural_match)] use std::cell::Cell; trait Foo<'a> { const C: Option>; diff --git a/tests/ui/nll/issue-55511.stderr b/tests/ui/nll/issue-55511.stderr index ac7cd54df71f..726630307bb2 100644 --- a/tests/ui/nll/issue-55511.stderr +++ b/tests/ui/nll/issue-55511.stderr @@ -1,5 +1,5 @@ error[E0597]: `a` does not live long enough - --> $DIR/issue-55511.rs:13:28 + --> $DIR/issue-55511.rs:12:28 | LL | let a = 22; | - binding `a` declared here diff --git a/tests/ui/nll/ty-outlives/impl-trait-captures.stderr b/tests/ui/nll/ty-outlives/impl-trait-captures.stderr index 3893cdf482e6..48569d1446dd 100644 --- a/tests/ui/nll/ty-outlives/impl-trait-captures.stderr +++ b/tests/ui/nll/ty-outlives/impl-trait-captures.stderr @@ -1,4 +1,4 @@ -error[E0700]: hidden type for `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0, T, DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0])` captures lifetime that does not appear in bounds +error[E0700]: hidden type for `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), ['a/#0, T, 'a/#0])` captures lifetime that does not appear in bounds --> $DIR/impl-trait-captures.rs:11:5 | LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> { @@ -8,7 +8,7 @@ LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> { LL | x | ^ | -help: to declare that `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), [DefId(0:9 ~ impl_trait_captures[aeb9]::foo::'a)_'a/#0, T, DefId(0:14 ~ impl_trait_captures[aeb9]::foo::{opaque#0}::'a)_'a/#2])` captures `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))`, you can add an explicit `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))` lifetime bound +help: to declare that `Opaque(DefId(0:13 ~ impl_trait_captures[aeb9]::foo::{opaque#0}), ['a/#0, T, 'a/#2])` captures `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))`, you can add an explicit `ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_))` lifetime bound | LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReLateParam(DefId(0:8 ~ impl_trait_captures[aeb9]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[aeb9]::foo::'_), '_)) { | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr b/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr index 7b896ce14266..66b57c772d54 100644 --- a/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr +++ b/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr @@ -352,7 +352,7 @@ LL | static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]); | ^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` help: add `#![feature(const_trait_impl)]` to the crate attributes to enable | LL + #![feature(const_trait_impl)] diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index a2d2388ff508..11126dbc65d2 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -8,14 +8,12 @@ fn f1_1(x: isize, ...) {} fn f1_2(...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic -//~| ERROR C-variadic function must be declared with at least one named argument extern "C" fn f2_1(x: isize, ...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic extern "C" fn f2_2(...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic -//~| ERROR C-variadic function must be declared with at least one named argument extern "C" fn f2_3(..., x: isize) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic @@ -26,7 +24,6 @@ extern "C" fn f3_1(x: isize, ...) {} extern "C" fn f3_2(...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic -//~| ERROR C-variadic function must be declared with at least one named argument extern "C" fn f3_3(..., x: isize) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic @@ -47,8 +44,6 @@ const extern "C" fn f4_3(..., x: isize, ...) {} //~| ERROR `...` must be the last argument of a C-variadic function extern "C" { - fn e_f1(...); - //~^ ERROR C-variadic function must be declared with at least one named argument fn e_f2(..., x: isize); //~^ ERROR `...` must be the last argument of a C-variadic function } @@ -60,7 +55,6 @@ impl X { //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic fn i_f2(...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic - //~| ERROR C-variadic function must be declared with at least one named argument fn i_f3(..., x: isize, ...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic //~| ERROR `...` must be the last argument of a C-variadic function @@ -80,10 +74,8 @@ trait T { //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic fn t_f3(...) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic - //~| ERROR C-variadic function must be declared with at least one named argument fn t_f4(...); //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic - //~| ERROR C-variadic function must be declared with at least one named argument fn t_f5(..., x: isize) {} //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic //~| ERROR `...` must be the last argument of a C-variadic function diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index 6a65ed79d4fb..f71e3863440f 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -4,12 +4,6 @@ error: only foreign or `unsafe extern "C"` functions may be C-variadic LL | fn f1_1(x: isize, ...) {} | ^^^ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9 - | -LL | fn f1_2(...) {} - | ^^^ - error: only foreign or `unsafe extern "C"` functions may be C-variadic --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9 | @@ -17,91 +11,79 @@ LL | fn f1_2(...) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:13:30 + --> $DIR/variadic-ffi-semantic-restrictions.rs:12:30 | LL | extern "C" fn f2_1(x: isize, ...) {} | ^^^ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:16:20 - | -LL | extern "C" fn f2_2(...) {} - | ^^^ - error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:16:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:15:20 | LL | extern "C" fn f2_2(...) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:20:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20 | LL | extern "C" fn f2_3(..., x: isize) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:20:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20 | LL | extern "C" fn f2_3(..., x: isize) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:24:30 + --> $DIR/variadic-ffi-semantic-restrictions.rs:22:30 | LL | extern "C" fn f3_1(x: isize, ...) {} | ^^^ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20 - | -LL | extern "C" fn f3_2(...) {} - | ^^^ - error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:25:20 | LL | extern "C" fn f3_2(...) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:31:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:28:20 | LL | extern "C" fn f3_3(..., x: isize) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:31:20 + --> $DIR/variadic-ffi-semantic-restrictions.rs:28:20 | LL | extern "C" fn f3_3(..., x: isize) {} | ^^^ error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:35:1 + --> $DIR/variadic-ffi-semantic-restrictions.rs:32:1 | LL | const unsafe extern "C" fn f4_1(x: isize, ...) {} | ^^^^^ `const` because of this ^^^ C-variadic because of this error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:39:1 + --> $DIR/variadic-ffi-semantic-restrictions.rs:36:1 | LL | const extern "C" fn f4_2(x: isize, ...) {} | ^^^^^ `const` because of this ^^^ C-variadic because of this error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:39:36 + --> $DIR/variadic-ffi-semantic-restrictions.rs:36:36 | LL | const extern "C" fn f4_2(x: isize, ...) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:44:26 + --> $DIR/variadic-ffi-semantic-restrictions.rs:41:26 | LL | const extern "C" fn f4_3(..., x: isize, ...) {} | ^^^ error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:44:1 + --> $DIR/variadic-ffi-semantic-restrictions.rs:41:1 | LL | const extern "C" fn f4_3(..., x: isize, ...) {} | ^^^^^ ^^^ ^^^ C-variadic because of this @@ -110,67 +92,55 @@ LL | const extern "C" fn f4_3(..., x: isize, ...) {} | `const` because of this error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:44:26 + --> $DIR/variadic-ffi-semantic-restrictions.rs:41:26 | LL | const extern "C" fn f4_3(..., x: isize, ...) {} | ^^^ ^^^ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:50:13 - | -LL | fn e_f1(...); - | ^^^ - error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:52:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:47:13 | LL | fn e_f2(..., x: isize); | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:59:23 + --> $DIR/variadic-ffi-semantic-restrictions.rs:54:23 | LL | fn i_f1(x: isize, ...) {} | ^^^ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13 - | -LL | fn i_f2(...) {} - | ^^^ - error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:56:13 | LL | fn i_f2(...) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:64:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:58:13 | LL | fn i_f3(..., x: isize, ...) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:64:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:58:13 | LL | fn i_f3(..., x: isize, ...) {} | ^^^ ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:67:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13 | LL | fn i_f4(..., x: isize, ...) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:67:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13 | LL | fn i_f4(..., x: isize, ...) {} | ^^^ ^^^ error: functions cannot be both `const` and C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:70:5 + --> $DIR/variadic-ffi-semantic-restrictions.rs:64:5 | LL | const fn i_f5(x: isize, ...) {} | ^^^^^ ^^^ C-variadic because of this @@ -178,73 +148,61 @@ LL | const fn i_f5(x: isize, ...) {} | `const` because of this error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:70:29 + --> $DIR/variadic-ffi-semantic-restrictions.rs:64:29 | LL | const fn i_f5(x: isize, ...) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:77:23 + --> $DIR/variadic-ffi-semantic-restrictions.rs:71:23 | LL | fn t_f1(x: isize, ...) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:79:23 + --> $DIR/variadic-ffi-semantic-restrictions.rs:73:23 | LL | fn t_f2(x: isize, ...); | ^^^ -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:81:13 +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/variadic-ffi-semantic-restrictions.rs:75:13 | LL | fn t_f3(...) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:81:13 - | -LL | fn t_f3(...) {} - | ^^^ - -error: C-variadic function must be declared with at least one named argument - --> $DIR/variadic-ffi-semantic-restrictions.rs:84:13 - | -LL | fn t_f4(...); - | ^^^ - -error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:84:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:77:13 | LL | fn t_f4(...); | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:87:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:79:13 | LL | fn t_f5(..., x: isize) {} | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:87:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:79:13 | LL | fn t_f5(..., x: isize) {} | ^^^ error: `...` must be the last argument of a C-variadic function - --> $DIR/variadic-ffi-semantic-restrictions.rs:90:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:82:13 | LL | fn t_f6(..., x: isize); | ^^^ error: only foreign or `unsafe extern "C"` functions may be C-variadic - --> $DIR/variadic-ffi-semantic-restrictions.rs:90:13 + --> $DIR/variadic-ffi-semantic-restrictions.rs:82:13 | LL | fn t_f6(..., x: isize); | ^^^ error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time - --> $DIR/variadic-ffi-semantic-restrictions.rs:35:43 + --> $DIR/variadic-ffi-semantic-restrictions.rs:32:43 | LL | const unsafe extern "C" fn f4_1(x: isize, ...) {} | ^^^ - value is dropped here @@ -252,7 +210,7 @@ LL | const unsafe extern "C" fn f4_1(x: isize, ...) {} | the destructor for this type cannot be evaluated in constant functions error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time - --> $DIR/variadic-ffi-semantic-restrictions.rs:39:36 + --> $DIR/variadic-ffi-semantic-restrictions.rs:36:36 | LL | const extern "C" fn f4_2(x: isize, ...) {} | ^^^ - value is dropped here @@ -260,13 +218,13 @@ LL | const extern "C" fn f4_2(x: isize, ...) {} | the destructor for this type cannot be evaluated in constant functions error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time - --> $DIR/variadic-ffi-semantic-restrictions.rs:70:29 + --> $DIR/variadic-ffi-semantic-restrictions.rs:64:29 | LL | const fn i_f5(x: isize, ...) {} | ^^^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 43 previous errors +error: aborting due to 36 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr index 2a1cd3a7aa4b..0b4d99727581 100644 --- a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr +++ b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr @@ -9,15 +9,3 @@ LL | if let CONSTANT = &&MyType { error: aborting due to 1 previous error -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `MyType` in a pattern, `MyType` must be annotated with `#[derive(PartialEq)]` - --> $DIR/const-partial_eq-fallback-ice.rs:14:12 - | -LL | if let CONSTANT = &&MyType { - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details - diff --git a/tests/ui/pattern/usefulness/consts-opaque.rs b/tests/ui/pattern/usefulness/consts-opaque.rs index 3e4617851823..a5743c633085 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.rs +++ b/tests/ui/pattern/usefulness/consts-opaque.rs @@ -93,10 +93,8 @@ fn main() { const QUUX: Quux = quux; match QUUX { - QUUX => {} //~WARN behave unpredictably - //~| previously accepted - QUUX => {} //~WARN behave unpredictably - //~| previously accepted + QUUX => {} //~ERROR behave unpredictably + QUUX => {} //~ERROR behave unpredictably _ => {} } @@ -105,17 +103,14 @@ fn main() { const WRAPQUUX: Wrap = Wrap(quux); match WRAPQUUX { - WRAPQUUX => {} //~WARN behave unpredictably - //~| previously accepted - WRAPQUUX => {} //~WARN behave unpredictably - //~| previously accepted + WRAPQUUX => {} //~ERROR behave unpredictably + WRAPQUUX => {} //~ERROR behave unpredictably Wrap(_) => {} } match WRAPQUUX { Wrap(_) => {} - WRAPQUUX => {} //~WARN behave unpredictably - //~| previously accepted + WRAPQUUX => {} //~ERROR behave unpredictably } match WRAPQUUX { @@ -123,9 +118,7 @@ fn main() { } match WRAPQUUX { - //~^ ERROR: non-exhaustive patterns: `Wrap(_)` not covered - WRAPQUUX => {} //~WARN behave unpredictably - //~| previously accepted + WRAPQUUX => {} //~ERROR behave unpredictably } #[derive(PartialEq, Eq)] @@ -136,11 +129,9 @@ fn main() { const WHOKNOWSQUUX: WhoKnows = WhoKnows::Yay(quux); match WHOKNOWSQUUX { - WHOKNOWSQUUX => {} //~WARN behave unpredictably - //~| previously accepted + WHOKNOWSQUUX => {} //~ERROR behave unpredictably WhoKnows::Yay(_) => {} - WHOKNOWSQUUX => {} //~WARN behave unpredictably - //~| previously accepted + WHOKNOWSQUUX => {} //~ERROR behave unpredictably WhoKnows::Nope => {} } } diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr index 6a5bd185e39b..d057309e4206 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.stderr +++ b/tests/ui/pattern/usefulness/consts-opaque.stderr @@ -1,75 +1,50 @@ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. --> $DIR/consts-opaque.rs:96:9 | LL | QUUX => {} | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:98:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:97:9 | LL | QUUX => {} | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:108:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:106:9 | LL | WRAPQUUX => {} | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:110:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:107:9 | LL | WRAPQUUX => {} | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:117:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:113:9 | LL | WRAPQUUX => {} | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:127:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:121:9 | LL | WRAPQUUX => {} | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:139:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:132:9 | LL | WHOKNOWSQUUX => {} | ^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:142:9 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/consts-opaque.rs:134:9 | LL | WHOKNOWSQUUX => {} | ^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 error: unreachable pattern --> $DIR/consts-opaque.rs:48:9 @@ -146,111 +121,5 @@ error: unreachable pattern LL | _ => {} // should not be emitting unreachable warning | ^ -error[E0004]: non-exhaustive patterns: `Wrap(_)` not covered - --> $DIR/consts-opaque.rs:125:11 - | -LL | match WRAPQUUX { - | ^^^^^^^^ pattern `Wrap(_)` not covered - | -note: `Wrap usize>` defined here - --> $DIR/consts-opaque.rs:104:12 - | -LL | struct Wrap(T); - | ^^^^ - = note: the matched value is of type `Wrap usize>` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -LL | WRAPQUUX => {}, Wrap(_) => todo!() - | ++++++++++++++++++++ - -error: aborting due to 10 previous errors; 8 warnings emitted - -For more information about this error, try `rustc --explain E0004`. -Future incompatibility report: Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:96:9 - | -LL | QUUX => {} - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:98:9 - | -LL | QUUX => {} - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:108:9 - | -LL | WRAPQUUX => {} - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:110:9 - | -LL | WRAPQUUX => {} - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:117:9 - | -LL | WRAPQUUX => {} - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:127:9 - | -LL | WRAPQUUX => {} - | ^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:139:9 - | -LL | WHOKNOWSQUUX => {} - | ^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/consts-opaque.rs:142:9 - | -LL | WHOKNOWSQUUX => {} - | ^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default +error: aborting due to 17 previous errors diff --git a/tests/ui/raw-ref-op/const-eval-compare-ice-105047.rs b/tests/ui/raw-ref-op/const-eval-compare-ice-105047.rs deleted file mode 100644 index 87ce4f1e14d9..000000000000 --- a/tests/ui/raw-ref-op/const-eval-compare-ice-105047.rs +++ /dev/null @@ -1,15 +0,0 @@ -// issue: rust-lang/rust#105047 -// ICE raw ptr comparison should already be caught in the trait systems - -#![feature(raw_ref_op)] - -const RCZ: *const i32 = &raw const *&0; - -const fn f() { - if let RCZ = &raw const *&0 { } - //~^ WARN function pointers and raw pointers not derived from integers in patterns - //~| ERROR pointers cannot be reliably compared during const eval - //~| WARN this was previously accepted by the compiler but is being phased out -} - -fn main() {} diff --git a/tests/ui/raw-ref-op/const-eval-compare-ice-105047.stderr b/tests/ui/raw-ref-op/const-eval-compare-ice-105047.stderr deleted file mode 100644 index 9c472cda2442..000000000000 --- a/tests/ui/raw-ref-op/const-eval-compare-ice-105047.stderr +++ /dev/null @@ -1,31 +0,0 @@ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/const-eval-compare-ice-105047.rs:9:12 - | -LL | if let RCZ = &raw const *&0 { } - | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -error: pointers cannot be reliably compared during const eval - --> $DIR/const-eval-compare-ice-105047.rs:9:12 - | -LL | if let RCZ = &raw const *&0 { } - | ^^^ - | - = note: see issue #53020 for more information - -error: aborting due to 1 previous error; 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/const-eval-compare-ice-105047.rs:9:12 - | -LL | if let RCZ = &raw const *&0 { } - | ^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - diff --git a/tests/ui/return/dont-suggest-through-inner-const.rs b/tests/ui/return/dont-suggest-through-inner-const.rs new file mode 100644 index 000000000000..b2347dedd52d --- /dev/null +++ b/tests/ui/return/dont-suggest-through-inner-const.rs @@ -0,0 +1,9 @@ +const fn f() -> usize { + //~^ ERROR mismatched types + const FIELD: usize = loop { + 0 + //~^ ERROR mismatched types + }; +} + +fn main() {} diff --git a/tests/ui/return/dont-suggest-through-inner-const.stderr b/tests/ui/return/dont-suggest-through-inner-const.stderr new file mode 100644 index 000000000000..6aeee74b0adf --- /dev/null +++ b/tests/ui/return/dont-suggest-through-inner-const.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/dont-suggest-through-inner-const.rs:4:9 + | +LL | 0 + | ^ expected `()`, found integer + +error[E0308]: mismatched types + --> $DIR/dont-suggest-through-inner-const.rs:1:17 + | +LL | const fn f() -> usize { + | - ^^^^^ expected `usize`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs deleted file mode 100644 index 22ea6f7534a7..000000000000 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Test explores how `#[structral_match]` behaves in tandem with -// `*const` and `*mut` pointers. - -//@ run-pass - -#![warn(pointer_structural_match)] - -struct NoDerive(#[allow(dead_code)] i32); - -// This impl makes NoDerive irreflexive -// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). -impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } - -impl Eq for NoDerive { } - -#[derive(PartialEq, Eq)] -struct WrapEmbedded(*const NoDerive); - -const WRAP_UNSAFE_EMBEDDED: WrapEmbedded = WrapEmbedded(std::ptr::null()); - -fn main() { - match WRAP_UNSAFE_EMBEDDED { - WRAP_UNSAFE_EMBEDDED => { println!("WRAP_UNSAFE_EMBEDDED correctly matched itself"); } - _ => { panic!("WRAP_UNSAFE_EMBEDDED did not match itself"); } - } -} diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs deleted file mode 100644 index cd513d2aff4d..000000000000 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Test explores how `#[structral_match]` behaves in tandem with -// `*const` and `*mut` pointers. - -//@ run-pass - -#![warn(pointer_structural_match)] - -struct NoDerive(#[allow(dead_code)] i32); - -// This impl makes NoDerive irreflexive -// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). -impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } - -impl Eq for NoDerive { } - -#[derive(PartialEq, Eq)] -struct WrapParam(*const X); - -const WRAP_UNSAFE_PARAM: WrapParam = WrapParam(std::ptr::null()); - -fn main() { - match WRAP_UNSAFE_PARAM { - WRAP_UNSAFE_PARAM => { println!("WRAP_UNSAFE_PARAM correctly matched itself"); } - _ => { panic!("WRAP_UNSAFE_PARAM did not match itself"); } - } -} diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs deleted file mode 100644 index 9595d00876bc..000000000000 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Test explores how `#[structral_match]` behaves in tandem with -// `*const` and `*mut` pointers. - -//@ run-pass - -#![warn(pointer_structural_match)] - -struct NoDerive(#[allow(dead_code)] i32); - -// This impl makes NoDerive irreflexive -// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). -impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } - -impl Eq for NoDerive { } - -#[derive(PartialEq, Eq)] -struct WrapEmbedded(*const NoDerive); - -const WRAP_UNSAFE_EMBEDDED: & &WrapEmbedded = & &WrapEmbedded(std::ptr::null()); - -fn main() { - match WRAP_UNSAFE_EMBEDDED { - WRAP_UNSAFE_EMBEDDED => { println!("WRAP_UNSAFE_EMBEDDED correctly matched itself"); } - _ => { panic!("WRAP_UNSAFE_EMBEDDED did not match itself"); } - } -} diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs deleted file mode 100644 index 9dce827a57cb..000000000000 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Test explores how `#[structral_match]` behaves in tandem with -// `*const` and `*mut` pointers. - -//@ run-pass - -#![warn(pointer_structural_match)] - -struct NoDerive(#[allow(dead_code)] i32); - -// This impl makes NoDerive irreflexive -// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). -impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } - -impl Eq for NoDerive { } - -#[derive(PartialEq, Eq)] -struct WrapParam(*const X); - -const WRAP_UNSAFE_PARAM: & &WrapParam = & &WrapParam(std::ptr::null()); - -fn main() { - match WRAP_UNSAFE_PARAM { - WRAP_UNSAFE_PARAM => { println!("WRAP_UNSAFE_PARAM correctly matched itself"); } - _ => { panic!("WRAP_UNSAFE_PARAM did not match itself"); } - } -} diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs index 112021c783fc..f840b4040b65 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs @@ -4,7 +4,6 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 -#![warn(indirect_structural_match)] struct NoDerive(i32); // This impl makes NoDerive irreflexive. diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr index 8bca7d9889cd..3d00ef2dfbf6 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr @@ -1,5 +1,5 @@ error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-direct-struct-param.rs:22:9 + --> $DIR/cant-hide-behind-direct-struct-param.rs:21:9 | LL | WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs index b64fbd9d49a1..898acefc83cc 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs @@ -4,8 +4,6 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 -#![warn(indirect_structural_match)] -//@ run-pass struct NoDerive(#[allow(dead_code)] i32); @@ -22,8 +20,7 @@ const WRAP_DOUBLY_INDIRECT_INLINE: & &WrapInline = & &WrapInline(& & NoDerive(0) fn main() { match WRAP_DOUBLY_INDIRECT_INLINE { WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } - //~^ WARN must be annotated with `#[derive(PartialEq)]` - //~| WARN this was previously accepted + //~^ ERROR must be annotated with `#[derive(PartialEq)]` _ => { println!("WRAP_DOUBLY_INDIRECT_INLINE correctly did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr index 9945041113d7..3636307e16c6 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr @@ -1,35 +1,11 @@ -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:24:9 +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` + --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:22:9 | LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:24:9 - | -LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs index be37217a7d45..7cbaada88a30 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs @@ -4,8 +4,6 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 -#![warn(indirect_structural_match)] -//@ run-pass struct NoDerive(#[allow(dead_code)] i32); @@ -22,8 +20,7 @@ const WRAP_DOUBLY_INDIRECT_PARAM: & &WrapParam = & &WrapParam(& & NoDe fn main() { match WRAP_DOUBLY_INDIRECT_PARAM { WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } - //~^ WARN must be annotated with `#[derive(PartialEq)]` - //~| WARN this was previously accepted + //~^ ERROR must be annotated with `#[derive(PartialEq)]` _ => { println!("WRAP_DOUBLY_INDIRECT_PARAM correctly did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr index 6ac261ae8143..40fd31762b2f 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr @@ -1,35 +1,11 @@ -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-doubly-indirect-param.rs:24:9 +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` + --> $DIR/cant-hide-behind-doubly-indirect-param.rs:22:9 | LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-doubly-indirect-param.rs:24:9 - | -LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs index e26234bd4553..ac868efed6fd 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs @@ -4,8 +4,6 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 -#![warn(indirect_structural_match)] -//@ run-pass struct NoDerive(#[allow(dead_code)] i32); @@ -22,8 +20,7 @@ const WRAP_INDIRECT_INLINE: & &WrapInline = & &WrapInline(NoDerive(0)); fn main() { match WRAP_INDIRECT_INLINE { WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } - //~^ WARN must be annotated with `#[derive(PartialEq)]` - //~| WARN this was previously accepted + //~^ ERROR must be annotated with `#[derive(PartialEq)]` _ => { println!("WRAP_INDIRECT_INLINE did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr index 41616fb90fe9..dbf1848326aa 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr @@ -1,35 +1,11 @@ -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:24:9 +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` + --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:22:9 | LL | WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } | ^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:24:9 - | -LL | WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } - | ^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs index 729f411a0215..cbfabec6819e 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs @@ -4,8 +4,6 @@ // through that we had intended to reject. // // See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 -#![warn(indirect_structural_match)] -//@ run-pass struct NoDerive(#[allow(dead_code)] i32); @@ -22,8 +20,7 @@ const WRAP_INDIRECT_PARAM: & &WrapParam = & &WrapParam(NoDerive(0)); fn main() { match WRAP_INDIRECT_PARAM { WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } - //~^ WARN must be annotated with `#[derive(PartialEq)]` - //~| WARN this was previously accepted + //~^ ERROR must be annotated with `#[derive(PartialEq)]` _ => { println!("WRAP_INDIRECT_PARAM correctly did not match itself"); } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr index 99dea5171d1b..58acc11a7449 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr @@ -1,35 +1,11 @@ -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-indirect-struct-param.rs:24:9 +error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` + --> $DIR/cant-hide-behind-indirect-struct-param.rs:22:9 | LL | WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-indirect-struct-param.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 1 warning emitted - -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]` - --> $DIR/cant-hide-behind-indirect-struct-param.rs:24:9 - | -LL | WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } - | ^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/cant-hide-behind-indirect-struct-param.rs:7:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.rs similarity index 76% rename from tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.rs rename to tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.rs index 25434e0050f0..d572d12c5b1c 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.rs @@ -1,7 +1,5 @@ -//@ run-pass - -// This file checks that fn ptrs are considered structurally matchable. -// See also rust-lang/rust#63479. +// This file checks that fn ptrs are *not* considered structurally matchable. +// See also rust-lang/rust#63479 and RFC 3535. fn main() { let mut count = 0; @@ -40,8 +38,7 @@ fn main() { const CFN1: Wrap = Wrap(trivial); let input: Wrap = Wrap(trivial); match Wrap(input) { - Wrap(CFN1) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN1) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -49,8 +46,7 @@ fn main() { const CFN2: Wrap = Wrap(sm_to); let input: Wrap = Wrap(sm_to); match Wrap(input) { - Wrap(CFN2) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN2) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -58,8 +54,7 @@ fn main() { const CFN3: Wrap SM> = Wrap(to_sm); let input: Wrap SM> = Wrap(to_sm); match Wrap(input) { - Wrap(CFN3) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN3) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -67,8 +62,7 @@ fn main() { const CFN4: Wrap = Wrap(not_sm_to); let input: Wrap = Wrap(not_sm_to); match Wrap(input) { - Wrap(CFN4) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN4) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -76,8 +70,7 @@ fn main() { const CFN5: Wrap NotSM> = Wrap(to_not_sm); let input: Wrap NotSM> = Wrap(to_not_sm); match Wrap(input) { - Wrap(CFN5) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN5) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -85,8 +78,7 @@ fn main() { const CFN6: Wrap = Wrap(r_sm_to); let input: Wrap = Wrap(r_sm_to); match Wrap(input) { - Wrap(CFN6) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN6) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -94,8 +86,7 @@ fn main() { const CFN7: Wrap &SM> = Wrap(r_to_r_sm); let input: Wrap &SM> = Wrap(r_to_r_sm); match Wrap(input) { - Wrap(CFN7) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN7) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -103,8 +94,7 @@ fn main() { const CFN8: Wrap = Wrap(r_not_sm_to); let input: Wrap = Wrap(r_not_sm_to); match Wrap(input) { - Wrap(CFN8) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN8) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -112,8 +102,7 @@ fn main() { const CFN9: Wrap &NotSM> = Wrap(r_to_r_not_sm); let input: Wrap &NotSM> = Wrap(r_to_r_not_sm); match Wrap(input) { - Wrap(CFN9) => count += 1, //~WARN behave unpredictably - //~| previously accepted + Wrap(CFN9) => count += 1, //~ERROR behave unpredictably Wrap(_) => {} }; @@ -135,8 +124,7 @@ fn main() { let input = Foo { alpha: not_sm_to, beta: to_not_sm, gamma: sm_to, delta: to_sm }; match input { - CFOO => count += 1, //~WARN behave unpredictably - //~| previously accepted + CFOO => count += 1, //~ERROR behave unpredictably Foo { .. } => {} }; diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr new file mode 100644 index 000000000000..0bc1e7fc89b5 --- /dev/null +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-not-structurally-matchable.stderr @@ -0,0 +1,62 @@ +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:41:14 + | +LL | Wrap(CFN1) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:49:14 + | +LL | Wrap(CFN2) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:57:14 + | +LL | Wrap(CFN3) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:65:14 + | +LL | Wrap(CFN4) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:73:14 + | +LL | Wrap(CFN5) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:81:14 + | +LL | Wrap(CFN6) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:89:14 + | +LL | Wrap(CFN7) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:97:14 + | +LL | Wrap(CFN8) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:105:14 + | +LL | Wrap(CFN9) => count += 1, + | ^^^^ + +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/fn-ptr-is-not-structurally-matchable.rs:127:9 + | +LL | CFOO => count += 1, + | ^^^^ + +error: aborting due to 10 previous errors + diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.stderr deleted file mode 100644 index 11163ba70ec6..000000000000 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.stderr +++ /dev/null @@ -1,203 +0,0 @@ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:43:14 - | -LL | Wrap(CFN1) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:52:14 - | -LL | Wrap(CFN2) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:61:14 - | -LL | Wrap(CFN3) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:70:14 - | -LL | Wrap(CFN4) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:79:14 - | -LL | Wrap(CFN5) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:88:14 - | -LL | Wrap(CFN6) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:97:14 - | -LL | Wrap(CFN7) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:106:14 - | -LL | Wrap(CFN8) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:115:14 - | -LL | Wrap(CFN9) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:138:9 - | -LL | CFOO => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - -warning: 10 warnings emitted - -Future incompatibility report: Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:43:14 - | -LL | Wrap(CFN1) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:52:14 - | -LL | Wrap(CFN2) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:61:14 - | -LL | Wrap(CFN3) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:70:14 - | -LL | Wrap(CFN4) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:79:14 - | -LL | Wrap(CFN5) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:88:14 - | -LL | Wrap(CFN6) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:97:14 - | -LL | Wrap(CFN7) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:106:14 - | -LL | Wrap(CFN8) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:115:14 - | -LL | Wrap(CFN9) => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/fn-ptr-is-structurally-matchable.rs:138:9 - | -LL | CFOO => count += 1, - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: `#[warn(pointer_structural_match)]` on by default - diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs index 81618b3b791e..0fa2370c95bf 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs @@ -10,8 +10,6 @@ // Issue 62307 pointed out a case where the structural-match checking // was too shallow. -#![warn(indirect_structural_match)] -//@ run-pass #[derive(Debug)] struct B(i32); @@ -29,15 +27,13 @@ fn main() { match RR_B0 { RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } - //~^ WARN must be annotated with `#[derive(PartialEq)]` - //~| WARN this was previously accepted + //~^ ERROR must be annotated with `#[derive(PartialEq)]` _ => { } } match RR_B1 { RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } - //~^ WARN must be annotated with `#[derive(PartialEq)]` - //~| WARN this was previously accepted + //~^ ERROR must be annotated with `#[derive(PartialEq)]` _ => { } } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr index d4ab1ce3ba2a..e79b05fdf9dc 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr @@ -1,63 +1,20 @@ -warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:31:9 +error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:29:9 | LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } | ^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:38:9 +error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` + --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:35:9 | LL | RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } | ^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 = note: the traits must be derived, manual `impl`s are not sufficient = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -warning: 2 warnings emitted - -Future incompatibility report: Future breakage diagnostic: -warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:31:9 - | -LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]` - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:38:9 - | -LL | RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 - = note: the traits must be derived, manual `impl`s are not sufficient - = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details -note: the lint level is defined here - --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9 - | -LL | #![warn(indirect_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.rs index 634aaf8115f2..9ceb72b68721 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.rs +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.rs @@ -1,12 +1,8 @@ -//@ run-pass - // The actual regression test from #63479. (Including this because my // first draft at fn-ptr-is-structurally-matchable.rs failed to actually // cover the case this hit; I've since expanded it accordingly, but the // experience left me wary of leaving this regression test out.) -#![warn(pointer_structural_match)] - #[derive(Eq)] struct A { a: i64 @@ -34,14 +30,12 @@ fn main() { let s = B(my_fn); match s { B(TEST) => println!("matched"), - //~^ WARN behave unpredictably - //~| WARN this was previously accepted by the compiler but is being phased out + //~^ ERROR behave unpredictably _ => panic!("didn't match") }; match (s.0, 0) { TEST2 => println!("matched"), - //~^ WARN behave unpredictably - //~| WARN this was previously accepted by the compiler but is being phased out + //~^ ERROR behave unpredictably _ => panic!("didn't match") } } diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr index 0edcf44c4d79..7b1832ed0fa5 100644 --- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr +++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr @@ -1,55 +1,14 @@ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-63479-match-fnptr.rs:36:7 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/issue-63479-match-fnptr.rs:32:7 | LL | B(TEST) => println!("matched"), | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-63479-match-fnptr.rs:8:9 - | -LL | #![warn(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-63479-match-fnptr.rs:42:5 +error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. + --> $DIR/issue-63479-match-fnptr.rs:37:5 | LL | TEST2 => println!("matched"), | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -warning: 2 warnings emitted - -Future incompatibility report: Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-63479-match-fnptr.rs:36:7 - | -LL | B(TEST) => println!("matched"), - | ^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-63479-match-fnptr.rs:8:9 - | -LL | #![warn(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -Future breakage diagnostic: -warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. - --> $DIR/issue-63479-match-fnptr.rs:42:5 - | -LL | TEST2 => println!("matched"), - | ^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #120362 -note: the lint level is defined here - --> $DIR/issue-63479-match-fnptr.rs:8:9 - | -LL | #![warn(pointer_structural_match)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs index d43fabcedec5..7bd372c16952 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs @@ -1,6 +1,6 @@ //@ check-pass -#![feature(const_trait_impl, lazy_cell)] +#![feature(const_trait_impl)] use std::sync::LazyLock; diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs index f89a463bc580..4d1cd4332fee 100644 --- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs +++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs @@ -7,7 +7,8 @@ struct S; impl Copy for S {} //~^ ERROR: mismatched types +//~| ERROR: the trait bound `S: Clone` is not satisfied +//~| ERROR: the constant `N` is not of type `usize` impl Copy for S {} -//~^ ERROR: conflicting implementations of trait `Copy` for type `S<_>` fn main() {} diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr index 1dac58e1f694..716a47879482 100644 --- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr +++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr @@ -1,11 +1,29 @@ -error[E0119]: conflicting implementations of trait `Copy` for type `S<_>` - --> $DIR/bad-const-wf-doesnt-specialize.rs:10:1 +error[E0277]: the trait bound `S: Clone` is not satisfied + --> $DIR/bad-const-wf-doesnt-specialize.rs:8:29 | LL | impl Copy for S {} - | -------------------------------- first implementation here -LL | -LL | impl Copy for S {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>` + | ^^^^ the trait `Clone` is not implemented for `S` + | + = help: the trait `Clone` is implemented for `S` +note: required by a bound in `Copy` + --> $SRC_DIR/core/src/marker.rs:LL:COL +help: consider annotating `S` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct S; + | + +error: the constant `N` is not of type `usize` + --> $DIR/bad-const-wf-doesnt-specialize.rs:8:29 + | +LL | impl Copy for S {} + | ^^^^ expected `usize`, found `i32` + | +note: required by a bound in `S` + --> $DIR/bad-const-wf-doesnt-specialize.rs:6:10 + | +LL | struct S; + | ^^^^^^^^^^^^^^ required by this bound in `S` error[E0308]: mismatched types --> $DIR/bad-const-wf-doesnt-specialize.rs:8:31 @@ -13,7 +31,7 @@ error[E0308]: mismatched types LL | impl Copy for S {} | ^ expected `usize`, found `i32` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0119, E0308. -For more information about an error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/static/static-mut-not-constant.stderr b/tests/ui/static/static-mut-not-constant.stderr index d125bec59435..46dc175cb298 100644 --- a/tests/ui/static/static-mut-not-constant.stderr +++ b/tests/ui/static/static-mut-not-constant.stderr @@ -5,7 +5,7 @@ LL | static mut a: Box = Box::new(3); | ^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error diff --git a/tests/ui/static/static-vec-repeat-not-constant.stderr b/tests/ui/static/static-vec-repeat-not-constant.stderr index db0c7eb8d35f..a3b930323d5b 100644 --- a/tests/ui/static/static-vec-repeat-not-constant.stderr +++ b/tests/ui/static/static-vec-repeat-not-constant.stderr @@ -5,7 +5,7 @@ LL | static a: [isize; 2] = [foo(); 2]; | ^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error: aborting due to 1 previous error diff --git a/tests/ui/statics/check-values-constraints.stderr b/tests/ui/statics/check-values-constraints.stderr index 45a699f575fb..24763c175fc8 100644 --- a/tests/ui/statics/check-values-constraints.stderr +++ b/tests/ui/statics/check-values-constraints.stderr @@ -26,7 +26,7 @@ LL | static STATIC11: Vec = vec![MyOwned]; | ^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0015]: cannot call non-const fn `::to_string` in statics @@ -36,7 +36,7 @@ LL | field2: SafeEnum::Variant4("str".to_string()), | ^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` help: add `#![feature(const_trait_impl)]` to the crate attributes to enable | LL + #![feature(const_trait_impl)] @@ -57,7 +57,7 @@ LL | vec![MyOwned], | ^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0010]: allocations are not allowed in statics @@ -75,7 +75,7 @@ LL | vec![MyOwned], | ^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0010]: allocations are not allowed in statics @@ -93,7 +93,7 @@ LL | &vec![MyOwned], | ^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0010]: allocations are not allowed in statics @@ -111,7 +111,7 @@ LL | &vec![MyOwned], | ^^^^^^^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0010]: allocations are not allowed in statics @@ -129,7 +129,7 @@ LL | static STATIC19: Vec = vec![3]; | ^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0010]: allocations are not allowed in statics @@ -147,7 +147,7 @@ LL | static x: Vec = vec![3]; | ^^^^^^^ | = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0507]: cannot move out of static item `x` diff --git a/tests/ui/sync/reentrantlockguard-sync.rs b/tests/ui/sync/reentrantlockguard-sync.rs new file mode 100644 index 000000000000..84d5b1834a88 --- /dev/null +++ b/tests/ui/sync/reentrantlockguard-sync.rs @@ -0,0 +1,15 @@ +#![feature(reentrant_lock)] +use std::sync::ReentrantLock; +use std::cell::Cell; + +// ReentrantLockGuard> must not be Sync, that would be unsound. + +fn test_sync(_t: T) {} + +fn main() +{ + let m = ReentrantLock::new(Cell::new(0i32)); + let guard = m.lock(); + test_sync(guard); + //~^ ERROR `Cell` cannot be shared between threads safely [E0277] +} diff --git a/tests/ui/sync/reentrantlockguard-sync.stderr b/tests/ui/sync/reentrantlockguard-sync.stderr new file mode 100644 index 000000000000..ed2e3e2f1124 --- /dev/null +++ b/tests/ui/sync/reentrantlockguard-sync.stderr @@ -0,0 +1,20 @@ +error[E0277]: `Cell` cannot be shared between threads safely + --> $DIR/reentrantlockguard-sync.rs:13:15 + | +LL | test_sync(guard); + | --------- ^^^^^ `Cell` cannot be shared between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Sync` is not implemented for `Cell`, which is required by `ReentrantLockGuard<'_, Cell>: Sync` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead + = note: required for `ReentrantLockGuard<'_, Cell>` to implement `Sync` +note: required by a bound in `test_sync` + --> $DIR/reentrantlockguard-sync.rs:7:17 + | +LL | fn test_sync(_t: T) {} + | ^^^^ required by this bound in `test_sync` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/typeck/index-of-projection.rs b/tests/ui/traits/next-solver/typeck/index-of-projection.rs new file mode 100644 index 000000000000..5023be0bb148 --- /dev/null +++ b/tests/ui/traits/next-solver/typeck/index-of-projection.rs @@ -0,0 +1,13 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// Fixes a regression in `rustc_attr` where we weren't normalizing the +// output type of a index operator performing a `Ty::builtin_index` call, +// leading to an ICE. + +fn main() { + let mut vec = [1, 2, 3]; + let x = || { + let [..] = &vec[..]; + }; +} diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs new file mode 100644 index 000000000000..5820e49a4e52 --- /dev/null +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs @@ -0,0 +1,28 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@[next] failure-status: 101 +//@[next] known-bug: unknown +//@[next] normalize-stderr-test "note: .*\n\n" -> "" +//@[next] normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> "" +//@[next] normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@[next] normalize-stderr-test "delayed at .*" -> "" +//@[next] rustc-env:RUST_BACKTRACE=0 +//@ check-pass + +#![feature(trait_upcasting)] + +trait Super { + type Assoc; +} + +trait Sub: Super {} + +impl Super for T { + type Assoc = i32; +} + +fn illegal(x: &dyn Sub) -> &dyn Super { + x +} + +fn main() {} diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-4.rs b/tests/ui/traits/trait-upcasting/type-checking-test-4.rs index f40c48f0d125..01759ec7a93c 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-4.rs +++ b/tests/ui/traits/trait-upcasting/type-checking-test-4.rs @@ -11,6 +11,10 @@ fn test_correct(x: &dyn Foo<'static>) { let _ = x as &dyn Bar<'static, 'static>; } +fn test_correct2<'a>(x: &dyn Foo<'a>) { + let _ = x as &dyn Bar<'_, '_>; +} + fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { let _ = x as &dyn Bar<'static, 'a>; // Error //~^ ERROR lifetime may not live long enough diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr index 8d506e5807ec..ccced5875778 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:15:13 + --> $DIR/type-checking-test-4.rs:19:13 | LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here @@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'static, 'a>; // Error | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:20:13 + --> $DIR/type-checking-test-4.rs:24:13 | LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here @@ -15,7 +15,7 @@ LL | let _ = x as &dyn Bar<'a, 'static>; // Error | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:26:5 + --> $DIR/type-checking-test-4.rs:30:5 | LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here @@ -24,7 +24,7 @@ LL | y.get_b() // ERROR | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:31:5 + --> $DIR/type-checking-test-4.rs:35:5 | LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here @@ -32,7 +32,7 @@ LL | <_ as Bar>::get_b(x) // ERROR | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:36:5 + --> $DIR/type-checking-test-4.rs:40:5 | LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here @@ -40,7 +40,7 @@ LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:44:5 + --> $DIR/type-checking-test-4.rs:48:5 | LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs new file mode 100644 index 000000000000..a3a1ce29465b --- /dev/null +++ b/tests/ui/traits/trait-upcasting/type-checking-test-opaques.rs @@ -0,0 +1,22 @@ +#![feature(trait_upcasting, type_alias_impl_trait)] + +//@ check-pass + +type Tait = impl Sized; + +trait Foo<'a>: Bar<'a, 'a, Tait> {} +trait Bar<'a, 'b, T> {} + +fn test_correct(x: &dyn Foo<'static>) { + let _ = x as &dyn Bar<'static, 'static, Tait>; +} + +fn test_correct2<'a>(x: &dyn Foo<'a>) { + let _ = x as &dyn Bar<'_, '_, Tait>; +} + +fn test_correct3<'a>(x: &dyn Foo<'a>, _: Tait) { + let _ = x as &dyn Bar<'_, '_, ()>; +} + +fn main() {} diff --git a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.current.stderr b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.current.stderr deleted file mode 100644 index a259abb28ae3..000000000000 --- a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.current.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/upcast-defining-opaque.rs:21:5 - | -LL | type Foo = impl Sized; - | ---------- the found opaque type -LL | -LL | fn upcast(x: &dyn Sub) -> &dyn Super { - | ----------------------- expected `&dyn Super` because of return type -LL | x - | ^ expected trait `Super`, found trait `Sub` - | - = note: expected reference `&dyn Super` - found reference `&dyn Sub` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs index cb1501a94a2a..07f1549e177f 100644 --- a/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs +++ b/tests/ui/traits/trait-upcasting/upcast-defining-opaque.rs @@ -1,7 +1,7 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver //@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] check-pass +//@check-pass #![feature(trait_upcasting, type_alias_impl_trait)] @@ -18,7 +18,7 @@ impl Super for T { type Foo = impl Sized; fn upcast(x: &dyn Sub) -> &dyn Super { - x //[current]~ mismatched types + x } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs new file mode 100644 index 000000000000..2a246900106c --- /dev/null +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs @@ -0,0 +1,27 @@ +//! Check that projections will constrain opaque types while looking for +//! matching impls. + +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@check-pass + +#![feature(type_alias_impl_trait)] + +struct Foo; + +type Bar = impl Sized; + +trait Trait { + type Assoc: Default; +} + +impl Trait<()> for Foo { + type Assoc = u32; +} + +fn bop(_: Bar) { + let x = >::Assoc::default(); +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr new file mode 100644 index 000000000000..0d6eac4216ba --- /dev/null +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr @@ -0,0 +1,19 @@ +error[E0283]: type annotations needed: cannot satisfy `Foo: Trait` + --> $DIR/constrain_in_projection2.rs:27:14 + | +LL | let x = >::Assoc::default(); + | ^^^ help: use the fully qualified path to an implementation: `::Assoc` + | +note: multiple `impl`s satisfying `Foo: Trait` found + --> $DIR/constrain_in_projection2.rs:18:1 + | +LL | impl Trait<()> for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl Trait for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr new file mode 100644 index 000000000000..0d6eac4216ba --- /dev/null +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.next.stderr @@ -0,0 +1,19 @@ +error[E0283]: type annotations needed: cannot satisfy `Foo: Trait` + --> $DIR/constrain_in_projection2.rs:27:14 + | +LL | let x = >::Assoc::default(); + | ^^^ help: use the fully qualified path to an implementation: `::Assoc` + | +note: multiple `impl`s satisfying `Foo: Trait` found + --> $DIR/constrain_in_projection2.rs:18:1 + | +LL | impl Trait<()> for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl Trait for Foo { + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs new file mode 100644 index 000000000000..0066131f0155 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs @@ -0,0 +1,31 @@ +//! Check that projections will constrain opaque types while looking for +//! matching impls and error if ambiguous. + +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +#![feature(type_alias_impl_trait)] + +struct Foo; + +type Bar = impl Sized; + +trait Trait { + type Assoc: Default; +} + +impl Trait<()> for Foo { + type Assoc = u32; +} + +impl Trait for Foo { + type Assoc = u32; +} + +fn bop(_: Bar) { + let x = >::Assoc::default(); + //~^ ERROR: cannot satisfy `Foo: Trait` +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr similarity index 90% rename from tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr rename to tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr index 461da20f37b6..a7ff097e8bf3 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/issue-84660-unsoundness.rs:23:1 + --> $DIR/issue-84660-unsoundness.rs:28:1 | LL | impl Trait for Out { | ------------------------------------ first implementation here diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr new file mode 100644 index 000000000000..607f0b062abd --- /dev/null +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr @@ -0,0 +1,23 @@ +error[E0284]: type annotations needed: cannot satisfy `>::Out == ()` + --> $DIR/issue-84660-unsoundness.rs:22:37 + | +LL | fn convert(_i: In) -> Self::Out { + | _____________________________________^ +LL | | +LL | | unreachable!(); +LL | | } + | |_____^ cannot satisfy `>::Out == ()` + +error[E0119]: conflicting implementations of trait `Trait` + --> $DIR/issue-84660-unsoundness.rs:28:1 + | +LL | impl Trait for Out { + | ------------------------------------ first implementation here +... +LL | impl Trait<(), In> for Out { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0119, E0284. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs index 48d4b0c96ff0..99a5d36066b0 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs @@ -1,6 +1,10 @@ // Another example from issue #84660, this time weaponized as a safe transmute: an opaque type in an // impl header being accepted was used to create unsoundness. +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + #![feature(type_alias_impl_trait)] trait Foo {} @@ -16,11 +20,13 @@ trait Trait { impl Trait for Out { type Out = Out; fn convert(_i: In) -> Self::Out { + //[next]~^ ERROR: type annotations needed unreachable!(); } } -impl Trait<(), In> for Out { //~ ERROR conflicting implementations of trait `Trait` +impl Trait<(), In> for Out { + //~^ ERROR conflicting implementations of trait `Trait` type Out = In; fn convert(i: In) -> Self::Out { i diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs index 82248971692c..70495c44706a 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs @@ -1,18 +1,21 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@check-pass + use std::fmt::Debug; type FooX = impl Debug; -trait Foo { } +trait Foo {} -impl Foo<()> for () { } +impl Foo<()> for () {} fn foo() -> impl Foo { - //~^ ERROR: the trait bound `(): Foo` is not satisfied - // FIXME(type-alias-impl-trait): We could probably make this work. () } -fn main() { } +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr new file mode 100644 index 000000000000..c7b7af152ab3 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr @@ -0,0 +1,17 @@ +error[E0283]: type annotations needed: cannot satisfy `(): Foo` + --> $DIR/nested-tait-inference2.rs:17:13 + | +LL | fn foo() -> impl Foo { + | ^^^^^^^^^^^^^^ + | +note: multiple `impl`s satisfying `(): Foo` found + --> $DIR/nested-tait-inference2.rs:14:1 + | +LL | impl Foo<()> for () {} + | ^^^^^^^^^^^^^^^^^^^ +LL | impl Foo for () {} + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr new file mode 100644 index 000000000000..9647d9e376eb --- /dev/null +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr @@ -0,0 +1,9 @@ +error[E0284]: type annotations needed: cannot satisfy `impl Foo == ()` + --> $DIR/nested-tait-inference2.rs:19:5 + | +LL | () + | ^^ cannot satisfy `impl Foo == ()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs index 0d7f5bad25f1..fe2f76e552ad 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs @@ -1,6 +1,10 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + use std::fmt::Debug; type FooX = impl Debug; @@ -11,8 +15,9 @@ impl Foo<()> for () {} impl Foo for () {} fn foo() -> impl Foo { - //~^ ERROR: the trait bound `(): Foo` is not satisfied + //[current]~^ ERROR: cannot satisfy `(): Foo` () + //[next]~^ ERROR: cannot satisfy `impl Foo == ()` } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr deleted file mode 100644 index 241342b05096..000000000000 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/nested-tait-inference2.rs:13:13 - | -LL | fn foo() -> impl Foo { - | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` -LL | -LL | () - | -- return type was inferred to be `()` here - | - = help: the following other types implement trait `Foo`: - <() as Foo<()>> - <() as Foo> - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr index a40dac06a01c..eff29303bf18 100644 --- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr +++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr @@ -22,21 +22,17 @@ note: previous use here LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) } | ^^^^^^^^^^^^^^^^^ -error[E0308]: mismatched types +error: concrete type differs from previous defining opaque type use --> $DIR/normalize-hidden-types.rs:43:25 | -LL | type Opaque = impl Sized; - | ---------- the expected opaque type -... LL | let _: Opaque = dyn_hoops::(0); - | ------ ^^^^^^^^^^^^^^^^^^ expected opaque type, found `*const dyn FnOnce(())` - | | - | expected due to this + | ^^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` | - = note: expected opaque type `typeck::Opaque` - found raw pointer `*const (dyn FnOnce(()) + 'static)` - = help: consider constraining the associated type `::Gat<'_>` to `()` or calling a method that returns `::Gat<'_>` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html +note: previous use here + --> $DIR/normalize-hidden-types.rs:44:9 + | +LL | None + | ^^^^ error: concrete type differs from previous defining opaque type use --> $DIR/normalize-hidden-types.rs:52:25 @@ -52,4 +48,3 @@ LL | None error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr deleted file mode 100644 index 3ae3590ca7fe..000000000000 --- a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0277]: can't compare `i32` with `Foo` - --> $DIR/self-referential-2.rs:10:13 - | -LL | fn bar() -> Bar { - | ^^^ no implementation for `i32 == Foo` -LL | 42_i32 - | ------ return type was inferred to be `i32` here - | - = help: the trait `PartialEq` is not implemented for `i32` - = help: the trait `PartialEq` is implemented for `i32` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.rs b/tests/ui/type-alias-impl-trait/self-referential-2.rs index f96364ccfcdd..f4102f2e2cb7 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-2.rs @@ -1,14 +1,14 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] check-pass +//@ check-pass #![feature(type_alias_impl_trait)] type Foo = impl std::fmt::Debug; type Bar = impl PartialEq; fn bar() -> Bar { - 42_i32 //[current]~^ ERROR can't compare `i32` with `Foo` + 42_i32 } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.rs b/tests/ui/type-alias-impl-trait/self-referential-3.rs index b33051da2d77..3b015ab322ac 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-3.rs @@ -5,7 +5,7 @@ type Bar<'a, 'b> = impl PartialEq> + std::fmt::Debug; fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - //~^ ERROR can't compare `&i32` with `Bar<'a, 'b>` + //~^ ERROR overflow normalizing the type alias `Bar<'a, 'b>` i } diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.stderr b/tests/ui/type-alias-impl-trait/self-referential-3.stderr index 32eac622e518..caa9f9691dda 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-3.stderr @@ -1,15 +1,11 @@ -error[E0277]: can't compare `&i32` with `Bar<'a, 'b>` +error[E0275]: overflow normalizing the type alias `Bar<'a, 'b>` --> $DIR/self-referential-3.rs:7:31 | LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'a, 'b>` -LL | -LL | i - | - return type was inferred to be `&i32` here + | ^^^^^^^^^^^ | - = help: the trait `PartialEq>` is not implemented for `&i32` - = help: the trait `PartialEq` is implemented for `i32` + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0275`. diff --git a/triagebot.toml b/triagebot.toml index 7c58402b737b..23e5c0a27f3a 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -122,6 +122,19 @@ issues). """ label = "O-apple" +# This ping group is meant for situations where a rustc/stdlib change breaks RfL. +# In that case, we want to notify the RfL group. +[ping.rust-for-linux] +alias = ["rfl"] +message = """\ +Hey Rust for Linux group! It looks like something broke the Rust for Linux integration. +Could you try to take a look? +In case it's useful, here are some [instructions] for tackling these sorts of issues. + +[instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/rust-for-linux.html +""" +label = "O-rfl" + [prioritize] label = "I-prioritize" @@ -455,6 +468,19 @@ message_on_remove = "PR #{number}'s beta-nomination has been removed." message_on_close = "PR #{number} has been closed. Thanks for participating!" message_on_reopen = "PR #{number} has been reopened. Pinging @*T-rustdoc*." +# FIXME: Patch triagebot to support `notify-zulip.