From 8cfd249198dd0e04558d725452b91f4db3984633 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 22 Sep 2023 19:47:34 +0000 Subject: [PATCH 1/8] Allow higher-ranked fn sigs in ValuePairs --- .../src/check/compare_impl_item.rs | 5 +++- compiler/rustc_hir_analysis/src/check/mod.rs | 11 ++++----- compiler/rustc_infer/src/infer/at.rs | 23 ++++++++++++++++++- .../src/infer/error_reporting/mod.rs | 9 +++----- .../trait_impl_difference.rs | 6 ++--- compiler/rustc_infer/src/infer/mod.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 5 +++- .../panic-handler-bad-signature-1.stderr | 4 ++-- .../panic-handler-bad-signature-2.stderr | 4 ++-- .../panic-handler-bad-signature-3.stderr | 2 +- .../panic-handler-bad-signature-5.stderr | 4 ++-- 11 files changed, 48 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 7be18a36d6369..ba58f0d57ad68 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1134,7 +1134,10 @@ fn report_trait_method_mismatch<'tcx>( &mut diag, &cause, trait_err_span.map(|sp| (sp, Cow::from("type in trait"))), - Some(infer::ValuePairs::Sigs(ExpectedFound { expected: trait_sig, found: impl_sig })), + Some(infer::ValuePairs::PolySigs(ExpectedFound { + expected: ty::Binder::dummy(trait_sig), + found: ty::Binder::dummy(impl_sig), + })), terr, false, false, diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 0cf3cee66b56e..88c98fa979e1c 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -573,10 +573,7 @@ pub fn check_function_signature<'tcx>( let norm_cause = ObligationCause::misc(cause.span, local_id); let actual_sig = ocx.normalize(&norm_cause, param_env, actual_sig); - let expected_ty = Ty::new_fn_ptr(tcx, expected_sig); - let actual_ty = Ty::new_fn_ptr(tcx, actual_sig); - - match ocx.eq(&cause, param_env, expected_ty, actual_ty) { + match ocx.eq(&cause, param_env, expected_sig, actual_sig) { Ok(()) => { let errors = ocx.select_all_or_error(); if !errors.is_empty() { @@ -595,9 +592,9 @@ pub fn check_function_signature<'tcx>( &mut diag, &cause, None, - Some(infer::ValuePairs::Sigs(ExpectedFound { - expected: tcx.liberate_late_bound_regions(fn_id, expected_sig), - found: tcx.liberate_late_bound_regions(fn_id, actual_sig), + Some(infer::ValuePairs::PolySigs(ExpectedFound { + expected: expected_sig, + found: actual_sig, })), err, false, diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 6d5db3336cfbf..2797d07976113 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -478,7 +478,28 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> { a: Self, b: Self, ) -> TypeTrace<'tcx> { - TypeTrace { cause: cause.clone(), values: Sigs(ExpectedFound::new(a_is_expected, a, b)) } + TypeTrace { + cause: cause.clone(), + values: PolySigs(ExpectedFound::new( + a_is_expected, + ty::Binder::dummy(a), + ty::Binder::dummy(b), + )), + } + } +} + +impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> { + fn to_trace( + cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self, + ) -> TypeTrace<'tcx> { + TypeTrace { + cause: cause.clone(), + values: PolySigs(ExpectedFound::new(a_is_expected, a, b)), + } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 1beb13cb94cac..e418864026f6c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1660,7 +1660,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { _ => (false, Mismatch::Fixed("type")), } } - ValuePairs::Sigs(infer::ExpectedFound { expected, found }) => { + ValuePairs::PolySigs(infer::ExpectedFound { expected, found }) => { OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span) .report(diag); (false, Mismatch::Fixed("signature")) @@ -2232,15 +2232,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ret => ret, } } - infer::Sigs(exp_found) => { + infer::PolySigs(exp_found) => { let exp_found = self.resolve_vars_if_possible(exp_found); if exp_found.references_error() { return None; } - let (exp, fnd) = self.cmp_fn_sig( - &ty::Binder::dummy(exp_found.expected), - &ty::Binder::dummy(exp_found.found), - ); + let (exp, fnd) = self.cmp_fn_sig(&exp_found.expected, &exp_found.found); Some((exp, fnd, None, None)) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index d2ba9966f0343..cb51254a14b0c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -35,14 +35,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { && let (Subtype(sup_trace), Subtype(sub_trace)) = (&sup_origin, &sub_origin) && let CompareImplItemObligation { trait_item_def_id, .. } = sub_trace.cause.code() && sub_trace.values == sup_trace.values - && let ValuePairs::Sigs(ExpectedFound { expected, found }) = sub_trace.values + && let ValuePairs::PolySigs(ExpectedFound { expected, found }) = sub_trace.values { // FIXME(compiler-errors): Don't like that this needs `Ty`s, but // all of the region highlighting machinery only deals with those. let guar = self.emit_err( var_origin.span(), - Ty::new_fn_ptr(self.cx.tcx,ty::Binder::dummy(expected)), - Ty::new_fn_ptr(self.cx.tcx,ty::Binder::dummy(found)), + Ty::new_fn_ptr(self.cx.tcx, expected), + Ty::new_fn_ptr(self.cx.tcx, found), *trait_item_def_id, ); return Some(guar); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 4cf9d44ed65de..aeb3177af0275 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -383,7 +383,7 @@ pub enum ValuePairs<'tcx> { Aliases(ExpectedFound>), TraitRefs(ExpectedFound>), PolyTraitRefs(ExpectedFound>), - Sigs(ExpectedFound>), + PolySigs(ExpectedFound>), ExistentialTraitRef(ExpectedFound>), ExistentialProjection(ExpectedFound>), } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 12118a0268bab..afba366a365a9 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2333,7 +2333,10 @@ impl CheckAttrVisitor<'_> { &mut diag, &cause, None, - Some(ValuePairs::Sigs(ExpectedFound { expected: expected_sig, found: sig })), + Some(ValuePairs::PolySigs(ExpectedFound { + expected: ty::Binder::dummy(expected_sig), + found: ty::Binder::dummy(sig), + })), terr, false, false, diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr index d12bfbf269eb7..85555c43906e8 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr +++ b/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr @@ -4,8 +4,8 @@ error[E0308]: `#[panic_handler]` function has wrong type LL | fn panic(info: PanicInfo) -> () {} | ^^^^^^^^^ expected `&PanicInfo<'_>`, found `PanicInfo<'_>` | - = note: expected signature `fn(&PanicInfo<'_>) -> !` - found signature `fn(PanicInfo<'_>)` + = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !` + found signature `for<'a> fn(PanicInfo<'a>)` error: aborting due to previous error diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-2.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-2.stderr index 06e32d5fb84a3..84eba2a5a63c2 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-2.stderr +++ b/tests/ui/panic-handler/panic-handler-bad-signature-2.stderr @@ -4,8 +4,8 @@ error[E0308]: `#[panic_handler]` function has wrong type LL | fn panic(info: &'static PanicInfo) -> ! | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other | - = note: expected fn pointer `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _` - found fn pointer `for<'a> fn(&'static PanicInfo<'a>) -> _` + = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _` + found signature `for<'a> fn(&'static PanicInfo<'a>) -> _` error: aborting due to previous error diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-3.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-3.stderr index 8365f5769ebe3..cdf55ab6534ea 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-3.stderr +++ b/tests/ui/panic-handler/panic-handler-bad-signature-3.stderr @@ -4,7 +4,7 @@ error[E0308]: `#[panic_handler]` function has wrong type LL | fn panic() -> ! { | ^^^^^^^^^^^^^^^ incorrect number of function parameters | - = note: expected signature `fn(&PanicInfo<'_>) -> _` + = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _` found signature `fn() -> _` error: aborting due to previous error diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-5.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-5.stderr index 22b8d5ca81151..20c17587590ca 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-5.stderr +++ b/tests/ui/panic-handler/panic-handler-bad-signature-5.stderr @@ -4,8 +4,8 @@ error[E0308]: `#[panic_handler]` function has wrong type LL | fn panic(info: &PanicInfo<'static>) -> ! | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other | - = note: expected fn pointer `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _` - found fn pointer `for<'a> fn(&'a PanicInfo<'static>) -> _` + = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _` + found signature `for<'a> fn(&'a PanicInfo<'static>) -> _` error: aborting due to previous error From 82e7cec16d7143907f145c895f7208c0a3906e03 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 23 Sep 2023 00:56:43 +0000 Subject: [PATCH 2/8] Tweak expected message to explain what it's actually signifying --- .../src/infer/error_reporting/note_and_explain.rs | 10 +++++++--- .../ui/associated-types/defaults-specialization.stderr | 4 ++-- .../specialization/specialization-default-types.stderr | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index 445f68160d286..b34900da83bb2 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -616,9 +616,13 @@ fn foo(&self) -> Self::T { String::new() } for item in &items[..] { if let hir::AssocItemKind::Type = item.kind { let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity(); - - if self.infcx.can_eq(param_env, assoc_ty, found) { - diag.span_label(item.span, "expected this associated type"); + if let hir::Defaultness::Default { has_value: true } = tcx.defaultness(item.id.owner_id) + && self.infcx.can_eq(param_env, assoc_ty, found) + { + diag.span_label( + item.span, + format!("associated type is `default` and may be overridden"), + ); return true; } } diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr index 7e21f7fc306d2..7ef433d859fa4 100644 --- a/tests/ui/associated-types/defaults-specialization.stderr +++ b/tests/ui/associated-types/defaults-specialization.stderr @@ -29,7 +29,7 @@ error[E0053]: method `make` has an incompatible type for trait --> $DIR/defaults-specialization.rs:35:18 | LL | default type Ty = bool; - | ----------------------- expected this associated type + | ----------------------- associated type is `default` and may be overridden LL | LL | fn make() -> bool { true } | ^^^^ @@ -76,7 +76,7 @@ error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:44:29 | LL | default type Ty = bool; - | ----------------------- expected this associated type + | ----------------------- associated type is `default` and may be overridden LL | LL | fn make() -> Self::Ty { true } | -------- ^^^^ expected associated type, found `bool` diff --git a/tests/ui/specialization/specialization-default-types.stderr b/tests/ui/specialization/specialization-default-types.stderr index ecccf29a107dc..774ac9536175d 100644 --- a/tests/ui/specialization/specialization-default-types.stderr +++ b/tests/ui/specialization/specialization-default-types.stderr @@ -12,7 +12,7 @@ error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:15:9 | LL | default type Output = Box; - | ----------------------------- expected this associated type + | ----------------------------- associated type is `default` and may be overridden LL | default fn generate(self) -> Self::Output { | ------------ expected `::Output` because of return type LL | Box::new(self) From c4a4926083e9f0b9aeef549f93cb66cd9d4076d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 23 Sep 2023 01:34:50 +0000 Subject: [PATCH 3/8] More accurate suggestion for `self.` and `Self::` Fix #115992. --- .../rustc_resolve/src/late/diagnostics.rs | 17 +++++--- tests/ui/suggestions/assoc_fn_without_self.rs | 8 ++++ .../suggestions/assoc_fn_without_self.stderr | 40 +++++++++++++++++-- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index c34b7df9b4603..44dba9b7be776 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -224,14 +224,21 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { && let FnKind::Fn(_, _, sig, ..) = fn_kind && let Some(items) = self.diagnostic_metadata.current_impl_items && let Some(item) = items.iter().find(|i| { - if let AssocItemKind::Fn(..) | AssocItemKind::Const(..) = &i.kind - && i.ident.name == item_str.name - // don't suggest if the item is in Fn signature arguments - // issue #112590 + if i.ident.name == item_str.name + // Don't suggest if the item is in Fn signature arguments (#112590). && !sig.span.contains(item_span) { debug!(?item_str.name); - return true + return match &i.kind { + AssocItemKind::Fn(fn_) + if !sig.decl.has_self() && fn_.sig.decl.has_self() => { + // Ensure that we only suggest `self.` if `self` is available, + // you can't call `fn foo(&self)` from `fn bar()` (#115992). + false + } + AssocItemKind::Fn(_) | AssocItemKind::Const(..) => true, + _ => false + } } false }) diff --git a/tests/ui/suggestions/assoc_fn_without_self.rs b/tests/ui/suggestions/assoc_fn_without_self.rs index 778d9847773f3..35c16ef3e9f7c 100644 --- a/tests/ui/suggestions/assoc_fn_without_self.rs +++ b/tests/ui/suggestions/assoc_fn_without_self.rs @@ -17,4 +17,12 @@ impl S { bar(); //~ ERROR cannot find function `bar` in this scope baz(2, 3); //~ ERROR cannot find function `baz` in this scope } + fn d(&self) { + fn c() { + foo(); //~ ERROR cannot find function `foo` in this scope + } + foo(); //~ ERROR cannot find function `foo` in this scope + bar(); //~ ERROR cannot find function `bar` in this scope + baz(2, 3); //~ ERROR cannot find function `baz` in this scope + } } diff --git a/tests/ui/suggestions/assoc_fn_without_self.stderr b/tests/ui/suggestions/assoc_fn_without_self.stderr index febdd67338c99..a7fab36bf8d84 100644 --- a/tests/ui/suggestions/assoc_fn_without_self.stderr +++ b/tests/ui/suggestions/assoc_fn_without_self.stderr @@ -12,6 +12,40 @@ LL | Self::foo(); error[E0425]: cannot find function `bar` in this scope --> $DIR/assoc_fn_without_self.rs:17:9 | +LL | bar(); + | ^^^ not found in this scope + +error[E0425]: cannot find function `baz` in this scope + --> $DIR/assoc_fn_without_self.rs:18:9 + | +LL | baz(2, 3); + | ^^^ not found in this scope + | +help: consider using the associated function + | +LL | Self::baz(2, 3); + | ++++++ + +error[E0425]: cannot find function `foo` in this scope + --> $DIR/assoc_fn_without_self.rs:14:13 + | +LL | foo(); + | ^^^ not found in this scope + +error[E0425]: cannot find function `foo` in this scope + --> $DIR/assoc_fn_without_self.rs:24:9 + | +LL | foo(); + | ^^^ not found in this scope + | +help: consider using the associated function + | +LL | Self::foo(); + | ++++++ + +error[E0425]: cannot find function `bar` in this scope + --> $DIR/assoc_fn_without_self.rs:25:9 + | LL | bar(); | ^^^ not found in this scope | @@ -21,7 +55,7 @@ LL | self.bar(); | +++++ error[E0425]: cannot find function `baz` in this scope - --> $DIR/assoc_fn_without_self.rs:18:9 + --> $DIR/assoc_fn_without_self.rs:26:9 | LL | baz(2, 3); | ^^^ not found in this scope @@ -32,11 +66,11 @@ LL | Self::baz(2, 3); | ++++++ error[E0425]: cannot find function `foo` in this scope - --> $DIR/assoc_fn_without_self.rs:14:13 + --> $DIR/assoc_fn_without_self.rs:22:13 | LL | foo(); | ^^^ not found in this scope -error: aborting due to 4 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0425`. From 0e986825762edd031bc6bf4a78d9162ac2ed6268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 23 Sep 2023 01:47:06 +0000 Subject: [PATCH 4/8] When encountering method on `Self` that we can't suggest, mention it --- .../rustc_resolve/src/late/diagnostics.rs | 58 +++++++++---------- .../suggestions/assoc_fn_without_self.stderr | 3 + 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 44dba9b7be776..c690ac6c043f9 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -214,6 +214,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { module: None, } } else { + let mut span_label = None; let item_span = path.last().unwrap().ident.span; let (mod_prefix, mod_str, module, suggestion) = if path.len() == 1 { debug!(?self.diagnostic_metadata.current_impl_items); @@ -224,39 +225,36 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { && let FnKind::Fn(_, _, sig, ..) = fn_kind && let Some(items) = self.diagnostic_metadata.current_impl_items && let Some(item) = items.iter().find(|i| { - if i.ident.name == item_str.name + i.ident.name == item_str.name // Don't suggest if the item is in Fn signature arguments (#112590). && !sig.span.contains(item_span) - { - debug!(?item_str.name); - return match &i.kind { - AssocItemKind::Fn(fn_) - if !sig.decl.has_self() && fn_.sig.decl.has_self() => { - // Ensure that we only suggest `self.` if `self` is available, - // you can't call `fn foo(&self)` from `fn bar()` (#115992). - false - } - AssocItemKind::Fn(_) | AssocItemKind::Const(..) => true, - _ => false - } - } - false }) { - let self_sugg = match &item.kind { - AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => "self.", - _ => "Self::", - }; - - Some(( - item_span.shrink_to_lo(), - match &item.kind { - AssocItemKind::Fn(..) => "consider using the associated function", - AssocItemKind::Const(..) => "consider using the associated constant", - _ => unreachable!("item kind was filtered above"), - }, - self_sugg.to_string() - )) + let sp = item_span.shrink_to_lo(); + match &item.kind { + AssocItemKind::Fn(fn_) + if !sig.decl.has_self() && fn_.sig.decl.has_self() => { + // Ensure that we only suggest `self.` if `self` is available, + // you can't call `fn foo(&self)` from `fn bar()` (#115992). + // We also want to mention that the method exists. + span_label = Some(( + item.ident.span, + "a method by that name is available on `Self` here", + )); + None + } + AssocItemKind::Fn(fn_) => Some(( + sp, + "consider using the associated function", + if fn_.sig.decl.has_self() { "self." } else { "Self::" }, + )), + AssocItemKind::Const(..) => Some(( + sp, + "consider using the associated constant", + "Self::", + )), + _ => None + } } else { None }; @@ -321,7 +319,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { msg: format!("cannot find {expected} `{item_str}` in {mod_prefix}{mod_str}"), fallback_label, span: item_span, - span_label: None, + span_label, could_be_expr: false, suggestion, module, diff --git a/tests/ui/suggestions/assoc_fn_without_self.stderr b/tests/ui/suggestions/assoc_fn_without_self.stderr index a7fab36bf8d84..26fcc2a018100 100644 --- a/tests/ui/suggestions/assoc_fn_without_self.stderr +++ b/tests/ui/suggestions/assoc_fn_without_self.stderr @@ -12,6 +12,9 @@ LL | Self::foo(); error[E0425]: cannot find function `bar` in this scope --> $DIR/assoc_fn_without_self.rs:17:9 | +LL | fn bar(&self) {} + | --- a method by that name is available on `Self` here +... LL | bar(); | ^^^ not found in this scope From ac5e18756a4f0987c5861e45b82ac6f410fd4734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 23 Sep 2023 01:54:05 +0000 Subject: [PATCH 5/8] Tweak wording and logic --- compiler/rustc_resolve/src/late/diagnostics.rs | 15 ++++++++++----- tests/ui/resolve/issue-103474.stderr | 2 +- tests/ui/resolve/issue-2356.stderr | 4 ++-- tests/ui/self/class-missing-self.stderr | 2 +- .../suggestions/assoc-const-without-self.stderr | 2 +- tests/ui/suggestions/assoc_fn_without_self.stderr | 10 +++++----- 6 files changed, 20 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index c690ac6c043f9..06a08f29a1ee8 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -243,15 +243,20 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { )); None } - AssocItemKind::Fn(fn_) => Some(( + AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => Some(( sp, - "consider using the associated function", - if fn_.sig.decl.has_self() { "self." } else { "Self::" }, + "consider using the method on `Self`", + "self.".to_string(), + )), + AssocItemKind::Fn(_) => Some(( + sp, + "consider using the associated function on `Self`", + "Self::".to_string(), )), AssocItemKind::Const(..) => Some(( sp, - "consider using the associated constant", - "Self::", + "consider using the associated constant on `Self`", + "Self::".to_string(), )), _ => None } diff --git a/tests/ui/resolve/issue-103474.stderr b/tests/ui/resolve/issue-103474.stderr index 415d231552a03..e48fb31eccc9a 100644 --- a/tests/ui/resolve/issue-103474.stderr +++ b/tests/ui/resolve/issue-103474.stderr @@ -19,7 +19,7 @@ error[E0425]: cannot find function `first` in this scope LL | first() | ^^^^^ not found in this scope | -help: consider using the associated function +help: consider using the method on `Self` | LL | self.first() | +++++ diff --git a/tests/ui/resolve/issue-2356.stderr b/tests/ui/resolve/issue-2356.stderr index 30f5f05952664..273e8b2a661fb 100644 --- a/tests/ui/resolve/issue-2356.stderr +++ b/tests/ui/resolve/issue-2356.stderr @@ -73,7 +73,7 @@ error[E0425]: cannot find function `static_method` in this scope LL | static_method(); | ^^^^^^^^^^^^^ not found in this scope | -help: consider using the associated function +help: consider using the associated function on `Self` | LL | Self::static_method(); | ++++++ @@ -102,7 +102,7 @@ error[E0425]: cannot find function `grow_older` in this scope LL | grow_older(); | ^^^^^^^^^^ not found in this scope | -help: consider using the associated function +help: consider using the associated function on `Self` | LL | Self::grow_older(); | ++++++ diff --git a/tests/ui/self/class-missing-self.stderr b/tests/ui/self/class-missing-self.stderr index 3c37d8197432c..08493b4f9a2da 100644 --- a/tests/ui/self/class-missing-self.stderr +++ b/tests/ui/self/class-missing-self.stderr @@ -10,7 +10,7 @@ error[E0425]: cannot find function `sleep` in this scope LL | sleep(); | ^^^^^ not found in this scope | -help: consider using the associated function +help: consider using the method on `Self` | LL | self.sleep(); | +++++ diff --git a/tests/ui/suggestions/assoc-const-without-self.stderr b/tests/ui/suggestions/assoc-const-without-self.stderr index 88d72da70cb9b..05528d277be5b 100644 --- a/tests/ui/suggestions/assoc-const-without-self.stderr +++ b/tests/ui/suggestions/assoc-const-without-self.stderr @@ -4,7 +4,7 @@ error[E0425]: cannot find value `A_CONST` in this scope LL | A_CONST | ^^^^^^^ not found in this scope | -help: consider using the associated constant +help: consider using the associated constant on `Self` | LL | Self::A_CONST | ++++++ diff --git a/tests/ui/suggestions/assoc_fn_without_self.stderr b/tests/ui/suggestions/assoc_fn_without_self.stderr index 26fcc2a018100..9cee7c7ee5ee8 100644 --- a/tests/ui/suggestions/assoc_fn_without_self.stderr +++ b/tests/ui/suggestions/assoc_fn_without_self.stderr @@ -4,7 +4,7 @@ error[E0425]: cannot find function `foo` in this scope LL | foo(); | ^^^ not found in this scope | -help: consider using the associated function +help: consider using the associated function on `Self` | LL | Self::foo(); | ++++++ @@ -24,7 +24,7 @@ error[E0425]: cannot find function `baz` in this scope LL | baz(2, 3); | ^^^ not found in this scope | -help: consider using the associated function +help: consider using the associated function on `Self` | LL | Self::baz(2, 3); | ++++++ @@ -41,7 +41,7 @@ error[E0425]: cannot find function `foo` in this scope LL | foo(); | ^^^ not found in this scope | -help: consider using the associated function +help: consider using the associated function on `Self` | LL | Self::foo(); | ++++++ @@ -52,7 +52,7 @@ error[E0425]: cannot find function `bar` in this scope LL | bar(); | ^^^ not found in this scope | -help: consider using the associated function +help: consider using the method on `Self` | LL | self.bar(); | +++++ @@ -63,7 +63,7 @@ error[E0425]: cannot find function `baz` in this scope LL | baz(2, 3); | ^^^ not found in this scope | -help: consider using the associated function +help: consider using the associated function on `Self` | LL | Self::baz(2, 3); | ++++++ From 7d8559ac9077e35a687d5b16f17f2f493421f3ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 23 Sep 2023 01:59:22 +0000 Subject: [PATCH 6/8] Add test --- ...ethod-in-self-not-available-in-assoc-fn.rs | 15 +++++++++++++ ...d-in-self-not-available-in-assoc-fn.stderr | 21 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs create mode 100644 tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs new file mode 100644 index 0000000000000..9e72c36151e5d --- /dev/null +++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs @@ -0,0 +1,15 @@ +struct Foo { + field: u32, +} + +impl Foo { + fn field(&self) -> u32 { + self.field + } + + fn new() -> Foo { + field; //~ ERROR cannot find value `field` in this scope + Foo { field } //~ ERROR cannot find value `field` in this scope + } +} +fn main() {} diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr new file mode 100644 index 0000000000000..2eb3861e5f11b --- /dev/null +++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr @@ -0,0 +1,21 @@ +error[E0425]: cannot find value `field` in this scope + --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:11:9 + | +LL | fn field(&self) -> u32 { + | ----- a method by that name is available on `Self` here +... +LL | field; + | ^^^^^ a field by this name exists in `Self` + +error[E0425]: cannot find value `field` in this scope + --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:12:15 + | +LL | fn field(&self) -> u32 { + | ----- a method by that name is available on `Self` here +... +LL | Foo { field } + | ^^^^^ a field by this name exists in `Self` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. From 8ec5639bc204217cf0a37ba92d35358f787b6d69 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 5 Sep 2023 17:14:37 +0000 Subject: [PATCH 7/8] Reuse calculate_debuginfo_offset for fragments. --- .../rustc_codegen_ssa/src/mir/debuginfo.rs | 43 +++++-------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index d156011476317..0dc30d21c5b40 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -158,8 +158,7 @@ fn calculate_debuginfo_offset< L: DebugInfoOffsetLocation<'tcx, Bx>, >( bx: &mut Bx, - local: mir::Local, - var: &PerLocalVarDebugInfo<'tcx, Bx::DIVariable>, + projection: &[mir::PlaceElem<'tcx>], base: L, ) -> DebugInfoOffset { let mut direct_offset = Size::ZERO; @@ -167,7 +166,7 @@ fn calculate_debuginfo_offset< let mut indirect_offsets = vec![]; let mut place = base; - for elem in &var.projection[..] { + for elem in projection { match *elem { mir::ProjectionElem::Deref => { indirect_offsets.push(Size::ZERO); @@ -188,11 +187,7 @@ fn calculate_debuginfo_offset< } => { let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset); let FieldsShape::Array { stride, count: _ } = place.layout().fields else { - span_bug!( - var.source_info.span, - "ConstantIndex on non-array type {:?}", - place.layout() - ) + bug!("ConstantIndex on non-array type {:?}", place.layout()) }; *offset += stride * index; place = place.project_constant_index(bx, index); @@ -200,11 +195,7 @@ fn calculate_debuginfo_offset< _ => { // Sanity check for `can_use_in_debuginfo`. debug_assert!(!elem.can_use_in_debuginfo()); - span_bug!( - var.source_info.span, - "unsupported var debuginfo place `{:?}`", - mir::Place { local, projection: var.projection }, - ) + bug!("unsupported var debuginfo projection `{:?}`", projection) } } } @@ -407,7 +398,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let Some(dbg_loc) = self.dbg_loc(var.source_info) else { return }; let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } = - calculate_debuginfo_offset(bx, local, &var, base.layout); + calculate_debuginfo_offset(bx, &var.projection, base.layout); // When targeting MSVC, create extra allocas for arguments instead of pointing multiple // dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records @@ -425,7 +416,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if should_create_individual_allocas { let DebugInfoOffset { direct_offset: _, indirect_offsets: _, result: place } = - calculate_debuginfo_offset(bx, local, &var, base); + calculate_debuginfo_offset(bx, &var.projection, base); // Create a variable which will be a pointer to the actual value let ptr_ty = Ty::new_ptr( @@ -532,23 +523,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let fragment = if let Some(ref fragment) = var.composite { let var_layout = self.cx.layout_of(var_ty); - let mut fragment_start = Size::ZERO; - let mut fragment_layout = var_layout; - - for elem in &fragment.projection { - match *elem { - mir::ProjectionElem::Field(field, _) => { - let i = field.index(); - fragment_start += fragment_layout.fields.offset(i); - fragment_layout = fragment_layout.field(self.cx, i); - } - _ => span_bug!( - var.source_info.span, - "unsupported fragment projection `{:?}`", - elem, - ), - } - } + let DebugInfoOffset { direct_offset, indirect_offsets, result: fragment_layout } = + calculate_debuginfo_offset(bx, &fragment.projection, var_layout); + debug_assert!(indirect_offsets.is_empty()); if fragment_layout.size == Size::ZERO { // Fragment is a ZST, so does not represent anything. Avoid generating anything @@ -559,7 +536,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // DWARF is concerned, it's not really a fragment. None } else { - Some(fragment_start..fragment_start + fragment_layout.size) + Some(direct_offset..direct_offset + fragment_layout.size) } } else { None From 2d25a25e5dc5636778d1e4e86bf6fa2d9a1be0af Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 23 Sep 2023 20:03:03 +0200 Subject: [PATCH 8/8] Migrate GUI colors test to original CSS color format --- tests/rustdoc-gui/default-settings.goml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rustdoc-gui/default-settings.goml b/tests/rustdoc-gui/default-settings.goml index 3466f3693f908..ff4abb65c0286 100644 --- a/tests/rustdoc-gui/default-settings.goml +++ b/tests/rustdoc-gui/default-settings.goml @@ -5,4 +5,4 @@ go-to: "file://" + |DOC_PATH| + "/settings/index.html" // Wait a bit to be sure the default theme is applied. // If the theme isn't applied, the command will time out. -wait-for-css: ("body", {"background-color": "rgb(15, 20, 25)"}) +wait-for-css: ("body", {"background-color": "#0f1419"})