diff options
Diffstat (limited to 'compiler')
21 files changed, 148 insertions, 169 deletions
diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index a504d0c9122..c94dfe39b69 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -105,8 +105,8 @@ impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { write!( formatter, - "({:?}: {:?}) due to {:?} ({:?})", - self.sup, self.sub, self.locations, self.variance_info + "({:?}: {:?}) due to {:?} ({:?}) ({:?})", + self.sup, self.sub, self.locations, self.variance_info, self.category, ) } } diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 84a0d4ba7ba..5971f7623f2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1119,6 +1119,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// short a lifetime. (But sometimes it is more useful to report /// it as a more direct conflict between the execution of a /// `Drop::drop` with an aliasing borrow.) + #[instrument(level = "debug", skip(self))] pub(crate) fn report_borrowed_value_does_not_live_long_enough( &mut self, location: Location, @@ -1126,13 +1127,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { place_span: (Place<'tcx>, Span), kind: Option<WriteKind>, ) { - debug!( - "report_borrowed_value_does_not_live_long_enough(\ - {:?}, {:?}, {:?}, {:?}\ - )", - location, borrow, place_span, kind - ); - let drop_span = place_span.1; let root_place = self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap(); @@ -1189,10 +1183,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let kind_place = kind.filter(|_| place_desc.is_some()).map(|k| (k, place_span.0)); let explanation = self.explain_why_borrow_contains_point(location, &borrow, kind_place); - debug!( - "report_borrowed_value_does_not_live_long_enough(place_desc: {:?}, explanation: {:?})", - place_desc, explanation - ); + debug!(?place_desc, ?explanation); + let err = match (place_desc, explanation) { // If the outlives constraint comes from inside the closure, // for example: @@ -1464,6 +1456,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err } + #[instrument(level = "debug", skip(self))] fn report_temporary_value_does_not_live_long_enough( &mut self, location: Location, @@ -1473,13 +1466,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { proper_span: Span, explanation: BorrowExplanation<'tcx>, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - debug!( - "report_temporary_value_does_not_live_long_enough(\ - {:?}, {:?}, {:?}, {:?}\ - )", - location, borrow, drop_span, proper_span - ); - if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } = explanation { diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index a6b8c6057e0..2f61849c383 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -336,26 +336,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// - second half is the place being accessed /// /// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points + #[instrument(level = "debug", skip(self))] pub(crate) fn explain_why_borrow_contains_point( &self, location: Location, borrow: &BorrowData<'tcx>, kind_place: Option<(WriteKind, Place<'tcx>)>, ) -> BorrowExplanation<'tcx> { - debug!( - "explain_why_borrow_contains_point(location={:?}, borrow={:?}, kind_place={:?})", - location, borrow, kind_place - ); - let regioncx = &self.regioncx; let body: &Body<'_> = &self.body; let tcx = self.infcx.tcx; let borrow_region_vid = borrow.region; - debug!("explain_why_borrow_contains_point: borrow_region_vid={:?}", borrow_region_vid); + debug!(?borrow_region_vid); let region_sub = self.regioncx.find_sub_region_live_at(borrow_region_vid, location); - debug!("explain_why_borrow_contains_point: region_sub={:?}", region_sub); + debug!(?region_sub); match find_use::find(body, regioncx, tcx, region_sub, location) { Some(Cause::LiveVar(local, location)) => { @@ -408,17 +404,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { opt_place_desc, } } else { - debug!( - "explain_why_borrow_contains_point: \ - Could not generate a region name" - ); + debug!("Could not generate a region name"); BorrowExplanation::Unexplained } } else { - debug!( - "explain_why_borrow_contains_point: \ - Could not generate an error region vid" - ); + debug!("Could not generate an error region vid"); BorrowExplanation::Unexplained } } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 0f8afb038f4..362c45ecd7e 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -975,6 +975,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } + #[instrument(level = "debug", skip(self, flow_state))] fn check_access_for_conflict( &mut self, location: Location, @@ -983,11 +984,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { rw: ReadOrWrite, flow_state: &Flows<'cx, 'tcx>, ) -> bool { - debug!( - "check_access_for_conflict(location={:?}, place_span={:?}, sd={:?}, rw={:?})", - location, place_span, sd, rw, - ); - let mut error_reported = false; let tcx = self.infcx.tcx; let body = self.body; @@ -1451,13 +1447,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Checks whether a borrow of this place is invalidated when the function /// exits + #[instrument(level = "debug", skip(self))] fn check_for_invalidation_at_exit( &mut self, location: Location, borrow: &BorrowData<'tcx>, span: Span, ) { - debug!("check_for_invalidation_at_exit({:?})", borrow); let place = borrow.borrowed_place; let mut root_place = PlaceRef { local: place.local, projection: &[] }; diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index 97335fd0dff..6e5a96bee97 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -44,6 +44,7 @@ pub(crate) fn places_conflict<'tcx>( /// access depth. The `bias` parameter is used to determine how the unknowable (comparing runtime /// array indices, for example) should be interpreted - this depends on what the caller wants in /// order to make the conservative choice and preserve soundness. +#[instrument(level = "debug", skip(tcx, body))] pub(super) fn borrow_conflicts_with_place<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, @@ -53,11 +54,6 @@ pub(super) fn borrow_conflicts_with_place<'tcx>( access: AccessDepth, bias: PlaceConflictBias, ) -> bool { - debug!( - "borrow_conflicts_with_place({:?}, {:?}, {:?}, {:?})", - borrow_place, access_place, access, bias, - ); - // This Local/Local case is handled by the more general code below, but // it's so common that it's a speed win to check for it first. if let Some(l1) = borrow_place.as_local() && let Some(l2) = access_place.as_local() { @@ -140,10 +136,9 @@ fn place_components_conflict<'tcx>( for (i, (borrow_c, &access_c)) in iter::zip(borrow_place.projection, access_place.projection).enumerate() { - debug!("borrow_conflicts_with_place: borrow_c = {:?}", borrow_c); - let borrow_proj_base = &borrow_place.projection[..i]; + debug!(?borrow_c, ?access_c); - debug!("borrow_conflicts_with_place: access_c = {:?}", access_c); + let borrow_proj_base = &borrow_place.projection[..i]; // Borrow and access path both have more components. // @@ -180,7 +175,7 @@ fn place_components_conflict<'tcx>( // idea, at least for now, so just give up and // report a conflict. This is unsafe code anyway so // the user could always use raw pointers. - debug!("borrow_conflicts_with_place: arbitrary -> conflict"); + debug!("arbitrary -> conflict"); return true; } Overlap::EqualOrDisjoint => { @@ -189,7 +184,7 @@ fn place_components_conflict<'tcx>( Overlap::Disjoint => { // We have proven the borrow disjoint - further // projections will remain disjoint. - debug!("borrow_conflicts_with_place: disjoint"); + debug!("disjoint"); return false; } } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 2894c6d29ec..f5bd5cd3bea 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1167,8 +1167,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Therefore, this method should only be used in diagnostic code, /// where displaying *some* named universal region is better than /// falling back to 'static. + #[instrument(level = "debug", skip(self))] pub(crate) fn approx_universal_upper_bound(&self, r: RegionVid) -> RegionVid { - debug!("approx_universal_upper_bound(r={:?}={})", r, self.region_value_str(r)); + debug!("{}", self.region_value_str(r)); // Find the smallest universal region that contains all other // universal regions within `region`. @@ -1177,7 +1178,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let static_r = self.universal_regions.fr_static; for ur in self.scc_values.universal_regions_outlived_by(r_scc) { let new_lub = self.universal_region_relations.postdom_upper_bound(lub, ur); - debug!("approx_universal_upper_bound: ur={:?} lub={:?} new_lub={:?}", ur, lub, new_lub); + debug!(?ur, ?lub, ?new_lub); // The upper bound of two non-static regions is static: this // means we know nothing about the relationship between these // two regions. Pick a 'better' one to use when constructing @@ -1201,7 +1202,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - debug!("approx_universal_upper_bound: r={:?} lub={:?}", r, lub); + debug!(?r, ?lub); lub } @@ -2048,6 +2049,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// creating a constraint path that forces `R` to outlive /// `from_region`, and then finding the best choices within that /// path to blame. + #[instrument(level = "debug", skip(self, target_test))] pub(crate) fn best_blame_constraint( &self, body: &Body<'tcx>, @@ -2055,16 +2057,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { from_region_origin: NllRegionVariableOrigin, target_test: impl Fn(RegionVid) -> bool, ) -> BlameConstraint<'tcx> { - debug!( - "best_blame_constraint(from_region={:?}, from_region_origin={:?})", - from_region, from_region_origin - ); - // Find all paths let (path, target_region) = self.find_constraint_paths_between_regions(from_region, target_test).unwrap(); debug!( - "best_blame_constraint: path={:#?}", + "path={:#?}", path.iter() .map(|c| format!( "{:?} ({:?}: {:?})", @@ -2116,7 +2113,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } }) .collect(); - debug!("best_blame_constraint: categorized_path={:#?}", categorized_path); + debug!("categorized_path={:#?}", categorized_path); // To find the best span to cite, we first try to look for the // final constraint that is interesting and where the `sup` is @@ -2214,10 +2211,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let best_choice = if blame_source { range.rev().find(find_region) } else { range.find(find_region) }; - debug!( - "best_blame_constraint: best_choice={:?} blame_source={}", - best_choice, blame_source - ); + debug!(?best_choice, ?blame_source); if let Some(i) = best_choice { if let Some(next) = categorized_path.get(i + 1) { @@ -2254,7 +2248,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // appears to be the most interesting point to report to the // user via an even more ad-hoc guess. categorized_path.sort_by(|p0, p1| p0.category.cmp(&p1.category)); - debug!("best_blame_constraint: sorted_path={:#?}", categorized_path); + debug!("sorted_path={:#?}", categorized_path); categorized_path.remove(0) } diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 451b82c5c18..29195b3922f 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -24,7 +24,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { /// **Any `rustc_infer::infer` operations that might generate region /// constraints should occur within this method so that those /// constraints can be properly localized!** - #[instrument(skip(self, category, op), level = "trace")] + #[instrument(skip(self, op), level = "trace")] pub(super) fn fully_perform_op<R, Op>( &mut self, locations: Locations, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index c1812aa4bba..a620c987052 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1043,6 +1043,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation; let inferred_ty = self.normalize(inferred_ty, Locations::All(span)); let annotation = self.instantiate_canonical_with_fresh_inference_vars(span, user_ty); + debug!(?annotation); match annotation { UserType::Ty(mut ty) => { ty = self.normalize(ty, Locations::All(span)); diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index 27d791d90a5..f8e982b7751 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -1,6 +1,6 @@ use crate::traits::*; -use rustc_middle::ty::{self, subst::GenericArgKind, ExistentialPredicate, Ty, TyCtxt}; +use rustc_middle::ty::{self, subst::GenericArgKind, Ty}; use rustc_session::config::Lto; use rustc_symbol_mangling::typeid_for_trait_ref; use rustc_target::abi::call::FnAbi; @@ -29,7 +29,7 @@ impl<'a, 'tcx> VirtualIndex { && bx.cx().sess().lto() == Lto::Fat { let typeid = - bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), get_trait_ref(bx.tcx(), ty))); + bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(ty))); let vtable_byte_offset = self.0 * bx.data_layout().pointer_size.bytes(); let type_checked_load = bx.type_checked_load(llvtable, vtable_byte_offset, typeid); let func = bx.extract_value(type_checked_load, 0); @@ -64,17 +64,13 @@ impl<'a, 'tcx> VirtualIndex { } } -fn get_trait_ref<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::PolyExistentialTraitRef<'tcx> { +/// This takes a valid `self` receiver type and extracts the principal trait +/// ref of the type. +fn expect_dyn_trait_in_self<'tcx>(ty: Ty<'tcx>) -> ty::PolyExistentialTraitRef<'tcx> { for arg in ty.peel_refs().walk() { if let GenericArgKind::Type(ty) = arg.unpack() { - if let ty::Dynamic(trait_refs, _) = ty.kind() { - return trait_refs[0].map_bound(|trait_ref| match trait_ref { - ExistentialPredicate::Trait(tr) => tr, - ExistentialPredicate::Projection(proj) => proj.trait_ref(tcx), - ExistentialPredicate::AutoTrait(_) => { - bug!("auto traits don't have functions") - } - }); + if let ty::Dynamic(data, _) = ty.kind() { + return data.principal().expect("expected principal trait object"); } } } diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index eb81f43c3fe..bba4b1815b4 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -15,7 +15,6 @@ use crate::interpret::{ /// The CTFE machine has some custom error kinds. #[derive(Clone, Debug)] pub enum ConstEvalErrKind { - NeedsRfc(String), ConstAccessesStatic, ModifiedGlobal, AssertFailure(AssertKind<ConstInt>), @@ -42,9 +41,6 @@ impl fmt::Display for ConstEvalErrKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use self::ConstEvalErrKind::*; match *self { - NeedsRfc(ref msg) => { - write!(f, "\"{}\" needs an rfc before being allowed inside constants", msg) - } ConstAccessesStatic => write!(f, "constant accesses static"), ModifiedGlobal => { write!(f, "modifying a static's initial value from another static's initializer") diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 6c1e61fccca..9ea9fbe0e0e 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -269,9 +269,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ); throw_inval!(AlreadyReported(guar)); } else { + // `find_mir_or_eval_fn` checks that this is a const fn before even calling us, + // so this should be unreachable. let path = ecx.tcx.def_path_str(def.did); - Err(ConstEvalErrKind::NeedsRfc(format!("calling extern function `{}`", path)) - .into()) + bug!("trying to call extern function `{path}` at compile-time"); } } _ => Ok(ecx.tcx.instance_mir(instance)), @@ -339,11 +340,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, // CTFE-specific intrinsics. let Some(ret) = target else { - return Err(ConstEvalErrKind::NeedsRfc(format!( - "calling intrinsic `{}`", - intrinsic_name - )) - .into()); + throw_unsup_format!("intrinsic `{intrinsic_name}` is not supported at compile-time"); }; match intrinsic_name { sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => { @@ -400,11 +397,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } } _ => { - return Err(ConstEvalErrKind::NeedsRfc(format!( - "calling intrinsic `{}`", - intrinsic_name - )) - .into()); + throw_unsup_format!( + "intrinsic `{intrinsic_name}` is not supported at compile-time" + ); } } @@ -447,7 +442,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, _left: &ImmTy<'tcx>, _right: &ImmTy<'tcx>, ) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> { - Err(ConstEvalErrKind::NeedsRfc("pointer arithmetic or comparison".to_string()).into()) + throw_unsup_format!("pointer arithmetic or comparison is not supported at compile-time"); } fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { @@ -469,7 +464,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, _ecx: &mut InterpCx<'mir, 'tcx, Self>, _ptr: Pointer<AllocId>, ) -> InterpResult<'tcx> { - Err(ConstEvalErrKind::NeedsRfc("exposing pointers".to_string()).into()) + // This is only reachable with -Zunleash-the-miri-inside-of-you. + throw_unsup_format!("exposing pointers is not possible at compile-time") } #[inline(always)] diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index b151d03681f..6ca98371497 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -479,6 +479,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { ) -> InterpResult<$tcx, Pointer<Option<AllocId>>> { // Allow these casts, but make the pointer not dereferenceable. // (I.e., they behave like transmutation.) + // This is correct because no pointers can ever be exposed in compile-time evaluation. Ok(Pointer::from_addr(addr)) } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index ca7862c9dc4..46f8c0e8d8b 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -372,7 +372,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { debug!( "canonical: region var found with vid {:?}, \ opportunistically resolved to {:?}", - vid, r + vid, resolved_vid ); let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid)); self.canonicalize_mode.canonicalize_free_region(self, r) diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 8dc20544f1b..64c759f73d4 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -63,8 +63,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>, { let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?; + debug!("query_response = {:#?}", query_response); let canonical_result = self.canonicalize_response(query_response); - debug!("canonical_result = {:#?}", canonical_result); Ok(self.tcx.arena.alloc(canonical_result)) @@ -125,6 +125,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { debug!("ambig_errors = {:#?}", ambig_errors); let region_obligations = self.take_registered_region_obligations(); + debug!(?region_obligations); let region_constraints = self.with_region_constraints(|region_constraints| { make_query_region_constraints( tcx, @@ -132,6 +133,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { region_constraints, ) }); + debug!(?region_constraints); let certainty = if ambig_errors.is_empty() { Certainty::Proven } else { Certainty::Ambiguous }; @@ -632,6 +634,8 @@ pub fn make_query_region_constraints<'tcx>( assert!(verifys.is_empty()); assert!(givens.is_empty()); + debug!(?constraints); + let outlives: Vec<_> = constraints .iter() .map(|(k, _)| match *k { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index c95738e0018..4689ebb6cee 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -504,7 +504,7 @@ pub enum FixupError<'tcx> { } /// See the `region_obligations` field for more information. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct RegionObligation<'tcx> { pub sub_region: ty::Region<'tcx>, pub sup_type: Ty<'tcx>, @@ -2027,16 +2027,6 @@ impl RegionVariableOrigin { } } -impl<'tcx> fmt::Debug for RegionObligation<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "RegionObligation(sub_region={:?}, sup_type={:?})", - self.sub_region, self.sup_type - ) - } -} - /// Replaces substs that reference param or infer variables with suitable /// placeholders. This function is meant to remove these param and infer /// substs when they're not actually needed to evaluate a constant. diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index dded0a0a6b1..fe78890ff6e 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -92,6 +92,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { sub_region: Region<'tcx>, cause: &ObligationCause<'tcx>, ) { + debug!(?sup_type, ?sub_region, ?cause); let origin = SubregionOrigin::from_obligation_cause(cause, || { infer::RelateParamBound( cause.span, @@ -248,14 +249,13 @@ where /// - `origin`, the reason we need this constraint /// - `ty`, the type `T` /// - `region`, the region `'a` + #[instrument(level = "debug", skip(self))] pub fn type_must_outlive( &mut self, origin: infer::SubregionOrigin<'tcx>, ty: Ty<'tcx>, region: ty::Region<'tcx>, ) { - debug!("type_must_outlive(ty={:?}, region={:?}, origin={:?})", ty, region, origin); - assert!(!ty.has_escaping_bound_vars()); let mut components = smallvec![]; diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index 413f06a97a2..90c554c2e04 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -243,6 +243,5 @@ macro_rules! declare_combined_early_lint_pass { } /// A lint pass boxed up as a trait object. -pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + sync::Sync + 'static>; -pub type LateLintPassObject = - Box<dyn for<'tcx> LateLintPass<'tcx> + sync::Send + sync::Sync + 'static>; +pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + 'static>; +pub type LateLintPassObject = Box<dyn for<'tcx> LateLintPass<'tcx> + sync::Send + 'static>; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1b47d11f6f8..6eca7dc52b2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -157,6 +157,7 @@ symbols! { BTreeSet, BinaryHeap, Borrow, + BorrowMut, Break, C, CStr, diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index d895b647db0..60e9b88107d 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -120,6 +120,7 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> { EarlyBinder(value).subst(self.tcx(), substs) } + #[instrument(level = "debug", skip(self))] fn relate_mir_and_user_ty( &mut self, mir_ty: Ty<'tcx>, @@ -132,8 +133,8 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> { let ty = tcx.type_of(def_id); let ty = self.subst(ty, substs); - debug!("relate_type_and_user_type: ty of def-id is {:?}", ty); let ty = self.normalize(ty); + debug!("relate_type_and_user_type: ty of def-id is {:?}", ty); self.relate(mir_ty, Variance::Invariant, ty)?; @@ -144,7 +145,7 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> { // outlives" error messages. let instantiated_predicates = self.tcx().predicates_of(def_id).instantiate(self.tcx(), substs); - debug!(?instantiated_predicates.predicates); + debug!(?instantiated_predicates); for instantiated_predicate in instantiated_predicates.predicates { let instantiated_predicate = self.normalize(instantiated_predicate); self.prove_predicate(instantiated_predicate, span); diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 71ae54bedce..33d74249e7b 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -2605,32 +2605,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some((fields, substs)) = self.get_field_candidates_considering_privacy(span, expr_t, mod_id) { - for candidate_field in fields { - if let Some(mut field_path) = self.check_for_nested_field_satisfying( - span, - &|candidate_field, _| candidate_field.ident(self.tcx()) == field, - candidate_field, - substs, - vec![], - mod_id, - ) { - // field_path includes `field` that we're looking for, so pop it. + let candidate_fields: Vec<_> = fields + .filter_map(|candidate_field| { + self.check_for_nested_field_satisfying( + span, + &|candidate_field, _| candidate_field.ident(self.tcx()) == field, + candidate_field, + substs, + vec![], + mod_id, + ) + }) + .map(|mut field_path| { field_path.pop(); - - let field_path_str = field_path + field_path .iter() .map(|id| id.name.to_ident_string()) .collect::<Vec<String>>() - .join("."); - debug!("field_path_str: {:?}", field_path_str); - - err.span_suggestion_verbose( - field.span.shrink_to_lo(), - "one of the expressions' fields has a field of the same name", - format!("{field_path_str}."), - Applicability::MaybeIncorrect, - ); - } + .join(".") + }) + .collect::<Vec<_>>(); + + let len = candidate_fields.len(); + if len > 0 { + err.span_suggestions( + field.span.shrink_to_lo(), + format!( + "{} of the expressions' fields {} a field of the same name", + if len > 1 { "some" } else { "one" }, + if len > 1 { "have" } else { "has" }, + ), + candidate_fields.iter().map(|path| format!("{path}.")), + Applicability::MaybeIncorrect, + ); } } err diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 8bb8c7ac515..e532f392157 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1350,42 +1350,68 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_name: Ident, ) { if let SelfSource::MethodCall(expr) = source - && let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id() - && let Some((fields, substs)) = self.get_field_candidates_considering_privacy(span, actual, mod_id) + && let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id() + && let Some((fields, substs)) = + self.get_field_candidates_considering_privacy(span, actual, mod_id) { let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)); - for candidate_field in fields { - if let Some(field_path) = self.check_for_nested_field_satisfying( - span, - &|_, field_ty| { - self.lookup_probe( - span, - item_name, - field_ty, - call_expr, - ProbeScope::AllTraits, - ) - .is_ok() - }, - candidate_field, - substs, - vec![], - mod_id, - ) { - let field_path_str = field_path + + let lang_items = self.tcx.lang_items(); + let never_mention_traits = [ + lang_items.clone_trait(), + lang_items.deref_trait(), + lang_items.deref_mut_trait(), + self.tcx.get_diagnostic_item(sym::AsRef), + self.tcx.get_diagnostic_item(sym::AsMut), + self.tcx.get_diagnostic_item(sym::Borrow), + self.tcx.get_diagnostic_item(sym::BorrowMut), + ]; + let candidate_fields: Vec<_> = fields + .filter_map(|candidate_field| { + self.check_for_nested_field_satisfying( + span, + &|_, field_ty| { + self.lookup_probe( + span, + item_name, + field_ty, + call_expr, + ProbeScope::TraitsInScope, + ) + .map_or(false, |pick| { + !never_mention_traits + .iter() + .flatten() + .any(|def_id| self.tcx.parent(pick.item.def_id) == *def_id) + }) + }, + candidate_field, + substs, + vec![], + mod_id, + ) + }) + .map(|field_path| { + field_path .iter() .map(|id| id.name.to_ident_string()) .collect::<Vec<String>>() - .join("."); - debug!("field_path_str: {:?}", field_path_str); - - err.span_suggestion_verbose( - item_name.span.shrink_to_lo(), - "one of the expressions' fields has a method of the same name", - format!("{field_path_str}."), - Applicability::MaybeIncorrect, - ); - } + .join(".") + }) + .collect(); + + let len = candidate_fields.len(); + if len > 0 { + err.span_suggestions( + item_name.span.shrink_to_lo(), + format!( + "{} of the expressions' fields {} a method of the same name", + if len > 1 { "some" } else { "one" }, + if len > 1 { "have" } else { "has" }, + ), + candidate_fields.iter().map(|path| format!("{path}.")), + Applicability::MaybeIncorrect, + ); } } } |
