From a97b41f1880f3aef9f4669ba56cf2e4d830825bc Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 19 Aug 2024 21:26:10 -0400 Subject: [PATCH 01/10] Use subtyping for UnsafeFnPointer coercion, too --- compiler/rustc_borrowck/src/type_check/mod.rs | 4 ++-- .../coercion/cast-higher-ranked-unsafe-fn-ptr.rs | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 tests/ui/coercion/cast-higher-ranked-unsafe-fn-ptr.rs diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 6983cda6ddf3b..3b3898ccd4da1 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2043,9 +2043,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig); - if let Err(terr) = self.eq_types( - *ty, + if let Err(terr) = self.sub_types( ty_fn_ptr_from, + *ty, location.to_locations(), ConstraintCategory::Cast { unsize_to: None }, ) { diff --git a/tests/ui/coercion/cast-higher-ranked-unsafe-fn-ptr.rs b/tests/ui/coercion/cast-higher-ranked-unsafe-fn-ptr.rs new file mode 100644 index 0000000000000..19723bee4d46e --- /dev/null +++ b/tests/ui/coercion/cast-higher-ranked-unsafe-fn-ptr.rs @@ -0,0 +1,14 @@ +//@ check-pass + +fn higher_ranked_fndef(ctx: &mut ()) {} + +fn test(higher_ranked_fnptr: fn(&mut ())) { + fn as_unsafe(_: unsafe fn(T)) {} + + // Make sure that we can cast higher-ranked fn items and pointers to + // a non-higher-ranked target. + as_unsafe(higher_ranked_fndef); + as_unsafe(higher_ranked_fnptr); +} + +fn main() {} From 147bb17f51b521269929f348b4b2a27afad8a273 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 24 Aug 2024 14:55:31 -0400 Subject: [PATCH 02/10] Rework how we emit errors for unresolved object lifetimes --- compiler/rustc_hir_analysis/src/collect.rs | 2 +- .../src/hir_ty_lowering/mod.rs | 7 ++-- .../src/hir_ty_lowering/object_safety.rs | 32 ++++++++++++------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index f75954c9edfb7..9e6c431a6e6a3 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -392,7 +392,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { } fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> { - if let RegionInferReason::BorrowedObjectLifetimeDefault = reason { + if let RegionInferReason::ObjectLifetimeDefault = reason { let e = struct_span_code_err!( self.dcx(), span, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 5c8ecf254a54e..73baa05bce660 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -85,10 +85,9 @@ pub enum PredicateFilter { #[derive(Debug)] pub enum RegionInferReason<'a> { - /// Lifetime on a trait object behind a reference. - /// This allows inferring information from the reference. - BorrowedObjectLifetimeDefault, - /// A trait object's lifetime. + /// Lifetime on a trait object that is spelled explicitly, e.g. `+ 'a` or `+ '_`. + ExplicitObjectLifetime, + /// A trait object's lifetime when it is elided, e.g. `dyn Any`. ObjectLifetimeDefault, /// Generic lifetime parameter Param(&'a ty::GenericParamDef), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index 31d1750f33dfd..082fbb2c41835 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -30,7 +30,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir_id: hir::HirId, hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)], lifetime: &hir::Lifetime, - borrowed: bool, + _borrowed: bool, representation: DynKind, ) -> Ty<'tcx> { let tcx = self.tcx(); @@ -325,22 +325,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { v.dedup(); let existential_predicates = tcx.mk_poly_existential_predicates(&v); - // Use explicitly-specified region bound. + // Use explicitly-specified region bound, unless the bound is missing. let region_bound = if !lifetime.is_elided() { - self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault) + self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime) } else { self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| { + // Curiously, we prefer object lifetime default for `+ '_`... if tcx.named_bound_var(lifetime.hir_id).is_some() { - self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault) + self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime) } else { - self.re_infer( - span, - if borrowed { - RegionInferReason::ObjectLifetimeDefault + let reason = + if let hir::LifetimeName::ImplicitObjectLifetimeDefault = lifetime.res { + if let hir::Node::Ty(hir::Ty { + kind: hir::TyKind::Ref(parent_lifetime, _), + .. + }) = tcx.parent_hir_node(hir_id) + && tcx.named_bound_var(parent_lifetime.hir_id).is_none() + { + // Parent lifetime must have failed to resolve. Don't emit a redundant error. + RegionInferReason::ExplicitObjectLifetime + } else { + RegionInferReason::ObjectLifetimeDefault + } } else { - RegionInferReason::BorrowedObjectLifetimeDefault - }, - ) + RegionInferReason::ExplicitObjectLifetime + }; + self.re_infer(span, reason) } }) }; From 6df0ccf49e7311ef0f81298edf0b77cd204c1ba3 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 24 Aug 2024 13:56:56 -0700 Subject: [PATCH 03/10] rustdoc: clean up tuple <-> primitive conversion docs This adds a minor missing feature to `fake_variadic`, so that it can render `impl From<(T,)> for [T; 1]` correctly. --- compiler/rustc_passes/src/check_attr.rs | 10 ++ library/core/src/tuple.rs | 36 ++++--- src/librustdoc/html/format.rs | 114 ++++++++++++++-------- tests/rustdoc/primitive-tuple-variadic.rs | 17 ++++ 4 files changed, 122 insertions(+), 55 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c93fb5c23b1c4..ffa406133cc43 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -951,6 +951,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> { bare_fn_ty.decl.inputs.len() == 1 } else { false + } + || if let Some(&[hir::GenericArg::Type(ty)]) = i + .of_trait + .as_ref() + .and_then(|trait_ref| trait_ref.path.segments.last()) + .map(|last_segment| last_segment.args().args) + { + matches!(&ty.kind, hir::TyKind::Tup([_])) + } else { + false }; if !is_valid { self.dcx().emit_err(errors::DocFakeVariadicNotValid { span: meta.span() }); diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 65d4d5cf2ce41..9ec92e2845034 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -122,23 +122,29 @@ macro_rules! tuple_impls { } } - #[stable(feature = "array_tuple_conv", since = "1.71.0")] - impl From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) { - #[inline] - #[allow(non_snake_case)] - fn from(array: [T; ${count($T)}]) -> Self { - let [$($T,)+] = array; - ($($T,)+) + maybe_tuple_doc! { + $($T)+ @ + #[stable(feature = "array_tuple_conv", since = "1.71.0")] + impl From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) { + #[inline] + #[allow(non_snake_case)] + fn from(array: [T; ${count($T)}]) -> Self { + let [$($T,)+] = array; + ($($T,)+) + } } } - #[stable(feature = "array_tuple_conv", since = "1.71.0")] - impl From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] { - #[inline] - #[allow(non_snake_case)] - fn from(tuple: ($(${ignore($T)} T,)+)) -> Self { - let ($($T,)+) = tuple; - [$($T,)+] + maybe_tuple_doc! { + $($T)+ @ + #[stable(feature = "array_tuple_conv", since = "1.71.0")] + impl From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] { + #[inline] + #[allow(non_snake_case)] + fn from(tuple: ($(${ignore($T)} T,)+)) -> Self { + let ($($T,)+) = tuple; + [$($T,)+] + } } } } @@ -148,7 +154,7 @@ macro_rules! tuple_impls { // Otherwise, it hides the docs entirely. macro_rules! maybe_tuple_doc { ($a:ident @ #[$meta:meta] $item:item) => { - #[doc(fake_variadic)] + #[cfg_attr(not(bootstrap), doc(fake_variadic))] #[doc = "This trait is implemented for tuples up to twelve items long."] #[$meta] $item diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 6357cfee141fd..5cbf8c5e19f45 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1288,56 +1288,90 @@ impl clean::Impl { if self.is_negative_trait_impl() { write!(f, "!")?; } - ty.print(cx).fmt(f)?; + if self.kind.is_fake_variadic() + && let generics = ty.generics() + && let &[inner_type] = generics.as_ref().map_or(&[][..], |v| &v[..]) + { + let last = ty.last(); + if f.alternate() { + write!(f, "{}<", last)?; + self.print_type(inner_type, f, use_absolute, cx)?; + write!(f, ">")?; + } else { + write!(f, "{}<", anchor(ty.def_id(), last, cx).to_string())?; + self.print_type(inner_type, f, use_absolute, cx)?; + write!(f, ">")?; + } + } else { + ty.print(cx).fmt(f)?; + } write!(f, " for ")?; } - if let clean::Type::Tuple(types) = &self.for_ - && let [clean::Type::Generic(name)] = &types[..] - && (self.kind.is_fake_variadic() || self.kind.is_auto()) - { - // Hardcoded anchor library/core/src/primitive_docs.rs - // Link should match `# Trait implementations` - primitive_link_fragment( - f, - PrimitiveType::Tuple, - format_args!("({name}₁, {name}₂, …, {name}ₙ)"), - "#trait-implementations-1", - cx, - )?; - } else if let clean::BareFunction(bare_fn) = &self.for_ - && let [clean::Argument { type_: clean::Type::Generic(name), .. }] = - &bare_fn.decl.inputs.values[..] - && (self.kind.is_fake_variadic() || self.kind.is_auto()) - { - // Hardcoded anchor library/core/src/primitive_docs.rs - // Link should match `# Trait implementations` - - print_higher_ranked_params_with_space(&bare_fn.generic_params, cx).fmt(f)?; - bare_fn.safety.print_with_space().fmt(f)?; - print_abi_with_space(bare_fn.abi).fmt(f)?; - let ellipsis = if bare_fn.decl.c_variadic { ", ..." } else { "" }; - primitive_link_fragment( - f, - PrimitiveType::Tuple, - format_args!("fn({name}₁, {name}₂, …, {name}ₙ{ellipsis})"), - "#trait-implementations-1", - cx, - )?; - // Write output. - if !bare_fn.decl.output.is_unit() { - write!(f, " -> ")?; - fmt_type(&bare_fn.decl.output, f, use_absolute, cx)?; - } - } else if let Some(ty) = self.kind.as_blanket_ty() { + if let Some(ty) = self.kind.as_blanket_ty() { fmt_type(ty, f, use_absolute, cx)?; } else { - fmt_type(&self.for_, f, use_absolute, cx)?; + self.print_type(&self.for_, f, use_absolute, cx)?; } print_where_clause(&self.generics, cx, 0, Ending::Newline).fmt(f) }) } + fn print_type<'a, 'tcx: 'a>( + &self, + type_: &clean::Type, + f: &mut fmt::Formatter<'_>, + use_absolute: bool, + cx: &'a Context<'tcx>, + ) -> Result<(), fmt::Error> { + if let clean::Type::Tuple(types) = type_ + && let [clean::Type::Generic(name)] = &types[..] + && (self.kind.is_fake_variadic() || self.kind.is_auto()) + { + // Hardcoded anchor library/core/src/primitive_docs.rs + // Link should match `# Trait implementations` + primitive_link_fragment( + f, + PrimitiveType::Tuple, + format_args!("({name}₁, {name}₂, …, {name}ₙ)"), + "#trait-implementations-1", + cx, + )?; + } else if let clean::Type::Array(ty, len) = type_ + && let clean::Type::Generic(name) = &**ty + && &len[..] == "1" + && (self.kind.is_fake_variadic() || self.kind.is_auto()) + { + primitive_link(f, PrimitiveType::Array, format_args!("[{name}; N]"), cx)?; + } else if let clean::BareFunction(bare_fn) = &type_ + && let [clean::Argument { type_: clean::Type::Generic(name), .. }] = + &bare_fn.decl.inputs.values[..] + && (self.kind.is_fake_variadic() || self.kind.is_auto()) + { + // Hardcoded anchor library/core/src/primitive_docs.rs + // Link should match `# Trait implementations` + + print_higher_ranked_params_with_space(&bare_fn.generic_params, cx).fmt(f)?; + bare_fn.safety.print_with_space().fmt(f)?; + print_abi_with_space(bare_fn.abi).fmt(f)?; + let ellipsis = if bare_fn.decl.c_variadic { ", ..." } else { "" }; + primitive_link_fragment( + f, + PrimitiveType::Tuple, + format_args!("fn({name}₁, {name}₂, …, {name}ₙ{ellipsis})"), + "#trait-implementations-1", + cx, + )?; + // Write output. + if !bare_fn.decl.output.is_unit() { + write!(f, " -> ")?; + fmt_type(&bare_fn.decl.output, f, use_absolute, cx)?; + } + } else { + fmt_type(&type_, f, use_absolute, cx)?; + } + Ok(()) + } } impl clean::Arguments { diff --git a/tests/rustdoc/primitive-tuple-variadic.rs b/tests/rustdoc/primitive-tuple-variadic.rs index 4b2fb786a8950..b15e996f929a9 100644 --- a/tests/rustdoc/primitive-tuple-variadic.rs +++ b/tests/rustdoc/primitive-tuple-variadic.rs @@ -16,3 +16,20 @@ pub trait Bar {} //@ has - '//section[@id="impl-Bar-for-(U,)"]/h3' 'impl Bar for (U₁, U₂, …, Uₙ)' #[doc(fake_variadic)] impl Bar for (U,) {} + +pub trait Baz { fn baz(&self) -> T { todo!() } } + +//@ has foo/trait.Baz.html +//@ has - '//section[@id="impl-Baz%3C(T,)%3E-for-%5BT;+1%5D"]/h3' 'impl Baz<(T₁, T₂, …, Tₙ)> for [T; N]' +#[doc(fake_variadic)] +impl Baz<(T,)> for [T; 1] {} + +//@ has foo/trait.Baz.html +//@ has - '//section[@id="impl-Baz%3C%5BT;+1%5D%3E-for-(T,)"]/h3' 'impl Baz<[T; N]> for (T₁, T₂, …, Tₙ)' +#[doc(fake_variadic)] +impl Baz<[T; 1]> for (T,) {} + +//@ has foo/trait.Baz.html +//@ has - '//section[@id="impl-Baz%3CT%3E-for-(T,)"]/h3' 'impl Baz for (T₁, T₂, …, Tₙ)' +#[doc(fake_variadic)] +impl Baz for (T,) {} From e7f11b6913eb1549847be2173a20d08f3cbf46ff Mon Sep 17 00:00:00 2001 From: mu001999 Date: Thu, 8 Aug 2024 08:17:55 +0800 Subject: [PATCH 04/10] Removes dead code from the compiler --- compiler/rustc_incremental/messages.ftl | 2 -- compiler/rustc_incremental/src/errors.rs | 7 ------- compiler/rustc_passes/messages.ftl | 4 ---- compiler/rustc_passes/src/errors.rs | 7 ------- .../src/maybe_transmutable/query_context.rs | 6 +----- library/alloc/tests/boxed.rs | 1 + 6 files changed, 2 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_incremental/messages.ftl b/compiler/rustc_incremental/messages.ftl index de2177ebb6e0f..2a65101d360d3 100644 --- a/compiler/rustc_incremental/messages.ftl +++ b/compiler/rustc_incremental/messages.ftl @@ -99,6 +99,4 @@ incremental_unrecognized_depnode = unrecognized `DepNode` variant: {$name} incremental_unrecognized_depnode_label = dep-node label `{$label}` not recognized -incremental_write_dep_graph = failed to write dependency graph to `{$path}`: {$err} - incremental_write_new = failed to write {$name} to `{$path}`: {$err} diff --git a/compiler/rustc_incremental/src/errors.rs b/compiler/rustc_incremental/src/errors.rs index b68c149d39823..c6f8b99bcd67b 100644 --- a/compiler/rustc_incremental/src/errors.rs +++ b/compiler/rustc_incremental/src/errors.rs @@ -272,13 +272,6 @@ pub struct LoadDepGraph { pub err: std::io::Error, } -#[derive(Diagnostic)] -#[diag(incremental_write_dep_graph)] -pub struct WriteDepGraph<'a> { - pub path: &'a Path, - pub err: std::io::Error, -} - #[derive(Diagnostic)] #[diag(incremental_move_dep_graph)] pub struct MoveDepGraph<'a> { diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index dfc726efeb998..bdc229a6c09e4 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -481,10 +481,6 @@ passes_must_not_suspend = `must_not_suspend` attribute should be applied to a struct, enum, union, or trait .label = is not a struct, enum, union, or trait -passes_must_use_async = - `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within - .label = this attribute does nothing, the `Future`s returned by async functions are already `must_use` - passes_must_use_no_effect = `#[must_use]` has no effect when applied to {$article} {$target} diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 1190e60f41f18..644ae23a761c3 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -371,13 +371,6 @@ pub struct FfiConstInvalidTarget { pub attr_span: Span, } -#[derive(LintDiagnostic)] -#[diag(passes_must_use_async)] -pub struct MustUseAsync { - #[label] - pub span: Span, -} - #[derive(LintDiagnostic)] #[diag(passes_must_use_no_effect)] pub struct MustUseNoEffect { diff --git a/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs b/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs index 95373916a71ae..f8b59bdf32684 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs @@ -4,7 +4,6 @@ use crate::layout; pub(crate) trait QueryContext { type Def: layout::Def; type Ref: layout::Ref; - type Scope: Copy; } #[cfg(test)] @@ -28,20 +27,17 @@ pub(crate) mod test { impl QueryContext for UltraMinimal { type Def = Def; type Ref = !; - type Scope = (); } } #[cfg(feature = "rustc")] mod rustc { - use rustc_middle::ty::{Ty, TyCtxt}; + use rustc_middle::ty::TyCtxt; use super::*; impl<'tcx> super::QueryContext for TyCtxt<'tcx> { type Def = layout::rustc::Def<'tcx>; type Ref = layout::rustc::Ref<'tcx>; - - type Scope = Ty<'tcx>; } } diff --git a/library/alloc/tests/boxed.rs b/library/alloc/tests/boxed.rs index faee64b2f6738..bfc31a626fadd 100644 --- a/library/alloc/tests/boxed.rs +++ b/library/alloc/tests/boxed.rs @@ -59,6 +59,7 @@ fn box_deref_lval() { assert_eq!(x.get(), 1000); } +#[allow(unused)] pub struct ConstAllocator; unsafe impl Allocator for ConstAllocator { From c29e328f6a2a3667034dc668c810373db7a68857 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Sat, 24 Aug 2024 21:55:16 +0300 Subject: [PATCH 05/10] gitignore: ignore ICE reports regardless of directory --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a36cb51de33ff..2e6499081a634 100644 --- a/.gitignore +++ b/.gitignore @@ -56,7 +56,9 @@ build/ /src/tools/x/target # Created by default with `src/ci/docker/run.sh` /obj/ -/rustc-ice* + +## ICE reports +rustc-ice-*.txt ## Temporary files *~ From ba24121ad6fef48793b6069e68a65a5a491272ef Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 25 Aug 2024 13:50:07 +0200 Subject: [PATCH 06/10] tweak rustc_allow_const_fn_unstable hint, and add back test for stable-const-can-only-call-stable-const --- compiler/rustc_const_eval/messages.ftl | 2 +- .../allow_const_fn_ptr_run_pass.rs | 2 -- .../min_const_fn_libstd_stability.rs | 4 +++- .../min_const_fn_libstd_stability.stderr | 18 +++++++++++++----- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 1442f1832b9b5..d7d64180ec9c1 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -419,7 +419,7 @@ const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn const_eval_unstable_in_stable = const-stable function cannot use `#[feature({$gate})]` .unstable_sugg = if it is not part of the public API, make this function unstably const - .bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks + .bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval) const_eval_unterminated_c_string = reading a null-terminated string starting at {$pointer} with no null found before end of allocation diff --git a/tests/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs b/tests/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs index a97eeadd92f4e..fe92787aec11b 100644 --- a/tests/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs +++ b/tests/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs @@ -1,6 +1,4 @@ //@ run-pass -#![feature(rustc_allow_const_fn_unstable)] - #![feature(rustc_attrs, staged_api)] #![stable(feature = "rust1", since = "1.0.0")] diff --git a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs index dc653370e5162..480b16b28a501 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs +++ b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs @@ -28,9 +28,11 @@ const fn bar2() -> u32 { foo2() } //~ ERROR not yet stable as a const fn // conformity is required const fn bar3() -> u32 { let x = std::cell::Cell::new(0u32); - x.get() + x.get(); //~^ ERROR const-stable function cannot use `#[feature(const_refs_to_cell)]` //~| ERROR cannot call non-const fn + foo() + //~^ ERROR is not yet stable as a const fn } // check whether this function cannot be called even with the feature gate active diff --git a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr index e5f8fa25b64ab..019deda063c78 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr +++ b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr @@ -17,7 +17,7 @@ LL | const fn bar2() -> u32 { foo2() } error: const-stable function cannot use `#[feature(const_refs_to_cell)]` --> $DIR/min_const_fn_libstd_stability.rs:31:5 | -LL | x.get() +LL | x.get(); | ^ | help: if it is not part of the public API, make this function unstably const @@ -25,7 +25,7 @@ help: if it is not part of the public API, make this function unstably const LL + #[rustc_const_unstable(feature = "...", issue = "...")] LL | const fn bar3() -> u32 { | -help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks +help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval) | LL + #[rustc_allow_const_fn_unstable(const_refs_to_cell)] LL | const fn bar3() -> u32 { @@ -34,19 +34,27 @@ LL | const fn bar3() -> u32 { error[E0015]: cannot call non-const fn `Cell::::get` in constant functions --> $DIR/min_const_fn_libstd_stability.rs:31:7 | -LL | x.get() +LL | x.get(); | ^^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +error: `foo` is not yet stable as a const fn + --> $DIR/min_const_fn_libstd_stability.rs:34:5 + | +LL | foo() + | ^^^^^ + | + = help: const-stable functions can only call other const-stable functions + error: `foo2_gated` is not yet stable as a const fn - --> $DIR/min_const_fn_libstd_stability.rs:43:32 + --> $DIR/min_const_fn_libstd_stability.rs:45:32 | LL | const fn bar2_gated() -> u32 { foo2_gated() } | ^^^^^^^^^^^^ | = help: const-stable functions can only call other const-stable functions -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0015`. From 8750e2424744f6365fbbfd3a42059eb51091e736 Mon Sep 17 00:00:00 2001 From: surechen Date: Thu, 22 Aug 2024 17:41:15 +0800 Subject: [PATCH 07/10] Fixing span manipulation and indentation of the suggestion introduced by #126187 According to comments: https://github.com/rust-lang/rust/pull/128084#issuecomment-2295254576 https://github.com/rust-lang/rust/pull/126187/files#r1634897691 --- .../src/error_reporting/traits/suggestions.rs | 11 +++++++--- ...turn-from-residual-sugg-issue-125997.fixed | 18 ++++++---------- ...urn-from-residual-sugg-issue-125997.stderr | 21 ++++++------------- .../ui/try-trait/try-operator-on-main.stderr | 2 -- 4 files changed, 20 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index a962be54c3d88..cc5b731a8d890 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -4667,10 +4667,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let hir::ExprKind::Block(b, _) = body.value.kind && b.expr.is_none() { + // The span of '}' in the end of block. + let span = self.tcx.sess.source_map().end_point(b.span); sugg_spans.push(( - // The span will point to the closing curly brace `}` of the block. - b.span.shrink_to_hi().with_lo(b.span.hi() - BytePos(1)), - "\n Ok(())\n}".to_string(), + span.shrink_to_lo(), + format!( + "{}{}", + " Ok(())\n", + self.tcx.sess.source_map().indentation_before(span).unwrap_or_default(), + ), )); } err.multipart_suggestion_verbose( diff --git a/tests/ui/return/return-from-residual-sugg-issue-125997.fixed b/tests/ui/return/return-from-residual-sugg-issue-125997.fixed index a5a133998259b..43a9907a9b496 100644 --- a/tests/ui/return/return-from-residual-sugg-issue-125997.fixed +++ b/tests/ui/return/return-from-residual-sugg-issue-125997.fixed @@ -9,7 +9,6 @@ use std::io::prelude::*; fn test1() -> Result<(), Box> { let mut _file = File::create("foo.txt")?; //~^ ERROR the `?` operator can only be used in a function - Ok(()) } @@ -17,7 +16,6 @@ fn test2() -> Result<(), Box> { let mut _file = File::create("foo.txt")?; //~^ ERROR the `?` operator can only be used in a function println!(); - Ok(()) } @@ -27,9 +25,8 @@ macro_rules! mac { let mut _file = File::create("foo.txt")?; //~^ ERROR the `?` operator can only be used in a function println!(); - - Ok(()) -} + Ok(()) + } }; } @@ -39,23 +36,20 @@ impl A { fn test4(&self) -> Result<(), Box> { let mut _file = File::create("foo.txt")?; //~^ ERROR the `?` operator can only be used in a method - - Ok(()) -} + Ok(()) + } fn test5(&self) -> Result<(), Box> { let mut _file = File::create("foo.txt")?; //~^ ERROR the `?` operator can only be used in a method println!(); - - Ok(()) -} + Ok(()) + } } fn main() -> Result<(), Box> { let mut _file = File::create("foo.txt")?; //~^ ERROR the `?` operator can only be used in a function mac!(); - Ok(()) } diff --git a/tests/ui/return/return-from-residual-sugg-issue-125997.stderr b/tests/ui/return/return-from-residual-sugg-issue-125997.stderr index a59f38c2ec644..e22f33fd242a6 100644 --- a/tests/ui/return/return-from-residual-sugg-issue-125997.stderr +++ b/tests/ui/return/return-from-residual-sugg-issue-125997.stderr @@ -12,9 +12,7 @@ help: consider adding return type LL ~ fn test1() -> Result<(), Box> { LL | let mut _file = File::create("foo.txt")?; LL | -LL + LL + Ok(()) -LL + } | error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) @@ -32,9 +30,7 @@ LL ~ fn test2() -> Result<(), Box> { LL | let mut _file = File::create("foo.txt")?; LL | LL | println!(); -LL + LL + Ok(()) -LL + } | error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `FromResidual`) @@ -51,9 +47,8 @@ help: consider adding return type LL ~ fn test4(&self) -> Result<(), Box> { LL | let mut _file = File::create("foo.txt")?; LL | -LL ~ -LL + Ok(()) -LL + } +LL ~ Ok(()) +LL ~ } | error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `FromResidual`) @@ -71,9 +66,8 @@ LL ~ fn test5(&self) -> Result<(), Box> { LL | let mut _file = File::create("foo.txt")?; LL | LL | println!(); -LL ~ -LL + Ok(()) -LL + } +LL ~ Ok(()) +LL ~ } | error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) @@ -91,9 +85,7 @@ LL ~ fn main() -> Result<(), Box> { LL | let mut _file = File::create("foo.txt")?; LL | LL | mac!(); -LL + LL + Ok(()) -LL + } | error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) @@ -115,9 +107,8 @@ LL ~ fn test3() -> Result<(), Box> { LL | let mut _file = File::create("foo.txt")?; LL | LL | println!(); -LL ~ -LL + Ok(()) -LL + } +LL ~ Ok(()) +LL ~ } | error: aborting due to 6 previous errors diff --git a/tests/ui/try-trait/try-operator-on-main.stderr b/tests/ui/try-trait/try-operator-on-main.stderr index d22117165c12b..311e8076ed48e 100644 --- a/tests/ui/try-trait/try-operator-on-main.stderr +++ b/tests/ui/try-trait/try-operator-on-main.stderr @@ -14,9 +14,7 @@ LL ~ fn main() -> Result<(), Box> { LL | // error for a `Try` type on a non-`Try` fn ... LL | try_trait_generic::<()>(); -LL + LL + Ok(()) -LL + } | error[E0277]: the `?` operator can only be applied to values that implement `Try` From 48f43fa0ed2f2e4ff2d9d53b9d72cfbc108a9034 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 25 Aug 2024 16:02:11 -0400 Subject: [PATCH 08/10] Avoid taking reference of &TyKind --- compiler/rustc_borrowck/src/borrowck_errors.rs | 2 +- compiler/rustc_borrowck/src/places_conflict.rs | 2 +- compiler/rustc_const_eval/src/interpret/cast.rs | 6 +++--- compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs | 2 +- compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 4 ++-- compiler/rustc_hir_typeck/src/method/suggest.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 2 +- compiler/rustc_middle/src/ty/layout.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 2 +- compiler/rustc_mir_build/src/build/expr/as_constant.rs | 2 +- compiler/rustc_mir_build/src/thir/constant.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 4 ++-- .../src/error_reporting/infer/suggest.rs | 2 +- 14 files changed, 18 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 76e39fe94af43..70f89e80dc94d 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -290,7 +290,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { ty: Ty<'_>, is_index: Option, ) -> Diag<'infcx> { - let type_name = match (&ty.kind(), is_index) { + let type_name = match (ty.kind(), is_index) { (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array", (&ty::Slice(_), _) => "slice", _ => span_bug!(move_from_span, "this path should not cause illegal move"), diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index 42d0c2038f8bb..311f17f15b9ee 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -201,7 +201,7 @@ fn place_components_conflict<'tcx>( let base_ty = base.ty(body, tcx).ty; - match (elem, &base_ty.kind(), access) { + match (elem, base_ty.kind(), access) { (_, _, Shallow(Some(ArtificialField::ArrayLength))) | (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => { // The array length is like additional fields on the diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 4901e4b2a4158..e8c9f145eea55 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -388,7 +388,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let (src_pointee_ty, dest_pointee_ty) = self.tcx.struct_lockstep_tails_for_codegen(source_ty, cast_ty, self.param_env); - match (&src_pointee_ty.kind(), &dest_pointee_ty.kind()) { + match (src_pointee_ty.kind(), dest_pointee_ty.kind()) { (&ty::Array(_, length), &ty::Slice(_)) => { let ptr = self.read_pointer(src)?; let val = Immediate::new_slice( @@ -478,9 +478,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { dest: &PlaceTy<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { trace!("Unsizing {:?} of type {} into {}", *src, src.layout.ty, cast_ty.ty); - match (&src.layout.ty.kind(), &cast_ty.ty.kind()) { + match (src.layout.ty.kind(), cast_ty.ty.kind()) { (&ty::Ref(_, s, _), &ty::Ref(_, c, _) | &ty::RawPtr(c, _)) - | (&ty::RawPtr(s, _), &ty::RawPtr(c, _)) => self.unsize_into_ptr(src, dest, *s, *c), + | (&ty::RawPtr(s, _), &ty::RawPtr(c, _)) => self.unsize_into_ptr(src, dest, s, c), (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { assert_eq!(def_a, def_b); // implies same number of fields diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index d77cbe3053653..af319fd53bde7 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -608,7 +608,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| { let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation }); - match &self_ty.kind() { + match self_ty.kind() { // Point at the type that couldn't satisfy the bound. ty::Adt(def, _) => { bound_spans.get_mut_or_insert_default(tcx.def_span(def.did())).push(msg) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 5c8ecf254a54e..d1a0da47b3d18 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1057,7 +1057,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Find the type of the associated item, and the trait where the associated // item is declared. - let bound = match (&qself_ty.kind(), qself_res) { + let bound = match (qself_ty.kind(), qself_res) { (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => { // `Self` in an impl of a trait -- we have a concrete self type and a // trait reference. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 703273968c5bb..11c6e65a21101 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2975,7 +2975,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut suffix_suggestion = sugg.clone(); suffix_suggestion.push(( if matches!( - (&expected_ty.kind(), &checked_ty.kind()), + (expected_ty.kind(), checked_ty.kind()), (ty::Int(_) | ty::Uint(_), ty::Float(_)) ) { // Remove fractional part from literal, for example `42.0f32` into `42` @@ -3077,7 +3077,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.multipart_suggestion_verbose(msg, suggestion, Applicability::MachineApplicable); }; - match (&expected_ty.kind(), &checked_ty.kind()) { + match (expected_ty.kind(), checked_ty.kind()) { (ty::Int(exp), ty::Int(found)) => { let (f2e_is_fallible, e2f_is_fallible) = match (exp.bit_width(), found.bit_width()) { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 3df32dd85052b..ffd46ea13b908 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1012,7 +1012,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| { let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation }); - match &self_ty.kind() { + match self_ty.kind() { // Point at the type that couldn't satisfy the bound. ty::Adt(def, _) => { bound_spans.get_mut_or_insert_default(tcx.def_span(def.did())).push(msg) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index c4f74adb4207b..a8e5e09c8bbeb 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1336,7 +1336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // More generally, the expected type wants a tuple variant with one field of an // N-arity-tuple, e.g., `V_i((p_0, .., p_N))`. Meanwhile, the user supplied a pattern // with the subpatterns directly in the tuple variant pattern, e.g., `V_i(p_0, .., p_N)`. - let missing_parentheses = match (&expected.kind(), fields, had_err) { + let missing_parentheses = match (expected.kind(), fields, had_err) { // #67037: only do this if we could successfully type-check the expected type against // the tuple struct pattern. Otherwise the args could get out of range on e.g., // `let P() = U;` where `P != U` with `struct P(T);`. diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 619981bf021e4..d0a9039441dc4 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1104,7 +1104,7 @@ where } fn is_never(this: TyAndLayout<'tcx>) -> bool { - this.ty.kind() == &ty::Never + matches!(this.ty.kind(), ty::Never) } fn is_tuple(this: TyAndLayout<'tcx>) -> bool { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 045c8ad39bee2..efbccca77c1f0 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -296,7 +296,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> (Ty<'tcx>, Ty<'tcx>) { let (mut a, mut b) = (source, target); loop { - match (&a.kind(), &b.kind()) { + match (a.kind(), b.kind()) { (&ty::Adt(a_def, a_args), &ty::Adt(b_def, b_args)) if a_def == b_def && a_def.is_struct() => { diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 4430aab73a819..4f1166f91118e 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -127,7 +127,7 @@ fn lit_to_mir_constant<'tcx>( Ok(ConstValue::Scalar(Scalar::from_uint(result, width))) }; - let value = match (lit, &ty.kind()) { + let value = match (lit, ty.kind()) { (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => { let s = s.as_str(); let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes()); diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 7b94867114d5a..b8877a64e47eb 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -29,7 +29,7 @@ pub(crate) fn lit_to_const<'tcx>( .unwrap_or_else(|| bug!("expected to create ScalarInt from uint {:?}", result))) }; - let valtree = match (lit, &ty.kind()) { + let valtree = match (lit, ty.kind()) { (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => { let str_bytes = s.as_str().as_bytes(); ty::ValTree::from_raw_bytes(tcx, str_bytes) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 77f6a1e17cefc..ff4207fbefda8 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1035,9 +1035,9 @@ fn find_vtable_types_for_unsizing<'tcx>( } }; - match (&source_ty.kind(), &target_ty.kind()) { + match (source_ty.kind(), target_ty.kind()) { (&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(b, _)) - | (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => ptr_vtable(*a, *b), + | (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => ptr_vtable(a, b), (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) if def_a.is_box() && def_b.is_box() => { ptr_vtable(source_ty.boxed_ty(), target_ty.boxed_ty()) } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index 35f68a56d2ddc..ba656493d462d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -382,7 +382,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if !expected_inner.is_fn() || !found_inner.is_fn() { return; } - match (&expected_inner.kind(), &found_inner.kind()) { + match (expected_inner.kind(), found_inner.kind()) { (ty::FnPtr(sig_tys, hdr), ty::FnDef(did, args)) => { let sig = sig_tys.with(*hdr); let expected_sig = &(self.normalize_fn_sig)(sig); From ecd2d115736581726ee9b77432561ea9480b3241 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 24 Aug 2024 15:03:51 -0400 Subject: [PATCH 09/10] Remove redundant flags that can be inferred from the HIR --- .../src/hir_ty_lowering/lint.rs | 21 +++++++++++---- .../src/hir_ty_lowering/mod.rs | 27 ++++--------------- .../src/hir_ty_lowering/object_safety.rs | 1 - .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- .../suggest-dyn-on-bare-trait-in-pat.rs | 14 ++++++++++ .../suggest-dyn-on-bare-trait-in-pat.stderr | 14 ++++++++++ 6 files changed, 50 insertions(+), 29 deletions(-) create mode 100644 tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.rs create mode 100644 tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 6aff518390ffc..7be45463f1512 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -15,11 +15,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// /// *Bare* trait object types are ones that aren't preceded by the keyword `dyn`. /// In edition 2021 and onward we emit a hard error for them. - pub(super) fn prohibit_or_lint_bare_trait_object_ty( - &self, - self_ty: &hir::Ty<'_>, - in_path: bool, - ) { + pub(super) fn prohibit_or_lint_bare_trait_object_ty(&self, self_ty: &hir::Ty<'_>) { let tcx = self.tcx(); let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) = @@ -28,6 +24,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { return; }; + let in_path = match tcx.parent_hir_node(self_ty.hir_id) { + hir::Node::Ty(hir::Ty { + kind: hir::TyKind::Path(hir::QPath::TypeRelative(qself, _)), + .. + }) + | hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Path(hir::QPath::TypeRelative(qself, _)), + .. + }) + | hir::Node::Pat(hir::Pat { + kind: hir::PatKind::Path(hir::QPath::TypeRelative(qself, _)), + .. + }) if qself.hir_id == self_ty.hir_id => true, + _ => false, + }; let needs_bracket = in_path && !tcx .sess diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 73baa05bce660..010d58bfb673c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1998,16 +1998,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } - /// Lower a type from the HIR to our internal notion of a type. - pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { - self.lower_ty_common(hir_ty, false, false) - } - - /// Lower a type inside of a path from the HIR to our internal notion of a type. - pub fn lower_ty_in_path(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { - self.lower_ty_common(hir_ty, false, true) - } - fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> { let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id()); match idx { @@ -2025,7 +2015,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// 2. `in_path`: Whether the type appears inside of a path. /// Used to provide correct diagnostics for bare trait object types. #[instrument(level = "debug", skip(self), ret)] - fn lower_ty_common(&self, hir_ty: &hir::Ty<'tcx>, borrowed: bool, in_path: bool) -> Ty<'tcx> { + pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { let tcx = self.tcx(); let result_ty = match &hir_ty.kind { @@ -2035,7 +2025,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::TyKind::Ref(region, mt) => { let r = self.lower_lifetime(region, RegionInferReason::Reference); debug!(?r); - let t = self.lower_ty_common(mt.ty, true, false); + let t = self.lower_ty(mt.ty); Ty::new_ref(tcx, r, t, mt.mutbl) } hir::TyKind::Never => tcx.types.never, @@ -2064,20 +2054,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) } hir::TyKind::TraitObject(bounds, lifetime, repr) => { - self.prohibit_or_lint_bare_trait_object_ty(hir_ty, in_path); + self.prohibit_or_lint_bare_trait_object_ty(hir_ty); let repr = match repr { TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn, TraitObjectSyntax::DynStar => ty::DynStar, }; - self.lower_trait_object_ty( - hir_ty.span, - hir_ty.hir_id, - bounds, - lifetime, - borrowed, - repr, - ) + self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr) } hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => { debug!(?maybe_qself, ?path); @@ -2105,7 +2088,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } hir::TyKind::Path(hir::QPath::TypeRelative(qself, segment)) => { debug!(?qself, ?segment); - let ty = self.lower_ty_common(qself, false, true); + let ty = self.lower_ty(qself); self.lower_assoc_path(hir_ty.hir_id, hir_ty.span, ty, qself, segment, false) .map(|(ty, _, _)| ty) .unwrap_or_else(|guar| Ty::new_error(tcx, guar)) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index 082fbb2c41835..52e167379b5dd 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -30,7 +30,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir_id: hir::HirId, hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)], lifetime: &hir::Lifetime, - _borrowed: bool, representation: DynKind, ) -> Ty<'tcx> { let tcx = self.tcx(); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index b169f75796b3a..21e6ac9332cdf 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -798,7 +798,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // to be object-safe. // We manually call `register_wf_obligation` in the success path // below. - let ty = self.lowerer().lower_ty_in_path(qself); + let ty = self.lowerer().lower_ty(qself); (LoweredTy::from_raw(self, span, ty), qself, segment) } QPath::LangItem(..) => { diff --git a/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.rs b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.rs new file mode 100644 index 0000000000000..19b5edb620f6b --- /dev/null +++ b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.rs @@ -0,0 +1,14 @@ +//@ edition: 2021 + +trait Trait {} + +impl dyn Trait { + const CONST: () = (); +} + +fn main() { + match () { + Trait::CONST => {} + //~^ ERROR trait objects must include the `dyn` keyword + } +} diff --git a/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr new file mode 100644 index 0000000000000..4446a89b63b15 --- /dev/null +++ b/tests/ui/dyn-keyword/suggest-dyn-on-bare-trait-in-pat.stderr @@ -0,0 +1,14 @@ +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/suggest-dyn-on-bare-trait-in-pat.rs:11:9 + | +LL | Trait::CONST => {} + | ^^^^^ + | +help: add `dyn` keyword before this trait + | +LL | ::CONST => {} + | ++++ + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0782`. From 1c58522068f36625c5a0deaafdb1411aafe541f9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 24 Aug 2024 16:57:47 -0400 Subject: [PATCH 10/10] Use FxHasher on new solver unconditionally --- Cargo.lock | 1 + compiler/rustc_type_ir/Cargo.toml | 1 + compiler/rustc_type_ir/src/data_structures.rs | 15 +++++++++------ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f2e2baea8e47c..24164470bf059 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4543,6 +4543,7 @@ dependencies = [ "bitflags 2.6.0", "derive-where", "indexmap", + "rustc-hash", "rustc_ast_ir", "rustc_data_structures", "rustc_index", diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 2750838bbe99f..0ffad8b87aafe 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" bitflags = "2.4.1" derive-where = "1.2.7" indexmap = "2.0.0" +rustc-hash = "1.1.0" rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false } rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } diff --git a/compiler/rustc_type_ir/src/data_structures.rs b/compiler/rustc_type_ir/src/data_structures.rs index 4ca97c0c86c0f..96036e53b0abb 100644 --- a/compiler/rustc_type_ir/src/data_structures.rs +++ b/compiler/rustc_type_ir/src/data_structures.rs @@ -1,8 +1,13 @@ +use std::hash::BuildHasherDefault; + +use rustc_hash::FxHasher; +pub use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet}; + +pub type IndexMap = indexmap::IndexMap>; +pub type IndexSet = indexmap::IndexSet>; + #[cfg(feature = "nightly")] mod impl_ { - pub use rustc_data_structures::fx::{ - FxHashMap as HashMap, FxHashSet as HashSet, FxIndexMap as IndexMap, FxIndexSet as IndexSet, - }; pub use rustc_data_structures::sso::{SsoHashMap, SsoHashSet}; pub use rustc_data_structures::stack::ensure_sufficient_stack; pub use rustc_data_structures::sync::Lrc; @@ -10,11 +15,9 @@ mod impl_ { #[cfg(not(feature = "nightly"))] mod impl_ { - pub use std::collections::{HashMap, HashMap as SsoHashMap, HashSet, HashSet as SsoHashSet}; + pub use std::collections::{HashMap as SsoHashMap, HashSet as SsoHashSet}; pub use std::sync::Arc as Lrc; - pub use indexmap::{IndexMap, IndexSet}; - #[inline] pub fn ensure_sufficient_stack(f: impl FnOnce() -> R) -> R { f() pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy