From 204c5162939760c7b16af7d42ec5ae8590dd8ae7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Apr 2023 17:20:28 +0000 Subject: [PATCH 01/11] Substitute missing item suggestion correctly --- .../rustc_hir_analysis/src/check/check.rs | 2 +- compiler/rustc_hir_analysis/src/check/mod.rs | 31 ++++++++++++++----- tests/ui/async-await/issue-74047.stderr | 2 +- tests/ui/issues/issue-3344.stderr | 2 +- tests/ui/suggestions/missing-assoc-fn.stderr | 2 +- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 0c54fd70c9b5..51ec5dd7a285 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -863,7 +863,7 @@ fn check_impl_items_against_trait<'tcx>( if !missing_items.is_empty() { let full_impl_span = tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id)); - missing_items_err(tcx, tcx.def_span(impl_id), &missing_items, full_impl_span); + missing_items_err(tcx, impl_id, &missing_items, full_impl_span); } if let Some(missing_items) = must_implement_one_of { diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 8fe4c44fca43..f147b4657ccc 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -198,7 +198,7 @@ fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_imp fn missing_items_err( tcx: TyCtxt<'_>, - impl_span: Span, + impl_def_id: LocalDefId, missing_items: &[ty::AssocItem], full_impl_span: Span, ) { @@ -211,6 +211,7 @@ fn missing_items_err( .collect::>() .join("`, `"); + let impl_span = tcx.def_span(impl_def_id); let mut err = struct_span_err!( tcx.sess, impl_span, @@ -229,7 +230,11 @@ fn missing_items_err( tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new()); for &trait_item in missing_items { - let snippet = suggestion_signature(trait_item, tcx); + let snippet = suggestion_signature( + tcx, + trait_item, + tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(), + ); let code = format!("{}{}\n{}", padding, snippet, padding); let msg = format!("implement the missing item: `{snippet}`"); let appl = Applicability::HasPlaceholders; @@ -301,11 +306,11 @@ fn default_body_is_unstable( /// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions. fn bounds_from_generic_predicates<'tcx>( tcx: TyCtxt<'tcx>, - predicates: ty::GenericPredicates<'tcx>, + predicates: impl IntoIterator, Span)>, ) -> (String, String) { let mut types: FxHashMap, Vec> = FxHashMap::default(); let mut projections = vec![]; - for (predicate, _) in predicates.predicates { + for (predicate, _) in predicates { debug!("predicate {:?}", predicate); let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { @@ -367,7 +372,7 @@ fn fn_sig_suggestion<'tcx>( tcx: TyCtxt<'tcx>, sig: ty::FnSig<'tcx>, ident: Ident, - predicates: ty::GenericPredicates<'tcx>, + predicates: impl IntoIterator, Span)>, assoc: ty::AssocItem, ) -> String { let args = sig @@ -436,7 +441,17 @@ pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> { /// Return placeholder code for the given associated item. /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a /// structured suggestion. -fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String { +fn suggestion_signature<'tcx>( + tcx: TyCtxt<'tcx>, + assoc: ty::AssocItem, + impl_trait_ref: ty::TraitRef<'tcx>, +) -> String { + let substs = ty::InternalSubsts::identity_for_item(tcx, assoc.def_id).rebase_onto( + tcx, + assoc.container_id(tcx), + impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).substs, + ); + match assoc.kind { ty::AssocKind::Fn => { // We skip the binder here because the binder would deanonymize all @@ -445,9 +460,9 @@ fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String { // regions just fine, showing `fn(&MyType)`. fn_sig_suggestion( tcx, - tcx.fn_sig(assoc.def_id).subst_identity().skip_binder(), + tcx.fn_sig(assoc.def_id).subst(tcx, substs).skip_binder(), assoc.ident(tcx), - tcx.predicates_of(assoc.def_id), + tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs), assoc, ) } diff --git a/tests/ui/async-await/issue-74047.stderr b/tests/ui/async-await/issue-74047.stderr index 28174825d8bc..9ba73f76923a 100644 --- a/tests/ui/async-await/issue-74047.stderr +++ b/tests/ui/async-await/issue-74047.stderr @@ -5,7 +5,7 @@ LL | impl TryFrom for MyStream {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Error`, `try_from` in implementation | = help: implement the missing item: `type Error = Type;` - = help: implement the missing item: `fn try_from(_: T) -> Result>::Error> { todo!() }` + = help: implement the missing item: `fn try_from(_: OtherStream) -> Result>::Error> { todo!() }` error: aborting due to previous error diff --git a/tests/ui/issues/issue-3344.stderr b/tests/ui/issues/issue-3344.stderr index 11d5999672e5..e849f5d0490d 100644 --- a/tests/ui/issues/issue-3344.stderr +++ b/tests/ui/issues/issue-3344.stderr @@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `partial_cmp` LL | impl PartialOrd for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation | - = help: implement the missing item: `fn partial_cmp(&self, _: &Rhs) -> Option { todo!() }` + = help: implement the missing item: `fn partial_cmp(&self, _: &Thing) -> Option { todo!() }` error: aborting due to previous error diff --git a/tests/ui/suggestions/missing-assoc-fn.stderr b/tests/ui/suggestions/missing-assoc-fn.stderr index 136ec2152e0b..77fa95628781 100644 --- a/tests/ui/suggestions/missing-assoc-fn.stderr +++ b/tests/ui/suggestions/missing-assoc-fn.stderr @@ -28,7 +28,7 @@ error[E0046]: not all trait items implemented, missing: `from_iter` LL | impl FromIterator<()> for X { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_iter` in implementation | - = help: implement the missing item: `fn from_iter(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = A { todo!() }` + = help: implement the missing item: `fn from_iter(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = () { todo!() }` error: aborting due to 3 previous errors From 73038d3a640f563e47554d781e958f6e4ed08bc2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Apr 2023 17:22:16 +0000 Subject: [PATCH 02/11] Make missing impl item suggestions more obvious that they're missing --- compiler/rustc_hir_analysis/src/check/mod.rs | 4 ++-- tests/ui/async-await/issue-74047.stderr | 2 +- tests/ui/missing/missing-items/m2.stderr | 2 +- tests/ui/span/issue-23729.stderr | 2 +- tests/ui/span/issue-23827.stderr | 2 +- tests/ui/span/issue-24356.stderr | 2 +- ...missing-assoc-fn-applicable-suggestions.rs | 16 ++++++++++++++ ...sing-assoc-fn-applicable-suggestions.fixed | 21 ------------------- ...missing-assoc-fn-applicable-suggestions.rs | 21 ++++++++----------- ...ing-assoc-fn-applicable-suggestions.stderr | 20 ++++++++---------- 10 files changed, 41 insertions(+), 51 deletions(-) create mode 100644 tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs delete mode 100644 tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index f147b4657ccc..9fba538f12e2 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -466,10 +466,10 @@ fn suggestion_signature<'tcx>( assoc, ) } - ty::AssocKind::Type => format!("type {} = Type;", assoc.name), + ty::AssocKind::Type => format!("type {} = /* Type */;", assoc.name), ty::AssocKind::Const => { let ty = tcx.type_of(assoc.def_id).subst_identity(); - let val = ty_kind_suggestion(ty).unwrap_or("value"); + let val = ty_kind_suggestion(ty).unwrap_or("todo!()"); format!("const {}: {} = {};", assoc.name, ty, val) } } diff --git a/tests/ui/async-await/issue-74047.stderr b/tests/ui/async-await/issue-74047.stderr index 9ba73f76923a..6bdb9ded4827 100644 --- a/tests/ui/async-await/issue-74047.stderr +++ b/tests/ui/async-await/issue-74047.stderr @@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Error`, `try_from` LL | impl TryFrom for MyStream {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Error`, `try_from` in implementation | - = help: implement the missing item: `type Error = Type;` + = help: implement the missing item: `type Error = /* Type */;` = help: implement the missing item: `fn try_from(_: OtherStream) -> Result>::Error> { todo!() }` error: aborting due to previous error diff --git a/tests/ui/missing/missing-items/m2.stderr b/tests/ui/missing/missing-items/m2.stderr index d18fb443aa46..835c9b2aa484 100644 --- a/tests/ui/missing/missing-items/m2.stderr +++ b/tests/ui/missing/missing-items/m2.stderr @@ -5,7 +5,7 @@ LL | impl m1::X for X { | ^^^^^^^^^^^^^^^^ missing `CONSTANT`, `Type`, `method`, `method2`, `method3`, `method4`, `method5` in implementation | = help: implement the missing item: `const CONSTANT: u32 = 42;` - = help: implement the missing item: `type Type = Type;` + = help: implement the missing item: `type Type = /* Type */;` = help: implement the missing item: `fn method(&self, _: String) -> ::Type { todo!() }` = help: implement the missing item: `fn method2(self: Box, _: String) -> ::Type { todo!() }` = help: implement the missing item: `fn method3(_: &Self, _: String) -> ::Type { todo!() }` diff --git a/tests/ui/span/issue-23729.stderr b/tests/ui/span/issue-23729.stderr index f88ce6c88db2..cd854e61f2f4 100644 --- a/tests/ui/span/issue-23729.stderr +++ b/tests/ui/span/issue-23729.stderr @@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Item` LL | impl Iterator for Recurrence { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation | - = help: implement the missing item: `type Item = Type;` + = help: implement the missing item: `type Item = /* Type */;` error: aborting due to previous error diff --git a/tests/ui/span/issue-23827.stderr b/tests/ui/span/issue-23827.stderr index 46a820f1b766..83a9e8c9b987 100644 --- a/tests/ui/span/issue-23827.stderr +++ b/tests/ui/span/issue-23827.stderr @@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Output` LL | impl FnOnce<(C,)> for Prototype { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Output` in implementation | - = help: implement the missing item: `type Output = Type;` + = help: implement the missing item: `type Output = /* Type */;` error: aborting due to previous error diff --git a/tests/ui/span/issue-24356.stderr b/tests/ui/span/issue-24356.stderr index a1f9b2550201..cf666e8b4a7a 100644 --- a/tests/ui/span/issue-24356.stderr +++ b/tests/ui/span/issue-24356.stderr @@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Target` LL | impl Deref for Thing { | ^^^^^^^^^^^^^^^^^^^^ missing `Target` in implementation | - = help: implement the missing item: `type Target = Type;` + = help: implement the missing item: `type Target = /* Type */;` error: aborting due to previous error diff --git a/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs b/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs new file mode 100644 index 000000000000..b026035a6a16 --- /dev/null +++ b/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs @@ -0,0 +1,16 @@ +pub trait TraitB { + type Item; +} + +pub trait TraitA { + type Type; + + fn bar(_: T) -> Self; + + fn baz(_: T) -> Self + where + T: TraitB, + ::Item: Copy; + + const A: usize; +} diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed deleted file mode 100644 index a0cb39a3f8a2..000000000000 --- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed +++ /dev/null @@ -1,21 +0,0 @@ -// run-rustfix -trait TraitB { - type Item; -} - -trait TraitA { - type Type; - fn bar(_: T) -> Self; - fn baz(_: T) -> Self where T: TraitB, ::Item: Copy; -} - -struct S; -struct Type; - -impl TraitA<()> for S { //~ ERROR not all trait items implemented -fn baz(_: T) -> Self where T: TraitB, ::Item: Copy { todo!() } -fn bar(_: T) -> Self { todo!() } -type Type = Type; -} - -fn main() {} diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs index c80ede1b2be2..11e0c9a3a72a 100644 --- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs +++ b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs @@ -1,18 +1,15 @@ -// run-rustfix -trait TraitB { - type Item; -} +// aux-build:missing-assoc-fn-applicable-suggestions.rs -trait TraitA { - type Type; - fn bar(_: T) -> Self; - fn baz(_: T) -> Self where T: TraitB, ::Item: Copy; -} +extern crate missing_assoc_fn_applicable_suggestions; +use missing_assoc_fn_applicable_suggestions::TraitA; struct S; -struct Type; - -impl TraitA<()> for S { //~ ERROR not all trait items implemented +impl TraitA<()> for S { + //~^ ERROR not all trait items implemented } +//~^ HELP implement the missing item: `type Type = /* Type */;` +//~| HELP implement the missing item: `fn bar(_: T) -> Self { todo!() }` +//~| HELP implement the missing item: `fn baz(_: T) -> Self where T: TraitB, ::Item: Copy { todo!() }` +//~| HELP implement the missing item: `const A: usize = 42;` fn main() {} diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr index 4c75fbe4c786..657a5c546d3d 100644 --- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr +++ b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr @@ -1,15 +1,13 @@ -error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz` - --> $DIR/missing-assoc-fn-applicable-suggestions.rs:15:1 +error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz`, `A` + --> $DIR/missing-assoc-fn-applicable-suggestions.rs:7:1 | -LL | type Type; - | --------- `Type` from trait -LL | fn bar(_: T) -> Self; - | ------------------------ `bar` from trait -LL | fn baz(_: T) -> Self where T: TraitB, ::Item: Copy; - | ------------------------------------------------------------------- `baz` from trait -... -LL | impl TraitA<()> for S { - | ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz` in implementation +LL | impl TraitA<()> for S { + | ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz`, `A` in implementation + | + = help: implement the missing item: `type Type = /* Type */;` + = help: implement the missing item: `fn bar(_: T) -> Self { todo!() }` + = help: implement the missing item: `fn baz(_: T) -> Self where T: TraitB, ::Item: Copy { todo!() }` + = help: implement the missing item: `const A: usize = 42;` error: aborting due to previous error From f362f6e9e6cb5d55bbac6a94353209c3e3a2ebb5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Apr 2023 17:47:33 +0000 Subject: [PATCH 03/11] Format missing GATs correctly --- compiler/rustc_hir_analysis/src/check/mod.rs | 8 +++++++- .../auxiliary/missing-item-sugg.rs | 5 +++++ .../ui/generic-associated-types/missing-item-sugg.rs | 11 +++++++++++ .../generic-associated-types/missing-item-sugg.stderr | 11 +++++++++++ .../missing-assoc-fn-applicable-suggestions.stderr | 2 +- 5 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs create mode 100644 tests/ui/generic-associated-types/missing-item-sugg.rs create mode 100644 tests/ui/generic-associated-types/missing-item-sugg.stderr diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 9fba538f12e2..4b3f3cf169dc 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -466,7 +466,13 @@ fn suggestion_signature<'tcx>( assoc, ) } - ty::AssocKind::Type => format!("type {} = /* Type */;", assoc.name), + ty::AssocKind::Type => { + let (generics, where_clauses) = bounds_from_generic_predicates( + tcx, + tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs), + ); + format!("type {}{generics} = /* Type */{where_clauses};", assoc.name) + } ty::AssocKind::Const => { let ty = tcx.type_of(assoc.def_id).subst_identity(); let val = ty_kind_suggestion(ty).unwrap_or("todo!()"); diff --git a/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs b/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs new file mode 100644 index 000000000000..5b10aab4b3f8 --- /dev/null +++ b/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs @@ -0,0 +1,5 @@ +pub trait Foo { + type Gat + where + T: std::fmt::Display; +} diff --git a/tests/ui/generic-associated-types/missing-item-sugg.rs b/tests/ui/generic-associated-types/missing-item-sugg.rs new file mode 100644 index 000000000000..35d573d81884 --- /dev/null +++ b/tests/ui/generic-associated-types/missing-item-sugg.rs @@ -0,0 +1,11 @@ +// aux-build:missing-item-sugg.rs + +extern crate missing_item_sugg; + +struct Local; +impl missing_item_sugg::Foo for Local { + //~^ ERROR not all trait items implemented, missing: `Gat` +} +//~^ HELP implement the missing item: `type Gat = /* Type */ where T: std::fmt::Display;` + +fn main() {} diff --git a/tests/ui/generic-associated-types/missing-item-sugg.stderr b/tests/ui/generic-associated-types/missing-item-sugg.stderr new file mode 100644 index 000000000000..378115f6d389 --- /dev/null +++ b/tests/ui/generic-associated-types/missing-item-sugg.stderr @@ -0,0 +1,11 @@ +error[E0046]: not all trait items implemented, missing: `Gat` + --> $DIR/missing-item-sugg.rs:6:1 + | +LL | impl missing_item_sugg::Foo for Local { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Gat` in implementation + | + = help: implement the missing item: `type Gat = /* Type */ where T: std::fmt::Display;` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr index 657a5c546d3d..4c2d2776d3d8 100644 --- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr +++ b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr @@ -1,7 +1,7 @@ error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz`, `A` --> $DIR/missing-assoc-fn-applicable-suggestions.rs:7:1 | -LL | impl TraitA<()> for S { +LL | impl TraitA<()> for S { | ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz`, `A` in implementation | = help: implement the missing item: `type Type = /* Type */;` From 4f757af1769dcb89a556d453d71fa2f2d5295ce7 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 20 Apr 2023 14:09:41 +0200 Subject: [PATCH 04/11] remove unused message --- compiler/rustc_hir_typeck/messages.ftl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 2c537bf4064a..5a935ceee356 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -3,10 +3,6 @@ hir_typeck_field_multiply_specified_in_initializer = .label = used more than once .previous_use_label = first use of `{$ident}` -hir_typeck_copy_impl_on_type_with_dtor = - the trait `Copy` cannot be implemented for this type; the type has a destructor - .label = `Copy` not allowed on types with destructors - hir_typeck_multiple_relaxed_default_bounds = type parameter has more than one relaxed default bound, only one is supported From 82cb8a2933e04bc362869e47f10b041242911c10 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 20 Apr 2023 14:17:52 +0200 Subject: [PATCH 05/11] more msg removal --- compiler/rustc_hir_typeck/messages.ftl | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 5a935ceee356..6d40df7d0ccf 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -3,17 +3,6 @@ hir_typeck_field_multiply_specified_in_initializer = .label = used more than once .previous_use_label = first use of `{$ident}` -hir_typeck_multiple_relaxed_default_bounds = - type parameter has more than one relaxed default bound, only one is supported - -hir_typeck_copy_impl_on_non_adt = - the trait `Copy` cannot be implemented for this type - .label = type is not a structure or enumeration - -hir_typeck_trait_object_declared_with_no_traits = - at least one trait is required for an object type - .alias_span = this alias does not contain a trait - hir_typeck_functional_record_update_on_non_struct = functional record update syntax requires a struct From 6b33245c5bfad0a114fbd9e1f1b9e544949ae9ec Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 20 Apr 2023 17:49:13 +0200 Subject: [PATCH 06/11] Add regression test for #46506 --- ...ssue-46506-pub-reexport-of-pub-reexport.rs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs diff --git a/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs b/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs new file mode 100644 index 000000000000..d8953eaf5970 --- /dev/null +++ b/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs @@ -0,0 +1,24 @@ +// This is a regression test for . +// This test ensures that if public re-exported is re-exported, it won't be inlined. + +#![crate_name = "foo"] + +// @has 'foo/associations/index.html' +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits' +// @has - '//*[@id="main-content"]//a[@href="trait.GroupedBy.html"]' 'GroupedBy' +// @has 'foo/associations/trait.GroupedBy.html' +pub mod associations { + mod belongs_to { + pub trait GroupedBy {} + } + pub use self::belongs_to::GroupedBy; +} + +// @has 'foo/prelude/index.html' +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports' +// @has - '//*[@id="main-content"]//*[@id="reexport.GroupedBy"]' 'pub use associations::GroupedBy;' +pub mod prelude { + pub use associations::GroupedBy; +} From 4fd7739aac547f99b5f0378ee1b6752258d234f7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 20 Apr 2023 16:54:39 +0000 Subject: [PATCH 07/11] Track if EvalCtxt has been tainted, make sure it can't be used to make query responses after --- .../rustc_trait_selection/src/solve/eval_ctxt.rs | 14 ++++++++++++++ .../src/solve/eval_ctxt/canonical.rs | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index bb574954587e..4c79445d345e 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -57,6 +57,13 @@ pub struct EvalCtxt<'a, 'tcx> { pub(super) search_graph: &'a mut SearchGraph<'tcx>, pub(super) nested_goals: NestedGoals<'tcx>, + + // Has this `EvalCtxt` errored out with `NoSolution` in `try_evaluate_added_goals`? + // + // If so, then it can no longer be used to make a canonical query response, + // since subsequent calls to `try_evaluate_added_goals` have possibly dropped + // ambiguous goals. Instead, use a probe. + tainted: bool, } #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -121,6 +128,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> { max_input_universe: ty::UniverseIndex::ROOT, var_values: CanonicalVarValues::dummy(), nested_goals: NestedGoals::new(), + tainted: false, }; let result = ecx.evaluate_goal(IsNormalizesToHack::No, goal); @@ -172,6 +180,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { max_input_universe: canonical_goal.max_universe, search_graph, nested_goals: NestedGoals::new(), + tainted: false, }; ecx.compute_goal(goal) }) @@ -391,6 +400,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { }, ); + if response.is_err() { + self.tainted = true; + } + self.nested_goals = goals; response } @@ -404,6 +417,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { max_input_universe: self.max_input_universe, search_graph: self.search_graph, nested_goals: self.nested_goals.clone(), + tainted: self.tainted, }; self.infcx.probe(|_| f(&mut ecx)) } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index 23cf0f0c724b..e7a6282cb3de 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -51,6 +51,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { certainty: Certainty, ) -> QueryResult<'tcx> { let goals_certainty = self.try_evaluate_added_goals()?; + assert!( + !self.tainted, + "EvalCtxt is tainted -- nested goals may have been dropped in a \ + previous call to `try_evaluate_added_goals!`" + ); + let certainty = certainty.unify_with(goals_certainty); let external_constraints = self.compute_external_query_constraints()?; From 3206100ed9273c1adcc661d30db460c2402d568c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 20 Apr 2023 18:40:34 +0000 Subject: [PATCH 08/11] Result is just bool but special --- compiler/rustc_trait_selection/src/solve/eval_ctxt.rs | 11 ++++++----- .../src/solve/eval_ctxt/canonical.rs | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 4c79445d345e..bd52957d162f 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -62,8 +62,9 @@ pub struct EvalCtxt<'a, 'tcx> { // // If so, then it can no longer be used to make a canonical query response, // since subsequent calls to `try_evaluate_added_goals` have possibly dropped - // ambiguous goals. Instead, use a probe. - tainted: bool, + // ambiguous goals. Instead, a probe needs to be introduced somewhere in the + // evaluation code. + tainted: Result<(), NoSolution>, } #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -128,7 +129,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> { max_input_universe: ty::UniverseIndex::ROOT, var_values: CanonicalVarValues::dummy(), nested_goals: NestedGoals::new(), - tainted: false, + tainted: Ok(()), }; let result = ecx.evaluate_goal(IsNormalizesToHack::No, goal); @@ -180,7 +181,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { max_input_universe: canonical_goal.max_universe, search_graph, nested_goals: NestedGoals::new(), - tainted: false, + tainted: Ok(()), }; ecx.compute_goal(goal) }) @@ -401,7 +402,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { ); if response.is_err() { - self.tainted = true; + self.tainted = Err(NoSolution); } self.nested_goals = goals; diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index e7a6282cb3de..2dea36811d80 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -51,8 +51,9 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { certainty: Certainty, ) -> QueryResult<'tcx> { let goals_certainty = self.try_evaluate_added_goals()?; - assert!( - !self.tainted, + assert_eq!( + self.tainted, + Ok(()), "EvalCtxt is tainted -- nested goals may have been dropped in a \ previous call to `try_evaluate_added_goals!`" ); From 6d99d6a9de9df76f47bccde605f5ec7f60bc2321 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Thu, 20 Apr 2023 16:41:33 +0300 Subject: [PATCH 09/11] ship clippy, miri and rustfmt with sysroot Signed-off-by: ozkanonur --- src/bootstrap/tool.rs | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 79eec6f848c2..f8da6df0c7cc 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -748,6 +748,7 @@ macro_rules! tool_extended { stable = $stable:expr $(,tool_std = $tool_std:literal)? $(,allow_features = $allow_features:expr)? + $(,add_bins_to_sysroot = $add_bins_to_sysroot:expr)? ;)+) => { $( #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -790,7 +791,7 @@ macro_rules! tool_extended { #[allow(unused_mut)] fn run(mut $sel, $builder: &Builder<'_>) -> Option { - $builder.ensure(ToolBuild { + let tool = $builder.ensure(ToolBuild { compiler: $sel.compiler, target: $sel.target, tool: $tool_name, @@ -800,7 +801,27 @@ macro_rules! tool_extended { is_optional_tool: true, source_type: SourceType::InTree, allow_features: concat!($($allow_features)*), - }) + })?; + + if (false $(|| !$add_bins_to_sysroot.is_empty())?) && $sel.compiler.stage > 0 { + let bindir = $builder.sysroot($sel.compiler).join("bin"); + t!(fs::create_dir_all(&bindir)); + + #[allow(unused_variables)] + let tools_out = $builder + .cargo_out($sel.compiler, Mode::ToolRustc, $sel.target); + + $(for add_bin in $add_bins_to_sysroot { + let bin_source = tools_out.join(exe(add_bin, $sel.target)); + let bin_destination = bindir.join(exe(add_bin, $sel.compiler.host)); + $builder.copy(&bin_source, &bin_destination); + })? + + let tool = bindir.join(exe($tool_name, $sel.compiler.host)); + Some(tool) + } else { + Some(tool) + } } } )+ @@ -814,15 +835,15 @@ macro_rules! tool_extended { tool_extended!((self, builder), Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true; CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true; - Clippy, "src/tools/clippy", "clippy-driver", stable=true; - Miri, "src/tools/miri", "miri", stable=false; - CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true; + Clippy, "src/tools/clippy", "clippy-driver", stable=true, add_bins_to_sysroot = ["clippy-driver", "cargo-clippy"]; + Miri, "src/tools/miri", "miri", stable=false, add_bins_to_sysroot = ["miri"]; + CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true, add_bins_to_sysroot = ["cargo-miri"]; // FIXME: tool_std is not quite right, we shouldn't allow nightly features. // But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0, // and this is close enough for now. Rls, "src/tools/rls", "rls", stable=true, tool_std=true; RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, tool_std=true; - Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true; + Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, add_bins_to_sysroot = ["rustfmt", "cargo-fmt"]; ); impl<'a> Builder<'a> { From 68fc568b89b364025b6f4d1b364e26b4d5b1e79a Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Fri, 21 Apr 2023 00:16:35 +0300 Subject: [PATCH 10/11] remove the early return in `Sysroot::run` which causes bypassing symlinking Signed-off-by: ozkanonur --- src/bootstrap/compile.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 8af5927e27fb..ab307d4d038c 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1328,7 +1328,6 @@ impl Step for Sysroot { true } }); - return INTERNER.intern_path(sysroot); } // Symlink the source root into the same location inside the sysroot, From a2f275da511bbe03ca53bb4c90a344340b1c8fff Mon Sep 17 00:00:00 2001 From: bohan Date: Thu, 20 Apr 2023 13:24:45 +0800 Subject: [PATCH 11/11] fix(error): normalize whitespace during msg_to_buffer --- compiler/rustc_errors/src/emitter.rs | 1 + tests/ui/extenv/issue-110547.rs | 7 +++++++ tests/ui/extenv/issue-110547.stderr | 29 ++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 tests/ui/extenv/issue-110547.rs create mode 100644 tests/ui/extenv/issue-110547.stderr diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index fe44799efdb6..cb3365f0c406 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1336,6 +1336,7 @@ impl EmitterWriter { // see? for (text, style) in msg.iter() { let text = self.translate_message(text, args).map_err(Report::new).unwrap(); + let text = &normalize_whitespace(&text); let lines = text.split('\n').collect::>(); if lines.len() > 1 { for (i, line) in lines.iter().enumerate() { diff --git a/tests/ui/extenv/issue-110547.rs b/tests/ui/extenv/issue-110547.rs new file mode 100644 index 000000000000..a6fb96ac0664 --- /dev/null +++ b/tests/ui/extenv/issue-110547.rs @@ -0,0 +1,7 @@ +// compile-flags: -C debug-assertions + +fn main() { + env!{"\t"}; //~ ERROR not defined at compile time + env!("\t"); //~ ERROR not defined at compile time + env!("\u{2069}"); //~ ERROR not defined at compile time +} diff --git a/tests/ui/extenv/issue-110547.stderr b/tests/ui/extenv/issue-110547.stderr new file mode 100644 index 000000000000..1219630d346a --- /dev/null +++ b/tests/ui/extenv/issue-110547.stderr @@ -0,0 +1,29 @@ +error: environment variable ` ` not defined at compile time + --> $DIR/issue-110547.rs:4:5 + | +LL | env!{"\t"}; + | ^^^^^^^^^^ + | + = help: use `std::env::var(" ")` to read the variable at run time + = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: environment variable ` ` not defined at compile time + --> $DIR/issue-110547.rs:5:5 + | +LL | env!("\t"); + | ^^^^^^^^^^ + | + = help: use `std::env::var(" ")` to read the variable at run time + = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: environment variable `` not defined at compile time + --> $DIR/issue-110547.rs:6:5 + | +LL | env!("\u{2069}"); + | ^^^^^^^^^^^^^^^^ + | + = help: use `std::env::var("")` to read the variable at run time + = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors +