diff options
| author | bors <bors@rust-lang.org> | 2024-04-03 02:13:07 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-04-03 02:13:07 +0000 |
| commit | b688d53a1736c17e49328a706a90829a9937a91a (patch) | |
| tree | 6e0c24f050e861b05aef27b8f2c7ba4ff1b061d2 /compiler | |
| parent | 40f743da23d869c57556bca473c0d360f8528f94 (diff) | |
| parent | f756095571c949c3c6f3b18f26c58d9cee92651a (diff) | |
| download | rust-b688d53a1736c17e49328a706a90829a9937a91a.tar.gz rust-b688d53a1736c17e49328a706a90829a9937a91a.zip | |
Auto merge of #123396 - jhpratt:rollup-oa54mh1, r=jhpratt
Rollup of 5 pull requests Successful merges: - #122865 (Split hir ty lowerer's error reporting code in check functions to mod errors.) - #122935 (rename ptr::from_exposed_addr -> ptr::with_exposed_provenance) - #123182 (Avoid expanding to unstable internal method) - #123203 (Add `Context::ext`) - #123380 (Improve bootstrap comments) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
23 files changed, 508 insertions, 377 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index b0bdf4af097..6405364c30c 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2279,7 +2279,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - CastKind::PointerFromExposedAddress => { + CastKind::PointerWithExposedProvenance => { let ty_from = op.ty(body, tcx); let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); @@ -2289,7 +2289,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span_mirbug!( self, rvalue, - "Invalid PointerFromExposedAddress cast {:?} -> {:?}", + "Invalid PointerWithExposedProvenance cast {:?} -> {:?}", ty_from, ty ) diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 8d0b84f62dc..249c16898ce 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -650,7 +650,7 @@ fn codegen_stmt<'tcx>( | CastKind::FnPtrToPtr | CastKind::PtrToPtr | CastKind::PointerExposeAddress - | CastKind::PointerFromExposedAddress, + | CastKind::PointerWithExposedProvenance, ref operand, to_ty, ) => { diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 4d55a95aa9d..783ad5d1dd1 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -965,7 +965,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }); } - sym::simd_expose_addr | sym::simd_from_exposed_addr | sym::simd_cast_ptr => { + sym::simd_expose_addr | sym::simd_with_exposed_provenance | sym::simd_cast_ptr => { intrinsic_args!(fx, args => (arg); intrinsic); ret.write_cvalue_transmute(fx, arg); } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index ab135e3ed64..e4ec7974e90 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -2139,7 +2139,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( return Ok(bx.ptrtoint(args[0].immediate(), llret_ty)); } - if name == sym::simd_from_exposed_addr { + if name == sym::simd_with_exposed_provenance { let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn); require!( in_len == out_len, diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 0e4018e44b7..6f7b98a262d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -509,7 +509,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Since int2ptr can have arbitrary integer types as input (so we have to do // sign extension and all that), it is currently best handled in the same code // path as the other integer-to-X casts. - | mir::CastKind::PointerFromExposedAddress => { + | mir::CastKind::PointerWithExposedProvenance => { assert!(bx.cx().is_backend_immediate(cast)); let ll_t_out = bx.cx().immediate_backend_type(cast); if operand.layout.abi.is_uninhabited() { diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index bbf11f169f9..e0d45f1fe11 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -40,9 +40,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_immediate(*res, dest)?; } - CastKind::PointerFromExposedAddress => { + CastKind::PointerWithExposedProvenance => { let src = self.read_immediate(src)?; - let res = self.pointer_from_exposed_address_cast(&src, cast_layout)?; + let res = self.pointer_with_exposed_provenance_cast(&src, cast_layout)?; self.write_immediate(*res, dest)?; } @@ -242,7 +242,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(ImmTy::from_scalar(self.cast_from_int_like(scalar, src.layout, cast_to.ty)?, cast_to)) } - pub fn pointer_from_exposed_address_cast( + pub fn pointer_with_exposed_provenance_cast( &self, src: &ImmTy<'tcx, M::Provenance>, cast_to: TyAndLayout<'tcx>, diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index da8e28d0298..b6dcc334147 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -547,7 +547,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => { self.check_op(ops::RawPtrToIntCast); } - Rvalue::Cast(CastKind::PointerFromExposedAddress, _, _) => { + Rvalue::Cast(CastKind::PointerWithExposedProvenance, _, _) => { // Since no pointer can ever get exposed (rejected above), this is easy to support. } diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 1388e08e2d5..e1e98ebc1e9 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -1076,7 +1076,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // FIXME(dyn-star): make sure nothing needs to be done here. } // FIXME: Add Checks for these - CastKind::PointerFromExposedAddress + CastKind::PointerWithExposedProvenance | CastKind::PointerExposeAddress | CastKind::PointerCoercion(_) => {} CastKind::IntToInt | CastKind::IntToFloat => { diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 30559871b4e..cdcf67b26f8 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -48,6 +48,23 @@ impl<'a> ExtCtxt<'a> { ast::Path { span, segments, tokens: None } } + pub fn macro_call( + &self, + span: Span, + path: ast::Path, + delim: ast::token::Delimiter, + tokens: ast::tokenstream::TokenStream, + ) -> P<ast::MacCall> { + P(ast::MacCall { + path, + args: P(ast::DelimArgs { + dspan: ast::tokenstream::DelimSpan { open: span, close: span }, + delim, + tokens, + }), + }) + } + pub fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy { ast::MutTy { ty, mutbl } } @@ -265,6 +282,10 @@ impl<'a> ExtCtxt<'a> { self.expr(span, ast::ExprKind::Field(expr, field)) } + pub fn expr_macro_call(&self, span: Span, call: P<ast::MacCall>) -> P<ast::Expr> { + self.expr(span, ast::ExprKind::MacCall(call)) + } + pub fn expr_binary( &self, sp: Span, @@ -410,18 +431,21 @@ impl<'a> ExtCtxt<'a> { self.expr(sp, ast::ExprKind::Tup(exprs)) } - pub fn expr_fail(&self, span: Span, msg: Symbol) -> P<ast::Expr> { - self.expr_call_global( + pub fn expr_unreachable(&self, span: Span) -> P<ast::Expr> { + self.expr_macro_call( span, - [sym::std, sym::rt, sym::begin_panic].iter().map(|s| Ident::new(*s, span)).collect(), - thin_vec![self.expr_str(span, msg)], + self.macro_call( + span, + self.path_global( + span, + [sym::std, sym::unreachable].map(|s| Ident::new(s, span)).to_vec(), + ), + ast::token::Delimiter::Parenthesis, + ast::tokenstream::TokenStream::default(), + ), ) } - pub fn expr_unreachable(&self, span: Span) -> P<ast::Expr> { - self.expr_fail(span, Symbol::intern("internal error: entered unreachable code")) - } - pub fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); self.expr_call_global(sp, ok, thin_vec![expr]) diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index ddea6044f92..00a0fca4907 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -628,7 +628,7 @@ pub fn check_intrinsic_type( | sym::simd_as | sym::simd_cast_ptr | sym::simd_expose_addr - | sym::simd_from_exposed_addr => (2, 0, vec![param(0)], param(1)), + | sym::simd_with_exposed_provenance => (2, 0, vec![param(0)], param(1)), sym::simd_bitmask => (2, 0, vec![param(0)], param(1)), sym::simd_select | sym::simd_select_bitmask => { (2, 0, vec![param(0), param(1), param(1)], param(1)) 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 ca2e14ee359..7a0890e50da 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -1,6 +1,6 @@ use crate::errors::{ self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams, - ParenthesizedFnTraitExpansion, + ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits, }; use crate::fluent_generated as fluent; use crate::hir_ty_lowering::HirTyLowerer; @@ -8,19 +8,26 @@ use crate::traits::error_reporting::report_object_safety_error; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::unord::UnordMap; +use rustc_errors::MultiSpan; use rustc_errors::{ codes::*, pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, }; use rustc_hir as hir; +use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::traits::FulfillmentError; use rustc_middle::query::Key; -use rustc_middle::ty::{self, suggest_constraining_type_param, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, suggest_constraining_type_param}; +use rustc_middle::ty::{AdtDef, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{Binder, TraitRef}; use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; -use rustc_span::symbol::{sym, Ident}; +use rustc_span::symbol::{kw, sym, Ident}; +use rustc_span::BytePos; use rustc_span::{Span, Symbol, DUMMY_SP}; -use rustc_trait_selection::traits::object_safety_violations_for_assoc_item; +use rustc_trait_selection::traits::{ + object_safety_violations_for_assoc_item, TraitAliasExpansionInfo, +}; impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// On missing type parameters, emit an E0393 error and provide a structured suggestion using @@ -1024,6 +1031,170 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Ok(()) } } + + pub fn report_prohibit_generics_error<'a>( + &self, + segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone, + args_visitors: impl Iterator<Item = &'a hir::GenericArg<'a>> + Clone, + err_extend: GenericsArgsErrExtend<'_>, + ) -> ErrorGuaranteed { + #[derive(PartialEq, Eq, Hash)] + enum ProhibitGenericsArg { + Lifetime, + Type, + Const, + Infer, + } + + let mut prohibit_args = FxIndexSet::default(); + args_visitors.for_each(|arg| { + match arg { + hir::GenericArg::Lifetime(_) => prohibit_args.insert(ProhibitGenericsArg::Lifetime), + hir::GenericArg::Type(_) => prohibit_args.insert(ProhibitGenericsArg::Type), + hir::GenericArg::Const(_) => prohibit_args.insert(ProhibitGenericsArg::Const), + hir::GenericArg::Infer(_) => prohibit_args.insert(ProhibitGenericsArg::Infer), + }; + }); + + let types_and_spans: Vec<_> = segments + .clone() + .flat_map(|segment| { + if segment.args().args.is_empty() { + None + } else { + Some(( + match segment.res { + hir::def::Res::PrimTy(ty) => { + format!("{} `{}`", segment.res.descr(), ty.name()) + } + hir::def::Res::Def(_, def_id) + if let Some(name) = self.tcx().opt_item_name(def_id) => + { + format!("{} `{name}`", segment.res.descr()) + } + hir::def::Res::Err => "this type".to_string(), + _ => segment.res.descr().to_string(), + }, + segment.ident.span, + )) + } + }) + .collect(); + let this_type = match &types_and_spans[..] { + [.., _, (last, _)] => format!( + "{} and {last}", + types_and_spans[..types_and_spans.len() - 1] + .iter() + .map(|(x, _)| x.as_str()) + .intersperse(", ") + .collect::<String>() + ), + [(only, _)] => only.to_string(), + [] => "this type".to_string(), + }; + + let arg_spans: Vec<Span> = segments + .clone() + .flat_map(|segment| segment.args().args) + .map(|arg| arg.span()) + .collect(); + + let mut kinds = Vec::with_capacity(4); + prohibit_args.iter().for_each(|arg| match arg { + ProhibitGenericsArg::Lifetime => kinds.push("lifetime"), + ProhibitGenericsArg::Type => kinds.push("type"), + ProhibitGenericsArg::Const => kinds.push("const"), + ProhibitGenericsArg::Infer => kinds.push("generic"), + }); + + let (kind, s) = match kinds[..] { + [.., _, last] => ( + format!( + "{} and {last}", + kinds[..kinds.len() - 1] + .iter() + .map(|&x| x) + .intersperse(", ") + .collect::<String>() + ), + "s", + ), + [only] => (only.to_string(), ""), + [] => unreachable!("expected at least one generic to prohibit"), + }; + let last_span = *arg_spans.last().unwrap(); + let span: MultiSpan = arg_spans.into(); + let mut err = struct_span_code_err!( + self.tcx().dcx(), + span, + E0109, + "{kind} arguments are not allowed on {this_type}", + ); + err.span_label(last_span, format!("{kind} argument{s} not allowed")); + for (what, span) in types_and_spans { + err.span_label(span, format!("not allowed on {what}")); + } + generics_args_err_extend(self.tcx(), segments.clone(), &mut err, err_extend); + let reported = err.emit(); + self.set_tainted_by_errors(reported); + reported + } + + pub fn report_trait_object_addition_traits_error( + &self, + regular_traits: &Vec<TraitAliasExpansionInfo<'_>>, + ) -> ErrorGuaranteed { + let tcx = self.tcx(); + let first_trait = ®ular_traits[0]; + let additional_trait = ®ular_traits[1]; + let mut err = struct_span_code_err!( + tcx.dcx(), + additional_trait.bottom().1, + E0225, + "only auto traits can be used as additional traits in a trait object" + ); + additional_trait.label_with_exp_info( + &mut err, + "additional non-auto trait", + "additional use", + ); + first_trait.label_with_exp_info(&mut err, "first non-auto trait", "first use"); + err.help(format!( + "consider creating a new trait with all of these as supertraits and using that \ + trait here instead: `trait NewTrait: {} {{}}`", + regular_traits + .iter() + // FIXME: This should `print_sugared`, but also needs to integrate projection bounds... + .map(|t| t.trait_ref().print_only_trait_path().to_string()) + .collect::<Vec<_>>() + .join(" + "), + )); + err.note( + "auto-traits like `Send` and `Sync` are traits that have special properties; \ + for more information on them, visit \ + <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>", + ); + let reported = err.emit(); + self.set_tainted_by_errors(reported); + reported + } + + pub fn report_trait_object_with_no_traits_error( + &self, + span: Span, + trait_bounds: &Vec<(Binder<'tcx, TraitRef<'tcx>>, Span)>, + ) -> ErrorGuaranteed { + let tcx = self.tcx(); + let trait_alias_span = trait_bounds + .iter() + .map(|&(trait_ref, _)| trait_ref.def_id()) + .find(|&trait_ref| tcx.is_trait_alias(trait_ref)) + .map(|trait_ref| tcx.def_span(trait_ref)); + let reported = + tcx.dcx().emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }); + self.set_tainted_by_errors(reported); + reported + } } /// Emits an error regarding forbidden type binding associations @@ -1031,7 +1202,7 @@ pub fn prohibit_assoc_item_binding( tcx: TyCtxt<'_>, span: Span, segment: Option<(&hir::PathSegment<'_>, Span)>, -) { +) -> ErrorGuaranteed { tcx.dcx().emit_err(AssocTypeBindingNotAllowed { span, fn_trait_expansion: if let Some((segment, span)) = segment @@ -1044,7 +1215,7 @@ pub fn prohibit_assoc_item_binding( } else { None }, - }); + }) } pub(crate) fn fn_trait_to_string( @@ -1099,3 +1270,208 @@ pub(crate) fn fn_trait_to_string( format!("{}<{}, Output={}>", trait_segment.ident, args, ret) } } + +/// Used for generics args error extend. +pub enum GenericsArgsErrExtend<'tcx> { + EnumVariant { + qself: &'tcx hir::Ty<'tcx>, + assoc_segment: &'tcx hir::PathSegment<'tcx>, + adt_def: AdtDef<'tcx>, + }, + OpaqueTy, + PrimTy(hir::PrimTy), + SelfTyAlias { + def_id: DefId, + span: Span, + }, + SelfTyParam(Span), + TyParam(DefId), + DefVariant, + None, +} + +fn generics_args_err_extend<'a>( + tcx: TyCtxt<'_>, + segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone, + err: &mut Diag<'_>, + err_extend: GenericsArgsErrExtend<'_>, +) { + match err_extend { + GenericsArgsErrExtend::EnumVariant { qself, assoc_segment, adt_def } => { + err.note("enum variants can't have type parameters"); + let type_name = tcx.item_name(adt_def.did()); + let msg = format!( + "you might have meant to specify type parameters on enum \ + `{type_name}`" + ); + let Some(args) = assoc_segment.args else { + return; + }; + // Get the span of the generics args *including* the leading `::`. + // We do so by stretching args.span_ext to the left by 2. Earlier + // it was done based on the end of assoc segment but that sometimes + // led to impossible spans and caused issues like #116473 + let args_span = args.span_ext.with_lo(args.span_ext.lo() - BytePos(2)); + if tcx.generics_of(adt_def.did()).count() == 0 { + // FIXME(estebank): we could also verify that the arguments being + // work for the `enum`, instead of just looking if it takes *any*. + err.span_suggestion_verbose( + args_span, + format!("{type_name} doesn't have generic parameters"), + "", + Applicability::MachineApplicable, + ); + return; + } + let Ok(snippet) = tcx.sess.source_map().span_to_snippet(args_span) else { + err.note(msg); + return; + }; + let (qself_sugg_span, is_self) = + if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind { + // If the path segment already has type params, we want to overwrite + // them. + match &path.segments { + // `segment` is the previous to last element on the path, + // which would normally be the `enum` itself, while the last + // `_` `PathSegment` corresponds to the variant. + [ + .., + hir::PathSegment { + ident, args, res: Res::Def(DefKind::Enum, _), .. + }, + _, + ] => ( + // We need to include the `::` in `Type::Variant::<Args>` + // to point the span to `::<Args>`, not just `<Args>`. + ident + .span + .shrink_to_hi() + .to(args.map_or(ident.span.shrink_to_hi(), |a| a.span_ext)), + false, + ), + [segment] => { + ( + // We need to include the `::` in `Type::Variant::<Args>` + // to point the span to `::<Args>`, not just `<Args>`. + segment.ident.span.shrink_to_hi().to(segment + .args + .map_or(segment.ident.span.shrink_to_hi(), |a| a.span_ext)), + kw::SelfUpper == segment.ident.name, + ) + } + _ => { + err.note(msg); + return; + } + } + } else { + err.note(msg); + return; + }; + let suggestion = vec![ + if is_self { + // Account for people writing `Self::Variant::<Args>`, where + // `Self` is the enum, and suggest replacing `Self` with the + // appropriate type: `Type::<Args>::Variant`. + (qself.span, format!("{type_name}{snippet}")) + } else { + (qself_sugg_span, snippet) + }, + (args_span, String::new()), + ]; + err.multipart_suggestion_verbose(msg, suggestion, Applicability::MaybeIncorrect); + } + GenericsArgsErrExtend::PrimTy(prim_ty) => { + let name = prim_ty.name_str(); + for segment in segments { + if let Some(args) = segment.args { + err.span_suggestion_verbose( + segment.ident.span.shrink_to_hi().to(args.span_ext), + format!("primitive type `{name}` doesn't have generic parameters"), + "", + Applicability::MaybeIncorrect, + ); + } + } + } + GenericsArgsErrExtend::OpaqueTy => { + err.note("`impl Trait` types can't have type parameters"); + } + GenericsArgsErrExtend::DefVariant => { + err.note("enum variants can't have type parameters"); + } + GenericsArgsErrExtend::TyParam(def_id) => { + if let Some(span) = tcx.def_ident_span(def_id) { + let name = tcx.item_name(def_id); + err.span_note(span, format!("type parameter `{name}` defined here")); + } + } + GenericsArgsErrExtend::SelfTyParam(span) => { + err.span_suggestion_verbose( + span, + "the `Self` type doesn't accept type parameters", + "", + Applicability::MaybeIncorrect, + ); + } + GenericsArgsErrExtend::SelfTyAlias { def_id, span } => { + let ty = tcx.at(span).type_of(def_id).instantiate_identity(); + let span_of_impl = tcx.span_of_impl(def_id); + let def_id = match *ty.kind() { + ty::Adt(self_def, _) => self_def.did(), + _ => return, + }; + + let type_name = tcx.item_name(def_id); + let span_of_ty = tcx.def_ident_span(def_id); + let generics = tcx.generics_of(def_id).count(); + + let msg = format!("`Self` is of type `{ty}`"); + if let (Ok(i_sp), Some(t_sp)) = (span_of_impl, span_of_ty) { + let mut span: MultiSpan = vec![t_sp].into(); + span.push_span_label( + i_sp, + format!("`Self` is on type `{type_name}` in this `impl`"), + ); + let mut postfix = ""; + if generics == 0 { + postfix = ", which doesn't have generic parameters"; + } + span.push_span_label(t_sp, format!("`Self` corresponds to this type{postfix}")); + err.span_note(span, msg); + } else { + err.note(msg); + } + for segment in segments { + if let Some(args) = segment.args + && segment.ident.name == kw::SelfUpper + { + if generics == 0 { + // FIXME(estebank): we could also verify that the arguments being + // work for the `enum`, instead of just looking if it takes *any*. + err.span_suggestion_verbose( + segment.ident.span.shrink_to_hi().to(args.span_ext), + "the `Self` type doesn't accept type parameters", + "", + Applicability::MachineApplicable, + ); + return; + } else { + err.span_suggestion_verbose( + segment.ident.span, + format!( + "the `Self` type doesn't accept type parameters, use the \ + concrete type's name `{type_name}` instead if you want to \ + specify its type parameters" + ), + type_name, + Applicability::MaybeIncorrect, + ); + } + } + } + } + _ => {} + } +} 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 8886a78c6ec..f726f2a7b89 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -14,7 +14,7 @@ //! trait references and bounds. mod bounds; -mod errors; +pub mod errors; pub mod generics; mod lint; mod object_safety; @@ -22,14 +22,14 @@ mod object_safety; use crate::bounds::Bounds; use crate::collect::HirPlaceholderCollector; use crate::errors::AmbiguousLifetimeBound; -use crate::hir_ty_lowering::errors::prohibit_assoc_item_binding; +use crate::hir_ty_lowering::errors::{prohibit_assoc_item_binding, GenericsArgsErrExtend}; use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args}; use crate::middle::resolve_bound_vars as rbv; use crate::require_c_abi_if_c_variadic; use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::{ - codes::*, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, FatalError, MultiSpan, + codes::*, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, FatalError, }; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; @@ -46,7 +46,7 @@ use rustc_middle::ty::{ use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::symbol::{kw, Ident, Symbol}; -use rustc_span::{sym, BytePos, Span, DUMMY_SP}; +use rustc_span::{sym, Span, DUMMY_SP}; use rustc_target::spec::abi; use rustc_trait_selection::traits::wf::object_region_bounds; use rustc_trait_selection::traits::{self, ObligationCtxt}; @@ -632,7 +632,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { trait_ref: &hir::TraitRef<'tcx>, self_ty: Ty<'tcx>, ) -> ty::TraitRef<'tcx> { - self.prohibit_generic_args(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {}); + let _ = self.prohibit_generic_args( + trait_ref.path.segments.split_last().unwrap().1.iter(), + GenericsArgsErrExtend::None, + ); self.lower_mono_trait_ref( trait_ref.path.span, @@ -681,7 +684,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()); let trait_segment = trait_ref.path.segments.last().unwrap(); - self.prohibit_generic_args(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {}); + let _ = self.prohibit_generic_args( + trait_ref.path.segments.split_last().unwrap().1.iter(), + GenericsArgsErrExtend::None, + ); self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false); let (generic_args, arg_count) = self.lower_generic_args_of_path( @@ -995,8 +1001,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir_ref_id: hir::HirId, span: Span, qself_ty: Ty<'tcx>, - qself: &hir::Ty<'_>, - assoc_segment: &hir::PathSegment<'tcx>, + qself: &'tcx hir::Ty<'tcx>, + assoc_segment: &'tcx hir::PathSegment<'tcx>, permit_variants: bool, ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> { debug!(%qself_ty, ?assoc_segment.ident); @@ -1020,99 +1026,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if let Some(variant_def) = variant_def { if permit_variants { tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None); - self.prohibit_generic_args(slice::from_ref(assoc_segment).iter(), |err| { - err.note("enum variants can't have type parameters"); - let type_name = tcx.item_name(adt_def.did()); - let msg = format!( - "you might have meant to specify type parameters on enum \ - `{type_name}`" - ); - let Some(args) = assoc_segment.args else { - return; - }; - // Get the span of the generics args *including* the leading `::`. - // We do so by stretching args.span_ext to the left by 2. Earlier - // it was done based on the end of assoc segment but that sometimes - // led to impossible spans and caused issues like #116473 - let args_span = args.span_ext.with_lo(args.span_ext.lo() - BytePos(2)); - if tcx.generics_of(adt_def.did()).count() == 0 { - // FIXME(estebank): we could also verify that the arguments being - // work for the `enum`, instead of just looking if it takes *any*. - err.span_suggestion_verbose( - args_span, - format!("{type_name} doesn't have generic parameters"), - "", - Applicability::MachineApplicable, - ); - return; - } - let Ok(snippet) = tcx.sess.source_map().span_to_snippet(args_span) - else { - err.note(msg); - return; - }; - let (qself_sugg_span, is_self) = - if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = - &qself.kind - { - // If the path segment already has type params, we want to overwrite - // them. - match &path.segments { - // `segment` is the previous to last element on the path, - // which would normally be the `enum` itself, while the last - // `_` `PathSegment` corresponds to the variant. - [ - .., - hir::PathSegment { - ident, - args, - res: Res::Def(DefKind::Enum, _), - .. - }, - _, - ] => ( - // We need to include the `::` in `Type::Variant::<Args>` - // to point the span to `::<Args>`, not just `<Args>`. - ident.span.shrink_to_hi().to(args - .map_or(ident.span.shrink_to_hi(), |a| a.span_ext)), - false, - ), - [segment] => ( - // We need to include the `::` in `Type::Variant::<Args>` - // to point the span to `::<Args>`, not just `<Args>`. - segment.ident.span.shrink_to_hi().to(segment - .args - .map_or(segment.ident.span.shrink_to_hi(), |a| { - a.span_ext - })), - kw::SelfUpper == segment.ident.name, - ), - _ => { - err.note(msg); - return; - } - } - } else { - err.note(msg); - return; - }; - let suggestion = vec![ - if is_self { - // Account for people writing `Self::Variant::<Args>`, where - // `Self` is the enum, and suggest replacing `Self` with the - // appropriate type: `Type::<Args>::Variant`. - (qself.span, format!("{type_name}{snippet}")) - } else { - (qself_sugg_span, snippet) - }, - (args_span, String::new()), - ]; - err.multipart_suggestion_verbose( - msg, - suggestion, - Applicability::MaybeIncorrect, - ); - }); + let _ = self.prohibit_generic_args( + slice::from_ref(assoc_segment).iter(), + GenericsArgsErrExtend::EnumVariant { qself, assoc_segment, adt_def }, + ); return Ok((qself_ty, DefKind::Variant, variant_def.def_id)); } else { variant_resolution = Some(variant_def.def_id); @@ -1624,111 +1541,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { pub fn prohibit_generic_args<'a>( &self, segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone, - extend: impl Fn(&mut Diag<'_>), - ) -> bool { - let args = segments.clone().flat_map(|segment| segment.args().args); - - let (lt, ty, ct, inf) = - args.clone().fold((false, false, false, false), |(lt, ty, ct, inf), arg| match arg { - hir::GenericArg::Lifetime(_) => (true, ty, ct, inf), - hir::GenericArg::Type(_) => (lt, true, ct, inf), - hir::GenericArg::Const(_) => (lt, ty, true, inf), - hir::GenericArg::Infer(_) => (lt, ty, ct, true), - }); - let mut emitted = false; - if lt || ty || ct || inf { - let types_and_spans: Vec<_> = segments - .clone() - .flat_map(|segment| { - if segment.args().args.is_empty() { - None - } else { - Some(( - match segment.res { - Res::PrimTy(ty) => { - format!("{} `{}`", segment.res.descr(), ty.name()) - } - Res::Def(_, def_id) - if let Some(name) = self.tcx().opt_item_name(def_id) => - { - format!("{} `{name}`", segment.res.descr()) - } - Res::Err => "this type".to_string(), - _ => segment.res.descr().to_string(), - }, - segment.ident.span, - )) - } - }) - .collect(); - let this_type = match &types_and_spans[..] { - [.., _, (last, _)] => format!( - "{} and {last}", - types_and_spans[..types_and_spans.len() - 1] - .iter() - .map(|(x, _)| x.as_str()) - .intersperse(", ") - .collect::<String>() - ), - [(only, _)] => only.to_string(), - [] => "this type".to_string(), - }; - - let arg_spans: Vec<Span> = args.map(|arg| arg.span()).collect(); - - let mut kinds = Vec::with_capacity(4); - if lt { - kinds.push("lifetime"); - } - if ty { - kinds.push("type"); - } - if ct { - kinds.push("const"); - } - if inf { - kinds.push("generic"); - } - let (kind, s) = match kinds[..] { - [.., _, last] => ( - format!( - "{} and {last}", - kinds[..kinds.len() - 1] - .iter() - .map(|&x| x) - .intersperse(", ") - .collect::<String>() - ), - "s", - ), - [only] => (only.to_string(), ""), - [] => unreachable!("expected at least one generic to prohibit"), - }; - let last_span = *arg_spans.last().unwrap(); - let span: MultiSpan = arg_spans.into(); - let mut err = struct_span_code_err!( - self.tcx().dcx(), - span, - E0109, - "{kind} arguments are not allowed on {this_type}", - ); - err.span_label(last_span, format!("{kind} argument{s} not allowed")); - for (what, span) in types_and_spans { - err.span_label(span, format!("not allowed on {what}")); - } - extend(&mut err); - self.set_tainted_by_errors(err.emit()); - emitted = true; + err_extend: GenericsArgsErrExtend<'_>, + ) -> Result<(), ErrorGuaranteed> { + let args_visitors = segments.clone().flat_map(|segment| segment.args().args); + let mut result = Ok(()); + if let Some(_) = args_visitors.clone().next() { + result = Err(self.report_prohibit_generics_error( + segments.clone(), + args_visitors, + err_extend, + )); } for segment in segments { // Only emit the first error to avoid overloading the user with error messages. if let Some(b) = segment.args().bindings.first() { - prohibit_assoc_item_binding(self.tcx(), b.span, None); - return true; + return Err(prohibit_assoc_item_binding(self.tcx(), b.span, None)); } } - emitted + + result } /// Probe path segments that are semantically allowed to have generic arguments. @@ -1893,9 +1725,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Check for desugared `impl Trait`. assert!(tcx.is_type_alias_impl_trait(did)); let item_segment = path.segments.split_last().unwrap(); - self.prohibit_generic_args(item_segment.1.iter(), |err| { - err.note("`impl Trait` types can't have type parameters"); - }); + let _ = self + .prohibit_generic_args(item_segment.1.iter(), GenericsArgsErrExtend::OpaqueTy); let args = self.lower_generic_args_of_path_segment(span, did, item_segment.0); Ty::new_opaque(tcx, did, args) } @@ -1908,7 +1739,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { did, ) => { assert_eq!(opt_self_ty, None); - self.prohibit_generic_args(path.segments.split_last().unwrap().1.iter(), |_| {}); + let _ = self.prohibit_generic_args( + path.segments.split_last().unwrap().1.iter(), + GenericsArgsErrExtend::None, + ); self.lower_path_segment(span, did, path.segments.last().unwrap()) } Res::Def(kind @ DefKind::Variant, def_id) if permit_variants => { @@ -1920,13 +1754,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.probe_generic_path_segments(path.segments, None, kind, def_id, span); let indices: FxHashSet<_> = generic_segments.iter().map(|GenericPathSegment(_, index)| index).collect(); - self.prohibit_generic_args( + let _ = self.prohibit_generic_args( path.segments.iter().enumerate().filter_map(|(index, seg)| { if !indices.contains(&index) { Some(seg) } else { None } }), - |err| { - err.note("enum variants can't have type parameters"); - }, + GenericsArgsErrExtend::DefVariant, ); let GenericPathSegment(def_id, index) = generic_segments.last().unwrap(); @@ -1934,27 +1766,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } Res::Def(DefKind::TyParam, def_id) => { assert_eq!(opt_self_ty, None); - self.prohibit_generic_args(path.segments.iter(), |err| { - if let Some(span) = tcx.def_ident_span(def_id) { - let name = tcx.item_name(def_id); - err.span_note(span, format!("type parameter `{name}` defined here")); - } - }); + let _ = self.prohibit_generic_args( + path.segments.iter(), + GenericsArgsErrExtend::TyParam(def_id), + ); self.lower_ty_param(hir_id) } Res::SelfTyParam { .. } => { // `Self` in trait or type alias. assert_eq!(opt_self_ty, None); - self.prohibit_generic_args(path.segments.iter(), |err| { + let _ = self.prohibit_generic_args( + path.segments.iter(), if let [hir::PathSegment { args: Some(args), ident, .. }] = &path.segments { - err.span_suggestion_verbose( + GenericsArgsErrExtend::SelfTyParam( ident.span.shrink_to_hi().to(args.span_ext), - "the `Self` type doesn't accept type parameters", - "", - Applicability::MaybeIncorrect, - ); - } - }); + ) + } else { + GenericsArgsErrExtend::None + }, + ); tcx.types.self_param } Res::SelfTyAlias { alias_to: def_id, forbid_generic, .. } => { @@ -1962,65 +1792,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assert_eq!(opt_self_ty, None); // Try to evaluate any array length constants. let ty = tcx.at(span).type_of(def_id).instantiate_identity(); - let span_of_impl = tcx.span_of_impl(def_id); - self.prohibit_generic_args(path.segments.iter(), |err| { - let def_id = match *ty.kind() { - ty::Adt(self_def, _) => self_def.did(), - _ => return, - }; - - let type_name = tcx.item_name(def_id); - let span_of_ty = tcx.def_ident_span(def_id); - let generics = tcx.generics_of(def_id).count(); - - let msg = format!("`Self` is of type `{ty}`"); - if let (Ok(i_sp), Some(t_sp)) = (span_of_impl, span_of_ty) { - let mut span: MultiSpan = vec![t_sp].into(); - span.push_span_label( - i_sp, - format!("`Self` is on type `{type_name}` in this `impl`"), - ); - let mut postfix = ""; - if generics == 0 { - postfix = ", which doesn't have generic parameters"; - } - span.push_span_label( - t_sp, - format!("`Self` corresponds to this type{postfix}"), - ); - err.span_note(span, msg); - } else { - err.note(msg); - } - for segment in path.segments { - if let Some(args) = segment.args - && segment.ident.name == kw::SelfUpper - { - if generics == 0 { - // FIXME(estebank): we could also verify that the arguments being - // work for the `enum`, instead of just looking if it takes *any*. - err.span_suggestion_verbose( - segment.ident.span.shrink_to_hi().to(args.span_ext), - "the `Self` type doesn't accept type parameters", - "", - Applicability::MachineApplicable, - ); - return; - } else { - err.span_suggestion_verbose( - segment.ident.span, - format!( - "the `Self` type doesn't accept type parameters, use the \ - concrete type's name `{type_name}` instead if you want to \ - specify its type parameters" - ), - type_name, - Applicability::MaybeIncorrect, - ); - } - } - } - }); + let _ = self.prohibit_generic_args( + path.segments.iter(), + GenericsArgsErrExtend::SelfTyAlias { def_id, span }, + ); // HACK(min_const_generics): Forbid generic `Self` types // here as we can't easily do that during nameres. // @@ -2061,7 +1836,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } Res::Def(DefKind::AssocTy, def_id) => { debug_assert!(path.segments.len() >= 2); - self.prohibit_generic_args(path.segments[..path.segments.len() - 2].iter(), |_| {}); + let _ = self.prohibit_generic_args( + path.segments[..path.segments.len() - 2].iter(), + GenericsArgsErrExtend::None, + ); // HACK: until we support `<Type as ~const Trait>`, assume all of them are. let constness = if tcx.has_attr(tcx.parent(def_id), sym::const_trait) { ty::BoundConstness::ConstIfConst @@ -2079,19 +1857,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } Res::PrimTy(prim_ty) => { assert_eq!(opt_self_ty, None); - self.prohibit_generic_args(path.segments.iter(), |err| { - let name = prim_ty.name_str(); - for segment in path.segments { - if let Some(args) = segment.args { - err.span_suggestion_verbose( - segment.ident.span.shrink_to_hi().to(args.span_ext), - format!("primitive type `{name}` doesn't have generic parameters"), - "", - Applicability::MaybeIncorrect, - ); - } - } - }); + let _ = self.prohibit_generic_args( + path.segments.iter(), + GenericsArgsErrExtend::PrimTy(prim_ty), + ); match prim_ty { hir::PrimTy::Bool => tcx.types.bool, hir::PrimTy::Char => tcx.types.char, 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 b5b3a9131c5..d3ca35ba481 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 @@ -1,5 +1,4 @@ use crate::bounds::Bounds; -use crate::errors::TraitObjectDeclaredWithNoTraits; use crate::hir_ty_lowering::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::{codes::*, struct_span_code_err}; @@ -86,47 +85,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id())); if regular_traits.len() > 1 { - let first_trait = ®ular_traits[0]; - let additional_trait = ®ular_traits[1]; - let mut err = struct_span_code_err!( - tcx.dcx(), - additional_trait.bottom().1, - E0225, - "only auto traits can be used as additional traits in a trait object" - ); - additional_trait.label_with_exp_info( - &mut err, - "additional non-auto trait", - "additional use", - ); - first_trait.label_with_exp_info(&mut err, "first non-auto trait", "first use"); - err.help(format!( - "consider creating a new trait with all of these as supertraits and using that \ - trait here instead: `trait NewTrait: {} {{}}`", - regular_traits - .iter() - // FIXME: This should `print_sugared`, but also needs to integrate projection bounds... - .map(|t| t.trait_ref().print_only_trait_path().to_string()) - .collect::<Vec<_>>() - .join(" + "), - )); - err.note( - "auto-traits like `Send` and `Sync` are traits that have special properties; \ - for more information on them, visit \ - <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>", - ); - self.set_tainted_by_errors(err.emit()); - } - - if regular_traits.is_empty() && auto_traits.is_empty() { - let trait_alias_span = trait_bounds - .iter() - .map(|&(trait_ref, _)| trait_ref.def_id()) - .find(|&trait_ref| tcx.is_trait_alias(trait_ref)) - .map(|trait_ref| tcx.def_span(trait_ref)); - let reported = - tcx.dcx().emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }); - self.set_tainted_by_errors(reported); + let _ = self.report_trait_object_addition_traits_error(®ular_traits); + } else if regular_traits.is_empty() && auto_traits.is_empty() { + let reported = self.report_trait_object_with_no_traits_error(span, &trait_bounds); return Ty::new_error(tcx, reported); } diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index f7af438ad16..fbdc3d1adb8 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -86,7 +86,7 @@ hir_typeck_invalid_callee = expected function, found {$ty} hir_typeck_lossy_provenance_int2ptr = strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}` .suggestion = use `.with_addr()` to adjust a valid pointer in the same allocation, to this address - .help = if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::from_exposed_addr()` instead + .help = if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead hir_typeck_lossy_provenance_ptr2int = under strict provenance it is considered bad style to cast pointer `{$expr_ty}` to integer `{$cast_ty}` diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 011607bacc6..8d4d0833eef 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -11,6 +11,7 @@ use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, GenericArg, Node, QPath}; +use rustc_hir_analysis::hir_ty_lowering::errors::GenericsArgsErrExtend; use rustc_hir_analysis::hir_ty_lowering::generics::{ check_generic_arg_count_for_call, lower_generic_args, }; @@ -1177,11 +1178,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let indices: FxHashSet<_> = generic_segments.iter().map(|GenericPathSegment(_, index)| index).collect(); - let generics_has_err = self.lowerer().prohibit_generic_args( + let generics_err = self.lowerer().prohibit_generic_args( segments.iter().enumerate().filter_map(|(index, seg)| { if !indices.contains(&index) || is_alias_variant_ctor { Some(seg) } else { None } }), - |_| {}, + GenericsArgsErrExtend::None, ); if let Res::Local(hid) = res { @@ -1191,7 +1192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return (ty, res); } - if generics_has_err { + if let Err(_) = generics_err { // Don't try to infer type parameters when prohibited generic arguments were given. user_self_ty = None; } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 9f09f46ea5a..7e9d35ca6c1 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2749,7 +2749,7 @@ declare_lint! { /// memory the pointer is allowed to read/write. Casting an integer, which /// doesn't have provenance, to a pointer requires the compiler to assign /// (guess) provenance. The compiler assigns "all exposed valid" (see the - /// docs of [`ptr::from_exposed_addr`] for more information about this + /// docs of [`ptr::with_exposed_provenance`] for more information about this /// "exposing"). This penalizes the optimiser and is not well suited for /// dynamic analysis/dynamic program verification (e.g. Miri or CHERI /// platforms). @@ -2757,11 +2757,11 @@ declare_lint! { /// It is much better to use [`ptr::with_addr`] instead to specify the /// provenance you want. If using this function is not possible because the /// code relies on exposed provenance then there is as an escape hatch - /// [`ptr::from_exposed_addr`]. + /// [`ptr::with_exposed_provenance`]. /// /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228 /// [`ptr::with_addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.with_addr - /// [`ptr::from_exposed_addr`]: https://doc.rust-lang.org/core/ptr/fn.from_exposed_addr.html + /// [`ptr::with_exposed_provenance`]: https://doc.rust-lang.org/core/ptr/fn.with_exposed_provenance.html pub FUZZY_PROVENANCE_CASTS, Allow, "a fuzzy integer to pointer cast is used", diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index f929a5cec25..947764307e4 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -426,7 +426,7 @@ impl<'tcx> Rvalue<'tcx> { | CastKind::FnPtrToPtr | CastKind::PtrToPtr | CastKind::PointerCoercion(_) - | CastKind::PointerFromExposedAddress + | CastKind::PointerWithExposedProvenance | CastKind::DynStar | CastKind::Transmute, _, diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 2d05af85249..1f6165babdf 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1312,8 +1312,8 @@ pub enum CastKind { /// See the docs on `expose_addr` for more details. PointerExposeAddress, /// An address-to-pointer cast that picks up an exposed provenance. - /// See the docs on `from_exposed_addr` for more details. - PointerFromExposedAddress, + /// See the docs on `with_exposed_provenance` for more details. + PointerWithExposedProvenance, /// Pointer related casts that are done by coercions. Note that reference-to-raw-ptr casts are /// translated into `&raw mut/const *r`, i.e., they are not actually casts. PointerCoercion(PointerCoercion), diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs index 50d629120ab..9bdc679d4e5 100644 --- a/compiler/rustc_middle/src/ty/cast.rs +++ b/compiler/rustc_middle/src/ty/cast.rs @@ -85,7 +85,7 @@ pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKin (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => { mir::CastKind::PointerExposeAddress } - (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerFromExposedAddress, + (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance, (_, Some(CastTy::DynStar)) => mir::CastKind::DynStar, (Some(CastTy::Int(_)), Some(CastTy::Int(_))) => mir::CastKind::IntToInt, (Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => mir::CastKind::FnPtrToPtr, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index 22e7e5323c7..9d91032c1d2 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -268,7 +268,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind { use rustc_middle::mir::CastKind::*; match self { PointerExposeAddress => stable_mir::mir::CastKind::PointerExposeAddress, - PointerFromExposedAddress => stable_mir::mir::CastKind::PointerFromExposedAddress, + PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance, PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)), DynStar => stable_mir::mir::CastKind::DynStar, IntToInt => stable_mir::mir::CastKind::IntToInt, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a94de14cb51..b1d4a63812f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1675,7 +1675,6 @@ symbols! { simd_fmin, simd_fpow, simd_fpowi, - simd_from_exposed_addr, simd_fsin, simd_fsqrt, simd_gather, @@ -1714,6 +1713,7 @@ symbols! { simd_shuffle_generic, simd_sub, simd_trunc, + simd_with_exposed_provenance, simd_xor, since, sinf128, diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index c875d3da47e..3ab4872fffe 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -65,7 +65,7 @@ pub use self::util::{ check_args_compatible, supertrait_def_ids, supertraits, transitive_bounds, transitive_bounds_that_define_assoc_item, SupertraitDefIds, }; -pub use self::util::{expand_trait_aliases, TraitAliasExpander}; +pub use self::util::{expand_trait_aliases, TraitAliasExpander, TraitAliasExpansionInfo}; pub use self::util::{get_vtable_index_of_object_method, impl_item_is_final, upcast_choices}; pub use self::util::{with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer}; diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 636bf919f5c..0d866f27dad 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -972,7 +972,7 @@ pub enum PointerCoercion { #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum CastKind { PointerExposeAddress, - PointerFromExposedAddress, + PointerWithExposedProvenance, PointerCoercion(PointerCoercion), DynStar, IntToInt, |
