From c3f568b3312bed99d0e4b95daecd3c9eca1ae895 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 23 Aug 2022 01:58:33 +0000 Subject: [PATCH 1/9] Do not report too many expr field candidates --- compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_typeck/src/check/expr.rs | 51 ++++++----- .../rustc_typeck/src/check/method/suggest.rs | 88 ++++++++++++------- src/test/ui/copy-a-resource.stderr | 4 - src/test/ui/issues/issue-2823.stderr | 4 - src/test/ui/noncopyable-class.stderr | 8 -- .../suggestions/too-many-field-suggestions.rs | 29 ++++++ .../too-many-field-suggestions.stderr | 44 ++++++++++ 8 files changed, 160 insertions(+), 69 deletions(-) create mode 100644 src/test/ui/suggestions/too-many-field-suggestions.rs create mode 100644 src/test/ui/suggestions/too-many-field-suggestions.stderr diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 156f53ac48626..43183fd8ec815 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_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 5ff62f36b4527..43aababeea8ae 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -2588,32 +2588,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::>() - .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::>(); + + 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 44c7c148c7533..70e6d33dae16a 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1338,42 +1338,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::>() - .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, + ); } } } diff --git a/src/test/ui/copy-a-resource.stderr b/src/test/ui/copy-a-resource.stderr index b92449c6e0aff..128087f1e3755 100644 --- a/src/test/ui/copy-a-resource.stderr +++ b/src/test/ui/copy-a-resource.stderr @@ -10,10 +10,6 @@ LL | let _y = x.clone(); = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: candidate #1: `Clone` -help: one of the expressions' fields has a method of the same name - | -LL | let _y = x.i.clone(); - | ++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-2823.stderr b/src/test/ui/issues/issue-2823.stderr index 208b340d06410..b5a2b2f55a6d4 100644 --- a/src/test/ui/issues/issue-2823.stderr +++ b/src/test/ui/issues/issue-2823.stderr @@ -10,10 +10,6 @@ LL | let _d = c.clone(); = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: candidate #1: `Clone` -help: one of the expressions' fields has a method of the same name - | -LL | let _d = c.x.clone(); - | ++ error: aborting due to previous error diff --git a/src/test/ui/noncopyable-class.stderr b/src/test/ui/noncopyable-class.stderr index 15e22e946da8a..0c696163a26c5 100644 --- a/src/test/ui/noncopyable-class.stderr +++ b/src/test/ui/noncopyable-class.stderr @@ -10,14 +10,6 @@ LL | let _y = x.clone(); = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: candidate #1: `Clone` -help: one of the expressions' fields has a method of the same name - | -LL | let _y = x.i.clone(); - | ++ -help: one of the expressions' fields has a method of the same name - | -LL | let _y = x.j.x.clone(); - | ++++ error: aborting due to previous error diff --git a/src/test/ui/suggestions/too-many-field-suggestions.rs b/src/test/ui/suggestions/too-many-field-suggestions.rs new file mode 100644 index 0000000000000..905f9502cf5be --- /dev/null +++ b/src/test/ui/suggestions/too-many-field-suggestions.rs @@ -0,0 +1,29 @@ +struct Thing { + a0: Foo, + a1: Foo, + a2: Foo, + a3: Foo, + a4: Foo, + a5: Foo, + a6: Foo, + a7: Foo, + a8: Foo, + a9: Foo, +} + +struct Foo { + field: Field, +} + +struct Field; + +impl Foo { + fn bar(&self) {} +} + +fn bar(t: Thing) { + t.bar(); //~ ERROR no method named `bar` found for struct `Thing` + t.field; //~ ERROR no field `field` on type `Thing` +} + +fn main() {} diff --git a/src/test/ui/suggestions/too-many-field-suggestions.stderr b/src/test/ui/suggestions/too-many-field-suggestions.stderr new file mode 100644 index 0000000000000..63ad6fdb16994 --- /dev/null +++ b/src/test/ui/suggestions/too-many-field-suggestions.stderr @@ -0,0 +1,44 @@ +error[E0599]: no method named `bar` found for struct `Thing` in the current scope + --> $DIR/too-many-field-suggestions.rs:25:7 + | +LL | struct Thing { + | ------------ method `bar` not found for this struct +... +LL | t.bar(); + | ^^^ method not found in `Thing` + | +help: some of the expressions' fields have a method of the same name + | +LL | t.a0.bar(); + | +++ +LL | t.a1.bar(); + | +++ +LL | t.a2.bar(); + | +++ +LL | t.a3.bar(); + | +++ + and 6 other candidates + +error[E0609]: no field `field` on type `Thing` + --> $DIR/too-many-field-suggestions.rs:26:7 + | +LL | t.field; + | ^^^^^ unknown field + | + = note: available fields are: `a0`, `a1`, `a2`, `a3`, `a4` ... and 5 others +help: some of the expressions' fields have a field of the same name + | +LL | t.a0.field; + | +++ +LL | t.a1.field; + | +++ +LL | t.a2.field; + | +++ +LL | t.a3.field; + | +++ + and 6 other candidates + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0599, E0609. +For more information about an error, try `rustc --explain E0599`. From f44d28377024ccbb95140277e726196a1a76a450 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Sat, 18 Jun 2022 14:28:47 -0700 Subject: [PATCH 2/9] Add the syntax of references to their documentation summary. Without this change, in , `reference` is the only entry in that list which does not contain the syntax by which the type is named in source code. With this change, it contains them, in roughly the same way as the `pointer` entry does. --- library/core/src/primitive_docs.rs | 2 +- library/std/src/primitive_docs.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 2b2ef64fdb1c3..242f44ade8a2d 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1223,7 +1223,7 @@ mod prim_usize {} #[doc(alias = "&")] #[doc(alias = "&mut")] // -/// References, both shared and mutable. +/// References, `&T` and `&mut T`. /// /// A reference represents a borrow of some owned value. You can get one by using the `&` or `&mut` /// operators on a value, or by using a [`ref`](../std/keyword.ref.html) or diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 2b2ef64fdb1c3..242f44ade8a2d 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -1223,7 +1223,7 @@ mod prim_usize {} #[doc(alias = "&")] #[doc(alias = "&mut")] // -/// References, both shared and mutable. +/// References, `&T` and `&mut T`. /// /// A reference represents a borrow of some owned value. You can get one by using the `&` or `&mut` /// operators on a value, or by using a [`ref`](../std/keyword.ref.html) or From a9f9145b094188d1915138385cb4dc8c8656090c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 28 Aug 2022 13:13:13 -0400 Subject: [PATCH 3/9] CTFE: exposing pointers and calling extern fn doesn't need an RFC, it is just impossible --- compiler/rustc_const_eval/src/const_eval/machine.rs | 8 +++++--- compiler/rustc_const_eval/src/interpret/machine.rs | 1 + src/test/ui/consts/miri_unleashed/ptr_arith.rs | 2 +- src/test/ui/consts/miri_unleashed/ptr_arith.stderr | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 6c1e61fccca19..55b5bbc70650f 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)), @@ -469,7 +470,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, _ecx: &mut InterpCx<'mir, 'tcx, Self>, _ptr: Pointer, ) -> 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 6bed8a7a00773..8df6737b83980 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -490,6 +490,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { ) -> InterpResult<$tcx, Pointer>> { // 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/src/test/ui/consts/miri_unleashed/ptr_arith.rs b/src/test/ui/consts/miri_unleashed/ptr_arith.rs index 13e6af36e0200..2d5cb9b683460 100644 --- a/src/test/ui/consts/miri_unleashed/ptr_arith.rs +++ b/src/test/ui/consts/miri_unleashed/ptr_arith.rs @@ -8,7 +8,7 @@ static PTR_INT_CAST: () = { let x = &0 as *const _ as usize; //~^ ERROR could not evaluate static initializer - //~| "exposing pointers" needs an rfc before being allowed inside constants + //~| exposing pointers let _v = x == x; }; diff --git a/src/test/ui/consts/miri_unleashed/ptr_arith.stderr b/src/test/ui/consts/miri_unleashed/ptr_arith.stderr index 00cff23fb3fbe..f5c5ee2b8ebad 100644 --- a/src/test/ui/consts/miri_unleashed/ptr_arith.stderr +++ b/src/test/ui/consts/miri_unleashed/ptr_arith.stderr @@ -2,7 +2,7 @@ error[E0080]: could not evaluate static initializer --> $DIR/ptr_arith.rs:9:13 | LL | let x = &0 as *const _ as usize; - | ^^^^^^^^^^^^^^^^^^^^^^^ "exposing pointers" needs an rfc before being allowed inside constants + | ^^^^^^^^^^^^^^^^^^^^^^^ exposing pointers is not possible at compile-time error[E0080]: could not evaluate static initializer --> $DIR/ptr_arith.rs:17:14 From f29c3c421b9fd2afb52062590c5f2e052f8d3815 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 28 Aug 2022 13:31:36 -0400 Subject: [PATCH 4/9] entirely get rid of NeedsRfc CTFE errors --- .../rustc_const_eval/src/const_eval/error.rs | 4 ---- .../rustc_const_eval/src/const_eval/machine.rs | 16 +++++----------- src/test/ui/consts/miri_unleashed/ptr_arith.rs | 3 +++ 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index eb81f43c3fe8c..bba4b1815b457 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), @@ -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 55b5bbc70650f..9ea9fbe0e0e54 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -340,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 => { @@ -401,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" + ); } } @@ -448,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> { diff --git a/src/test/ui/consts/miri_unleashed/ptr_arith.rs b/src/test/ui/consts/miri_unleashed/ptr_arith.rs index 2d5cb9b683460..6a19b294585ae 100644 --- a/src/test/ui/consts/miri_unleashed/ptr_arith.rs +++ b/src/test/ui/consts/miri_unleashed/ptr_arith.rs @@ -19,4 +19,7 @@ static PTR_INT_TRANSMUTE: () = unsafe { //~| unable to turn pointer into raw bytes }; +// I'd love to test pointer comparison, but that is not possible since +// their `PartialEq` impl is non-`const`. + fn main() {} From 8050c1993b0a5dc43aab836e8323c2835a13448f Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Sun, 28 Aug 2022 02:35:44 +0100 Subject: [PATCH 5/9] Rustdoc-Json: Retain Stripped Modules when they are imported, not when they have items. Fixes #101103 Fixes #100973 --- src/librustdoc/json/conversions.rs | 8 +++- src/librustdoc/json/import_finder.rs | 38 +++++++++++++++++++ src/librustdoc/json/mod.rs | 8 +++- .../rustdoc-json/reexport/glob_collision.rs | 28 ++++++++++++++ .../rustdoc-json/reexport/glob_empty_mod.rs | 8 ++++ .../rustdoc-json/reexport/in_root_and_mod.rs | 3 +- .../rustdoc-json/reexport/mod_not_included.rs | 14 +++++++ .../reexport/private_two_names.rs | 3 +- .../rustdoc-json/reexport/rename_private.rs | 3 +- .../rustdoc-json/reexport/simple_private.rs | 5 +-- src/test/rustdoc-json/stripped_modules.rs | 2 +- 11 files changed, 107 insertions(+), 13 deletions(-) create mode 100644 src/librustdoc/json/import_finder.rs create mode 100644 src/test/rustdoc-json/reexport/glob_collision.rs create mode 100644 src/test/rustdoc-json/reexport/glob_empty_mod.rs create mode 100644 src/test/rustdoc-json/reexport/mod_not_included.rs diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index c4e8b6f5f8449..20b9eb1c27e92 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -46,10 +46,14 @@ impl JsonRenderer<'_> { clean::KeywordItem => return None, clean::StrippedItem(ref inner) => { match &**inner { - // We document non-empty stripped modules as with `Module::is_stripped` set to + // We document stripped modules as with `Module::is_stripped` set to // `true`, to prevent contained items from being orphaned for downstream users, // as JSON does no inlining. - clean::ModuleItem(m) if !m.items.is_empty() => from_clean_item(item, self.tcx), + clean::ModuleItem(_) + if self.imported_items.contains(&item_id.expect_def_id()) => + { + from_clean_item(item, self.tcx) + } _ => return None, } } diff --git a/src/librustdoc/json/import_finder.rs b/src/librustdoc/json/import_finder.rs new file mode 100644 index 0000000000000..c5c687df74fd8 --- /dev/null +++ b/src/librustdoc/json/import_finder.rs @@ -0,0 +1,38 @@ +use rustc_data_structures::fx::FxHashSet; +use rustc_hir::def_id::DefId; + +use crate::{ + clean::{self, Import, ImportSource, Item}, + fold::DocFolder, +}; + +/// Get the id's of all items that are `pub use`d in the crate. +/// +/// We need this to know if a stripped module is `pub use mod::*`, to decide +/// if it needs to be kept in the index, despite being stripped. +/// +/// See [#100973](https://github.com/rust-lang/rust/issues/100973) and +/// [#101103](https://github.com/rust-lang/rust/issues/101103) for times when +/// this information is needed. +pub(crate) fn get_imports(krate: clean::Crate) -> (clean::Crate, FxHashSet) { + let mut finder = ImportFinder { imported: FxHashSet::default() }; + let krate = finder.fold_crate(krate); + (krate, finder.imported) +} + +struct ImportFinder { + imported: FxHashSet, +} + +impl DocFolder for ImportFinder { + fn fold_item(&mut self, i: Item) -> Option { + match *i.kind { + clean::ImportItem(Import { source: ImportSource { did: Some(did), .. }, .. }) => { + self.imported.insert(did); + Some(i) + } + + _ => Some(self.fold_item_recur(i)), + } + } +} diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 7b1b059e14dcb..577aad8f3bb93 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -5,6 +5,7 @@ //! docs for usage and details. mod conversions; +mod import_finder; use std::cell::RefCell; use std::fs::{create_dir_all, File}; @@ -12,7 +13,7 @@ use std::io::{BufWriter, Write}; use std::path::PathBuf; use std::rc::Rc; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def_id::DefId; use rustc_middle::ty::TyCtxt; use rustc_session::Session; @@ -39,6 +40,7 @@ pub(crate) struct JsonRenderer<'tcx> { /// The directory where the blob will be written to. out_path: PathBuf, cache: Rc, + imported_items: FxHashSet, } impl<'tcx> JsonRenderer<'tcx> { @@ -157,12 +159,16 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { tcx: TyCtxt<'tcx>, ) -> Result<(Self, clean::Crate), Error> { debug!("Initializing json renderer"); + + let (krate, imported_items) = import_finder::get_imports(krate); + Ok(( JsonRenderer { tcx, index: Rc::new(RefCell::new(FxHashMap::default())), out_path: options.output, cache: Rc::new(cache), + imported_items, }, krate, )) diff --git a/src/test/rustdoc-json/reexport/glob_collision.rs b/src/test/rustdoc-json/reexport/glob_collision.rs new file mode 100644 index 0000000000000..f91144dbfad50 --- /dev/null +++ b/src/test/rustdoc-json/reexport/glob_collision.rs @@ -0,0 +1,28 @@ +// Regression test for https://github.com/rust-lang/rust/issues/100973 + +#![feature(no_core)] +#![no_core] + +// @set m1 = "$.index[*][?(@.name == 'm1' && @.kind == 'module')].id" +// @is "$.index[*][?(@.name == 'm1' && @.kind == 'module')].inner.items" [] +// @is "$.index[*][?(@.name == 'm1' && @.kind == 'module')].inner.is_stripped" true +mod m1 { + pub fn f() {} +} +// @set m2 = "$.index[*][?(@.name == 'm2' && @.kind == 'module')].id" +// @is "$.index[*][?(@.name == 'm2' && @.kind == 'module')].inner.items" [] +// @is "$.index[*][?(@.name == 'm2' && @.kind == 'module')].inner.is_stripped" true +mod m2 { + pub fn f(_: u8) {} +} + +// @set m1_use = "$.index[*][?(@.inner.name=='m1')].id" +// @is "$.index[*][?(@.inner.name=='m1')].inner.id" $m1 +// @is "$.index[*][?(@.inner.name=='m1')].inner.glob" true +pub use m1::*; +// @set m2_use = "$.index[*][?(@.inner.name=='m2')].id" +// @is "$.index[*][?(@.inner.name=='m2')].inner.id" $m2 +// @is "$.index[*][?(@.inner.name=='m2')].inner.glob" true +pub use m2::*; + +// @ismany "$.index[*][?(@.inner.is_crate==true)].inner.items[*]" $m1_use $m2_use diff --git a/src/test/rustdoc-json/reexport/glob_empty_mod.rs b/src/test/rustdoc-json/reexport/glob_empty_mod.rs new file mode 100644 index 0000000000000..da68228352c1c --- /dev/null +++ b/src/test/rustdoc-json/reexport/glob_empty_mod.rs @@ -0,0 +1,8 @@ +// Regression test for https://github.com/rust-lang/rust/issues/100973 + +// @is "$.index[*][?(@.name=='m1' && @.kind == 'module')].inner.is_stripped" true +// @set m1 = "$.index[*][?(@.name=='m1')].id" +mod m1 {} + +// @is "$.index[*][?(@.inner.name=='m1' && @.kind=='import')].inner.id" $m1 +pub use m1::*; diff --git a/src/test/rustdoc-json/reexport/in_root_and_mod.rs b/src/test/rustdoc-json/reexport/in_root_and_mod.rs index 68cb694f49949..7b97ebf2129eb 100644 --- a/src/test/rustdoc-json/reexport/in_root_and_mod.rs +++ b/src/test/rustdoc-json/reexport/in_root_and_mod.rs @@ -1,8 +1,7 @@ #![feature(no_core)] #![no_core] -// @is "$.index[*][?(@.name=='foo')].kind" \"module\" -// @is "$.index[*][?(@.name=='foo')].inner.is_stripped" "true" +// @!has "$.index[*][?(@.name=='foo')]" mod foo { // @has "$.index[*][?(@.name=='Foo')]" pub struct Foo; diff --git a/src/test/rustdoc-json/reexport/mod_not_included.rs b/src/test/rustdoc-json/reexport/mod_not_included.rs new file mode 100644 index 0000000000000..7b7600ef20f08 --- /dev/null +++ b/src/test/rustdoc-json/reexport/mod_not_included.rs @@ -0,0 +1,14 @@ +// Regression test for https://github.com/rust-lang/rust/issues/101103 + +#![feature(no_core)] +#![no_core] + +mod m1 { + pub fn x() {} +} + +pub use m1::x; + +// @has "$.index[*][?(@.name=='x' && @.kind=='function')]" +// @has "$.index[*][?(@.kind=='import' && @.inner.name=='x')].inner.source" '"m1::x"' +// @!has "$.index[*][?(@.name=='m1')]" diff --git a/src/test/rustdoc-json/reexport/private_two_names.rs b/src/test/rustdoc-json/reexport/private_two_names.rs index ec78b06d09ac8..9858538a9d046 100644 --- a/src/test/rustdoc-json/reexport/private_two_names.rs +++ b/src/test/rustdoc-json/reexport/private_two_names.rs @@ -6,8 +6,7 @@ #![no_core] #![feature(no_core)] -// @is "$.index[*][?(@.name=='style')].kind" \"module\" -// @is "$.index[*][?(@.name=='style')].inner.is_stripped" "true" +// @!has "$.index[*][?(@.name=='style')]" mod style { // @set color_struct_id = "$.index[*][?(@.kind=='struct' && @.name=='Color')].id" pub struct Color; diff --git a/src/test/rustdoc-json/reexport/rename_private.rs b/src/test/rustdoc-json/reexport/rename_private.rs index 1537f834481f4..8fd850f9b1370 100644 --- a/src/test/rustdoc-json/reexport/rename_private.rs +++ b/src/test/rustdoc-json/reexport/rename_private.rs @@ -3,8 +3,7 @@ #![no_core] #![feature(no_core)] -// @is "$.index[*][?(@.name=='inner')].kind" \"module\" -// @is "$.index[*][?(@.name=='inner')].inner.is_stripped" "true" +// @!has "$.index[*][?(@.kind=='inner')]" mod inner { // @has "$.index[*][?(@.name=='Public')]" pub struct Public; diff --git a/src/test/rustdoc-json/reexport/simple_private.rs b/src/test/rustdoc-json/reexport/simple_private.rs index 82348b383c363..d058ce0598d43 100644 --- a/src/test/rustdoc-json/reexport/simple_private.rs +++ b/src/test/rustdoc-json/reexport/simple_private.rs @@ -2,16 +2,15 @@ #![no_core] #![feature(no_core)] -// @is "$.index[*][?(@.name=='inner')].kind" \"module\" -// @is "$.index[*][?(@.name=='inner')].inner.is_stripped" "true" +// @!has "$.index[*][?(@.name=='inner')]" mod inner { // @set pub_id = "$.index[*][?(@.name=='Public')].id" pub struct Public; } // @is "$.index[*][?(@.kind=='import')].inner.name" \"Public\" +// @is "$.index[*][?(@.kind=='import')].inner.id" $pub_id // @set use_id = "$.index[*][?(@.kind=='import')].id" pub use inner::Public; -// @ismany "$.index[*][?(@.name=='inner')].inner.items[*]" $pub_id // @ismany "$.index[*][?(@.name=='simple_private')].inner.items[*]" $use_id diff --git a/src/test/rustdoc-json/stripped_modules.rs b/src/test/rustdoc-json/stripped_modules.rs index 33e95ce69d059..d2664b49e9c29 100644 --- a/src/test/rustdoc-json/stripped_modules.rs +++ b/src/test/rustdoc-json/stripped_modules.rs @@ -12,7 +12,7 @@ mod pub_inner_unreachable { pub fn pub_inner_1() {} } -// @has "$.index[*][?(@.name=='pub_inner_reachable')]" +// @!has "$.index[*][?(@.name=='pub_inner_reachable')]" mod pub_inner_reachable { // @has "$.index[*][?(@.name=='pub_inner_2')]" pub fn pub_inner_2() {} From 891ebf90a50d7158258b30177bbd7a555f2af0cf Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Sun, 28 Aug 2022 02:43:13 +0100 Subject: [PATCH 6/9] check_missing_items.py: Check imports --- src/etc/check_missing_items.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/etc/check_missing_items.py b/src/etc/check_missing_items.py index ce06a79a21c3f..025f320e3a103 100644 --- a/src/etc/check_missing_items.py +++ b/src/etc/check_missing_items.py @@ -187,3 +187,9 @@ def check_type(ty): check_generic_bound(bound) if item["inner"]["default"]: check_type(item["inner"]["default"]) + elif item["kind"] == "import": + if item["inner"]["id"]: + inner_id = item["inner"]["id"] + assert valid_id(inner_id) + if inner_id in crate["index"] and inner_id not in visited: + work_list.add(inner_id) From 72fe79244d39c356e6fa1da4dfa58354983f98f7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 29 Aug 2022 04:19:14 +0000 Subject: [PATCH 7/9] Simplify get_trait_ref a bit --- compiler/rustc_codegen_ssa/src/meth.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index 27d791d90a51a..f8e982b775189 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"); } } } From 74f2d582d237770b092923702fe073300dcf46ed Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Mon, 29 Aug 2022 10:00:22 -0400 Subject: [PATCH 8/9] Remove `Sync` requirement from lint pass objects as they are created on demand --- compiler/rustc_lint/src/passes.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index 413f06a97a245..90c554c2e040b 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; -pub type LateLintPassObject = - Box LateLintPass<'tcx> + sync::Send + sync::Sync + 'static>; +pub type EarlyLintPassObject = Box; +pub type LateLintPassObject = Box LateLintPass<'tcx> + sync::Send + 'static>; From 8033c3c27d520c034603ef4abafae24dea5adc01 Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Mon, 29 Aug 2022 02:00:08 -0400 Subject: [PATCH 9/9] Various changes to logging of borrowck-related code --- .../rustc_borrowck/src/constraints/mod.rs | 4 ++-- .../src/diagnostics/conflict_errors.rs | 22 ++++------------- .../src/diagnostics/explain_borrow.rs | 20 ++++------------ compiler/rustc_borrowck/src/lib.rs | 8 ++----- .../rustc_borrowck/src/places_conflict.rs | 15 ++++-------- .../rustc_borrowck/src/region_infer/mod.rs | 24 +++++++------------ .../src/type_check/canonical.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 1 + .../src/infer/canonical/canonicalizer.rs | 2 +- .../src/infer/canonical/query_response.rs | 6 ++++- compiler/rustc_infer/src/infer/mod.rs | 12 +--------- .../src/infer/outlives/obligations.rs | 4 ++-- compiler/rustc_traits/src/type_op.rs | 5 ++-- 13 files changed, 41 insertions(+), 84 deletions(-) diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index a504d0c91222e..c94dfe39b6903 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 84a0d4ba7ba10..5971f7623f215 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, ) { - 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 68f9a7c5007c8..1c31d2f744599 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 0f8afb038f455..362c45ecd7e67 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 97335fd0dffae..6e5a96bee97e6 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 2894c6d29ec43..f5bd5cd3beaed 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 451b82c5c1870..29195b3922fcd 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( &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 293d847ec9ab7..4d620a3aa476b 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_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index ca7862c9dc467..46f8c0e8d8b9a 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 8dc20544f1b1a..64c759f73d410 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 c95738e0018c0..4689ebb6cee24 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 dded0a0a6b1b4..fe78890ff6ed7 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_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index d895b647db0b1..60e9b88107dd6 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);