diff options
Diffstat (limited to 'compiler')
24 files changed, 319 insertions, 103 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 114b9835b98..4ace80a7344 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -308,7 +308,6 @@ impl ParenthesizedArgs { } } -use crate::AstDeref; pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId}; /// Modifiers on a trait bound like `~const`, `?` and `!`. @@ -2349,7 +2348,7 @@ impl Ty { pub fn is_maybe_parenthesised_infer(&self) -> bool { match &self.kind { TyKind::Infer => true, - TyKind::Paren(inner) => inner.ast_deref().is_maybe_parenthesised_infer(), + TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(), _ => false, } } diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 7f98e7ba8a6..21de7ff7719 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -13,34 +13,6 @@ use crate::{ Ty, Variant, Visibility, WherePredicate, }; -/// A utility trait to reduce boilerplate. -/// Standard `Deref(Mut)` cannot be reused due to coherence. -pub trait AstDeref { - type Target; - fn ast_deref(&self) -> &Self::Target; - fn ast_deref_mut(&mut self) -> &mut Self::Target; -} - -macro_rules! impl_not_ast_deref { - ($($T:ty),+ $(,)?) => { - $( - impl !AstDeref for $T {} - )+ - }; -} - -impl_not_ast_deref!(AssocItem, Expr, ForeignItem, Item, Stmt); - -impl<T> AstDeref for P<T> { - type Target = T; - fn ast_deref(&self) -> &Self::Target { - self - } - fn ast_deref_mut(&mut self) -> &mut Self::Target { - self - } -} - /// A trait for AST nodes having an ID. pub trait HasNodeId { fn node_id(&self) -> NodeId; @@ -81,12 +53,12 @@ impl_has_node_id!( WherePredicate, ); -impl<T: AstDeref<Target: HasNodeId>> HasNodeId for T { +impl<T: HasNodeId> HasNodeId for P<T> { fn node_id(&self) -> NodeId { - self.ast_deref().node_id() + (**self).node_id() } fn node_id_mut(&mut self) -> &mut NodeId { - self.ast_deref_mut().node_id_mut() + (**self).node_id_mut() } } @@ -138,21 +110,21 @@ impl_has_tokens_none!( WherePredicate ); -impl<T: AstDeref<Target: HasTokens>> HasTokens for T { +impl<T: HasTokens> HasTokens for Option<T> { fn tokens(&self) -> Option<&LazyAttrTokenStream> { - self.ast_deref().tokens() + self.as_ref().and_then(|inner| inner.tokens()) } fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> { - self.ast_deref_mut().tokens_mut() + self.as_mut().and_then(|inner| inner.tokens_mut()) } } -impl<T: HasTokens> HasTokens for Option<T> { +impl<T: HasTokens> HasTokens for P<T> { fn tokens(&self) -> Option<&LazyAttrTokenStream> { - self.as_ref().and_then(|inner| inner.tokens()) + (**self).tokens() } fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> { - self.as_mut().and_then(|inner| inner.tokens_mut()) + (**self).tokens_mut() } } @@ -273,13 +245,13 @@ impl_has_attrs!( ); impl_has_attrs_none!(Attribute, AttrItem, Block, Pat, Path, Ty, Visibility); -impl<T: AstDeref<Target: HasAttrs>> HasAttrs for T { - const SUPPORTS_CUSTOM_INNER_ATTRS: bool = T::Target::SUPPORTS_CUSTOM_INNER_ATTRS; +impl<T: HasAttrs> HasAttrs for P<T> { + const SUPPORTS_CUSTOM_INNER_ATTRS: bool = T::SUPPORTS_CUSTOM_INNER_ATTRS; fn attrs(&self) -> &[Attribute] { - self.ast_deref().attrs() + (**self).attrs() } fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { - self.ast_deref_mut().visit_attrs(f) + (**self).visit_attrs(f); } } @@ -343,13 +315,22 @@ impl<Wrapped, Tag> AstNodeWrapper<Wrapped, Tag> { } } -impl<Wrapped, Tag> AstDeref for AstNodeWrapper<Wrapped, Tag> { - type Target = Wrapped; - fn ast_deref(&self) -> &Self::Target { - &self.wrapped +impl<Wrapped: HasNodeId, Tag> HasNodeId for AstNodeWrapper<Wrapped, Tag> { + fn node_id(&self) -> NodeId { + self.wrapped.node_id() + } + fn node_id_mut(&mut self) -> &mut NodeId { + self.wrapped.node_id_mut() + } +} + +impl<Wrapped: HasAttrs, Tag> HasAttrs for AstNodeWrapper<Wrapped, Tag> { + const SUPPORTS_CUSTOM_INNER_ATTRS: bool = Wrapped::SUPPORTS_CUSTOM_INNER_ATTRS; + fn attrs(&self) -> &[Attribute] { + self.wrapped.attrs() } - fn ast_deref_mut(&mut self) -> &mut Self::Target { - &mut self.wrapped + fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) { + self.wrapped.visit_attrs(f); } } diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index e572ec99dab..c08622cac86 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -46,7 +46,7 @@ pub mod tokenstream; pub mod visit; pub use self::ast::*; -pub use self::ast_traits::{AstDeref, AstNodeWrapper, HasAttrs, HasNodeId, HasTokens}; +pub use self::ast_traits::{AstNodeWrapper, HasAttrs, HasNodeId, HasTokens}; /// Requirements for a `StableHashingContext` to be used in this crate. /// This is a hack to allow using the `HashStable_Generic` derive macro diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index 0913dc91a53..f3ac932e1b7 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -8,7 +8,7 @@ use std::env::VarError; use rustc_ast::token::{self, LitKind}; use rustc_ast::tokenstream::TokenStream; -use rustc_ast::{AstDeref, ExprKind, GenericArg, Mutability}; +use rustc_ast::{ExprKind, GenericArg, Mutability}; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; use rustc_span::{Ident, Span, Symbol, kw, sym}; use thin_vec::thin_vec; @@ -148,13 +148,13 @@ pub(crate) fn expand_env<'cx>( cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVar { span, var: *symbol, - var_expr: var_expr.ast_deref(), + var_expr: &var_expr, }) } else { cx.dcx().emit_err(errors::EnvNotDefined::CustomEnvVar { span, var: *symbol, - var_expr: var_expr.ast_deref(), + var_expr: &var_expr, }) } } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index e866b896255..9018d78b00a 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -1109,6 +1109,43 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, old); } + sym::minimumf32 => { + intrinsic_args!(fx, args => (a, b); intrinsic); + let a = a.load_scalar(fx); + let b = b.load_scalar(fx); + + let val = fx.bcx.ins().fmin(a, b); + let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f32)); + ret.write_cvalue(fx, val); + } + sym::minimumf64 => { + intrinsic_args!(fx, args => (a, b); intrinsic); + let a = a.load_scalar(fx); + let b = b.load_scalar(fx); + + let val = fx.bcx.ins().fmin(a, b); + let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f64)); + ret.write_cvalue(fx, val); + } + sym::maximumf32 => { + intrinsic_args!(fx, args => (a, b); intrinsic); + let a = a.load_scalar(fx); + let b = b.load_scalar(fx); + + let val = fx.bcx.ins().fmax(a, b); + let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f32)); + ret.write_cvalue(fx, val); + } + sym::maximumf64 => { + intrinsic_args!(fx, args => (a, b); intrinsic); + let a = a.load_scalar(fx); + let b = b.load_scalar(fx); + + let val = fx.bcx.ins().fmax(a, b); + let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f64)); + ret.write_cvalue(fx, val); + } + sym::minnumf32 => { intrinsic_args!(fx, args => (a, b); intrinsic); let a = a.load_scalar(fx); diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 6720f6186d1..9e5ebf3a9a4 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -2454,7 +2454,6 @@ impl ToGccOrdering for AtomicOrdering { use MemOrdering::*; let ordering = match self { - AtomicOrdering::Unordered => __ATOMIC_RELAXED, AtomicOrdering::Relaxed => __ATOMIC_RELAXED, // TODO(antoyo): check if that's the same. AtomicOrdering::Acquire => __ATOMIC_ACQUIRE, AtomicOrdering::Release => __ATOMIC_RELEASE, diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 2ed5ec4381e..9caceca9295 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -74,8 +74,44 @@ fn get_simple_intrinsic<'gcc, 'tcx>( sym::fabsf64 => "fabs", sym::minnumf32 => "fminf", sym::minnumf64 => "fmin", + sym::minimumf32 => "fminimumf", + sym::minimumf64 => "fminimum", + sym::minimumf128 => { + // GCC doesn't have the intrinsic we want so we use the compiler-builtins one + // https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fminimumf128.html + let f128_type = cx.type_f128(); + return Some(cx.context.new_function( + None, + FunctionType::Extern, + f128_type, + &[ + cx.context.new_parameter(None, f128_type, "a"), + cx.context.new_parameter(None, f128_type, "b"), + ], + "fminimumf128", + false, + )); + } sym::maxnumf32 => "fmaxf", sym::maxnumf64 => "fmax", + sym::maximumf32 => "fmaximumf", + sym::maximumf64 => "fmaximum", + sym::maximumf128 => { + // GCC doesn't have the intrinsic we want so we use the compiler-builtins one + // https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fmaximumf128.html + let f128_type = cx.type_f128(); + return Some(cx.context.new_function( + None, + FunctionType::Extern, + f128_type, + &[ + cx.context.new_parameter(None, f128_type, "a"), + cx.context.new_parameter(None, f128_type, "b"), + ], + "fmaximumf128", + false, + )); + } sym::copysignf32 => "copysignf", sym::copysignf64 => "copysign", sym::copysignf128 => "copysignl", diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index ed50515b707..b0d8e11d1fb 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -1009,11 +1009,27 @@ impl<'ll> CodegenCx<'ll, '_> { ifn!("llvm.minnum.f64", fn(t_f64, t_f64) -> t_f64); ifn!("llvm.minnum.f128", fn(t_f128, t_f128) -> t_f128); + ifn!("llvm.minimum.f16", fn(t_f16, t_f16) -> t_f16); + ifn!("llvm.minimum.f32", fn(t_f32, t_f32) -> t_f32); + ifn!("llvm.minimum.f64", fn(t_f64, t_f64) -> t_f64); + // There are issues on x86_64 and aarch64 with the f128 variant. + // - https://github.com/llvm/llvm-project/issues/139380 + // - https://github.com/llvm/llvm-project/issues/139381 + // ifn!("llvm.minimum.f128", fn(t_f128, t_f128) -> t_f128); + ifn!("llvm.maxnum.f16", fn(t_f16, t_f16) -> t_f16); ifn!("llvm.maxnum.f32", fn(t_f32, t_f32) -> t_f32); ifn!("llvm.maxnum.f64", fn(t_f64, t_f64) -> t_f64); ifn!("llvm.maxnum.f128", fn(t_f128, t_f128) -> t_f128); + ifn!("llvm.maximum.f16", fn(t_f16, t_f16) -> t_f16); + ifn!("llvm.maximum.f32", fn(t_f32, t_f32) -> t_f32); + ifn!("llvm.maximum.f64", fn(t_f64, t_f64) -> t_f64); + // There are issues on x86_64 and aarch64 with the f128 variant. + // - https://github.com/llvm/llvm-project/issues/139380 + // - https://github.com/llvm/llvm-project/issues/139381 + // ifn!("llvm.maximum.f128", fn(t_f128, t_f128) -> t_f128); + ifn!("llvm.floor.f16", fn(t_f16) -> t_f16); ifn!("llvm.floor.f32", fn(t_f32) -> t_f32); ifn!("llvm.floor.f64", fn(t_f64) -> t_f64); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index bfaad8f2f1e..5ca57375292 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -103,11 +103,23 @@ fn get_simple_intrinsic<'ll>( sym::minnumf64 => "llvm.minnum.f64", sym::minnumf128 => "llvm.minnum.f128", + sym::minimumf16 => "llvm.minimum.f16", + sym::minimumf32 => "llvm.minimum.f32", + sym::minimumf64 => "llvm.minimum.f64", + // There are issues on x86_64 and aarch64 with the f128 variant, + // let's instead use the instrinsic fallback body. + // sym::minimumf128 => "llvm.minimum.f128", sym::maxnumf16 => "llvm.maxnum.f16", sym::maxnumf32 => "llvm.maxnum.f32", sym::maxnumf64 => "llvm.maxnum.f64", sym::maxnumf128 => "llvm.maxnum.f128", + sym::maximumf16 => "llvm.maximum.f16", + sym::maximumf32 => "llvm.maximum.f32", + sym::maximumf64 => "llvm.maximum.f64", + // There are issues on x86_64 and aarch64 with the f128 variant, + // let's instead use the instrinsic fallback body. + // sym::maximumf128 => "llvm.maximum.f128", sym::copysignf16 => "llvm.copysign.f16", sym::copysignf32 => "llvm.copysign.f32", sym::copysignf64 => "llvm.copysign.f64", diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index ffb490dcdc2..a249cb86ed4 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -415,6 +415,7 @@ impl AtomicRmwBinOp { pub(crate) enum AtomicOrdering { #[allow(dead_code)] NotAtomic = 0, + #[allow(dead_code)] Unordered = 1, Monotonic = 2, // Consume = 3, // Not specified yet. @@ -428,7 +429,6 @@ impl AtomicOrdering { pub(crate) fn from_generic(ao: rustc_codegen_ssa::common::AtomicOrdering) -> Self { use rustc_codegen_ssa::common::AtomicOrdering as Common; match ao { - Common::Unordered => Self::Unordered, Common::Relaxed => Self::Monotonic, Common::Acquire => Self::Acquire, Common::Release => Self::Release, diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index 965bd34ac14..6d0c9d8d066 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -61,7 +61,6 @@ pub enum AtomicRmwBinOp { #[derive(Copy, Clone, Debug)] pub enum AtomicOrdering { - Unordered, Relaxed, Acquire, Release, diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 63025a4574f..b0fcfee2adf 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -336,7 +336,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; let parse_ordering = |bx: &Bx, s| match s { - "unordered" => Unordered, "relaxed" => Relaxed, "acquire" => Acquire, "release" => Release, diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 04a8ed1e0f1..090b2a692cf 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -493,11 +493,21 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { sym::minnumf64 => self.float_min_intrinsic::<Double>(args, dest)?, sym::minnumf128 => self.float_min_intrinsic::<Quad>(args, dest)?, + sym::minimumf16 => self.float_minimum_intrinsic::<Half>(args, dest)?, + sym::minimumf32 => self.float_minimum_intrinsic::<Single>(args, dest)?, + sym::minimumf64 => self.float_minimum_intrinsic::<Double>(args, dest)?, + sym::minimumf128 => self.float_minimum_intrinsic::<Quad>(args, dest)?, + sym::maxnumf16 => self.float_max_intrinsic::<Half>(args, dest)?, sym::maxnumf32 => self.float_max_intrinsic::<Single>(args, dest)?, sym::maxnumf64 => self.float_max_intrinsic::<Double>(args, dest)?, sym::maxnumf128 => self.float_max_intrinsic::<Quad>(args, dest)?, + sym::maximumf16 => self.float_maximum_intrinsic::<Half>(args, dest)?, + sym::maximumf32 => self.float_maximum_intrinsic::<Single>(args, dest)?, + sym::maximumf64 => self.float_maximum_intrinsic::<Double>(args, dest)?, + sym::maximumf128 => self.float_maximum_intrinsic::<Quad>(args, dest)?, + sym::copysignf16 => self.float_copysign_intrinsic::<Half>(args, dest)?, sym::copysignf32 => self.float_copysign_intrinsic::<Single>(args, dest)?, sym::copysignf64 => self.float_copysign_intrinsic::<Double>(args, dest)?, @@ -830,6 +840,38 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(()) } + fn float_minimum_intrinsic<F>( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &MPlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>, + { + let a: F = self.read_scalar(&args[0])?.to_float()?; + let b: F = self.read_scalar(&args[1])?.to_float()?; + let res = a.minimum(b); + let res = self.adjust_nan(res, &[a, b]); + self.write_scalar(res, dest)?; + interp_ok(()) + } + + fn float_maximum_intrinsic<F>( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &MPlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>, + { + let a: F = self.read_scalar(&args[0])?.to_float()?; + let b: F = self.read_scalar(&args[1])?.to_float()?; + let res = a.maximum(b); + let res = self.adjust_nan(res, &[a, b]); + self.write_scalar(res, dest)?; + interp_ok(()) + } + fn float_copysign_intrinsic<F>( &mut self, args: &[OpTy<'tcx, M::Provenance>], diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index d4853d1357f..81d4d59ee04 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1,4 +1,3 @@ -use std::ops::Deref; use std::path::PathBuf; use std::rc::Rc; use std::sync::Arc; @@ -1117,7 +1116,6 @@ enum AddSemicolon { /// of functionality used by `InvocationCollector`. trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized { type OutputTy = SmallVec<[Self; 1]>; - type AttrsTy: Deref<Target = [ast::Attribute]> = ast::AttrVec; type ItemKind = ItemKind; const KIND: AstFragmentKind; fn to_annotatable(self) -> Annotatable; @@ -1134,7 +1132,7 @@ trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized { fn is_mac_call(&self) -> bool { false } - fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { + fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) { unreachable!() } fn delegation(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> { @@ -1189,7 +1187,7 @@ impl InvocationCollectorNode for P<ast::Item> { fn is_mac_call(&self) -> bool { matches!(self.kind, ItemKind::MacCall(..)) } - fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { + fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) { let node = self.into_inner(); match node.kind { ItemKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No), @@ -1345,7 +1343,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag> fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, AssocItemKind::MacCall(..)) } - fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { + fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) { let item = self.wrapped.into_inner(); match item.kind { AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No), @@ -1386,7 +1384,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag> fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, AssocItemKind::MacCall(..)) } - fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { + fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) { let item = self.wrapped.into_inner(); match item.kind { AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No), @@ -1427,7 +1425,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitImplItem fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, AssocItemKind::MacCall(..)) } - fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { + fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) { let item = self.wrapped.into_inner(); match item.kind { AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No), @@ -1465,7 +1463,7 @@ impl InvocationCollectorNode for P<ast::ForeignItem> { fn is_mac_call(&self) -> bool { matches!(self.kind, ForeignItemKind::MacCall(..)) } - fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { + fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) { let node = self.into_inner(); match node.kind { ForeignItemKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No), @@ -1579,7 +1577,6 @@ impl InvocationCollectorNode for ast::Arm { } impl InvocationCollectorNode for ast::Stmt { - type AttrsTy = ast::AttrVec; const KIND: AstFragmentKind = AstFragmentKind::Stmts; fn to_annotatable(self) -> Annotatable { Annotatable::Stmt(P(self)) @@ -1599,7 +1596,7 @@ impl InvocationCollectorNode for ast::Stmt { StmtKind::Let(..) | StmtKind::Empty => false, } } - fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { + fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) { // We pull macro invocations (both attributes and fn-like macro calls) out of their // `StmtKind`s and treat them as statement macro invocations, not as items or expressions. let (add_semicolon, mac, attrs) = match self.kind { @@ -1693,7 +1690,7 @@ impl InvocationCollectorNode for P<ast::Ty> { fn is_mac_call(&self) -> bool { matches!(self.kind, ast::TyKind::MacCall(..)) } - fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { + fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) { let node = self.into_inner(); match node.kind { TyKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No), @@ -1717,7 +1714,7 @@ impl InvocationCollectorNode for P<ast::Pat> { fn is_mac_call(&self) -> bool { matches!(self.kind, PatKind::MacCall(..)) } - fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { + fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) { let node = self.into_inner(); match node.kind { PatKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No), @@ -1728,7 +1725,6 @@ impl InvocationCollectorNode for P<ast::Pat> { impl InvocationCollectorNode for P<ast::Expr> { type OutputTy = P<ast::Expr>; - type AttrsTy = ast::AttrVec; const KIND: AstFragmentKind = AstFragmentKind::Expr; fn to_annotatable(self) -> Annotatable { Annotatable::Expr(self) @@ -1745,7 +1741,7 @@ impl InvocationCollectorNode for P<ast::Expr> { fn is_mac_call(&self) -> bool { matches!(self.kind, ExprKind::MacCall(..)) } - fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { + fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) { let node = self.into_inner(); match node.kind { ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No), @@ -1757,7 +1753,6 @@ impl InvocationCollectorNode for P<ast::Expr> { struct OptExprTag; impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, OptExprTag> { type OutputTy = Option<P<ast::Expr>>; - type AttrsTy = ast::AttrVec; const KIND: AstFragmentKind = AstFragmentKind::OptExpr; fn to_annotatable(self) -> Annotatable { Annotatable::Expr(self.wrapped) @@ -1772,7 +1767,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, OptExprTag> { fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, ast::ExprKind::MacCall(..)) } - fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { + fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) { let node = self.wrapped.into_inner(); match node.kind { ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No), @@ -1794,7 +1789,6 @@ impl DummyAstNode for MethodReceiverTag { } impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, MethodReceiverTag> { type OutputTy = Self; - type AttrsTy = ast::AttrVec; const KIND: AstFragmentKind = AstFragmentKind::MethodReceiverExpr; fn descr() -> &'static str { "an expression" @@ -1811,7 +1805,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, MethodReceiverTag> fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, ast::ExprKind::MacCall(..)) } - fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) { + fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) { let node = self.wrapped.into_inner(); match node.kind { ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No), diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 692784bf171..9fd158ad154 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -103,10 +103,18 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::minnumf32 | sym::minnumf64 | sym::minnumf128 + | sym::minimumf16 + | sym::minimumf32 + | sym::minimumf64 + | sym::minimumf128 | sym::maxnumf16 | sym::maxnumf32 | sym::maxnumf64 | sym::maxnumf128 + | sym::maximumf16 + | sym::maximumf32 + | sym::maximumf64 + | sym::maximumf128 | sym::rustc_peek | sym::type_name | sym::forget @@ -374,11 +382,21 @@ pub(crate) fn check_intrinsic_type( sym::minnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), sym::minnumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128), + sym::minimumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16), + sym::minimumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), + sym::minimumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), + sym::minimumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128), + sym::maxnumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16), sym::maxnumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), sym::maxnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), sym::maxnumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128), + sym::maximumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16), + sym::maximumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), + sym::maximumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), + sym::maximumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128), + sym::copysignf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16), sym::copysignf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), sym::copysignf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 91dde13be55..d010f1fc851 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -223,10 +223,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) { } _ => (), } - }); - - tcx.par_hir_body_owners(|item_def_id| { - let def_kind = tcx.def_kind(item_def_id); // Skip `AnonConst`s because we feed their `type_of`. if !matches!(def_kind, DefKind::AnonConst) { tcx.ensure_ok().typeck(item_def_id); diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 41b43f64798..95e31e4af1e 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -976,6 +976,9 @@ declare_lint! { /// ```rust /// #[unsafe(no_mangle)] /// fn foo<T>(t: T) {} + /// + /// #[unsafe(export_name = "bar")] + /// fn bar<T>(t: T) {} /// ``` /// /// {{produces}} @@ -983,10 +986,11 @@ declare_lint! { /// ### Explanation /// /// A function with generics must have its symbol mangled to accommodate - /// the generic parameter. The [`no_mangle` attribute] has no effect in - /// this situation, and should be removed. + /// the generic parameter. The [`no_mangle`] and [`export_name`] attributes + /// have no effect in this situation, and should be removed. /// - /// [`no_mangle` attribute]: https://doc.rust-lang.org/reference/abi.html#the-no_mangle-attribute + /// [`no_mangle`]: https://doc.rust-lang.org/reference/abi.html#the-no_mangle-attribute + /// [`export_name`]: https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute NO_MANGLE_GENERIC_ITEMS, Warn, "generic items must be mangled" @@ -997,7 +1001,7 @@ declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GEN impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { let attrs = cx.tcx.hir_attrs(it.hir_id()); - let check_no_mangle_on_generic_fn = |no_mangle_attr: &hir::Attribute, + let check_no_mangle_on_generic_fn = |attr: &hir::Attribute, impl_generics: Option<&hir::Generics<'_>>, generics: &hir::Generics<'_>, span| { @@ -1010,7 +1014,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { cx.emit_span_lint( NO_MANGLE_GENERIC_ITEMS, span, - BuiltinNoMangleGeneric { suggestion: no_mangle_attr.span() }, + BuiltinNoMangleGeneric { suggestion: attr.span() }, ); break; } @@ -1019,8 +1023,10 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { }; match it.kind { hir::ItemKind::Fn { generics, .. } => { - if let Some(no_mangle_attr) = attr::find_by_name(attrs, sym::no_mangle) { - check_no_mangle_on_generic_fn(no_mangle_attr, None, generics, it.span); + if let Some(attr) = attr::find_by_name(attrs, sym::export_name) + .or_else(|| attr::find_by_name(attrs, sym::no_mangle)) + { + check_no_mangle_on_generic_fn(attr, None, generics, it.span); } } hir::ItemKind::Const(..) => { @@ -1048,11 +1054,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { hir::ItemKind::Impl(hir::Impl { generics, items, .. }) => { for it in *items { if let hir::AssocItemKind::Fn { .. } = it.kind { - if let Some(no_mangle_attr) = - attr::find_by_name(cx.tcx.hir_attrs(it.id.hir_id()), sym::no_mangle) + let attrs = cx.tcx.hir_attrs(it.id.hir_id()); + if let Some(attr) = attr::find_by_name(attrs, sym::export_name) + .or_else(|| attr::find_by_name(attrs, sym::no_mangle)) { check_no_mangle_on_generic_fn( - no_mangle_attr, + attr, Some(generics), cx.tcx.hir_get_generics(it.id.owner_id.def_id).unwrap(), it.span, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2d69a1c2b55..dda0faa3afe 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1924,6 +1924,9 @@ impl<'tcx> TyCtxt<'tcx> { def_id: DefId, args: GenericArgsRef<'tcx>, ) -> Option<&'tcx CoroutineLayout<'tcx>> { + if args[0].has_placeholders() || args[0].has_non_region_param() { + return None; + } let instance = InstanceKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args)); self.mir_shims(instance).coroutine_layout_raw() } diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index 0fcc3d8f6b3..a97e0eaa9c6 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -11,6 +11,7 @@ pulldown-cmark = { version = "0.11", features = ["html"], default-features = fal rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_attr_data_structures = { path = "../rustc_attr_data_structures" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 74daad08394..0b16983c2c7 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -5,6 +5,7 @@ use rustc_ast::{ self as ast, CRATE_NODE_ID, Crate, ItemKind, MetaItemInner, MetaItemKind, ModKind, NodeId, Path, }; use rustc_ast_pretty::pprust; +use rustc_attr_data_structures::{self as attr, Stability}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::unord::UnordSet; use rustc_errors::codes::*; @@ -110,6 +111,7 @@ pub(crate) struct ImportSuggestion { pub via_import: bool, /// An extra note that should be issued if this item is suggested pub note: Option<String>, + pub is_stable: bool, } /// Adjust the impl span so that just the `impl` keyword is taken by removing @@ -1172,13 +1174,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ThinVec::<ast::PathSegment>::new(), true, start_did.is_local() || !self.tcx.is_doc_hidden(start_did), + true, )]; let mut worklist_via_import = vec![]; - while let Some((in_module, path_segments, accessible, doc_visible)) = match worklist.pop() { - None => worklist_via_import.pop(), - Some(x) => Some(x), - } { + while let Some((in_module, path_segments, accessible, doc_visible, is_stable)) = + match worklist.pop() { + None => worklist_via_import.pop(), + Some(x) => Some(x), + } + { let in_module_is_extern = !in_module.def_id().is_local(); in_module.for_each_child(self, |this, ident, ns, name_binding| { // Avoid non-importable candidates. @@ -1258,6 +1263,27 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { candidates.remove(idx); } + let is_stable = if is_stable + && let Some(did) = did + && this.is_stable(did, path.span) + { + true + } else { + false + }; + + // Rreplace unstable suggestions if we meet a new stable one, + // and do nothing if any other situation. For example, if we + // meet `std::ops::Range` after `std::range::legacy::Range`, + // we will remove the latter and then insert the former. + if is_stable + && let Some(idx) = candidates + .iter() + .position(|v: &ImportSuggestion| v.did == did && !v.is_stable) + { + candidates.remove(idx); + } + if candidates.iter().all(|v: &ImportSuggestion| v.did != did) { // See if we're recommending TryFrom, TryInto, or FromIterator and add // a note about editions @@ -1289,6 +1315,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { doc_visible: child_doc_visible, note, via_import, + is_stable, }); } } @@ -1315,8 +1342,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if !is_extern_crate_that_also_appears_in_prelude || alias_import { // add the module to the lookup if seen_modules.insert(module.def_id()) { - if via_import { &mut worklist_via_import } else { &mut worklist } - .push((module, path_segments, child_accessible, child_doc_visible)); + if via_import { &mut worklist_via_import } else { &mut worklist }.push( + ( + module, + path_segments, + child_accessible, + child_doc_visible, + is_stable && this.is_stable(module.def_id(), name_binding.span), + ), + ); } } } @@ -1326,6 +1360,34 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { candidates } + fn is_stable(&self, did: DefId, span: Span) -> bool { + if did.is_local() { + return true; + } + + match self.tcx.lookup_stability(did) { + Some(Stability { + level: attr::StabilityLevel::Unstable { implied_by, .. }, + feature, + .. + }) => { + if span.allows_unstable(feature) { + true + } else if self.tcx.features().enabled(feature) { + true + } else if let Some(implied_by) = implied_by + && self.tcx.features().enabled(implied_by) + { + true + } else { + false + } + } + Some(_) => true, + None => false, + } + } + /// When name resolution fails, this method can be used to look up candidate /// entities with the expected name. It allows filtering them using the /// supplied predicate (which should be used to only accept the types of diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index d4fe446cc9f..b538be34f31 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2501,6 +2501,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { doc_visible, note: None, via_import: false, + is_stable: true, }, )); } else { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8df211b0840..3a95447308a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1301,6 +1301,10 @@ symbols! { match_beginning_vert, match_default_bindings, matches_macro, + maximumf128, + maximumf16, + maximumf32, + maximumf64, maxnumf128, maxnumf16, maxnumf32, @@ -1335,6 +1339,10 @@ symbols! { min_generic_const_args, min_specialization, min_type_alias_impl_trait, + minimumf128, + minimumf16, + minimumf32, + minimumf64, minnumf128, minnumf16, minnumf32, diff --git a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs index bb3e3e544cb..8f93523909e 100644 --- a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Lld, Target, TargetMetadata, add_link_args, base}; +use crate::spec::{FramePointer, LinkerFlavor, Lld, Target, TargetMetadata, add_link_args, base}; pub(crate) fn target() -> Target { let mut base = base::windows_msvc::opts(); @@ -10,6 +10,12 @@ pub(crate) fn target() -> Target { &["/machine:arm64ec", "softintrin.lib"], ); + // Microsoft recommends enabling frame pointers on Arm64 Windows. + // From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers + // "The frame pointer (x29) is required for compatibility with fast stack walking used by ETW + // and other services. It must point to the previous {x29, x30} pair on the stack." + base.frame_pointer = FramePointer::NonLeaf; + Target { llvm_target: "arm64ec-pc-windows-msvc".into(), metadata: TargetMetadata { diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 5a21925ba04..5428aa4cf70 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -693,17 +693,17 @@ static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ static LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ // tidy-alphabetical-start - ("d", Unstable(sym::loongarch_target_feature), &["f"]), + ("d", Stable, &["f"]), ("div32", Unstable(sym::loongarch_target_feature), &[]), - ("f", Unstable(sym::loongarch_target_feature), &[]), - ("frecipe", Unstable(sym::loongarch_target_feature), &[]), + ("f", Stable, &[]), + ("frecipe", Stable, &[]), ("lam-bh", Unstable(sym::loongarch_target_feature), &[]), ("lamcas", Unstable(sym::loongarch_target_feature), &[]), - ("lasx", Unstable(sym::loongarch_target_feature), &["lsx"]), - ("lbt", Unstable(sym::loongarch_target_feature), &[]), + ("lasx", Stable, &["lsx"]), + ("lbt", Stable, &[]), ("ld-seq-sa", Unstable(sym::loongarch_target_feature), &[]), - ("lsx", Unstable(sym::loongarch_target_feature), &["d"]), - ("lvz", Unstable(sym::loongarch_target_feature), &[]), + ("lsx", Stable, &["d"]), + ("lvz", Stable, &[]), ("relax", Unstable(sym::loongarch_target_feature), &[]), ("scq", Unstable(sym::loongarch_target_feature), &[]), ("ual", Unstable(sym::loongarch_target_feature), &[]), |
