From 619e0441784126defd42454ec1949e0a4dd0e4fa Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 14 Apr 2024 10:26:59 -0400 Subject: [PATCH 1/3] Fix pretty hir for anon consts in diagnostics --- Cargo.lock | 1 + compiler/rustc_driver_impl/src/pretty.rs | 19 +------------------ compiler/rustc_hir_analysis/src/check/errs.rs | 8 ++++---- compiler/rustc_hir_pretty/src/lib.rs | 16 ++++++---------- compiler/rustc_hir_typeck/src/_match.rs | 2 +- compiler/rustc_hir_typeck/src/callee.rs | 3 ++- compiler/rustc_hir_typeck/src/lib.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 6 +++--- compiler/rustc_middle/Cargo.toml | 1 + compiler/rustc_middle/src/hir/map/mod.rs | 7 +++++++ .../consts/value-suggestion-ice-123906.stderr | 2 +- ...dings-in-pattern-with-ty-err-doesnt-ice.rs | 2 +- ...s-in-pattern-with-ty-err-doesnt-ice.stderr | 4 +++- 13 files changed, 32 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1f26dd7c43c..9a414c3ef61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4278,6 +4278,7 @@ dependencies = [ "rustc_fluent_macro", "rustc_graphviz", "rustc_hir", + "rustc_hir_pretty", "rustc_index", "rustc_macros", "rustc_query_system", diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index c0c6201f73d..40f6f764993 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -24,20 +24,6 @@ impl pprust_ast::PpAnn for AstNoAnn {} -struct HirNoAnn<'tcx> { - tcx: TyCtxt<'tcx>, -} - -impl<'tcx> pprust_hir::PpAnn for HirNoAnn<'tcx> { - fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { - pprust_hir::PpAnn::nested( - &(&self.tcx.hir() as &dyn hir::intravisit::Map<'_>), - state, - nested, - ) - } -} - struct AstIdentifiedAnn; impl pprust_ast::PpAnn for AstIdentifiedAnn { @@ -300,10 +286,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { ) }; match s { - PpHirMode::Normal => { - let annotation = HirNoAnn { tcx }; - f(&annotation) - } + PpHirMode::Normal => f(&tcx), PpHirMode::Identified => { let annotation = HirIdentifiedAnn { tcx }; f(&annotation) diff --git a/compiler/rustc_hir_analysis/src/check/errs.rs b/compiler/rustc_hir_analysis/src/check/errs.rs index 548f9b0810f..a49626eed35 100644 --- a/compiler/rustc_hir_analysis/src/check/errs.rs +++ b/compiler/rustc_hir_analysis/src/check/errs.rs @@ -12,7 +12,7 @@ pub fn maybe_expr_static_mut(tcx: TyCtxt<'_>, expr: hir::Expr<'_>) { let hir_id = expr.hir_id; if let hir::ExprKind::AddrOf(borrow_kind, m, expr) = expr.kind && matches!(borrow_kind, hir::BorrowKind::Ref) - && let Some(var) = is_path_static_mut(*expr) + && let Some(var) = path_if_static_mut(tcx, expr) { handle_static_mut_ref(tcx, span, var, span.edition().at_least_rust_2024(), m, hir_id); } @@ -24,7 +24,7 @@ pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) { && let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind && let hir::ByRef::Yes(rmutbl) = ba.0 && let Some(init) = loc.init - && let Some(var) = is_path_static_mut(*init) + && let Some(var) = path_if_static_mut(tcx, init) { handle_static_mut_ref( tcx, @@ -37,13 +37,13 @@ pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) { } } -fn is_path_static_mut(expr: hir::Expr<'_>) -> Option { +fn path_if_static_mut(tcx: TyCtxt<'_>, expr: &hir::Expr<'_>) -> Option { if let hir::ExprKind::Path(qpath) = expr.kind && let hir::QPath::Resolved(_, path) = qpath && let hir::def::Res::Def(def_kind, _) = path.res && let hir::def::DefKind::Static { mutability: Mutability::Mut, nested: false } = def_kind { - return Some(qpath_to_string(&qpath)); + return Some(qpath_to_string(&tcx, &qpath)); } None } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 39312614c1b..151e4a36849 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -49,10 +49,6 @@ fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {} fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {} } -pub struct NoAnn; - -impl PpAnn for NoAnn {} - impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> { fn nested(&self, state: &mut State<'_>, nested: Nested) { match nested { @@ -190,16 +186,16 @@ fn to_string(ann: &dyn PpAnn, f: F) -> String printer.s.eof() } -pub fn ty_to_string(ty: &hir::Ty<'_>) -> String { - to_string(&NoAnn, |s| s.print_type(ty)) +pub fn ty_to_string(ann: &dyn PpAnn, ty: &hir::Ty<'_>) -> String { + to_string(ann, |s| s.print_type(ty)) } -pub fn qpath_to_string(segment: &hir::QPath<'_>) -> String { - to_string(&NoAnn, |s| s.print_qpath(segment, false)) +pub fn qpath_to_string(ann: &dyn PpAnn, segment: &hir::QPath<'_>) -> String { + to_string(ann, |s| s.print_qpath(segment, false)) } -pub fn pat_to_string(pat: &hir::Pat<'_>) -> String { - to_string(&NoAnn, |s| s.print_pat(pat)) +pub fn pat_to_string(ann: &dyn PpAnn, pat: &hir::Pat<'_>) -> String { + to_string(ann, |s| s.print_pat(pat)) } impl<'a> State<'a> { diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 2a2fd0a41a6..01092a8a94e 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -395,7 +395,7 @@ pub fn maybe_get_coercion_reason( return self.get_fn_decl(hir_id).map(|(_, fn_decl, _)| { let (ty, span) = match fn_decl.output { hir::FnRetTy::DefaultReturn(span) => ("()".to_string(), span), - hir::FnRetTy::Return(ty) => (ty_to_string(ty), ty.span), + hir::FnRetTy::Return(ty) => (ty_to_string(&self.tcx, ty), ty.span), }; (span, format!("expected `{ty}` because of this return type")) }); diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index aa94632b2b0..8f8ca1a12e5 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -724,7 +724,8 @@ fn report_invalid_callee( def::CtorOf::Variant => "enum variant", }; let removal_span = callee_expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi()); - unit_variant = Some((removal_span, descr, rustc_hir_pretty::qpath_to_string(qpath))); + unit_variant = + Some((removal_span, descr, rustc_hir_pretty::qpath_to_string(&self.tcx, qpath))); } let callee_ty = self.resolve_vars_if_possible(callee_ty); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 476df9ae793..a159afbb3d8 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -374,7 +374,7 @@ fn report_unexpected_variant_res( Res::Def(DefKind::Variant, _) => "struct variant", _ => res.descr(), }; - let path_str = rustc_hir_pretty::qpath_to_string(qpath); + let path_str = rustc_hir_pretty::qpath_to_string(&tcx, qpath); let err = tcx .dcx() .struct_span_err(span, format!("expected {expected}, found {res_descr} `{path_str}`")) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index bb47f8dfba4..6981e0dceca 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1561,7 +1561,7 @@ fn error_tuple_variant_index_shorthand( { let has_shorthand_field_name = field_patterns.iter().any(|field| field.is_shorthand); if has_shorthand_field_name { - let path = rustc_hir_pretty::qpath_to_string(qpath); + let path = rustc_hir_pretty::qpath_to_string(&self.tcx, qpath); let mut err = struct_span_code_err!( self.dcx(), pat.span, @@ -1743,7 +1743,7 @@ fn error_tuple_variant_as_struct_pat( return None; } - let path = rustc_hir_pretty::qpath_to_string(qpath); + let path = rustc_hir_pretty::qpath_to_string(&self.tcx, qpath); let mut err = struct_span_code_err!( self.dcx(), pat.span, @@ -1793,7 +1793,7 @@ fn get_suggested_tuple_struct_pattern( f } } - Err(_) => rustc_hir_pretty::pat_to_string(field.pat), + Err(_) => rustc_hir_pretty::pat_to_string(&self.tcx, field.pat), } }) .collect::>() diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 6c3ff237d59..d1cdabc293d 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -25,6 +25,7 @@ rustc_feature = { path = "../rustc_feature" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } +rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_query_system = { path = "../rustc_query_system" } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 72f849b534a..399bbf166e6 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -13,6 +13,7 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_hir::intravisit::Visitor; use rustc_hir::*; +use rustc_hir_pretty as pprust_hir; use rustc_middle::hir::nested_filter; use rustc_span::def_id::StableCrateId; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -999,6 +1000,12 @@ fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> { } } +impl<'tcx> pprust_hir::PpAnn for TyCtxt<'tcx> { + fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { + pprust_hir::PpAnn::nested(&(&self.hir() as &dyn intravisit::Map<'_>), state, nested) + } +} + pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { let krate = tcx.hir_crate(()); let hir_body_hash = krate.opt_hir_hash.expect("HIR hash missing while computing crate hash"); diff --git a/tests/ui/consts/value-suggestion-ice-123906.stderr b/tests/ui/consts/value-suggestion-ice-123906.stderr index 8e2c316400d..779a40e2450 100644 --- a/tests/ui/consts/value-suggestion-ice-123906.stderr +++ b/tests/ui/consts/value-suggestion-ice-123906.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/value-suggestion-ice-123906.rs:3:9 | LL | fn as_chunks() -> [u8; N] { - | ------- expected `[u8; ]` because of this return type + | ------- expected `[u8; N]` because of this return type LL | loop { | ---- this loop is expected to be of type `[u8; N]` LL | break; diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs index 5c96c653df5..196da30b864 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs @@ -3,5 +3,5 @@ fn main() { //~^ ERROR expected a pattern, found an expression //~| ERROR cannot find type `T` in this scope //~| ERROR const and type arguments are not allowed on builtin type `str` -//~| ERROR expected unit struct, unit variant or constant, found associated function `str<, T>::as_bytes` +//~| ERROR expected unit struct, unit variant or constant, found associated function `str< } diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr index d62c019a1e1..8df0613695b 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr @@ -24,7 +24,9 @@ LL - let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; LL + let str::as_bytes; | -error[E0533]: expected unit struct, unit variant or constant, found associated function `str<, T>::as_bytes` +error[E0533]: expected unit struct, unit variant or constant, found associated function `str<{ + fn str() { let (/*ERROR*/); } + }, T>::as_bytes` --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:9 | LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; From 9d72808b1ea383628fcee2c09441bfce7c73ef51 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 14 Apr 2024 10:51:25 -0400 Subject: [PATCH 2/3] Add test --- tests/ui/enum/error-variant-with-turbofishes.rs | 8 ++++++++ tests/ui/enum/error-variant-with-turbofishes.stderr | 9 +++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/ui/enum/error-variant-with-turbofishes.rs create mode 100644 tests/ui/enum/error-variant-with-turbofishes.stderr diff --git a/tests/ui/enum/error-variant-with-turbofishes.rs b/tests/ui/enum/error-variant-with-turbofishes.rs new file mode 100644 index 00000000000..a58d24ce20a --- /dev/null +++ b/tests/ui/enum/error-variant-with-turbofishes.rs @@ -0,0 +1,8 @@ +enum Struct { Variant { x: [(); N] } } + +fn test() { + let x = Struct::<0>::Variant; + //~^ ERROR expected value, found struct variant `Struct<0>::Variant` +} + +fn main() {} diff --git a/tests/ui/enum/error-variant-with-turbofishes.stderr b/tests/ui/enum/error-variant-with-turbofishes.stderr new file mode 100644 index 00000000000..66bed1c0d85 --- /dev/null +++ b/tests/ui/enum/error-variant-with-turbofishes.stderr @@ -0,0 +1,9 @@ +error[E0533]: expected value, found struct variant `Struct<0>::Variant` + --> $DIR/error-variant-with-turbofishes.rs:4:13 + | +LL | let x = Struct::<0>::Variant; + | ^^^^^^^^^^^^^^^^^^^^ not a value + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0533`. From 2beb6a4782b484c8d5159beb8231a4e883bb1113 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 14 Apr 2024 11:04:18 -0400 Subject: [PATCH 3/3] Fix clippy --- src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs | 2 +- src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs | 2 +- src/tools/clippy/clippy_lints/src/mut_reference.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs index 68841076f77..2c168405ee2 100644 --- a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs @@ -77,7 +77,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) { let (help, final_suggestion) = if let Some(method) = omit_cast.corresponding_item() { // don't force absolute path - let method = qpath_to_string(method); + let method = qpath_to_string(&cx.tcx, method); ("try call directly", format!("{method}{turbofish}()")) } else { let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app); diff --git a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs index d1f637ec78c..310675d01a2 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs @@ -19,7 +19,7 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm<' if is_type_diagnostic_item(cx, ex_ty, sym::Result) { for arm in arms { if let PatKind::TupleStruct(ref path, inner, _) = arm.pat.kind { - let path_str = rustc_hir_pretty::qpath_to_string(path); + let path_str = rustc_hir_pretty::qpath_to_string(&cx.tcx, path); if path_str == "Err" { let mut matching_wild = inner.iter().any(is_wild); let mut ident_bind_name = kw::Underscore; diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs index 6867f76a723..0a3b769c3e6 100644 --- a/src/tools/clippy/clippy_lints/src/mut_reference.rs +++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs @@ -49,7 +49,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { cx, arguments.iter().collect(), cx.typeck_results().expr_ty(fn_expr), - &rustc_hir_pretty::qpath_to_string(path), + &rustc_hir_pretty::qpath_to_string(&cx.tcx, path), "function", ); }