diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 3e1fff594040e..cc244b44eb033 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1378,15 +1378,6 @@ pub enum UnsafeSource { UserProvided, } -/// Track whether under `feature(min_generic_const_args)` this anon const -/// was explicitly disambiguated as an anon const or not through the use of -/// `const { ... }` syntax. -#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)] -pub enum MgcaDisambiguation { - AnonConst, - Direct, -} - /// A constant (expression) that's not an item or associated item, /// but needs its own `DefId` for type-checking, const-eval, etc. /// These are usually found nested inside types (e.g., array lengths) @@ -1396,7 +1387,6 @@ pub enum MgcaDisambiguation { pub struct AnonConst { pub id: NodeId, pub value: Box, - pub mgca_disambiguation: MgcaDisambiguation, } /// An expression. @@ -1627,6 +1617,7 @@ impl Expr { | ExprKind::UnsafeBinderCast(..) | ExprKind::While(..) | ExprKind::Yield(YieldKind::Postfix(..)) + | ExprKind::DirectConstArg(..) | ExprKind::Err(_) | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs), } @@ -1920,6 +1911,9 @@ pub enum ExprKind { UnsafeBinderCast(UnsafeBinderCastKind, Box, Option>), + /// An mGCA `direct_const_arg!()` expression. + DirectConstArg(Box), + /// Placeholder for an expression that wasn't syntactically well formed in some way. Err(ErrorGuaranteed), @@ -2564,6 +2558,8 @@ pub enum TyKind { /// Usually not written directly in user code but indirectly via the macro /// `core::field::field_of!(...)`. FieldOf(Box, Option, Ident), + /// An mGCA `direct_const_arg!()` expression. + DirectConstArg(Box), /// Sometimes we need a dummy value when no error has occurred. Dummy, /// Placeholder for a kind that has failed to be defined. diff --git a/compiler/rustc_ast/src/expand/typetree.rs b/compiler/rustc_ast/src/expand/typetree.rs index 9619c80904426..00fea30ba94e5 100644 --- a/compiler/rustc_ast/src/expand/typetree.rs +++ b/compiler/rustc_ast/src/expand/typetree.rs @@ -28,6 +28,9 @@ pub enum Kind { Anything, Integer, Pointer, + // We prefer to directly lower to things that our Enzyme backend supports. + // However, it's sometimes convenient to pass ptr+int as one type. + RustSlice, Half, Float, Double, @@ -57,6 +60,9 @@ impl TypeTree { } Self(ints) } + pub fn add_indirection(self) -> Self { + Self(vec![Type { offset: 0, size: 1, kind: Kind::Pointer, child: self }]) + } } #[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, StableHash)] @@ -72,6 +78,11 @@ pub struct Type { pub kind: Kind, pub child: TypeTree, } +impl Type { + pub fn from_ty(offset: isize, other: &Type) -> Self { + Self { offset, size: other.size, kind: other.kind, child: other.child.clone() } + } +} impl Type { pub fn add_offset(self, add: isize) -> Self { diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 0c98b0e5e7b4f..e68ba52a0730b 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -155,6 +155,7 @@ pub fn leading_labeled_expr(mut expr: &ast::Expr) -> bool { | Yeet(..) | Yield(..) | UnsafeBinderCast(..) + | DirectConstArg(..) | Err(..) | Dummy => return false, } @@ -240,6 +241,7 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option> { | Try(_) | Yeet(None) | UnsafeBinderCast(..) + | DirectConstArg(..) | Err(_) | Dummy => { break None; @@ -301,6 +303,7 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> { | ast::TyKind::CVarArgs | ast::TyKind::Pat(..) | ast::TyKind::FieldOf(..) + | ast::TyKind::DirectConstArg(..) | ast::TyKind::Dummy | ast::TyKind::Err(..) => break None, } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index fb4e76321d150..e25c1a0b31937 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -418,7 +418,6 @@ macro_rules! common_visitor_and_walkers { UnsafeBinderCastKind, BinOpKind, BlockCheckMode, - MgcaDisambiguation, BorrowKind, BoundAsyncness, BoundConstness, @@ -1074,6 +1073,8 @@ macro_rules! common_visitor_and_walkers { visit_visitable!($($mut)? vis, bytes), ExprKind::UnsafeBinderCast(kind, expr, ty) => visit_visitable!($($mut)? vis, kind, expr, ty), + ExprKind::DirectConstArg(expr) => + visit_visitable!($($mut)? vis, expr), ExprKind::Err(_guar) => {} ExprKind::Dummy => {} } diff --git a/compiler/rustc_ast_lowering/src/delegation/generics.rs b/compiler/rustc_ast_lowering/src/delegation/generics.rs index cd7b23c18971d..4d9bc09faeecb 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::{GenericParamDefKind, TyCtxt}; use rustc_middle::{bug, ty}; use rustc_span::symbol::kw; -use rustc_span::{Ident, Span, sym}; +use rustc_span::{ErrorGuaranteed, Ident, Span, sym}; use crate::LoweringContext; use crate::delegation::resolution::resolver::DelegationResolver; @@ -281,7 +281,7 @@ impl<'hir> DelegationResolver<'_, 'hir> { &self, delegation: &'a Delegation, sig_id: DefId, - ) -> GenericsResolution<'a, 'hir> { + ) -> Result, ErrorGuaranteed> { let tcx = self.tcx(); let delegation_parent_kind = tcx.def_kind(tcx.local_parent(self.owner_id())); @@ -300,9 +300,8 @@ impl<'hir> DelegationResolver<'_, 'hir> { let qself_is_none = delegation.qself.is_none(); let parent_args = if let [.., parent_segment, _] = &delegation.path.segments[..] { - if let Some(res) = self.get_resolution_id(parent_segment.id) - && matches!(tcx.def_kind(res), DefKind::Trait | DefKind::TraitAlias) - { + let res = self.get_resolution_id(parent_segment.id)?; + if matches!(tcx.def_kind(res), DefKind::Trait | DefKind::TraitAlias) { sig_parent_params = &tcx.generics_of(sig_parent).own_params; self.get_user_args(parent_segment) .map(|args| ParentSegmentArgs::Specified(args)) @@ -314,7 +313,7 @@ impl<'hir> DelegationResolver<'_, 'hir> { ParentSegmentArgs::Invalid }; - GenericsResolution { + Ok(GenericsResolution { parent_args, sig_parent_params, qself_is_none, @@ -326,7 +325,7 @@ impl<'hir> DelegationResolver<'_, 'hir> { child_args: self.get_user_args( delegation.path.segments.last().expect("must be at least one segment"), ), - } + }) } fn get_user_args<'a>(&self, segment: &'a PathSegment) -> Option<&'a AngleBracketedArgs> { @@ -350,14 +349,14 @@ impl<'hir> DelegationResolver<'_, 'hir> { &self, delegation: &Delegation, sig_id: DefId, - ) -> GenericsGenerationResults<'hir> { + ) -> Result, ErrorGuaranteed> { let res @ GenericsResolution { trait_impl, generate_self, sig_child_params, sig_parent_params, .. - } = self.resolve_generics(delegation, sig_id); + } = self.resolve_generics(delegation, sig_id)?; // If we are in trait impl always generate function whose generics matches // those that are defined in trait. @@ -374,7 +373,7 @@ impl<'hir> DelegationResolver<'_, 'hir> { let child = GenericsGenerationResult::new(child); - return GenericsGenerationResults { parent, child, self_ty_propagation_kind: None }; + return Ok(GenericsGenerationResults { parent, child, self_ty_propagation_kind: None }); } let tcx = self.tcx(); @@ -421,7 +420,7 @@ impl<'hir> DelegationResolver<'_, 'hir> { DelegationGenerics::generate_all(sig_child_params, GenericsPosition::Child, trait_impl) }; - GenericsGenerationResults { + Ok(GenericsGenerationResults { parent: GenericsGenerationResult::new(parent_generics), child: GenericsGenerationResult::new(child_generics), self_ty_propagation_kind: match res.free_to_trait_delegation { @@ -435,7 +434,7 @@ impl<'hir> DelegationResolver<'_, 'hir> { }), false => None, }, - } + }) } /// Generates generic argument slots for user-specified `args` and diff --git a/compiler/rustc_ast_lowering/src/delegation/mod.rs b/compiler/rustc_ast_lowering/src/delegation/mod.rs index cd742a6c30671..08429a6025456 100644 --- a/compiler/rustc_ast_lowering/src/delegation/mod.rs +++ b/compiler/rustc_ast_lowering/src/delegation/mod.rs @@ -45,6 +45,7 @@ use hir::def::Res; use rustc_abi::ExternAbi; use rustc_ast as ast; use rustc_ast::*; +use rustc_hir::def::DefKind; use rustc_hir::{self as hir, FnDeclFlags}; use rustc_middle::ty::Asyncness; use rustc_span::def_id::DefId; @@ -249,20 +250,19 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut unused_target_expr = false; let block_id = self.lower_body(|this| { - let &DelegationResolution { - param_info, span, should_generate_block, is_method, .. - } = res; - + let &DelegationResolution { param_info, span, is_method, .. } = res; let ParamInfo { param_count, .. } = param_info; + let arguments_to_map = &res.sig_mapping.arguments_to_map; let mut parameters: Vec> = Vec::with_capacity(param_count); let mut args: Vec> = Vec::with_capacity(param_count); - let mut stmts: &[hir::Stmt<'hir>] = &[]; + let mut stmts = vec![]; // Consider non-specified target expression as generated, // as we do not want to emit error when target expression is // not specified. - unused_target_expr = block.is_some() && (param_count == 0 || !should_generate_block); + unused_target_expr = + block.is_some() && (param_count == 0 || arguments_to_map.is_empty()); for idx in 0..param_count { let (param, pat_node_id) = this.generate_param(is_method, idx, span); @@ -271,41 +271,38 @@ impl<'hir> LoweringContext<'_, 'hir> { let generate_arg = |this: &mut Self| this.generate_arg(is_method, idx, param.pat.hir_id, span); - let arg = if let Some(block) = block - && idx == 0 - && should_generate_block - { - let mut self_resolver = SelfResolver { - ctxt: this, - path_id: delegation.id, - self_param_id: pat_node_id, - }; - self_resolver.visit_block(block); - // Target expr needs to lower `self` path. - this.ident_and_label_to_local_id.insert(pat_node_id, param.pat.hir_id.local_id); - - // Lower with `HirId::INVALID` as we will use only expr and stmts. - // FIXME(fn_delegation): Alternatives for target expression lowering: - // https://github.com/rust-lang/rfcs/pull/3530#issuecomment-2197170600. - let block = this.lower_block_noalloc(HirId::INVALID, block, false); - - stmts = block.stmts; - - // The behavior of the delegation's target expression differs from the - // behavior of the usual block, where if there is no final expression - // the `()` is returned. In case of the similar situation in delegation - // (no final expression) we propagate first argument instead of replacing - // it with `()`. - if let Some(&expr) = block.expr { expr } else { generate_arg(this) } - } else { - generate_arg(this) - }; + let arg = block + .filter(|_| arguments_to_map.contains(&idx)) + .and_then(|block| { + let block = this.lower_block_maybe_more_than_once( + block, + pat_node_id, + param.pat.hir_id.local_id, + delegation.id, + ); + + stmts.push(block.stmts); + + // The behavior of the delegation's target expression differs from the + // behavior of the usual block, where if there is no final expression + // the `()` is returned. In case of the similar situation in delegation + // (no final expression) we propagate first argument instead of replacing + // it with `()`. + block.expr.copied() + }) + .unwrap_or_else(|| generate_arg(this)); args.push(arg); } - let (final_expr, hir_id) = - this.finalize_body_lowering(delegation, stmts, args, res, generics, span); + let (final_expr, hir_id) = this.finalize_body_lowering( + delegation, + this.arena.alloc_from_iter(stmts.into_iter().flatten().copied()), + args, + res, + generics, + span, + ); call_expr_id = hir_id; @@ -317,6 +314,48 @@ impl<'hir> LoweringContext<'_, 'hir> { (block_id, call_expr_id, unused_target_expr) } + fn lower_block_maybe_more_than_once( + &mut self, + block: &Block, + pat_node_id: NodeId, + param_local_id: hir::ItemLocalId, + delegation_id: NodeId, + ) -> hir::Block<'hir> { + let mut self_resolver = SelfResolver { + ctxt: self, + path_id: delegation_id, + self_param_id: pat_node_id, + overwrites: vec![], + }; + + self_resolver.visit_block(block); + + let overwrites = self_resolver.overwrites; + + // Target expr needs to lower `self` path. + self.ident_and_label_to_local_id.insert(pat_node_id, param_local_id); + + let block = cfg_select! { + debug_assertions => { + crate::re_lowering::ReloweringChecker::allow_relowering(self, |this| { + this.lower_block_noalloc(HirId::INVALID, block, false) + }) + }, + _ => self.lower_block_noalloc(HirId::INVALID, block, false) + }; + + // Remove node ids for which we overwrote resolution to generated param + // before block lowering as block can be relowered. We need to do it because + // check in `SelfResolver` uses `get_partial_res` to decide whether to overwrite + // resolution, and if it is already overwritten from previous block lowering this + // check will not pass. + for id in overwrites { + self.partial_res_overrides.remove(&id); + } + + block + } + fn finalize_body_lowering( &mut self, delegation: &Delegation, @@ -392,8 +431,12 @@ impl<'hir> LoweringContext<'_, 'hir> { let args = self.arena.alloc_from_iter(args); let call = self.mk_expr(hir::ExprKind::Call(callee_path, args), span); - let expr = if let Some((parent, of_trait)) = res.output_self_mapping { - let res = Res::SelfTyAlias { alias_to: parent.to_def_id(), is_trait_impl: of_trait }; + let expr = if res.sig_mapping.map_return { + let res = Res::SelfTyAlias { + alias_to: res.parent.to_def_id(), + is_trait_impl: self.tcx.def_kind(res.parent) == DefKind::Impl { of_trait: true }, + }; + let ident = Ident::new(kw::SelfUpper, span); let path = self.create_resolved_path(res, ident, span); @@ -453,11 +496,14 @@ impl<'hir> LoweringContext<'_, 'hir> { }) .unwrap_or_else(|| self.arena.alloc_from_iter(args_iter.consume_all(self))); + // Do not omit constraints as there might be some and they must be present in HIR (#158812). + let has_constraints = segment.args.is_some_and(|a| !a.constraints.is_empty()); + // Needed for better error messages (`trait-impl-wrong-args-count.rs` test). - segment.args = (!new_args.is_empty()).then(|| { + segment.args = (has_constraints || !new_args.is_empty()).then(|| { &*self.arena.alloc(hir::GenericArgs { args: new_args, - constraints: &[], + constraints: segment.args.map(|a| a.constraints).unwrap_or(&[]), parenthesized: hir::GenericArgsParentheses::No, span_ext: segment.args.map_or(span, |args| args.span_ext), }) @@ -538,6 +584,7 @@ struct SelfResolver<'a, 'b, 'hir> { ctxt: &'a mut LoweringContext<'b, 'hir>, path_id: NodeId, self_param_id: NodeId, + overwrites: Vec, } impl SelfResolver<'_, '_, '_> { @@ -546,6 +593,7 @@ impl SelfResolver<'_, '_, '_> { && let Some(Res::Local(sig_id)) = res.full_res() && sig_id == self.path_id { + self.overwrites.push(id); self.ctxt.partial_res_overrides.insert(id, self.self_param_id); } } diff --git a/compiler/rustc_ast_lowering/src/delegation/resolution.rs b/compiler/rustc_ast_lowering/src/delegation/resolution.rs index 3cb40d256ba8b..21fbed81b3e0b 100644 --- a/compiler/rustc_ast_lowering/src/delegation/resolution.rs +++ b/compiler/rustc_ast_lowering/src/delegation/resolution.rs @@ -6,7 +6,7 @@ use rustc_ast as ast; use rustc_ast::*; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; -use rustc_middle::span_bug; +use rustc_middle::{span_bug, ty}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::{ErrorGuaranteed, Span}; @@ -14,7 +14,8 @@ use crate::delegation::generics::GenericsGenerationResults; use crate::delegation::resolution::resolver::DelegationResolver; use crate::diagnostics::{ CycleInDelegationSignatureResolution, DelegationAttemptedBlockWithDefsDeletion, - DelegationBlockSpecifiedWhenNoParams, UnresolvedDelegationCallee, + DelegationAttemptedBlockWithDefsRelowering, DelegationBlockSpecifiedWhenNoParams, + UnresolvedDelegationCallee, }; /// Summary info about function parameters. @@ -30,21 +31,28 @@ pub(super) struct ParamInfo { pub splatted: Option, } +#[derive(Default)] +pub(super) struct SigMapping { + pub map_return: bool, + pub arguments_to_map: FxHashSet, +} + pub(super) struct DelegationResolution { pub sig_id: DefId, pub is_method: bool, pub param_info: ParamInfo, pub span: Span, - pub should_generate_block: bool, - pub call_path_res: Option, + pub call_path_res: DefId, pub source: DelegationSource, - pub output_self_mapping: Option<(LocalDefId, bool)>, + pub parent: LocalDefId, + pub sig_mapping: SigMapping, } pub(super) mod resolver { use rustc_ast::NodeId; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::TyCtxt; + use rustc_span::ErrorGuaranteed; use crate::LoweringContext; @@ -87,8 +95,10 @@ pub(super) mod resolver { } #[inline] - pub(crate) fn get_resolution_id(&self, id: NodeId) -> Option { - self.0.get_partial_res(id).and_then(|r| r.expect_full_res().opt_def_id()) + pub(crate) fn get_resolution_id(&self, id: NodeId) -> Result { + self.0.get_partial_res(id).and_then(|r| r.expect_full_res().opt_def_id()).ok_or_else( + || self.tcx().dcx().delayed_bug(format!("failed to resolve node {id:?}")), + ) } } } @@ -126,25 +136,31 @@ impl<'tcx> DelegationResolver<'_, 'tcx> { let sig = tcx.fn_sig(sig_id).skip_binder().skip_binder(); let param_count = sig.inputs().len() + usize::from(sig.c_variadic()); + let parent = tcx.local_parent(def_id); + + let (should_generate_block, contains_defs) = + self.check_block_soundness(delegation, sig_id, is_method, param_count)?; let res = DelegationResolution { is_method, span, sig_id, + parent, // FIXME(splat): use `sig.splatted()` once FnSig has it param_info: ParamInfo { param_count, c_variadic: sig.c_variadic(), splatted: None }, - should_generate_block: self.check_block_soundness( + source: delegation.source, + call_path_res: self.get_resolution_id(delegation.id)?, + sig_mapping: self.create_self_mapping( delegation, - sig_id, - is_method, - param_count, + span, + should_generate_block, + parent, + sig, + contains_defs, )?, - source: delegation.source, - call_path_res: self.get_resolution_id(delegation.id), - output_self_mapping: self.should_map_return_value(delegation), }; - Ok((res, self.resolve_and_generate_generics(delegation, sig_id))) + Ok((res, self.resolve_and_generate_generics(delegation, sig_id)?)) } fn check_for_cycles(&self, mut def_id: DefId, span: Span) -> Result<(), ErrorGuaranteed> { @@ -180,13 +196,13 @@ impl<'tcx> DelegationResolver<'_, 'tcx> { sig_id: DefId, is_method: bool, param_count: usize, - ) -> Result { + ) -> Result<(/* should generate block */ bool, /* contains defs */ bool), ErrorGuaranteed> { let tcx = self.tcx(); let should_generate_block = is_method || matches!(tcx.def_kind(sig_id), DefKind::Fn) || matches!(delegation.source, DelegationSource::Single); - let Some(block) = &delegation.body else { return Ok(should_generate_block) }; + let Some(block) = &delegation.body else { return Ok((should_generate_block, false)) }; // Report an error if user has explicitly specified delegation's target expression // in a single delegation when reused function has no params. @@ -194,44 +210,84 @@ impl<'tcx> DelegationResolver<'_, 'tcx> { let err = DelegationBlockSpecifiedWhenNoParams { span: block.span }; return Err(tcx.dcx().emit_err(err)); } - struct DefinitionsFinder<'a, 'hir> { - ctx: &'a DelegationResolver<'a, 'hir>, + resolver: &'a DelegationResolver<'a, 'hir>, } impl<'a> Visitor<'a> for DefinitionsFinder<'a, '_> { type Result = ControlFlow<()>; fn visit_id(&mut self, id: NodeId) -> Self::Result { - match self.ctx.is_definition(id) { + match self.resolver.is_definition(id) { true => ControlFlow::Break(()), false => ControlFlow::Continue(()), } } } - let mut collector = DefinitionsFinder { ctx: self }; + let mut collector = DefinitionsFinder { resolver: self }; let contains_defs = collector.visit_block(block).is_break(); // If there are definitions inside and we can't delete target expression, then report an error. // FIXME(fn_delegation): support deletion of target expression with defs inside. if should_generate_block || !contains_defs { - Ok(should_generate_block) + Ok((should_generate_block, contains_defs)) } else { Err(tcx.dcx().emit_err(DelegationAttemptedBlockWithDefsDeletion { span: block.span })) } } - fn should_map_return_value(&self, delegation: &Delegation) -> Option<(LocalDefId, bool)> { + fn create_self_mapping( + &self, + delegation: &Delegation, + span: Span, + should_generate_block: bool, + parent: LocalDefId, + sig: ty::FnSig<'tcx>, + contains_defs: bool, + ) -> Result { + let mut mapping = SigMapping::default(); + if should_generate_block { + mapping.arguments_to_map.insert(0); + } + + if self.can_perform_self_mapping(delegation, parent)? { + mapping.map_return = sig.output().is_param(0); + + let arguments_to_map = sig + .inputs() + .iter() + .enumerate() + .skip(1) // Already checked above. + .filter_map(|(idx, param)| param.is_param(0).then_some(idx)); + + mapping.arguments_to_map.extend(arguments_to_map); + } + + // We can't yet map more than one argument if there are definitions inside. + // FIXME(fn_delegation): support relowering with defs inside + if contains_defs && mapping.arguments_to_map.len() > 1 { + return Err(self + .tcx() + .dcx() + .emit_err(DelegationAttemptedBlockWithDefsRelowering { span })); + } + + Ok(mapping) + } + + fn can_perform_self_mapping( + &self, + delegation: &Delegation, + parent: LocalDefId, + ) -> Result { // Heuristic: don't do wrapping if there is no target expression. if delegation.body.is_none() { - return None; + return Ok(false); } let tcx = self.tcx(); - let parent = tcx.local_parent(self.owner_id()); - let parent_kind = tcx.def_kind(parent); // Apply wrapping for delegations inside // 1) Trait impls, as the return type of both signature function @@ -244,21 +300,13 @@ impl<'tcx> DelegationResolver<'_, 'tcx> { // 2) Inherent methods when delegating to trait, as we change the type of // `Self` to type of struct or enum we delegate from. if !matches!(tcx.def_kind(parent), DefKind::Impl { .. }) { - return None; + return Ok(false); } - let is_trait_impl = parent_kind == DefKind::Impl { of_trait: true }; - // Check that delegation path resolves to a trait AssocFn, not to a free method. - Some((parent, is_trait_impl)).filter(|_| { - self.get_resolution_id(delegation.id).is_some_and(|id| { - tcx.def_kind(id) == DefKind::AssocFn - // Check that the return type of the callee is `Self` param. - // After previous check we are sure that `sig_id` and `delegation.id` - // point to the same function. - && tcx.def_kind(tcx.parent(id)) == DefKind::Trait - && tcx.fn_sig(id).skip_binder().output().skip_binder().is_param(0) - }) - }) + // After previous check we are sure that `sig_id` and `delegation.id` + // point to the same function. + let id = self.get_resolution_id(delegation.id)?; + Ok(tcx.def_kind(id) == DefKind::AssocFn && tcx.def_kind(tcx.parent(id)) == DefKind::Trait) } } diff --git a/compiler/rustc_ast_lowering/src/diagnostics.rs b/compiler/rustc_ast_lowering/src/diagnostics.rs index 238a16d9b859d..2d559f97ae1e8 100644 --- a/compiler/rustc_ast_lowering/src/diagnostics.rs +++ b/compiler/rustc_ast_lowering/src/diagnostics.rs @@ -569,3 +569,12 @@ pub(crate) struct DelegationInfersMismatch { pub expected: Symbol, pub actual: Symbol, } + +#[derive(Diagnostic)] +#[diag( + "attempted to lower target expression with definitions more than once while mapping argument" +)] +pub(crate) struct DelegationAttemptedBlockWithDefsRelowering { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index f66d1ac16c907..4ed23e032d234 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -498,6 +498,18 @@ impl<'hir> LoweringContext<'_, 'hir> { } ExprKind::MacCall(_) => panic!("{:?} shouldn't exist here", e.span), + + ExprKind::DirectConstArg(_) => { + let e = self + .tcx + .dcx() + .struct_span_err( + e.span, + "expected expression, found `direct_const_arg!()` constant", + ) + .emit(); + hir::ExprKind::Err(e) + } }; hir::Expr { hir_id: expr_hir_id, kind, span } @@ -599,11 +611,7 @@ impl<'hir> LoweringContext<'_, 'hir> { arg }; - let anon_const = AnonConst { - id: node_id, - value: const_value, - mgca_disambiguation: MgcaDisambiguation::AnonConst, - }; + let anon_const = AnonConst { id: node_id, value: const_value }; generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const))); } else { real_args.push(arg); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 35e16ce78a8a8..868f5e27e89b8 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -100,6 +100,49 @@ pub fn provide(providers: &mut Providers) { providers.lower_to_hir = lower_to_hir; } +#[cfg(debug_assertions)] +pub(crate) mod re_lowering { + use rustc_ast::NodeId; + use rustc_ast::node_id::NodeMap; + use rustc_hir::{self as hir}; + + use crate::LoweringContext; + + #[derive(Debug, Default)] + pub(crate) struct ReloweringChecker { + node_id_to_local_id: NodeMap, + can_relower: bool, + } + + impl ReloweringChecker { + pub(crate) fn assert_node_is_not_relowered( + &mut self, + ast_node_id: NodeId, + local_id: hir::ItemLocalId, + ) { + if !self.can_relower { + let old = self.node_id_to_local_id.insert(ast_node_id, local_id); + assert_eq!(old, None); + } + } + + pub(crate) fn allow_relowering<'a, 'hir, TRes>( + ctx: &mut LoweringContext<'a, 'hir>, + op: impl FnOnce(&mut LoweringContext<'a, 'hir>) -> TRes, + ) -> TRes { + assert!(!ctx.relowering_checker.can_relower, "reentrant relowering is not supported"); + + ctx.relowering_checker.can_relower = true; + + let res = op(ctx); + + ctx.relowering_checker.can_relower = false; + + res + } + } +} + struct LoweringContext<'a, 'hir> { tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>, @@ -146,7 +189,7 @@ struct LoweringContext<'a, 'hir> { ident_and_label_to_local_id: NodeMap, /// NodeIds that are lowered inside the current HIR owner. Only used for duplicate lowering check. #[cfg(debug_assertions)] - node_id_to_local_id: NodeMap, + relowering_checker: re_lowering::ReloweringChecker, /// The `NodeId` space is split in two. /// `0..resolver.next_node_id` are created by the resolver on the AST. /// The higher part `resolver.next_node_id..next_node_id` are created during lowering. @@ -205,8 +248,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // and we never call `lower_node_id(owner)`. item_local_id_counter: hir::ItemLocalId::new(1), ident_and_label_to_local_id: Default::default(), + #[cfg(debug_assertions)] - node_id_to_local_id: Default::default(), + relowering_checker: Default::default(), + trait_map: Default::default(), next_node_id: resolver.next_node_id, node_id_to_def_id: NodeMap::default(), @@ -808,7 +853,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let current_ident_and_label_to_local_id = mem::take(&mut self.ident_and_label_to_local_id); #[cfg(debug_assertions)] - let current_node_id_to_local_id = mem::take(&mut self.node_id_to_local_id); + let current_relowering_checker = mem::take(&mut self.relowering_checker); let current_trait_map = mem::take(&mut self.trait_map); let current_owner = mem::replace(&mut self.current_hir_id_owner, owner_id); let current_local_counter = @@ -824,10 +869,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Always allocate the first `HirId` for the owner itself. #[cfg(debug_assertions)] - { - let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO); - debug_assert_eq!(_old, None); - } + self.relowering_checker.assert_node_is_not_relowered(owner, hir::ItemLocalId::ZERO); let item = f(self); assert_eq!(owner_id, item.def_id()); @@ -845,7 +887,7 @@ impl<'hir> LoweringContext<'_, 'hir> { #[cfg(debug_assertions)] { - self.node_id_to_local_id = current_node_id_to_local_id; + self.relowering_checker = current_relowering_checker; } self.trait_map = current_trait_map; self.current_hir_id_owner = current_owner; @@ -936,10 +978,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Check whether the same `NodeId` is lowered more than once. #[cfg(debug_assertions)] - { - let old = self.node_id_to_local_id.insert(ast_node_id, local_id); - assert_eq!(old, None); - } + self.relowering_checker.assert_node_is_not_relowered(ast_node_id, local_id); hir_id } @@ -1439,6 +1478,16 @@ impl<'hir> LoweringContext<'_, 'hir> { } } } + TyKind::DirectConstArg(expr) + if self.tcx.features().min_generic_const_args() => + { + let ct = match self.can_lower_expr_to_const_arg_direct(expr) { + Ok(()) => self.lower_expr_to_const_arg_direct(expr, None), + Err(e) => e.emit(self), + }; + let ct = self.arena.alloc(ct); + return GenericArg::Const(ct.try_as_ambig_ct().unwrap()); + } _ => {} } GenericArg::Type(self.lower_ty_alloc(ty, itctx).try_as_ambig_ty().unwrap()) @@ -1711,6 +1760,14 @@ impl<'hir> LoweringContext<'_, 'hir> { ); hir::TyKind::Err(guar) } + TyKind::DirectConstArg(_) => { + let e = self + .tcx + .dcx() + .struct_span_err(t.span, "expected type, found `direct_const_arg!()` constant") + .emit(); + hir::TyKind::Err(e) + } TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"), }; @@ -2629,23 +2686,86 @@ impl<'hir> LoweringContext<'_, 'hir> { } #[instrument(level = "debug", skip(self), ret)] - fn lower_expr_to_const_arg_direct(&mut self, expr: &Expr) -> hir::ConstArg<'hir> { - let span = self.lower_span(expr.span); - - let overly_complex_const = |this: &mut Self| { - let msg = "complex const arguments must be placed inside of a `const` block"; - let e = if expr::WillCreateDefIdsVisitor.visit_expr(expr).is_break() { - // FIXME(mgca): make this non-fatal once we have a better way to handle - // nested items in const args - // Issue: https://github.com/rust-lang/rust/issues/154539 - this.dcx().struct_span_fatal(expr.span, msg).emit() - } else { - this.dcx().struct_span_err(expr.span, msg).emit() - }; + fn can_lower_expr_to_const_arg_direct( + &mut self, + expr: &Expr, + ) -> Result<(), UnrepresentableConstArgError> { + let is_mgca = self.tcx.features().min_generic_const_args(); + // Note the only stable case is currently ExprKind::Path. All others have an is_mgca guard. + match &expr.kind { + ExprKind::Call(func, args) + if is_mgca && let ExprKind::Path(_qself, _path) = &func.kind => + { + for arg in args { + self.can_lower_expr_to_const_arg_direct(arg)?; + } + Ok(()) + } + ExprKind::Tup(exprs) if is_mgca => { + for expr in exprs { + self.can_lower_expr_to_const_arg_direct(expr)?; + } + Ok(()) + } + ExprKind::Path(qself, path) + if is_mgca + || path.is_potential_trivial_const_arg() + && matches!( + self.get_partial_res(expr.id) + .and_then(|partial_res| partial_res.full_res()), + Some(Res::Def(DefKind::ConstParam, _)) + ) => + { + Ok(()) + } + ExprKind::Struct(se) if is_mgca => { + for f in &se.fields { + self.can_lower_expr_to_const_arg_direct(&f.expr)?; + } + Ok(()) + } + ExprKind::Array(elements) if is_mgca => { + for element in elements { + self.can_lower_expr_to_const_arg_direct(element)?; + } + Ok(()) + } + ExprKind::Underscore if is_mgca => Ok(()), + ExprKind::Block(block, _) + if is_mgca + && let [stmt] = block.stmts.as_slice() + && let StmtKind::Expr(expr) = &stmt.kind => + { + self.can_lower_expr_to_const_arg_direct(expr) + } + ExprKind::Lit(literal) if is_mgca => Ok(()), + ExprKind::Unary(UnOp::Neg, inner_expr) + if is_mgca && let ExprKind::Lit(_) = &inner_expr.kind => + { + Ok(()) + } + ExprKind::ConstBlock(anon) if is_mgca => Ok(()), + ExprKind::DirectConstArg(expr) if is_mgca => { + // Always report this as able to be represented directly. If it turns out not to be, + // `lower_expr_to_const_arg_direct` will report an error. + Ok(()) + } + _ => Err(UnrepresentableConstArgError::new(expr)), + } + } - ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(e), span } - }; + /// It is not allowed to call this function without checking can_lower_expr_to_const_arg_direct + /// first, as we assume all feature gates/etc. have been checked already. + #[instrument(level = "debug", skip(self), ret)] + fn lower_expr_to_const_arg_direct( + &mut self, + expr: &Expr, + id_override: Option, + ) -> hir::ConstArg<'hir> { + debug_assert!(self.can_lower_expr_to_const_arg_direct(expr).is_ok()); + let span = self.lower_span(expr.span); + let node_id = id_override.unwrap_or(expr.id); match &expr.kind { ExprKind::Call(func, args) if let ExprKind::Path(qself, path) = &func.kind => { let qpath = self.lower_qpath( @@ -2659,23 +2779,27 @@ impl<'hir> LoweringContext<'_, 'hir> { ); let lowered_args = self.arena.alloc_from_iter(args.iter().map(|arg| { - let const_arg = self.lower_expr_to_const_arg_direct(arg); + let const_arg = self.lower_expr_to_const_arg_direct(arg, None); &*self.arena.alloc(const_arg) })); ConstArg { - hir_id: self.next_id(), + hir_id: self.lower_node_id(node_id), kind: hir::ConstArgKind::TupleCall(qpath, lowered_args), span, } } ExprKind::Tup(exprs) => { let exprs = self.arena.alloc_from_iter(exprs.iter().map(|expr| { - let expr = self.lower_expr_to_const_arg_direct(&expr); + let expr = self.lower_expr_to_const_arg_direct(expr, None); &*self.arena.alloc(expr) })); - ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Tup(exprs), span } + ConstArg { + hir_id: self.lower_node_id(node_id), + kind: hir::ConstArgKind::Tup(exprs), + span, + } } ExprKind::Path(qself, path) => { let qpath = self.lower_qpath( @@ -2689,7 +2813,11 @@ impl<'hir> LoweringContext<'_, 'hir> { None, ); - ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath), span } + ConstArg { + hir_id: self.lower_node_id(node_id), + kind: hir::ConstArgKind::Path(qpath), + span, + } } ExprKind::Struct(se) => { let path = self.lower_qpath( @@ -2711,7 +2839,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // then go unused as the `Target::ExprField` is not actually // corresponding to `Node::ExprField`. self.lower_attrs(hir_id, &f.attrs, f.span, Target::ExprField); - let expr = self.lower_expr_to_const_arg_direct(&f.expr); + let expr = self.lower_expr_to_const_arg_direct(&f.expr, None); &*self.arena.alloc(hir::ConstArgExprField { hir_id, @@ -2722,14 +2850,14 @@ impl<'hir> LoweringContext<'_, 'hir> { })); ConstArg { - hir_id: self.next_id(), + hir_id: self.lower_node_id(node_id), kind: hir::ConstArgKind::Struct(path, fields), span, } } ExprKind::Array(elements) => { let lowered_elems = self.arena.alloc_from_iter(elements.iter().map(|element| { - let const_arg = self.lower_expr_to_const_arg_direct(element); + let const_arg = self.lower_expr_to_const_arg_direct(element, None); &*self.arena.alloc(const_arg) })); let array_expr = self.arena.alloc(hir::ConstArgArrayExpr { @@ -2738,31 +2866,28 @@ impl<'hir> LoweringContext<'_, 'hir> { }); ConstArg { - hir_id: self.next_id(), + hir_id: self.lower_node_id(node_id), kind: hir::ConstArgKind::Array(array_expr), span, } } ExprKind::Underscore => ConstArg { - hir_id: self.lower_node_id(expr.id), + hir_id: self.lower_node_id(node_id), kind: hir::ConstArgKind::Infer(()), span, }, - ExprKind::Block(block, _) => { + ExprKind::Block(block, _) if let [stmt] = block.stmts.as_slice() - && let StmtKind::Expr(expr) = &stmt.kind - { - return self.lower_expr_to_const_arg_direct(expr); - } - - overly_complex_const(self) + && let StmtKind::Expr(expr) = &stmt.kind => + { + return self.lower_expr_to_const_arg_direct(expr, id_override); } ExprKind::Lit(literal) => { let span = self.lower_span(expr.span); let literal = self.lower_lit(literal, span); ConstArg { - hir_id: self.lower_node_id(expr.id), + hir_id: self.lower_node_id(node_id), kind: hir::ConstArgKind::Literal { lit: literal.node, negated: false }, span, } @@ -2773,29 +2898,45 @@ impl<'hir> LoweringContext<'_, 'hir> { let span = self.lower_span(expr.span); let literal = self.lower_lit(literal, span); - if !matches!(literal.node, LitKind::Int(..)) { + let kind = if !matches!(literal.node, LitKind::Int(..)) { let err = self.dcx().struct_span_err(expr.span, "negated literal must be an integer"); - - return ConstArg { - hir_id: self.next_id(), - kind: hir::ConstArgKind::Error(err.emit()), - span, - }; - } - - ConstArg { - hir_id: self.lower_node_id(expr.id), - kind: hir::ConstArgKind::Literal { lit: literal.node, negated: true }, - span, - } + hir::ConstArgKind::Error(err.emit()) + } else { + hir::ConstArgKind::Literal { lit: literal.node, negated: true } + }; + ConstArg { hir_id: self.lower_node_id(node_id), kind, span } } ExprKind::ConstBlock(anon_const) => { + // Do not use lower_anon_const_to_const_arg, as that attempts to represent the body + // directly. Instead, force an anon const. let def_id = self.local_def_id(anon_const.id); assert_eq!(DefKind::InlineConst, self.tcx.def_kind(def_id)); - self.lower_anon_const_to_const_arg(anon_const, span) + let lowered_anon = self.lower_anon_const_to_anon_const(anon_const, span); + ConstArg { + hir_id: self.lower_node_id(node_id), + kind: hir::ConstArgKind::Anon(lowered_anon), + span, + } + } + ExprKind::DirectConstArg(expr) => { + // `can_lower_expr_to_const_arg_direct` always returns success upon encountering a + // ExprKind::DirectConstArg, which effectively forces the expression to be lowered + // as a direct arg. If it actually turns out to not be possible, emit an error + // instead. + match self.can_lower_expr_to_const_arg_direct(expr) { + Ok(()) => self.lower_expr_to_const_arg_direct(expr, id_override), + Err(err) => err.emit(self), + } + } + _ => { + span_bug!( + expr.span, + "lower_expr_to_const_arg_direct encountered an unlowerable expression, either \ + can_lower_expr_to_const_arg_direct returned Ok() on something it shouldn't \ + have, or you forgot to check can_lower_expr_to_const_arg_direct first" + ); } - _ => overly_complex_const(self), } } @@ -2814,67 +2955,23 @@ impl<'hir> LoweringContext<'_, 'hir> { anon: &AnonConst, span: Span, ) -> hir::ConstArg<'hir> { - let tcx = self.tcx; - - // We cannot change parsing depending on feature gates available, - // we can only require feature gates to be active as a delayed check. - // Thus we just parse anon consts generally and make the real decision - // making in ast lowering. - // FIXME(min_generic_const_args): revisit once stable - if tcx.features().min_generic_const_args() { - return match anon.mgca_disambiguation { - MgcaDisambiguation::AnonConst => { - let lowered_anon = self.lower_anon_const_to_anon_const(anon, span); - ConstArg { - hir_id: self.next_id(), - kind: hir::ConstArgKind::Anon(lowered_anon), - span: lowered_anon.span, - } - } - MgcaDisambiguation::Direct => self.lower_expr_to_const_arg_direct(&anon.value), - }; - } - - // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments - // currently have to be wrapped in curly brackets, so it's necessary to special-case. - let expr = if let ExprKind::Block(block, _) = &anon.value.kind - && let [stmt] = block.stmts.as_slice() - && let StmtKind::Expr(expr) = &stmt.kind - && let ExprKind::Path(..) = &expr.kind - { - expr - } else { + // Stable only allows one nesting of blocks for directly represented paths. mGCA allows + // arbitrarily many, and are handled inside lower_expr_to_const_arg_direct for consistency. + let expr = if self.tcx.features().min_generic_const_args() { &anon.value + } else { + anon.value.maybe_unwrap_block() }; - let maybe_res = - self.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res()); - if let ExprKind::Path(qself, path) = &expr.kind - && path.is_potential_trivial_const_arg() - && matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))) - { - let qpath = self.lower_qpath( - expr.id, - qself, - path, - ParamMode::Explicit, - AllowReturnTypeNotation::No, - ImplTraitContext::Disallowed(ImplTraitPosition::Path), - None, - ); - - return ConstArg { - hir_id: self.lower_node_id(anon.id), - kind: hir::ConstArgKind::Path(qpath), - span: self.lower_span(expr.span), - }; + if self.can_lower_expr_to_const_arg_direct(expr).is_ok() { + return self.lower_expr_to_const_arg_direct(expr, Some(anon.id)); } let lowered_anon = self.lower_anon_const_to_anon_const(anon, anon.value.span); ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon), - span: self.lower_span(expr.span), + span: self.lower_span(anon.value.span), } } @@ -3170,3 +3267,36 @@ impl<'hir> GenericArgsCtor<'hir> { this.arena.alloc(ga) } } + +#[derive(Debug)] +struct UnrepresentableConstArgError { + span: Span, + will_create_def_ids: bool, +} + +impl UnrepresentableConstArgError { + fn new(expr: &Expr) -> Self { + Self { + span: expr.span, + will_create_def_ids: expr::WillCreateDefIdsVisitor.visit_expr(expr).is_break(), + } + } + + fn emit<'hir>(self, lowering_context: &mut LoweringContext<'_, 'hir>) -> ConstArg<'hir> { + let msg = "complex const arguments must be placed inside of a `const` block"; + let e = if self.will_create_def_ids { + // FIXME(mgca): make this non-fatal once we have a better way to handle + // nested items in const args + // Issue: https://github.com/rust-lang/rust/issues/154539 + lowering_context.dcx().struct_span_fatal(self.span, msg).emit() + } else { + lowering_context.dcx().struct_span_err(self.span, msg).emit() + }; + + ConstArg { + hir_id: lowering_context.next_id(), + kind: hir::ConstArgKind::Error(e), + span: self.span, + } + } +} diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 8b2da2acaa520..e6e9ad7f3ef8c 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1441,6 +1441,12 @@ impl<'a> State<'a> { self.end(ib); self.pclose(); } + ast::TyKind::DirectConstArg(expr) => { + self.word_nbsp("core::direct_const_arg!"); + self.popen(); + self.print_expr(expr, FixupContext::default()); + self.pclose() + } } self.end(ib); } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 176e91e544ec5..4f3281641359d 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -883,6 +883,12 @@ impl<'a> State<'a> { self.word("/*DUMMY*/"); self.pclose(); } + ast::ExprKind::DirectConstArg(expr) => { + self.word_nbsp("core::direct_const_arg!"); + self.popen(); + self.print_expr(expr, FixupContext::default()); + self.pclose() + } } self.ann.post(self, AnnNode::Expr(expr)); diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index f15acc154baf3..1bc2bc8342559 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -323,6 +323,7 @@ impl<'cx, 'a> Context<'cx, 'a> { | ExprKind::Yeet(_) | ExprKind::Become(_) | ExprKind::Yield(_) + | ExprKind::DirectConstArg(_) | ExprKind::UnsafeBinderCast(..) => {} } } diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 311a24280cfb7..bd5bf3a687d92 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -16,7 +16,7 @@ mod llvm_enzyme { use rustc_ast::{ self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocItemKind, BindingMode, FnRetTy, FnSig, GenericArg, GenericArgs, GenericParamKind, Generics, ItemKind, - MetaItemInner, MgcaDisambiguation, PatKind, Path, PathSegment, TyKind, Visibility, + MetaItemInner, PatKind, Path, PathSegment, TyKind, Visibility, }; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_hir::attrs::RustcAutodiff; @@ -602,11 +602,7 @@ mod llvm_enzyme { } GenericParamKind::Const { .. } => { let expr = ecx.expr_path(ast::Path::from_ident(p.ident)); - let anon_const = AnonConst { - id: ast::DUMMY_NODE_ID, - value: expr, - mgca_disambiguation: MgcaDisambiguation::Direct, - }; + let anon_const = AnonConst { id: ast::DUMMY_NODE_ID, value: expr }; Some(AngleBracketedArg::Arg(GenericArg::Const(anon_const))) } GenericParamKind::Lifetime { .. } => None, @@ -861,7 +857,6 @@ mod llvm_enzyme { let anon_const = rustc_ast::AnonConst { id: ast::DUMMY_NODE_ID, value: ecx.expr_usize(span, 1 + x.width as usize), - mgca_disambiguation: MgcaDisambiguation::Direct, }; TyKind::Array(ty.clone(), anon_const) }; @@ -876,7 +871,6 @@ mod llvm_enzyme { let anon_const = rustc_ast::AnonConst { id: ast::DUMMY_NODE_ID, value: ecx.expr_usize(span, x.width as usize), - mgca_disambiguation: MgcaDisambiguation::Direct, }; let kind = TyKind::Array(ty.clone(), anon_const); let ty = diff --git a/compiler/rustc_builtin_macros/src/direct_const_arg.rs b/compiler/rustc_builtin_macros/src/direct_const_arg.rs new file mode 100644 index 0000000000000..51c169134e03f --- /dev/null +++ b/compiler/rustc_builtin_macros/src/direct_const_arg.rs @@ -0,0 +1,39 @@ +use rustc_ast::ast; +use rustc_ast::tokenstream::TokenStream; +use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; +use rustc_span::Span; + +use crate::util::get_single_expr_from_tts; + +pub(crate) fn expand<'cx>( + cx: &'cx mut ExtCtxt<'_>, + span: Span, + tts: TokenStream, +) -> MacroExpanderResult<'cx> { + let ExpandResult::Ready(expr) = get_single_expr_from_tts(cx, span, tts, "direct_const_arg!") + else { + return ExpandResult::Retry(()); + }; + let expr = match expr { + Ok(expr) => expr, + Err(err) => return ExpandResult::Ready(DummyResult::any(span, err)), + }; + + let id = ast::DUMMY_NODE_ID; + ExpandResult::Ready(Box::new(base::MacEager { + expr: Some(Box::new(ast::Expr { + id, + kind: ast::ExprKind::DirectConstArg(expr.clone()), + span, + attrs: Default::default(), + tokens: None, + })), + ty: Some(Box::new(ast::Ty { + id, + kind: ast::TyKind::DirectConstArg(expr), + span, + tokens: None, + })), + ..Default::default() + })) +} diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 4a5ff44c402ab..991f773df55f4 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -34,6 +34,7 @@ mod define_opaque; mod derive; mod deriving; mod diagnostics; +mod direct_const_arg; mod edition_panic; mod eii; mod env; @@ -80,6 +81,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { concat_bytes: concat_bytes::expand_concat_bytes, const_format_args: format::expand_format_args, core_panic: edition_panic::expand_panic, + direct_const_arg: direct_const_arg::expand, env: env::expand_env, file: source_util::expand_file, format_args: format::expand_format_args, diff --git a/compiler/rustc_builtin_macros/src/pattern_type.rs b/compiler/rustc_builtin_macros/src/pattern_type.rs index 53ab3fcd9b34b..065ba9f6a2096 100644 --- a/compiler/rustc_builtin_macros/src/pattern_type.rs +++ b/compiler/rustc_builtin_macros/src/pattern_type.rs @@ -1,5 +1,5 @@ use rustc_ast::tokenstream::TokenStream; -use rustc_ast::{AnonConst, DUMMY_NODE_ID, MgcaDisambiguation, Ty, TyPat, TyPatKind, ast, token}; +use rustc_ast::{AnonConst, DUMMY_NODE_ID, Ty, TyPat, TyPatKind, ast, token}; use rustc_errors::PResult; use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; use rustc_parse::exp; @@ -60,20 +60,8 @@ fn ty_pat(kind: TyPatKind, span: Span) -> TyPat { fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> TyPat { let kind = match pat.kind { ast::PatKind::Range(start, end, include_end) => TyPatKind::Range( - start.map(|value| { - Box::new(AnonConst { - id: DUMMY_NODE_ID, - value, - mgca_disambiguation: MgcaDisambiguation::Direct, - }) - }), - end.map(|value| { - Box::new(AnonConst { - id: DUMMY_NODE_ID, - value, - mgca_disambiguation: MgcaDisambiguation::Direct, - }) - }), + start.map(|value| Box::new(AnonConst { id: DUMMY_NODE_ID, value })), + end.map(|value| Box::new(AnonConst { id: DUMMY_NODE_ID, value })), include_end, ), ast::PatKind::Or(variants) => { diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 804547745c5d5..23cf01a84f7fd 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1180,7 +1180,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { // vs. copying a struct with mixed types requires different derivative handling. // The TypeTree tells Enzyme exactly what memory layout to expect. if let Some(tt) = tt { - crate::typetree::add_tt(self.cx().llmod, self.cx().llcx, memcpy, tt); + crate::typetree::add_tt(self, memcpy, tt); } } diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs index ee17468ec0c03..10e152a7c8c63 100644 --- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs +++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs @@ -143,7 +143,6 @@ pub(crate) fn adjust_activity_to_abi<'tcx>( // FIXME(ZuseZ4): This logic is a bit more complicated than it should be, can we simplify it // using iterators and peek()? fn match_args_from_caller_to_enzyme<'ll, 'tcx>( - cx: &SimpleCx<'ll>, builder: &mut Builder<'_, 'll, 'tcx>, width: u32, args: &mut Vec<&'ll Value>, @@ -157,6 +156,7 @@ fn match_args_from_caller_to_enzyme<'ll, 'tcx>( // need to match those. // FIXME(ZuseZ4): This logic is a bit more complicated than it should be, can we simplify it // using iterators and peek()? + let cx = &builder.scx; let mut outer_pos: usize = 0; let mut activity_pos = 0; @@ -292,8 +292,7 @@ fn match_args_from_caller_to_enzyme<'ll, 'tcx>( // FIXME(ZuseZ4): `outer_fn` should include upstream safety checks to // cover some assumptions of enzyme/autodiff, which could lead to UB otherwise. pub(crate) fn generate_enzyme_call<'ll, 'tcx>( - builder: &mut Builder<'_, 'll, 'tcx>, - cx: &SimpleCx<'ll>, + bx: &mut Builder<'_, 'll, 'tcx>, fn_to_diff: &'ll Value, outer_name: &str, ret_ty: &'ll Type, @@ -303,6 +302,7 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>( dest_place: Option>, fnc_tree: FncTree, ) -> IntrinsicResult<'tcx, &'ll Value> { + let cx: &SimpleCx<'ll> = &bx.scx; // We have to pick the name depending on whether we want forward or reverse mode autodiff. let mut ad_name: String = match attrs.mode { DiffMode::Forward => "__enzyme_fwddiff", @@ -369,34 +369,27 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>( args.push(cx.get_const_int(cx.type_i64(), attrs.width as u64)); } - match_args_from_caller_to_enzyme( - &cx, - builder, - attrs.width, - &mut args, - &attrs.input_activity, - fn_args, - ); + match_args_from_caller_to_enzyme(bx, attrs.width, &mut args, &attrs.input_activity, fn_args); if !fnc_tree.args.is_empty() || !fnc_tree.ret.0.is_empty() { - crate::typetree::add_tt(cx.llmod, cx.llcx, fn_to_diff, fnc_tree); + crate::typetree::add_tt(&bx, fn_to_diff, fnc_tree); } - let call = builder.call(enzyme_ty, None, None, ad_fn, &args, None, None); + let call = bx.call(enzyme_ty, None, None, ad_fn, &args, None, None); - let fn_ret_ty = builder.cx.val_ty(call); - if fn_ret_ty == builder.cx.type_void() || fn_ret_ty == builder.cx.type_struct(&[], false) { + let fn_ret_ty = bx.cx.val_ty(call); + if fn_ret_ty == bx.cx.type_void() || fn_ret_ty == bx.cx.type_struct(&[], false) { // If we return void or an empty struct, then our caller (due to how we generated it) // does not expect a return value. As such, we have no pointer (or place) into which // we could store our value, and would store into an undef, which would cause UB. // As such, we just ignore the return value in those cases. IntrinsicResult::Operand(OperandValue::ZeroSized) } else if let Some(dest_place) = dest_place { - builder.store_to_place(call, dest_place); + bx.store_to_place(call, dest_place); IntrinsicResult::WroteIntoPlace } else { IntrinsicResult::Operand( - OperandRef::from_immediate_or_packed_pair(builder, call, dest_layout).val, + OperandRef::from_immediate_or_packed_pair(bx, call, dest_layout).val, ) } } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 7bd604bdbbd76..bd7a4cfe38d48 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -225,7 +225,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { ) } sym::autodiff => { - return codegen_autodiff(self, tcx, instance, args, result_layout, result_place); + return codegen_autodiff(self, instance, args, result_layout, result_place); } sym::offload => { if tcx.sess.opts.unstable_opts.offload.is_empty() { @@ -1743,12 +1743,12 @@ fn codegen_retag_inner<'ll, 'tcx>( fn codegen_autodiff<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, - tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>, args: &[OperandRef<'tcx, &'ll Value>], result_layout: ty::layout::TyAndLayout<'tcx>, result_place: Option>, ) -> IntrinsicResult<'tcx, &'ll Value> { + let tcx = bx.tcx; if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) { let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutEnable); } @@ -1815,7 +1815,6 @@ fn codegen_autodiff<'ll, 'tcx>( // Build body generate_enzyme_call( bx, - bx.cx, fn_to_diff, &diff_symbol, llret_ty, diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index 195e050a9b651..68ec7870811d2 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -66,6 +66,7 @@ unsafe extern "C" { NameLen: libc::size_t, ) -> Option<&Value>; + pub(crate) safe fn LLVMRustIsCall(V: &Value) -> bool; } unsafe extern "C" { @@ -292,6 +293,11 @@ pub(crate) mod Enzyme_AD { unsafe { (self.EnzymeTypeTreeToString)(tree) } } + pub(crate) fn tree_to_cstr(&self, tree: *mut EnzymeTypeTree) -> &std::ffi::CStr { + let c_str = self.tree_to_string(tree); + unsafe { std::ffi::CStr::from_ptr(c_str) } + } + pub(crate) fn tree_to_string_free(&self, ch: *const c_char) { unsafe { (self.EnzymeTypeTreeToStringFree)(ch) } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index e9bc6ae0e80ef..a2d17e93b4996 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -76,6 +76,21 @@ pub(crate) fn CreateAttrStringValue<'ll>( ) } } +pub(crate) fn CreateAttrStringValueFromCStr<'ll>( + llcx: &'ll Context, + attr: &std::ffi::CStr, + value: &std::ffi::CStr, +) -> &'ll Attribute { + unsafe { + LLVMCreateStringAttribute( + llcx, + (*attr).as_ptr(), + (*attr).to_bytes().len() as c_uint, + (*value).as_ptr(), + (*value).to_bytes().len() as c_uint, + ) + } +} pub(crate) fn CreateAttrString<'ll>(llcx: &'ll Context, attr: &str) -> &'ll Attribute { unsafe { diff --git a/compiler/rustc_codegen_llvm/src/typetree.rs b/compiler/rustc_codegen_llvm/src/typetree.rs index 4f433f273c8cc..7c2e09227e46b 100644 --- a/compiler/rustc_codegen_llvm/src/typetree.rs +++ b/compiler/rustc_codegen_llvm/src/typetree.rs @@ -1,35 +1,47 @@ -use std::ffi::{CString, c_char, c_uint}; +use std::ffi::{CString, c_char}; -use rustc_ast::expand::typetree::{FncTree, TypeTree as RustTypeTree}; +use rustc_ast::expand::typetree::{FncTree, Kind, TypeTree as RustTypeTree}; use crate::attributes; +use crate::context::FullCx; use crate::llvm::{self, EnzymeWrapper, Value}; fn to_enzyme_typetree( - rust_typetree: RustTypeTree, + rust_typetree: &RustTypeTree, _data_layout: &str, llcx: &llvm::Context, -) -> llvm::TypeTree { +) -> (llvm::TypeTree, Vec) { let mut enzyme_tt = llvm::TypeTree::new(); - process_typetree_recursive(&mut enzyme_tt, &rust_typetree, &[], llcx); - enzyme_tt + let extra_ints = process_typetree_recursive(&mut enzyme_tt, &rust_typetree, &[], llcx); + + let mut int_vec = vec![]; + for _ in 0..extra_ints { + let mut int_tt = llvm::TypeTree::new(); + int_tt.insert(&[0], llvm::CConcreteType::DT_Integer, llcx); + int_vec.push(int_tt); + } + + (enzyme_tt, int_vec) } + fn process_typetree_recursive( enzyme_tt: &mut llvm::TypeTree, rust_typetree: &RustTypeTree, parent_indices: &[i64], llcx: &llvm::Context, -) { +) -> u32 { + let mut extra_ints = 0; for rust_type in &rust_typetree.0 { let concrete_type = match rust_type.kind { - rustc_ast::expand::typetree::Kind::Anything => llvm::CConcreteType::DT_Anything, - rustc_ast::expand::typetree::Kind::Integer => llvm::CConcreteType::DT_Integer, - rustc_ast::expand::typetree::Kind::Pointer => llvm::CConcreteType::DT_Pointer, - rustc_ast::expand::typetree::Kind::Half => llvm::CConcreteType::DT_Half, - rustc_ast::expand::typetree::Kind::Float => llvm::CConcreteType::DT_Float, - rustc_ast::expand::typetree::Kind::Double => llvm::CConcreteType::DT_Double, - rustc_ast::expand::typetree::Kind::F128 => llvm::CConcreteType::DT_FP128, - rustc_ast::expand::typetree::Kind::Unknown => llvm::CConcreteType::DT_Unknown, + Kind::Anything => llvm::CConcreteType::DT_Anything, + Kind::Integer => llvm::CConcreteType::DT_Integer, + Kind::Pointer => llvm::CConcreteType::DT_Pointer, + Kind::RustSlice => llvm::CConcreteType::DT_Pointer, + Kind::Half => llvm::CConcreteType::DT_Half, + Kind::Float => llvm::CConcreteType::DT_Float, + Kind::Double => llvm::CConcreteType::DT_Double, + Kind::F128 => llvm::CConcreteType::DT_FP128, + Kind::Unknown => llvm::CConcreteType::DT_Unknown, }; let mut indices = parent_indices.to_vec(); @@ -43,21 +55,28 @@ fn process_typetree_recursive( enzyme_tt.insert(&indices, concrete_type, llcx); - if rust_type.kind == rustc_ast::expand::typetree::Kind::Pointer + if matches!(rust_type.kind, Kind::RustSlice) { + // We lower slices to `ptr,int`, so add the int here. + extra_ints += 1; + } + + if matches!(rust_type.kind, Kind::Pointer | Kind::RustSlice) && !rust_type.child.0.is_empty() { process_typetree_recursive(enzyme_tt, &rust_type.child, &indices, llcx); } } + extra_ints +} + +// Describes all the locations in which we know how to apply an Enzyme TypeTree. +enum TTLocation { + Definition, + Callsite, } #[cfg_attr(not(feature = "llvm_enzyme"), allow(unused))] -pub(crate) fn add_tt<'ll>( - llmod: &'ll llvm::Module, - llcx: &'ll llvm::Context, - fn_def: &'ll Value, - tt: FncTree, -) { +pub(crate) fn add_tt<'tcx, 'll>(cx: &FullCx<'ll, 'tcx>, fn_def: &'ll Value, tt: FncTree) { // TypeTree processing uses functions from Enzyme, which we might not have available if we did // not build this compiler with `llvm_enzyme`. This feature is not strictly necessary, but // skipping this function increases the chance that Enzyme fails to compile some code. @@ -66,6 +85,16 @@ pub(crate) fn add_tt<'ll>( #[cfg(not(feature = "llvm_enzyme"))] return; + let tcx = cx.tcx; + if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) { + return; + } + if tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::NoTT) { + return; + } + + let llmod = cx.llmod; + let llcx = cx.llcx; let inputs = tt.args; let ret_tt: RustTypeTree = tt.ret; @@ -77,41 +106,81 @@ pub(crate) fn add_tt<'ll>( let attr_name = "enzyme_type"; let c_attr_name = CString::new(attr_name).unwrap(); + let tt_location: TTLocation = + if llvm::LLVMRustIsCall(fn_def) { TTLocation::Callsite } else { TTLocation::Definition }; + + let mut offset = 0; for (i, input) in inputs.iter().enumerate() { - unsafe { - let enzyme_tt = to_enzyme_typetree(input.clone(), llvm_data_layout, llcx); + let (enzyme_tt, extra_ints) = to_enzyme_typetree(&input, llvm_data_layout, llcx); + + // This scope is just a visual reminder that we *must* drop the enzyme_wrapper before + // we drop any typetrees (mainly enzyme_tt and extra_ints). Drop calls can not accept + // arguments like an enzyme_wrapper, so the typetree drop impl has to call get_instance + // on the static enzyme instance, which is behind a Mutex. Therefore we'd deadlock if we + // hold the enzyme_wrapper while dropping the typetrees. + { let enzyme_wrapper = EnzymeWrapper::get_instance(); - let c_str = enzyme_wrapper.tree_to_string(enzyme_tt.inner); - let c_str = std::ffi::CStr::from_ptr(c_str); - - let attr = llvm::LLVMCreateStringAttribute( - llcx, - c_attr_name.as_ptr(), - c_attr_name.as_bytes().len() as c_uint, - c_str.as_ptr(), - c_str.to_bytes().len() as c_uint, - ); - - attributes::apply_to_llfn(fn_def, llvm::AttributePlace::Argument(i as u32), &[attr]); + let c_str = enzyme_wrapper.tree_to_cstr(enzyme_tt.inner); + + let attr = llvm::CreateAttrStringValueFromCStr(llcx, &c_attr_name, &c_str); + let arg_pos = llvm::AttributePlace::Argument(i as u32 + offset); + // FIXME(autodiff): We currently know that this is correct for all the cases in which we + // call this function. But we should make it more robust for the future. + match tt_location { + TTLocation::Definition => { + attributes::apply_to_llfn(fn_def, arg_pos, &[attr]); + } + TTLocation::Callsite => { + attributes::apply_to_callsite(fn_def, arg_pos, &[attr]); + } + } enzyme_wrapper.tree_to_string_free(c_str.as_ptr()); + for v in &extra_ints { + offset += 1; + let c_str = enzyme_wrapper.tree_to_cstr(v.inner); + let int_attr = llvm::CreateAttrStringValueFromCStr(llcx, &c_attr_name, &c_str); + let arg_pos = llvm::AttributePlace::Argument(i as u32 + offset); + match tt_location { + TTLocation::Definition => { + attributes::apply_to_llfn(fn_def, arg_pos, &[int_attr]); + } + TTLocation::Callsite => { + attributes::apply_to_callsite(fn_def, arg_pos, &[int_attr]); + } + } + enzyme_wrapper.tree_to_string_free(c_str.as_ptr()); + } + } + } + // We will only fail this if Rust types got lowered to LLVM in a way that we didn't predict. + // Error, so we can learn from our mistakes. + if matches!(tt_location, TTLocation::Definition) { + let expected = offset as usize + inputs.len(); + let actual = llvm::count_params(fn_def) as usize; + if expected != actual { + tcx.dcx().warn(format!( + "autodiff type-tree failure. We expected {expected} LLVM argument(s), \ + but the generated LLVM function has {actual} parameter(s)" + )); } } - unsafe { - let enzyme_tt = to_enzyme_typetree(ret_tt, llvm_data_layout, llcx); + // FIXME(autodiff): We should think more about what it means if a function returns a slice or + // other fat ptrs. + let (enzyme_tt, _extra_ints) = to_enzyme_typetree(&ret_tt, llvm_data_layout, llcx); + if ret_tt != RustTypeTree::new() { let enzyme_wrapper = EnzymeWrapper::get_instance(); - let c_str = enzyme_wrapper.tree_to_string(enzyme_tt.inner); - let c_str = std::ffi::CStr::from_ptr(c_str); - - let ret_attr = llvm::LLVMCreateStringAttribute( - llcx, - c_attr_name.as_ptr(), - c_attr_name.as_bytes().len() as c_uint, - c_str.as_ptr(), - c_str.to_bytes().len() as c_uint, - ); - - attributes::apply_to_llfn(fn_def, llvm::AttributePlace::ReturnValue, &[ret_attr]); + let c_str = enzyme_wrapper.tree_to_cstr(enzyme_tt.inner); + let ret_attr = llvm::CreateAttrStringValueFromCStr(llcx, &c_attr_name, &c_str); + let arg_pos = llvm::AttributePlace::ReturnValue; + match tt_location { + TTLocation::Definition => { + attributes::apply_to_llfn(fn_def, arg_pos, &[ret_attr]); + } + TTLocation::Callsite => { + attributes::apply_to_callsite(fn_def, arg_pos, &[ret_attr]); + } + } enzyme_wrapper.tree_to_string_free(c_str.as_ptr()); } } diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 39c2529152566..0d27ff90991b3 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -2,10 +2,12 @@ use std::assert_matches; use std::ops::Deref; use rustc_abi::{Align, Scalar, Size, WrappingRange}; +use rustc_ast::expand::typetree::{FncTree, TypeTree}; use rustc_hir::attrs::AttributeKind; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout}; +use rustc_middle::ty::typetree::typetree_from_ty; use rustc_middle::ty::{AtomicOrdering, Instance, Ty}; use rustc_session::config::OptLevel; use rustc_span::Span; @@ -456,7 +458,7 @@ pub trait BuilderMethods<'a, 'tcx>: src_align: Align, size: Self::Value, flags: MemFlags, - tt: Option, + tt: Option, ); fn memmove( &mut self, @@ -517,6 +519,10 @@ pub trait BuilderMethods<'a, 'tcx>: let temp = self.load_operand(src.with_type(layout)); temp.val.store_with_flags(self, dst.with_type(layout), flags); } else if !layout.is_zst() { + let tt = typetree_from_ty(self.tcx(), layout.ty); + // We seem to pass all values to memcpy with one more indirection. + let tt = tt.add_indirection(); + let fnc_tree = FncTree { args: vec![tt.clone(), tt], ret: TypeTree::new() }; let bytes = self.const_usize(layout.size.bytes()); let bytes = if layout.peel_transparent_wrappers(self).ty.is_scalable_vector() { let vscale = self.vscale(self.type_i64()); @@ -524,7 +530,7 @@ pub trait BuilderMethods<'a, 'tcx>: } else { bytes }; - self.memcpy(dst.llval, dst.align, src.llval, src.align, bytes, flags, None); + self.memcpy(dst.llval, dst.align, src.llval, src.align, bytes, flags, Some(fnc_tree)); } } diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 01886a97f55a2..f3792d4d45235 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -2,8 +2,8 @@ use rustc_ast::token::Delimiter; use rustc_ast::tokenstream::TokenStream; use rustc_ast::util::literal; use rustc_ast::{ - self as ast, AnonConst, AttrItem, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, - MgcaDisambiguation, PatKind, UnOp, attr, token, tokenstream, + self as ast, AnonConst, AttrItem, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, PatKind, + UnOp, attr, token, tokenstream, }; use rustc_span::{DUMMY_SP, Ident, Span, Spanned, Symbol, kw, sym}; use thin_vec::{ThinVec, thin_vec}; @@ -100,7 +100,6 @@ impl<'a> ExtCtxt<'a> { attrs: AttrVec::new(), tokens: None, }), - mgca_disambiguation: MgcaDisambiguation::Direct, } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index ec0228475feba..ee401376a6a5c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3877,7 +3877,7 @@ pub enum DelegationSelfTyPropagationKind { #[derive(Debug, Clone, Copy, PartialEq, Eq, StableHash)] pub struct DelegationInfo { pub call_expr_id: HirId, - pub call_path_res: Option, + pub call_path_res: DefId, /// Id of the child segment in delegation: `reuse Trait::foo`, /// `child_seg_id` points to `foo`. diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index 20223b66405cd..a1a466e82c95e 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -34,7 +34,7 @@ pub struct Autoderef<'a, 'tcx> { // Meta infos: infcx: &'a InferCtxt<'tcx>, span: Span, - body_id: LocalDefId, + body_def_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, // Current state: @@ -119,7 +119,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { Autoderef { infcx, span, - body_id: body_def_id, + body_def_id, param_env, state: AutoderefSnapshot { steps: vec![], @@ -149,7 +149,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { (tcx.lang_items().deref_trait()?, tcx.lang_items().deref_target()?) }; let trait_ref = ty::TraitRef::new(tcx, trait_def_id, [ty]); - let cause = traits::ObligationCause::misc(self.span, self.body_id); + let cause = traits::ObligationCause::misc(self.span, self.body_def_id); let obligation = traits::Obligation::new( tcx, cause.clone(), @@ -181,7 +181,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { ) -> Option<(Ty<'tcx>, PredicateObligations<'tcx>)> { let ocx = ObligationCtxt::new(self.infcx); let normalized_ty = ocx.normalize( - &traits::ObligationCause::misc(self.span, self.body_id), + &traits::ObligationCause::misc(self.span, self.body_def_id), self.param_env, ty, ); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index af779152ed675..1379ac2175e0b 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -177,10 +177,10 @@ fn compare_method_predicate_entailment<'tcx>( trait_m: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { - // This node-id should be used for the `body_id` field on each + // This node-id should be used for the `body_def_id` field on each // `ObligationCause` (and the `FnCtxt`). // - // FIXME(@lcnr): remove that after removing `cause.body_id` from + // FIXME(@lcnr): remove that after removing `cause.body_def_id` from // obligations. let impl_m_def_id = impl_m.def_id.expect_local(); let impl_m_span = tcx.def_span(impl_m_def_id); @@ -798,7 +798,7 @@ struct ImplTraitInTraitCollector<'a, 'tcx, E> { types: FxIndexMap, ty::GenericArgsRef<'tcx>)>, span: Span, param_env: ty::ParamEnv<'tcx>, - body_id: LocalDefId, + impl_m_id: LocalDefId, } impl<'a, 'tcx, E> ImplTraitInTraitCollector<'a, 'tcx, E> @@ -809,9 +809,9 @@ where ocx: &'a ObligationCtxt<'a, 'tcx, E>, span: Span, param_env: ty::ParamEnv<'tcx>, - body_id: LocalDefId, + impl_m_id: LocalDefId, ) -> Self { - ImplTraitInTraitCollector { ocx, types: FxIndexMap::default(), span, param_env, body_id } + ImplTraitInTraitCollector { ocx, types: FxIndexMap::default(), span, param_env, impl_m_id } } } @@ -847,7 +847,7 @@ where { let pred = pred.fold_with(self); let pred = self.ocx.normalize( - &ObligationCause::misc(self.span, self.body_id), + &ObligationCause::misc(self.span, self.impl_m_id), self.param_env, Unnormalized::new_wip(pred), ); @@ -856,7 +856,7 @@ where self.cx(), ObligationCause::new( self.span, - self.body_id, + self.impl_m_id, ObligationCauseCode::WhereClause(def_id, pred_span), ), self.param_env, @@ -2346,7 +2346,7 @@ fn compare_type_predicate_entailment<'tcx>( return Ok(()); } - // This `DefId` should be used for the `body_id` field on each + // This `DefId` should be used for the `body_def_id` field on each // `ObligationCause` (and the `FnCtxt`). This is what // `regionck_item` expects. let impl_ty_def_id = impl_ty.def_id.expect_local(); diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 811ed83e0bf48..d6a5db4c22f24 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -214,6 +214,17 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { "synthetic HIR should have its `generics_of` explicitly fed" ), + Node::ConstArg(..) => { + // These can show up in mGCA when representing "direct" const arguments. The + // DefCollector cannot know whether an anon const will be represented by an actual HIR + // Node::AnonConst, or whether it will be represented directly, so it must generate a + // DefId. If it ends up being direct, this DefId is then attached to the top-level + // ConstArg, which is what we are seeing here. + debug_assert!(tcx.features().min_generic_const_args()); + // Forward to the real parent. + Some(tcx.local_parent(def_id)) + } + _ => span_bug!(tcx.def_span(def_id), "generics_of: unexpected node kind {node:?}"), }; diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 3f3373d372ddd..ebf9907e64e64 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -216,7 +216,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { prior_arm: Option<(Option, Ty<'tcx>, Span)>, ) { // First, check that we're actually in the tail of a function. - let Some(body) = self.tcx.hir_maybe_body_owned_by(self.body_id) else { + let Some(body) = self.tcx.hir_maybe_body_owned_by(self.body_def_id) else { return; }; let hir::ExprKind::Block(block, _) = body.value.kind else { @@ -233,7 +233,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Next, make sure that we have no type expectation. let Some(ret) = - self.tcx.hir_node_by_def_id(self.body_id).fn_decl().map(|decl| decl.output.span()) + self.tcx.hir_node_by_def_id(self.body_def_id).fn_decl().map(|decl| decl.output.span()) else { return; }; diff --git a/compiler/rustc_hir_typeck/src/autoderef.rs b/compiler/rustc_hir_typeck/src/autoderef.rs index f7700179d2a3a..6b0707c901393 100644 --- a/compiler/rustc_hir_typeck/src/autoderef.rs +++ b/compiler/rustc_hir_typeck/src/autoderef.rs @@ -15,7 +15,7 @@ use super::{FnCtxt, PlaceOp}; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn autoderef(&'a self, span: Span, base_ty: Ty<'tcx>) -> Autoderef<'a, 'tcx> { - Autoderef::new(self, self.param_env, self.body_id, span, base_ty) + Autoderef::new(self, self.param_env, self.body_def_id, span, base_ty) } pub(crate) fn try_overloaded_deref( diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index bb822f8d0f68d..3cc4dc5f9fb5e 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -39,11 +39,11 @@ pub(crate) fn check_legal_trait_for_method_call( receiver: Option, expr_span: Span, trait_id: DefId, - body_id: DefId, + body_def_id: DefId, ) -> Result<(), ErrorGuaranteed> { if tcx.is_lang_item(trait_id, LangItem::Drop) // Allow calling `Drop::pin_drop` in `Drop::drop` - && !tcx.is_lang_item(tcx.parent(body_id), LangItem::Drop) + && !tcx.is_lang_item(tcx.parent(body_def_id), LangItem::Drop) { let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) { diagnostics::ExplicitDestructorCallSugg::Snippet { @@ -724,17 +724,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; }; - let Some(path_res_id) = info.call_path_res else { return None }; - // Check that delegation has first provided arg and that the call path // resolves to a trait method (inherent methods are not yet supported). if arg_exprs.is_empty() - || !self.tcx.opt_associated_item(path_res_id).is_some_and(|i| i.is_method()) + || !self.tcx.opt_associated_item(info.call_path_res).is_some_and(|i| i.is_method()) { return None; } - Some(ProbeScope::Single(path_res_id)) + Some(ProbeScope::Single(info.call_path_res)) } /// Attempts to reinterpret `method(rcvr, args...)` as `rcvr.method(args...)` @@ -1042,7 +1040,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { callee_did: DefId, callee_args: GenericArgsRef<'tcx>, ) { - let const_context = self.tcx.hir_body_const_context(self.body_id); + let const_context = self.tcx.hir_body_const_context(self.body_def_id); if let hir::Constness::Const { always: true } = self.tcx.constness(callee_did) { match const_context { @@ -1062,7 +1060,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // If we have `rustc_do_not_const_check`, do not check `[const]` bounds. - if self.has_rustc_attrs && find_attr!(self.tcx, self.body_id, RustcDoNotConstCheck) { + if self.has_rustc_attrs && find_attr!(self.tcx, self.body_def_id, RustcDoNotConstCheck) { return; } diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index f7f0b69873e1e..a28ab5887de2b 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -64,7 +64,7 @@ pub(crate) struct CastCheck<'tcx> { cast_ty: Ty<'tcx>, cast_span: Span, span: Span, - pub body_id: LocalDefId, + pub body_def_id: LocalDefId, } /// The kind of pointer and associated metadata (thin, length or vtable) - we @@ -247,8 +247,15 @@ impl<'a, 'tcx> CastCheck<'tcx> { span: Span, ) -> Result, ErrorGuaranteed> { let expr_span = expr.span.find_ancestor_inside(span).unwrap_or(expr.span); - let check = - CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span, body_id: fcx.body_id }; + let check = CastCheck { + expr, + expr_ty, + expr_span, + cast_ty, + cast_span, + span, + body_def_id: fcx.body_def_id, + }; // For better error messages, check for some obviously unsized // cases now. We do a more thorough check at the end, once diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 2ecbb8863bf91..986e127ac6b8b 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1258,7 +1258,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let sig = if fn_attrs.safe_target_features { // Allow the coercion if the current function has all the features that would be // needed to call the coercee safely. - match tcx.adjust_target_feature_sig(def_id, sig, self.body_id.into()) { + match tcx.adjust_target_feature_sig(def_id, sig, self.body_def_id.into()) { Some(adjusted_sig) => adjusted_sig, None if matches!(expected_safety, Some(hir::Safety::Safe)) => { return Err(TypeError::TargetFeatureCast(def_id)); @@ -1477,12 +1477,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn can_coerce<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - body_id: LocalDefId, + body_def_id: LocalDefId, ty: Ty<'tcx>, output_ty: Ty<'tcx>, ) -> bool { - let root_ctxt = crate::typeck_root_ctxt::TypeckRootCtxt::new(tcx, body_id); - let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, body_id); + let root_ctxt = crate::typeck_root_ctxt::TypeckRootCtxt::new(tcx, body_def_id); + let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, body_def_id); fn_ctxt.may_coerce(ty, output_ty) } @@ -2057,7 +2057,7 @@ impl<'tcx> CoerceMany<'tcx> { if due_to_block && let Some(expr) = expression && let Some(parent_fn_decl) = - fcx.tcx.hir_fn_decl_by_hir_id(fcx.tcx.local_def_id_to_hir_id(fcx.body_id)) + fcx.tcx.hir_fn_decl_by_hir_id(fcx.tcx.local_def_id_to_hir_id(fcx.body_def_id)) { fcx.suggest_missing_break_or_return_expr( &mut err, @@ -2066,14 +2066,14 @@ impl<'tcx> CoerceMany<'tcx> { expected, found, block_or_return_id, - fcx.body_id, + fcx.body_def_id, ); } let is_return_position = fcx .tcx .hir_get_fn_id_for_return_block(block_or_return_id) - .is_some_and(|fn_id| fn_id == fcx.tcx.local_def_id_to_hir_id(fcx.body_id)); + .is_some_and(|fn_id| fn_id == fcx.tcx.local_def_id_to_hir_id(fcx.body_def_id)); if is_return_position && let Some(sp) = fcx.ret_coercion_span.get() @@ -2083,7 +2083,7 @@ impl<'tcx> CoerceMany<'tcx> { // may occur at the first return expression we see in the closure // (if it conflicts with the declared return type). Skip adding a // note in this case, since it would be incorrect. - && let Some(fn_sig) = fcx.body_fn_sig() + && let Some(fn_sig) = fcx.fn_sig() && fn_sig.output().is_ty_var() { err.span_note(sp, format!("return type inferred to be `{expected}` here")); @@ -2096,7 +2096,7 @@ impl<'tcx> CoerceMany<'tcx> { /// sure we consider `dyn Trait: Sized` where clauses, which are trivially /// false but technically valid for typeck. fn is_return_ty_definitely_unsized(&self, fcx: &FnCtxt<'_, 'tcx>) -> bool { - if let Some(sig) = fcx.body_fn_sig() { + if let Some(sig) = fcx.fn_sig() { !fcx.predicate_may_hold(&Obligation::new( fcx.tcx, ObligationCause::dummy(), diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index bd8295ba3a328..66c214a1be98a 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -332,7 +332,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let mut expr_finder = FindExprs { hir_id: local_hir_id, uses: init.into_iter().collect() }; - let body = self.tcx.hir_body_owned_by(self.body_id); + let body = self.tcx.hir_body_owned_by(self.body_def_id); expr_finder.visit_expr(body.value); // Replaces all of the variables in the given type with a fresh inference variable. diff --git a/compiler/rustc_hir_typeck/src/expectation.rs b/compiler/rustc_hir_typeck/src/expectation.rs index ab66e44032f93..37c8d7b2ae24e 100644 --- a/compiler/rustc_hir_typeck/src/expectation.rs +++ b/compiler/rustc_hir_typeck/src/expectation.rs @@ -76,9 +76,9 @@ impl<'a, 'tcx> Expectation<'tcx> { pub(super) fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> { let span = match ty.kind() { ty::Adt(adt_def, _) => fcx.tcx.def_span(adt_def.did()), - _ => fcx.tcx.def_span(fcx.body_id), + _ => fcx.tcx.def_span(fcx.body_def_id), }; - let cause = ObligationCause::misc(span, fcx.body_id); + let cause = ObligationCause::misc(span, fcx.body_def_id); // FIXME(#155345): Missing normalization call match fcx.tcx.struct_tail_raw(ty, &cause, |ty| ty.skip_normalization(), || {}).kind() { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 0cd80a6a83c87..5a30f0fb56c66 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -965,7 +965,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return_expr_ty, ); - if let Some(fn_sig) = self.body_fn_sig() + if let Some(fn_sig) = self.fn_sig() && fn_sig.output().has_opaque_types() { // Point any obligations that were registered due to opaque type @@ -2764,8 +2764,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return Ty::new_error(self.tcx(), guar); } - let (ident, def_scope) = - self.tcx.adjust_ident_and_get_scope(field, base_def.did(), self.body_id); + let (ident, def_scope) = self.tcx.adjust_ident_and_get_scope( + field, + base_def.did(), + self.body_def_id, + ); if let Some((idx, field)) = self.find_adt_field(*base_def, ident) { self.write_field_index(expr.hir_id, idx); @@ -2938,7 +2941,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field_ident.span, "field not available in `impl Future`, but it is available in its `Output`", ); - match self.tcx.coroutine_kind(self.body_id) { + match self.tcx.coroutine_kind(self.body_def_id) { Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => { err.span_suggestion_verbose( base.span.shrink_to_hi(), @@ -2949,7 +2952,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => { let mut span: MultiSpan = base.span.into(); - span.push_span_label(self.tcx.def_span(self.body_id), "this is not `async`"); + span.push_span_label(self.tcx.def_span(self.body_def_id), "this is not `async`"); err.span_note( span, "this implements `Future` and its output type has the field, \ @@ -3119,7 +3122,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } fn point_at_param_definition(&self, err: &mut Diag<'_>, param: ty::ParamTy) { - let generics = self.tcx.generics_of(self.body_id); + let generics = self.tcx.generics_of(self.body_def_id); let generic_param = generics.type_param(param, self.tcx); if let ty::GenericParamDefKind::Type { synthetic: true, .. } = generic_param.kind { return; @@ -3703,7 +3706,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) -> Ty<'tcx> { if let rustc_ast::AsmMacro::NakedAsm = asm.asm_macro { - if !find_attr!(self.tcx, self.body_id, Naked(..)) { + if !find_attr!(self.tcx, self.body_def_id, Naked(..)) { self.tcx.dcx().emit_err(NakedAsmOutsideNakedFn { span }); } } @@ -3802,8 +3805,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .emit(); break; }; - let (subident, sub_def_scope) = - self.tcx.adjust_ident_and_get_scope(subfield, variant.def_id, self.body_id); + let (subident, sub_def_scope) = self.tcx.adjust_ident_and_get_scope( + subfield, + variant.def_id, + self.body_def_id, + ); let Some((subindex, field)) = variant .fields @@ -3854,7 +3860,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (ident, def_scope) = self.tcx.adjust_ident_and_get_scope( field, container_def.did(), - self.body_id, + self.body_def_id, ); let fields = &container_def.non_enum_variant().fields; diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 7b39b953e3be0..96ede89664fea 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -217,7 +217,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> { } fn body_owner_def_id(&self) -> LocalDefId { - self.body_id + self.body_def_id } fn tcx(&self) -> TyCtxt<'tcx> { diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 9af35b55f40b1..0e34a6120b609 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -293,7 +293,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { root_vid: ty::TyVid, ) { let unsafe_infer_vars = unsafe_infer_vars.get_or_init(|| { - let unsafe_infer_vars = compute_unsafe_infer_vars(self, self.body_id); + let unsafe_infer_vars = compute_unsafe_infer_vars(self, self.body_def_id); debug!(?unsafe_infer_vars); unsafe_infer_vars }); @@ -378,8 +378,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> { let sugg = self.try_to_suggest_annotations(diverging_vids, coercions); self.tcx.emit_node_span_lint( lint::builtin::DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK, - self.tcx.local_def_id_to_hir_id(self.body_id), - self.tcx.def_span(self.body_id), + self.tcx.local_def_id_to_hir_id(self.body_def_id), + self.tcx.def_span(self.body_def_id), diagnostics::DependencyOnUnitNeverTypeFallback { obligation_span: never_error.obligation.cause.span, obligation: never_error.obligation.predicate, @@ -446,8 +446,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { diverging_vids: &[ty::TyVid], coercions: &VecGraph, ) -> diagnostics::SuggestAnnotations { - let body = - self.tcx.hir_maybe_body_owned_by(self.body_id).expect("body id must have an owner"); + let body = self.tcx.hir_body_owned_by(self.body_def_id); // For each diverging var, look through the HIR for a place to give it // a type annotation. We do this per var because we only really need one // suggestion to influence a var to be `()`. @@ -633,9 +632,9 @@ pub(crate) enum UnsafeUseReason { /// `compute_unsafe_infer_vars` will return `{ id(?X) -> (hir_id, span, Call) }` fn compute_unsafe_infer_vars<'a, 'tcx>( fcx: &'a FnCtxt<'a, 'tcx>, - body_id: LocalDefId, + body_def_id: LocalDefId, ) -> UnordMap { - let body = fcx.tcx.hir_maybe_body_owned_by(body_id).expect("body id must have an owner"); + let body = fcx.tcx.hir_body_owned_by(body_def_id); let mut res = UnordMap::default(); struct UnsafeInferVarsVisitor<'a, 'tcx> { @@ -763,7 +762,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( UnsafeInferVarsVisitor { fcx, res: &mut res }.visit_expr(&body.value); - debug!(?res, "collected the following unsafe vars for {body_id:?}"); + debug!(?res, "collected the following unsafe vars for {body_def_id:?}"); res } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 37e198d51a831..9a1b1f8300957 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -213,7 +213,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // let it keep doing that and just ensure that compilation won't succeed. self.dcx().span_delayed_bug( self.tcx.hir_span(id), - format!("`{prev}` overridden by `{ty}` for {id:?} in {:?}", self.body_id), + format!("`{prev}` overridden by `{ty}` for {id:?} in {:?}", self.body_def_id), ); } } @@ -1070,7 +1070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { arg_span, span, container_id, - self.body_id.to_def_id(), + self.body_def_id.to_def_id(), ) { self.set_tainted_by_errors(e); } @@ -1192,7 +1192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // error in `validate_res_from_ribs` -- it's just difficult to tell whether the // self type has any generic types during rustc_resolve, which is what we use // to determine if this is a hard error or warning. - if std::iter::successors(Some(self.body_id.to_def_id()), |&def_id| { + if std::iter::successors(Some(self.body_def_id.to_def_id()), |&def_id| { self.tcx.generics_of(def_id).parent }) .all(|def_id| def_id != impl_def_id) @@ -1534,7 +1534,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let guar = self.tainted_by_errors().unwrap_or_else(|| { self.err_ctxt() .emit_inference_failure_err( - self.body_id, + self.body_def_id, sp, ty.into(), TypeAnnotationNeeded::E0282, @@ -1560,7 +1560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let e = self.tainted_by_errors().unwrap_or_else(|| { self.err_ctxt() .emit_inference_failure_err( - self.body_id, + self.body_def_id, sp, ct.into(), TypeAnnotationNeeded::E0282, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 7d85a5a4ded63..1b6f366b9d133 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -68,9 +68,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut deferred_cast_checks = self.root_ctxt.deferred_cast_checks.borrow_mut(); debug!("FnCtxt::check_casts: {} deferred checks", deferred_cast_checks.len()); for cast in deferred_cast_checks.drain(..) { - let body_id = std::mem::replace(&mut self.body_id, cast.body_id); + let body_def_id = std::mem::replace(&mut self.body_def_id, cast.body_def_id); cast.check(self); - self.body_id = body_id; + self.body_def_id = body_def_id; } } @@ -346,7 +346,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // in `execute_delegation_aware_arguments_check`. let checked_ty = self .tcx - .hir_opt_delegation_info(self.body_id) + .hir_opt_delegation_info(self.body_def_id) .and_then(|_| self.typeck_results.borrow().node_type_opt(provided_arg.hir_id)) .unwrap_or_else(|| self.check_expr_with_expectation(provided_arg, expectation)); @@ -1627,7 +1627,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let callee_ty = callee_ty.peel_refs(); match *callee_ty.kind() { ty::Param(param) => { - let param = self.tcx.generics_of(self.body_id).type_param(param, self.tcx); + let param = self.tcx.generics_of(self.body_def_id).type_param(param, self.tcx); if param.kind.is_synthetic() { // if it's `impl Fn() -> ..` then just fall down to the def-id based logic def_id = param.def_id; @@ -1636,7 +1636,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // and point at that. let instantiated = self .tcx - .explicit_predicates_of(self.body_id) + .explicit_predicates_of(self.body_def_id) .instantiate_identity(self.tcx); // FIXME(compiler-errors): This could be problematic if something has two // fn-like predicates with different args, but callable types really never diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 6d2e36e081a5e..e9f935ba73cf9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -43,7 +43,7 @@ use crate::{CoroutineTypes, Diverges, EnclosingBreakables, TypeckRootCtxt}; /// /// [`InferCtxt`]: infer::InferCtxt pub(crate) struct FnCtxt<'a, 'tcx> { - pub(super) body_id: LocalDefId, + pub(super) body_def_id: LocalDefId, /// The parameter environment used for proving trait obligations /// in this function. This can change when we descend into @@ -138,12 +138,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn new( root_ctxt: &'a TypeckRootCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - body_id: LocalDefId, + body_def_id: LocalDefId, ) -> FnCtxt<'a, 'tcx> { let (diverging_fallback_behavior, diverging_block_behavior) = never_type_behavior(root_ctxt.tcx); FnCtxt { - body_id, + body_def_id, param_env, ret_coercion: None, ret_coercion_span: Cell::new(None), @@ -179,7 +179,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, code: ObligationCauseCode<'tcx>, ) -> ObligationCause<'tcx> { - ObligationCause::new(span, self.body_id, code) + ObligationCause::new(span, self.body_def_id, code) } pub(crate) fn misc(&self, span: Span) -> ObligationCause<'tcx> { @@ -230,7 +230,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { } fn item_def_id(&self) -> LocalDefId { - self.body_id + self.body_def_id } fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index b3fec86229fae..6fb72f414a049 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -40,11 +40,11 @@ use crate::method::probe; use crate::method::probe::{IsSuggestion, Mode, ProbeScope}; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub(crate) fn body_fn_sig(&self) -> Option> { + pub(crate) fn fn_sig(&self) -> Option> { self.typeck_results .borrow() .liberated_fn_sigs() - .get(self.tcx.local_def_id_to_hir_id(self.body_id)) + .get(self.tcx.local_def_id_to_hir_id(self.body_def_id)) .copied() } @@ -170,7 +170,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, ty: Ty<'tcx>, ) -> Option<(DefIdOrName, Ty<'tcx>, Vec>)> { - self.err_ctxt().extract_callable_info(self.body_id, self.param_env, ty) + self.err_ctxt().extract_callable_info(self.body_def_id, self.param_env, ty) } pub(crate) fn suggest_two_fn_call( @@ -2292,7 +2292,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; }; let ret_ty_matches = |diagnostic_item| { - let Some(sig) = self.body_fn_sig() else { + let Some(sig) = self.fn_sig() else { return false; }; let ty::Adt(kind, _) = sig.output().kind() else { diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs index 85c8400f227bd..21954203a705a 100644 --- a/compiler/rustc_hir_typeck/src/gather_locals.rs +++ b/compiler/rustc_hir_typeck/src/gather_locals.rs @@ -193,7 +193,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { // ascription, or if it's an implicit `self` parameter ObligationCauseCode::SizedArgumentType( if ty_span == ident.span - && self.fcx.tcx.is_closure_like(self.fcx.body_id.into()) + && self.fcx.tcx.is_closure_like(self.fcx.body_def_id.into()) { None } else { diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 335caf571aa6f..6b5f084fc3dbe 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -378,7 +378,7 @@ fn extend_err_with_const_context( fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Option> { let tcx = fcx.tcx; - let def_id = fcx.body_id; + let def_id = fcx.body_def_id; let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer(()), span, .. }) = node.ty() { if let Some(item) = tcx.opt_associated_item(def_id.into()) diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index d5169cd30aa9a..d5dc17837f1ed 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -702,7 +702,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { Some(self.self_expr.span), self.call_expr.span, trait_def_id, - self.body_id.to_def_id(), + self.body_def_id.to_def_id(), ) { self.set_tainted_by_errors(e); diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index ce22ab937391e..811f0eafec16b 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -511,7 +511,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && !self.tcx.features().arbitrary_self_types(); let mut err = self.err_ctxt().emit_inference_failure_err( - self.body_id, + self.body_def_id, err_span, ty.into(), TypeAnnotationNeeded::E0282, @@ -811,7 +811,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let is_accessible = if let Some(name) = self.method_name { let item = candidate.item; let container_id = item.container_id(self.tcx); - let def_scope = self.tcx.adjust_ident_and_get_scope(name, container_id, self.body_id).1; + let def_scope = + self.tcx.adjust_ident_and_get_scope(name, container_id, self.body_def_id).1; item.visibility(self.tcx).is_accessible_from(def_scope, self.tcx) } else { true diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 0a72f1d47b8b8..42c08f6409e8a 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -160,7 +160,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match *ty.peel_refs().kind() { ty::Param(param) => { - let generics = self.tcx.generics_of(self.body_id); + let generics = self.tcx.generics_of(self.body_def_id); let generic_param = generics.type_param(param, self.tcx); for unsatisfied in unsatisfied_predicates.iter() { // The parameter implements `IntoIterator` @@ -634,7 +634,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { impl<'a, 'tcx> LetVisitor<'a, 'tcx> { // Check scope of binding. fn is_sub_scope(&self, sub_id: hir::ItemLocalId, super_id: hir::ItemLocalId) -> bool { - let scope_tree = self.fcx.tcx.region_scope_tree(self.fcx.body_id); + let scope_tree = self.fcx.tcx.region_scope_tree(self.fcx.body_def_id); if let Some(sub_var_scope) = scope_tree.var_scope(sub_id) && let Some(super_var_scope) = scope_tree.var_scope(super_id) && scope_tree.is_subscope_of(sub_var_scope, super_var_scope) @@ -742,7 +742,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let hir::def::Res::Local(recv_id) = path.res && let Some(segment) = path.segments.first() { - let body = self.tcx.hir_body_owned_by(self.body_id); + let body = self.tcx.hir_body_owned_by(self.body_def_id); if let Node::Expr(call_expr) = self.tcx.parent_hir_node(rcvr.hir_id) { let mut let_visitor = LetVisitor { @@ -1148,7 +1148,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let mut ty_span = match rcvr_ty.kind() { ty::Param(param_type) => { - Some(param_type.span_from_generics(self.tcx, self.body_id.to_def_id())) + Some(param_type.span_from_generics(self.tcx, self.body_def_id.to_def_id())) } ty::Adt(def, _) if def.did().is_local() => Some(self.tcx.def_span(def.did())), _ => None, @@ -1779,7 +1779,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Param(_) => { // Account for `fn` items like in `issue-35677.rs` to // suggest restricting its type params. - Some(self.tcx.hir_node_by_def_id(self.body_id)) + Some(self.tcx.hir_node_by_def_id(self.body_def_id)) } ty::Adt(def, _) => { def.did().as_local().map(|def_id| self.tcx.hir_node_by_def_id(def_id)) @@ -2842,7 +2842,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, }); if let Some((field, field_ty)) = field_receiver { - let scope = tcx.parent_module_from_def_id(self.body_id); + let scope = tcx.parent_module_from_def_id(self.body_def_id); let is_accessible = field.vis.is_accessible_from(scope, tcx); if is_accessible { @@ -3147,7 +3147,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { seg1.ident.span, StashKey::CallAssocMethod, |err| { - let body = self.tcx.hir_body_owned_by(self.body_id); + let body = self.tcx.hir_body_owned_by(self.body_def_id); struct LetVisitor { ident_name: Symbol, } @@ -3997,7 +3997,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let parent_map = self.tcx.visible_parent_map(()); - let scope = self.tcx.parent_module_from_def_id(self.body_id); + let scope = self.tcx.parent_module_from_def_id(self.body_def_id); let (accessible_candidates, inaccessible_candidates): (Vec<_>, Vec<_>) = candidates.into_iter().partition(|id| { let vis = self.tcx.visibility(*id); @@ -4555,7 +4555,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Obtain the span for `param` and use it for a structured suggestion. if let Some(param) = param_type { - let generics = self.tcx.generics_of(self.body_id.to_def_id()); + let generics = self.tcx.generics_of(self.body_def_id.to_def_id()); let type_param = generics.type_param(param, self.tcx); let tcx = self.tcx; if let Some(def_id) = type_param.def_id.as_local() { diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index fd52c7f4b4d26..682ae998b411d 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -517,7 +517,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &mut err, trait_pred, output_associated_item, - self.body_id, + self.body_def_id, ); } } @@ -1004,7 +1004,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &mut err, pred, None, - self.body_id, + self.body_def_id, ); } } diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs index 6c55251bdef5a..797077d97c133 100644 --- a/compiler/rustc_hir_typeck/src/opaque_types.rs +++ b/compiler/rustc_hir_typeck/src/opaque_types.rs @@ -163,13 +163,18 @@ impl<'tcx> FnCtxt<'_, 'tcx> { if let Some(guar) = self.tainted_by_errors() { guar } else { - report_item_does_not_constrain_error(self.tcx, self.body_id, def_id, None) + report_item_does_not_constrain_error( + self.tcx, + self.body_def_id, + def_id, + None, + ) } } UsageKind::NonDefiningUse(opaque_type_key, hidden_type) => { report_item_does_not_constrain_error( self.tcx, - self.body_id, + self.body_def_id, def_id, Some((opaque_type_key, hidden_type.span)), ) @@ -186,7 +191,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { .unwrap_or_else(|| hidden_type.ty.into()); self.err_ctxt() .emit_inference_failure_err( - self.body_id, + self.body_def_id, hidden_type.span, infer_var, TypeAnnotationNeeded::E0282, @@ -235,7 +240,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { return UsageKind::UnconstrainedHiddenType(hidden_type); } - let cause = ObligationCause::misc(hidden_type.span, self.body_id); + let cause = ObligationCause::misc(hidden_type.span, self.body_def_id); let at = self.at(&cause, self.param_env); let hidden_type = match solve::deeply_normalize(at, Unnormalized::new_wip(hidden_type)) { Ok(hidden_type) => hidden_type, diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 3d50befe042f1..4161975d88ea9 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -948,8 +948,8 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { // We must deeply normalize in the new solver, since later lints expect // that types that show up in the typeck are fully normalized. let mut value = if self.should_normalize && self.fcx.next_trait_solver() { - let body_id = tcx.hir_body_owner_def_id(self.body.id()); - let cause = ObligationCause::misc(self.span.to_span(tcx), body_id); + let body_def_id = tcx.hir_body_owner_def_id(self.body.id()); + let cause = ObligationCause::misc(self.span.to_span(tcx), body_def_id); let at = self.fcx.at(&cause, self.fcx.param_env); let universes = vec![None; outer_exclusive_binder(&value).as_usize()]; match solve::deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index f381146726734..2d05e33e44891 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -26,7 +26,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn replace_opaque_types_with_inference_vars>>( &self, value: T, - body_id: LocalDefId, + body_def_id: LocalDefId, span: Span, param_env: ty::ParamEnv<'tcx>, ) -> InferOk<'tcx, T> { @@ -60,7 +60,7 @@ impl<'tcx> InferCtxt<'tcx> { self.tcx, ObligationCause::new( span, - body_id, + body_def_id, traits::ObligationCauseCode::OpaqueReturnType(None), ), goal.param_env, diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 0536a6c909507..219d7efa391e3 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -158,11 +158,11 @@ impl<'tcx, O> Obligation<'tcx, O> { pub fn misc( tcx: TyCtxt<'tcx>, span: Span, - body_id: LocalDefId, + body_def_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, trait_ref: impl Upcast, O>, ) -> Obligation<'tcx, O> { - Obligation::new(tcx, ObligationCause::misc(span, body_id), param_env, trait_ref) + Obligation::new(tcx, ObligationCause::misc(span, body_def_id), param_env, trait_ref) } pub fn with

( diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 5d1b82b0bb48c..4c22310571f1a 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -417,13 +417,19 @@ trait UnusedDelimLint { } // either function/method call, or something this lint doesn't care about ref call_or_other => { - let (args_to_check, ctx) = match *call_or_other { - Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg), - MethodCall(ref call) => (&call.args[..], UnusedDelimsCtx::MethodArg), + let (args_to_check, ctx, callee_from_expansion) = match *call_or_other { + Call(ref callee, ref args) => { + (&args[..], UnusedDelimsCtx::FunctionArg, callee.span.from_expansion()) + } + MethodCall(ref call) => ( + &call.args[..], + UnusedDelimsCtx::MethodArg, + call.seg.ident.span.from_expansion(), + ), Closure(ref closure) if matches!(closure.fn_decl.output, FnRetTy::Default(_)) => { - (&[closure.body.clone()][..], UnusedDelimsCtx::ClosureBody) + (&[closure.body.clone()][..], UnusedDelimsCtx::ClosureBody, false) } // actual catch-all arm _ => { @@ -438,6 +444,11 @@ trait UnusedDelimLint { return; } for arg in args_to_check { + // Whether an expression is wrapped in a block can change which `macro_rules!` + // arm is taken. Don't report the braces as unused in that case. (Issue #158747) + if callee_from_expansion && Self::block_wraps_expanded_expr(arg) { + continue; + } self.check_unused_delims_expr(cx, arg, ctx, false, None, None, false); } return; @@ -516,6 +527,20 @@ trait UnusedDelimLint { false, ); } + + // Returns true for a user-written block whose only expression came from a macro expansion. + fn block_wraps_expanded_expr(value: &ast::Expr) -> bool { + if let ast::ExprKind::Block(ref block, None) = value.kind + && block.rules == ast::BlockCheckMode::Default + && !value.span.from_expansion() + && let [stmt] = block.stmts.as_slice() + && let ast::StmtKind::Expr(ref expr) = stmt.kind + { + expr.span.from_expansion() + } else { + false + } + } } declare_lint! { diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 3b8e6f6415365..f500041a12d8b 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -160,6 +160,10 @@ extern "C" void LLVMRustPrintStatisticsJSON(RustStringRef OutBuf) { llvm::PrintStatisticsJSON(OS); } +extern "C" bool LLVMRustIsCall(LLVMValueRef V) { + return llvm::isa(llvm::unwrap(V)); +} + // Some of the functions here rely on LLVM modules that may not always be // available. As such, we only try to build it in the first place, if // llvm.offload is enabled. diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 16a5a6c8877a5..6a7942a2bad29 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1108,7 +1108,7 @@ fn should_encode_mir( // instance_mir uses mir_for_ctfe rather than optimized_mir for constructors DefKind::Ctor(_, _) => (true, false), // Constants - DefKind::AnonConst { .. } + DefKind::AnonConst | DefKind::InlineConst | DefKind::AssocConst { .. } | DefKind::Const { .. } => (true, false), @@ -1438,27 +1438,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // for trivial const arguments which are directly lowered to // `ConstArgKind::Path`. We never actually access this `DefId` // anywhere so we don't need to encode it for other crates. + // FIXME(mgca): This probably isn't true, they probably are accessed, but, test case? if def_kind == DefKind::AnonConst - && match tcx.hir_node_by_def_id(local_id) { - hir::Node::ConstArg(hir::ConstArg { kind, .. }) => match kind { - // Skip encoding defs for these as they should not have had a `DefId` created - hir::ConstArgKind::Error(..) - | hir::ConstArgKind::Struct(..) - | hir::ConstArgKind::Array(..) - | hir::ConstArgKind::TupleCall(..) - | hir::ConstArgKind::Tup(..) - | hir::ConstArgKind::Path(..) - | hir::ConstArgKind::Literal { .. } - | hir::ConstArgKind::Infer(..) => true, - hir::ConstArgKind::Anon(..) => false, - }, - _ => false, - } + && matches!(tcx.hir_node_by_def_id(local_id), hir::Node::ConstArg(_)) { - // MGCA doesn't have unnecessary DefIds - if !tcx.features().min_generic_const_args() { - continue; - } + continue; } if def_kind == DefKind::Field diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 4cd124248e093..58a8eeeb242c0 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -44,13 +44,13 @@ use crate::ty::{self, AdtKind, GenericArgsRef, Ty}; pub struct ObligationCause<'tcx> { pub span: Span, - /// The ID of the fn body that triggered this obligation. This is + /// The ID of the fn that triggered this obligation. This is /// used for region obligations to determine the precise /// environment in which the region obligation should be evaluated /// (in particular, closures can add new assumptions). See the /// field `region_obligations` of the `FulfillmentContext` for more /// information. - pub body_id: LocalDefId, + pub body_def_id: LocalDefId, code: ObligationCauseCodeHandle<'tcx>, } @@ -62,7 +62,7 @@ pub struct ObligationCause<'tcx> { // which is hashed as an interned pointer. See #90996. impl Hash for ObligationCause<'_> { fn hash(&self, state: &mut H) { - self.body_id.hash(state); + self.body_def_id.hash(state); self.span.hash(state); } } @@ -71,14 +71,14 @@ impl<'tcx> ObligationCause<'tcx> { #[inline] pub fn new( span: Span, - body_id: LocalDefId, + body_def_id: LocalDefId, code: ObligationCauseCode<'tcx>, ) -> ObligationCause<'tcx> { - ObligationCause { span, body_id, code: code.into() } + ObligationCause { span, body_def_id, code: code.into() } } - pub fn misc(span: Span, body_id: LocalDefId) -> ObligationCause<'tcx> { - ObligationCause::new(span, body_id, ObligationCauseCode::Misc) + pub fn misc(span: Span, body_def_id: LocalDefId) -> ObligationCause<'tcx> { + ObligationCause::new(span, body_def_id, ObligationCauseCode::Misc) } #[inline(always)] @@ -88,7 +88,7 @@ impl<'tcx> ObligationCause<'tcx> { #[inline(always)] pub fn dummy_with_span(span: Span) -> ObligationCause<'tcx> { - ObligationCause { span, body_id: CRATE_DEF_ID, code: Default::default() } + ObligationCause { span, body_def_id: CRATE_DEF_ID, code: Default::default() } } #[inline] diff --git a/compiler/rustc_middle/src/ty/typetree.rs b/compiler/rustc_middle/src/ty/typetree.rs index 9e941bdb849ec..d4cda033a7e87 100644 --- a/compiler/rustc_middle/src/ty/typetree.rs +++ b/compiler/rustc_middle/src/ty/typetree.rs @@ -32,12 +32,19 @@ pub fn fnc_typetrees<'tcx>(tcx: TyCtxt<'tcx>, fn_ty: Ty<'tcx>) -> FncTree { // Create TypeTree for return type let ret = typetree_from_ty(tcx, sig.output()); - FncTree { args, ret } + let f = FncTree { args, ret }; + f } /// Generate a TypeTree for a specific type. /// Mainly a convenience wrapper around the actual implementation. pub fn typetree_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> TypeTree { + if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) { + return TypeTree::new(); + } + if tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::NoTT) { + return TypeTree::new(); + } let mut visited = Vec::new(); typetree_from_ty_impl_inner(tcx, ty, 0, &mut visited, false) } @@ -46,6 +53,40 @@ pub fn typetree_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> TypeTree { /// from pathological deeply nested types. Combined with cycle detection. const MAX_TYPETREE_DEPTH: usize = 6; +fn handle_indirection<'a>( + ty: Ty<'a>, + tcx: TyCtxt<'a>, + depth: usize, + visited: &mut Vec>, +) -> TypeTree { + let Some(inner_ty) = ty.builtin_deref(true) else { + bug!("incorrect autodiff typetree handling for type: {}", ty); + }; + // slices are represented as `&'{erased} mut [f32]` + // This reads as a reference to a slice of f32. + // So we'd end up with ptr->RustSlice->f32 without this extra handling + if inner_ty.is_slice() { + if let ty::Slice(element_ty) = inner_ty.kind() { + let element_tree = + typetree_from_ty_impl_inner(tcx, *element_ty, depth + 1, visited, false); + return TypeTree(vec![Type { + offset: -1, + size: tcx.data_layout.pointer_size().bytes_usize(), + kind: Kind::RustSlice, + child: element_tree, + }]); + } + } + + let child = typetree_from_ty_impl_inner(tcx, inner_ty, depth + 1, visited, true); + return TypeTree(vec![Type { + offset: -1, + size: tcx.data_layout.pointer_size().bytes_usize(), + kind: Kind::Pointer, + child, + }]); +} + /// Internal implementation with context about whether this is for a reference target. fn typetree_from_ty_impl_inner<'tcx>( tcx: TyCtxt<'tcx>, @@ -64,43 +105,12 @@ fn typetree_from_ty_impl_inner<'tcx>( } visited.push(ty); - if ty.is_scalar() { - let (kind, size) = if ty.is_integral() || ty.is_char() || ty.is_bool() { - (Kind::Integer, ty.primitive_size(tcx).bytes_usize()) - } else if ty.is_floating_point() { - match ty { - x if x == tcx.types.f16 => (Kind::Half, 2), - x if x == tcx.types.f32 => (Kind::Float, 4), - x if x == tcx.types.f64 => (Kind::Double, 8), - x if x == tcx.types.f128 => (Kind::F128, 16), - _ => (Kind::Integer, 0), - } - } else { - (Kind::Integer, 0) - }; - - // Use offset 0 for scalars that are direct targets of references (like &f64) - // Use offset -1 for scalars used directly (like function return types) - let offset = if is_reference_target && !ty.is_array() { 0 } else { -1 }; - return TypeTree(vec![Type { offset, size, kind, child: TypeTree::new() }]); - } - - if ty.is_ref() || ty.is_raw_ptr() || ty.is_box() { - let Some(inner_ty) = ty.builtin_deref(true) else { - return TypeTree::new(); - }; - - let child = typetree_from_ty_impl_inner(tcx, inner_ty, depth + 1, visited, true); - return TypeTree(vec![Type { - offset: -1, - size: tcx.data_layout.pointer_size().bytes_usize(), - kind: Kind::Pointer, - child, - }]); - } - - if ty.is_array() { - if let ty::Array(element_ty, len_const) = ty.kind() { + match ty.kind() { + // See handle_indirection for an explanation on why we don't handle it here. + ty::Slice(..) => bug!("incorrect autodiff typetree handling for slice: {}", ty), + ty::Ref(..) | ty::RawPtr(..) => handle_indirection(ty, tcx, depth, visited), + ty::Adt(def, _) if def.is_box() => handle_indirection(ty, tcx, depth, visited), + ty::Array(element_ty, len_const) => { let len = len_const.try_to_target_usize(tcx).unwrap_or(0); if len == 0 { return TypeTree::new(); @@ -109,65 +119,44 @@ fn typetree_from_ty_impl_inner<'tcx>( typetree_from_ty_impl_inner(tcx, *element_ty, depth + 1, visited, false); let mut types = Vec::new(); for elem_type in &element_tree.0 { - types.push(Type { - offset: -1, - size: elem_type.size, - kind: elem_type.kind, - child: elem_type.child.clone(), - }); + types.push(Type::from_ty(-1, elem_type)); } - return TypeTree(types); - } - } - - if ty.is_slice() { - if let ty::Slice(element_ty) = ty.kind() { - let element_tree = - typetree_from_ty_impl_inner(tcx, *element_ty, depth + 1, visited, false); - return element_tree; - } - } - - if let ty::Tuple(tuple_types) = ty.kind() { - if tuple_types.is_empty() { - return TypeTree::new(); + TypeTree(types) } + ty::Tuple(tuple_types) => { + if tuple_types.is_empty() { + return TypeTree::new(); + } - let mut types = Vec::new(); - let mut current_offset = 0; + let mut types = Vec::new(); + let mut current_offset = 0; - for tuple_ty in tuple_types.iter() { - let element_tree = - typetree_from_ty_impl_inner(tcx, tuple_ty, depth + 1, visited, false); + for tuple_ty in tuple_types.iter() { + let element_tree = + typetree_from_ty_impl_inner(tcx, tuple_ty, depth + 1, visited, false); - let element_layout = tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(tuple_ty)) - .ok() - .map(|layout| layout.size.bytes_usize()) - .unwrap_or(0); + let element_layout = tcx + .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(tuple_ty)) + .ok() + .map(|layout| layout.size.bytes_usize()) + .unwrap_or(0); - for elem_type in &element_tree.0 { - types.push(Type { - offset: if elem_type.offset == -1 { + for elem_type in &element_tree.0 { + let offset = if elem_type.offset == -1 { current_offset as isize } else { current_offset as isize + elem_type.offset - }, - size: elem_type.size, - kind: elem_type.kind, - child: elem_type.child.clone(), - }); + }; + types.push(Type::from_ty(offset, elem_type)); + } + + current_offset += element_layout; } - current_offset += element_layout; + TypeTree(types) } - - return TypeTree(types); - } - - if let ty::Adt(adt_def, args) = ty.kind() { - if adt_def.is_struct() { + ty::Adt(adt_def, args) if adt_def.is_struct() => { let struct_layout = tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)); if let Ok(layout) = struct_layout { @@ -186,23 +175,37 @@ fn typetree_from_ty_impl_inner<'tcx>( let field_offset = layout.fields.offset(field_idx).bytes_usize(); for elem_type in &field_tree.0 { - types.push(Type { - offset: if elem_type.offset == -1 { - field_offset as isize - } else { - field_offset as isize + elem_type.offset - }, - size: elem_type.size, - kind: elem_type.kind, - child: elem_type.child.clone(), - }); + let offset = if elem_type.offset == -1 { + field_offset as isize + } else { + field_offset as isize + elem_type.offset + }; + types.push(Type::from_ty(offset, elem_type)); } } - return TypeTree(types); + TypeTree(types) + } else { + TypeTree::new() } } + ty::Char | ty::Bool | ty::Infer(ty::IntVar(_)) | ty::Int(_) | ty::Uint(_) => { + let kind = Kind::Integer; + let size = ty.primitive_size(tcx).bytes_usize(); + let offset = if is_reference_target { 0 } else { -1 }; + TypeTree(vec![Type { offset, size, kind, child: TypeTree::new() }]) + } + ty::Float(_) | ty::Infer(ty::FloatVar(_)) => { + let (enzyme_ty, size) = match ty { + x if x == tcx.types.f16 => (Kind::Half, 2), + x if x == tcx.types.f32 => (Kind::Float, 4), + x if x == tcx.types.f64 => (Kind::Double, 8), + x if x == tcx.types.f128 => (Kind::F128, 16), + _ => bug!("Unexpected floating point type: {:?}", ty), + }; + let offset = if is_reference_target { 0 } else { -1 }; + TypeTree(vec![Type { offset, size, kind: enzyme_ty, child: TypeTree::new() }]) + } + _ => TypeTree::new(), } - - TypeTree::new() } diff --git a/compiler/rustc_parse/src/parser/asm.rs b/compiler/rustc_parse/src/parser/asm.rs index 3fab234adaad4..11460e775d36d 100644 --- a/compiler/rustc_parse/src/parser/asm.rs +++ b/compiler/rustc_parse/src/parser/asm.rs @@ -1,4 +1,4 @@ -use rustc_ast::{self as ast, AsmMacro, MgcaDisambiguation}; +use rustc_ast::{self as ast, AsmMacro}; use rustc_span::{Span, Symbol, kw}; use super::{ExpKeywordPair, ForceCollect, IdentIsRaw, Trailing, UsePreAttrPos}; @@ -149,7 +149,7 @@ fn parse_asm_operand<'a>( let block = p.parse_block()?; ast::InlineAsmOperand::Label { block } } else if p.eat_keyword(exp!(Const)) { - let anon_const = p.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?; + let anon_const = p.parse_expr_anon_const()?; ast::InlineAsmOperand::Const { anon_const } } else if p.eat_keyword(exp!(Sym)) { let expr = p.parse_expr()?; diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 28e2841b9f1fe..a91ee634f3d47 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -7,7 +7,7 @@ use rustc_ast::util::parser::AssocOp; use rustc_ast::{ self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, Block, BlockCheckMode, Expr, ExprKind, GenericArg, GenericArgs, Generics, Item, ItemKind, - MgcaDisambiguation, Param, Pat, PatKind, Path, PathSegment, QSelf, Recovered, Ty, TyKind, + Param, Pat, PatKind, Path, PathSegment, QSelf, Recovered, Ty, TyKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; @@ -2585,11 +2585,7 @@ impl<'a> Parser<'a> { self.dcx().emit_err(UnexpectedConstParamDeclaration { span: param.span(), sugg }); let value = self.mk_expr_err(param.span(), guar); - Some(GenericArg::Const(AnonConst { - id: ast::DUMMY_NODE_ID, - value, - mgca_disambiguation: MgcaDisambiguation::Direct, - })) + Some(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value })) } pub(super) fn recover_const_param_declaration( @@ -2673,11 +2669,7 @@ impl<'a> Parser<'a> { ); let guar = err.emit(); let value = self.mk_expr_err(start.to(expr.span), guar); - return Ok(GenericArg::Const(AnonConst { - id: ast::DUMMY_NODE_ID, - value, - mgca_disambiguation: MgcaDisambiguation::Direct, - })); + return Ok(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value })); } else if snapshot.token == token::Colon && expr.span.lo() == snapshot.token.span.hi() && matches!(expr.kind, ExprKind::Path(..)) @@ -2746,11 +2738,7 @@ impl<'a> Parser<'a> { ); let guar = err.emit(); let value = self.mk_expr_err(span, guar); - GenericArg::Const(AnonConst { - id: ast::DUMMY_NODE_ID, - value, - mgca_disambiguation: MgcaDisambiguation::Direct, - }) + GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }) } /// Some special error handling for the "top-level" patterns in a match arm, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index df1877b82cb93..e151899a57228 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -15,8 +15,8 @@ use rustc_ast::visit::{Visitor, walk_expr}; use rustc_ast::{ self as ast, AnonConst, Arm, AssignOp, AssignOpKind, AttrStyle, AttrVec, BinOp, BinOpKind, BlockCheckMode, CaptureBy, ClosureBinder, DUMMY_NODE_ID, Expr, ExprField, ExprKind, FnDecl, - FnRetTy, Guard, Label, MacCall, MetaItemLit, MgcaDisambiguation, Movability, Param, - RangeLimits, StmtKind, Ty, TyKind, UnOp, UnsafeBinderCastKind, YieldKind, + FnRetTy, Guard, Label, MacCall, MetaItemLit, Movability, Param, RangeLimits, StmtKind, Ty, + TyKind, UnOp, UnsafeBinderCastKind, YieldKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -83,15 +83,8 @@ impl<'a> Parser<'a> { ) } - pub fn parse_expr_anon_const( - &mut self, - mgca_disambiguation: impl FnOnce(&Self, &Expr) -> MgcaDisambiguation, - ) -> PResult<'a, AnonConst> { - self.parse_expr().map(|value| AnonConst { - id: DUMMY_NODE_ID, - mgca_disambiguation: mgca_disambiguation(self, &value), - value, - }) + pub fn parse_expr_anon_const(&mut self) -> PResult<'a, AnonConst> { + self.parse_expr().map(|value| AnonConst { id: DUMMY_NODE_ID, value }) } fn parse_expr_catch_underscore( @@ -1672,7 +1665,7 @@ impl<'a> Parser<'a> { let first_expr = self.parse_expr()?; if self.eat(exp!(Semi)) { // Repeating array syntax: `[ 0; 512 ]` - let count = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::Direct)?; + let count = self.parse_expr_anon_const()?; self.expect(close)?; ExprKind::Repeat(first_expr, count) } else if self.eat(exp!(Comma)) { @@ -4508,6 +4501,7 @@ impl MutVisitor for CondChecker<'_> { | ExprKind::IncludedBytes(_) | ExprKind::FormatArgs(_) | ExprKind::Err(_) + | ExprKind::DirectConstArg(_) | ExprKind::Dummy => { // These would forbid any let expressions they contain already. } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 98b2ed1642582..90bfc9ece6b18 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1696,9 +1696,9 @@ impl<'a> Parser<'a> { if self.may_recover() { self.parse_where_clause()? } else { WhereClause::default() }; let rhs = match (self.eat(exp!(Eq)), const_arg) { - (true, true) => ConstItemRhsKind::TypeConst { - rhs: Some(self.parse_expr_anon_const(|_, _| MgcaDisambiguation::Direct)?), - }, + (true, true) => { + ConstItemRhsKind::TypeConst { rhs: Some(self.parse_expr_anon_const()?) } + } (true, false) => ConstItemRhsKind::Body { rhs: Some(self.parse_expr()?) }, (false, true) => ConstItemRhsKind::TypeConst { rhs: None }, (false, false) => ConstItemRhsKind::Body { rhs: None }, @@ -1918,11 +1918,8 @@ impl<'a> Parser<'a> { VariantData::Unit(DUMMY_NODE_ID) }; - let disr_expr = if this.eat(exp!(Eq)) { - Some(this.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?) - } else { - None - }; + let disr_expr = + if this.eat(exp!(Eq)) { Some(this.parse_expr_anon_const()?) } else { None }; let span = vlo.to(this.prev_token.span); if ident.name == kw::Underscore { @@ -2143,7 +2140,7 @@ impl<'a> Parser<'a> { if p.token == token::Eq { let mut snapshot = p.create_snapshot_for_diagnostic(); snapshot.bump(); - match snapshot.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst) { + match snapshot.parse_expr_anon_const() { Ok(const_expr) => { let sp = ty.span.shrink_to_hi().to(const_expr.value.span); p.psess.gated_spans.gate(sym::default_field_values, sp); @@ -2372,7 +2369,7 @@ impl<'a> Parser<'a> { } let default = if self.token == token::Eq { self.bump(); - let const_expr = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?; + let const_expr = self.parse_expr_anon_const()?; let sp = ty.span.shrink_to_hi().to(const_expr.value.span); self.psess.gated_spans.gate(sym::default_field_values, sp); Some(const_expr) diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 64255d51a7c69..d25caa2456f85 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -36,8 +36,8 @@ use rustc_ast::util::classify; use rustc_ast::{ self as ast, AnonConst, AttrArgs, AttrId, BinOpKind, ByRef, Const, CoroutineKind, DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, ImplRestriction, - MgcaDisambiguation, MutRestriction, Mutability, Recovered, RestrictionKind, Safety, StrLit, - Visibility, VisibilityKind, + MutRestriction, Mutability, Recovered, RestrictionKind, Safety, StrLit, Visibility, + VisibilityKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; @@ -1298,7 +1298,6 @@ impl<'a> Parser<'a> { let anon_const = AnonConst { id: DUMMY_NODE_ID, value: self.mk_expr(blk.span, ExprKind::Block(blk, None)), - mgca_disambiguation: MgcaDisambiguation::AnonConst, }; let blk_span = anon_const.value.span; let kind = if pat { diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index ea86c08915b31..d3839579d1311 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -4,8 +4,8 @@ use ast::token::IdentIsRaw; use rustc_ast::token::{self, MetaVarKind, Token, TokenKind}; use rustc_ast::{ self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocItemConstraint, - AssocItemConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, MgcaDisambiguation, - ParenthesizedArgs, Path, PathSegment, QSelf, + AssocItemConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs, + Path, PathSegment, QSelf, }; use rustc_errors::{Applicability, Diag, PResult}; use rustc_span::{BytePos, Ident, Span, kw, sym}; @@ -876,13 +876,12 @@ impl<'a> Parser<'a> { /// the caller. pub(super) fn parse_const_arg(&mut self) -> PResult<'a, AnonConst> { // Parse const argument. - let (value, mgca_disambiguation) = if self.token.kind == token::OpenBrace { - let value = self.parse_expr_block(None, self.token.span, BlockCheckMode::Default)?; - (value, MgcaDisambiguation::Direct) + let value = if self.token.kind == token::OpenBrace { + self.parse_expr_block(None, self.token.span, BlockCheckMode::Default)? } else { self.parse_unambiguous_unbraced_const_arg()? }; - Ok(AnonConst { id: ast::DUMMY_NODE_ID, value, mgca_disambiguation }) + Ok(AnonConst { id: ast::DUMMY_NODE_ID, value }) } /// Attempt to parse a const argument that has not been enclosed in braces. @@ -892,9 +891,7 @@ impl<'a> Parser<'a> { /// - Single-segment paths (i.e. standalone generic const parameters). /// All other expressions that can be parsed will emit an error suggesting the expression be /// wrapped in braces. - pub(super) fn parse_unambiguous_unbraced_const_arg( - &mut self, - ) -> PResult<'a, (Box, MgcaDisambiguation)> { + pub(super) fn parse_unambiguous_unbraced_const_arg(&mut self) -> PResult<'a, Box> { let start = self.token.span; let attrs = self.parse_outer_attributes()?; let (expr, _) = @@ -915,7 +912,7 @@ impl<'a> Parser<'a> { }); } - Ok((expr, MgcaDisambiguation::Direct)) + Ok(expr) } /// Parse a generic argument in a path segment. @@ -1019,11 +1016,7 @@ impl<'a> Parser<'a> { GenericArg::Type(_) => GenericArg::Type(self.mk_ty(attr_span, TyKind::Err(guar))), GenericArg::Const(_) => { let error_expr = self.mk_expr(attr_span, ExprKind::Err(guar)); - GenericArg::Const(AnonConst { - id: ast::DUMMY_NODE_ID, - value: error_expr, - mgca_disambiguation: MgcaDisambiguation::Direct, - }) + GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value: error_expr }) } GenericArg::Lifetime(lt) => GenericArg::Lifetime(lt), })); diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 9c873711e2f87..00edb4c1e4994 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -2,9 +2,9 @@ use rustc_ast::token::{self, IdentIsRaw, MetaVarKind, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ self as ast, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnPtrTy, FnRetTy, - GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MgcaDisambiguation, - MutTy, Mutability, Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, - TraitObjectSyntax, Ty, TyKind, UnsafeBinderTy, + GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, + Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, + TyKind, UnsafeBinderTy, }; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Applicability, Diag, E0516, PResult}; @@ -660,7 +660,7 @@ impl<'a> Parser<'a> { }; let ty = if self.eat(exp!(Semi)) { - let mut length = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::Direct)?; + let mut length = self.parse_expr_anon_const()?; if let Err(e) = self.expect(exp!(CloseBracket)) { // Try to recover from `X` when `X::` works @@ -704,7 +704,7 @@ impl<'a> Parser<'a> { // FIXME(mgca): recovery is broken for `const {` args // we first try to parse pattern like `[u8 5]` - let length = match self.parse_expr_anon_const(|_, _| MgcaDisambiguation::Direct) { + let length = match self.parse_expr_anon_const() { Ok(length) => length, Err(e) => { e.cancel(); @@ -813,7 +813,7 @@ impl<'a> Parser<'a> { /// an error type. fn parse_typeof_ty(&mut self, lo: Span) -> PResult<'a, TyKind> { self.expect(exp!(OpenParen))?; - let _expr = self.parse_expr_anon_const(|_, _| MgcaDisambiguation::AnonConst)?; + let _expr = self.parse_expr_anon_const()?; self.expect(exp!(CloseParen))?; let span = lo.to(self.prev_token.span); let guar = self diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index 2f3fbc28ad49d..57d1b12e8a178 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -660,7 +660,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { If, While, ForLoop, Loop, Match, Closure, Block, Await, Move, Use, TryBlock, Assign, AssignOp, Field, Index, Range, Underscore, Path, AddrOf, Break, Continue, Ret, InlineAsm, FormatArgs, OffsetOf, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet, - Become, IncludedBytes, Gen, UnsafeBinderCast, Err, Dummy + Become, IncludedBytes, Gen, UnsafeBinderCast, Err, Dummy, DirectConstArg ] ); ast_visit::walk_expr(self, e) @@ -688,8 +688,9 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { ImplicitSelf, MacCall, CVarArgs, - Dummy, FieldOf, + DirectConstArg, + Dummy, Err ] ); diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index de3f8c380fc44..81c6db6a9d6d7 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -425,26 +425,9 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { fn visit_anon_const(&mut self, constant: &'a AnonConst) { // Note that `visit_anon_const` is skipped for AnonConst nodes wrapped in an // ExprKind::ConstBlock - these are handled in visit_expr, and are DefKind::InlineConst. - - // `MgcaDisambiguation::Direct` is set even when MGCA is disabled, so - // to avoid affecting stable we have to feature gate the not creating - // anon consts - if !self.r.features.min_generic_const_args() { - let parent = self - .create_def(constant.id, None, DefKind::AnonConst, constant.value.span) - .def_id(); - return self.with_parent(parent, |this| visit::walk_anon_const(this, constant)); - } - - match constant.mgca_disambiguation { - MgcaDisambiguation::Direct => visit::walk_anon_const(self, constant), - MgcaDisambiguation::AnonConst => { - let parent = self - .create_def(constant.id, None, DefKind::AnonConst, constant.value.span) - .def_id(); - self.with_parent(parent, |this| visit::walk_anon_const(this, constant)); - } - }; + let parent = + self.create_def(constant.id, None, DefKind::AnonConst, constant.value.span).def_id(); + self.with_parent(parent, |this| visit::walk_anon_const(this, constant)); } #[instrument(level = "debug", skip(self))] diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8e23e290e9ab4..6832aa2a889a1 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -822,6 +822,7 @@ symbols! { diagnostic_on_unmatched_args, dialect, direct, + direct_const_arg, discriminant_kind, discriminant_type, discriminant_value, diff --git a/compiler/rustc_target/src/spec/abi_map.rs b/compiler/rustc_target/src/spec/abi_map.rs index f7a7ae1eb7555..dd69afec47975 100644 --- a/compiler/rustc_target/src/spec/abi_map.rs +++ b/compiler/rustc_target/src/spec/abi_map.rs @@ -60,6 +60,8 @@ impl AbiMap { Arch::Msp430 => ArchKind::Msp430, Arch::Nvptx64 => ArchKind::Nvptx, Arch::RiscV32 | Arch::RiscV64 => ArchKind::Riscv, + Arch::SpirV => ArchKind::Spirv, + Arch::Wasm32 | Arch::Wasm64 => ArchKind::Wasm, Arch::X86 => ArchKind::X86, Arch::X86_64 => ArchKind::X86_64, _ => ArchKind::Other, @@ -102,8 +104,6 @@ impl AbiMap { (ExternAbi::RustPreserveNone, _) => CanonAbi::RustPreserveNone, (ExternAbi::RustTail, _) => CanonAbi::RustTail, - (ExternAbi::Custom, _) => CanonAbi::Custom, - (ExternAbi::Swift, _) => CanonAbi::Swift, (ExternAbi::System { .. }, ArchKind::X86) @@ -122,6 +122,9 @@ impl AbiMap { // always and forever (ExternAbi::RustInvalid, _) => return AbiMapping::Invalid, + (ExternAbi::Custom, ArchKind::Wasm | ArchKind::Spirv) => return AbiMapping::Invalid, + (ExternAbi::Custom, _) => CanonAbi::Custom, + (ExternAbi::EfiApi, ArchKind::Arm(..)) => CanonAbi::Arm(ArmCall::Aapcs), (ExternAbi::EfiApi, ArchKind::X86_64) => CanonAbi::X86(X86Call::Win64), ( @@ -221,6 +224,8 @@ enum ArchKind { Riscv, X86, X86_64, + Wasm, + Spirv, /// Architectures which don't need other considerations for ABI lowering Other, } diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs index 35c477d2bdaf8..1e6b9a7bdc267 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs @@ -1,12 +1,15 @@ use crate::spec::{ Arch, Cc, CfgAbi, LinkerFlavor, Lld, LlvmAbi, StackProbeType, Target, TargetMetadata, - TargetOptions, base, + TargetOptions, add_link_args, base, }; pub(crate) fn target() -> Target { let mut base = base::freebsd::opts(); base.cpu = "ppc64le".into(); base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + // long double is IEEE-128; f128 soft-float ops emit the PPC __*kf* helpers, + // which compiler_builtins lacks. Resolve them from base libgcc. + add_link_args(&mut base.late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-lgcc"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; base.cfg_abi = CfgAbi::ElfV2; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 9822e8cdef8b2..63a55c32b54ce 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -1813,7 +1813,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } - let body_owner_def_id = (cause.body_id != CRATE_DEF_ID).then(|| cause.body_id.to_def_id()); + let body_owner_def_id = + (cause.body_def_id != CRATE_DEF_ID).then(|| cause.body_def_id.to_def_id()); self.note_and_explain_type_err(diag, terr, cause, span, body_owner_def_id); if let Some(exp_found) = exp_found && let exp_found = TypeError::Sorts(exp_found) @@ -1945,7 +1946,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let TypeError::ArraySize(sz) = terr else { return None; }; - let tykind = match self.tcx.hir_node_by_def_id(trace.cause.body_id) { + let tykind = match self.tcx.hir_node_by_def_id(trace.cause.body_def_id) { hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { body: body_id, .. }, .. }) => { 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 aa10b4ee6d39c..71f81bb633ba6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -173,7 +173,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { exp_span, exp_found.expected, exp_found.found, ); - match self.tcx.coroutine_kind(cause.body_id) { + match self.tcx.coroutine_kind(cause.body_def_id) { Some(hir::CoroutineKind::Desugared( hir::CoroutineDesugaring::Async | hir::CoroutineDesugaring::AsyncGen, _, @@ -636,7 +636,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - self.tcx.hir_maybe_body_owned_by(cause.body_id).and_then(|body| { + self.tcx.hir_maybe_body_owned_by(cause.body_def_id).and_then(|body| { IfVisitor { err_span: span, found_if: false } .visit_body(&body) .is_break() diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 622c0b619431e..40bae03a649db 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -144,14 +144,14 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( }, ); - // If our `body_id` has been set (and isn't just from a dummy obligation cause), + // If our `body_def_id` has been set (and isn't just from a dummy obligation cause), // then try to look for a param-env clause that would apply. The way we compute // this is somewhat manual, since we need the spans, so we elaborate this directly // from `predicates_of` rather than actually looking at the param-env which // otherwise would be more appropriate. - let body_id = obligation.cause.body_id; - if body_id != CRATE_DEF_ID { - let predicates = tcx.predicates_of(body_id.to_def_id()).instantiate_identity(tcx); + let body_def_id = obligation.cause.body_def_id; + if body_def_id != CRATE_DEF_ID { + let predicates = tcx.predicates_of(body_def_id.to_def_id()).instantiate_identity(tcx); for (pred, span) in elaborate(tcx, predicates.into_iter().map(|(c, s)| (c.skip_norm_wip(), s))) { @@ -231,7 +231,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return match self.tainted_by_errors() { None => self .emit_inference_failure_err( - obligation.cause.body_id, + obligation.cause.body_def_id, span, trait_pred.self_ty().skip_binder().into(), TypeAnnotationNeeded::E0282, @@ -285,7 +285,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) .collect(); self.emit_inference_failure_err_with_type_hint( - obligation.cause.body_id, + obligation.cause.body_def_id, span, term, TypeAnnotationNeeded::E0283, @@ -369,7 +369,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { impl_candidates.as_slice(), obligation, trait_pred, - obligation.cause.body_id, + obligation.cause.body_def_id, &mut err, false, obligation.param_env, @@ -384,7 +384,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } if term.is_some_and(|term| term.as_type().is_some()) - && let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) + && let Some(body) = + self.tcx.hir_maybe_body_owned_by(obligation.cause.body_def_id) { let mut expr_finder = FindExprBySpan::new(span, self.tcx); expr_finder.visit_expr(&body.value); @@ -546,7 +547,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } self.emit_inference_failure_err( - obligation.cause.body_id, + obligation.cause.body_def_id, span, term, TypeAnnotationNeeded::E0282, @@ -565,7 +566,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // both must be type variables, or the other would've been instantiated assert!(a.is_ty_var() && b.is_ty_var()); self.emit_inference_failure_err( - obligation.cause.body_id, + obligation.cause.body_def_id, span, a.into(), TypeAnnotationNeeded::E0282, @@ -599,7 +600,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let predicate = self.tcx.short_string(predicate, &mut long_ty_path); if let Some(term) = term { self.emit_inference_failure_err( - obligation.cause.body_id, + obligation.cause.body_def_id, span, term, TypeAnnotationNeeded::E0284, @@ -631,7 +632,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { data.walk().filter_map(ty::GenericArg::as_term).find(|term| term.is_infer()); if let Some(term) = term { self.emit_inference_failure_err( - obligation.cause.body_id, + obligation.cause.body_def_id, span, term, TypeAnnotationNeeded::E0284, @@ -653,7 +654,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ..)) => self .emit_inference_failure_err( - obligation.cause.body_id, + obligation.cause.body_def_id, span, ct.into(), TypeAnnotationNeeded::E0284, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index e1b1a41f37a74..617ec6c4ac229 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -468,7 +468,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } if let Some(s) = parent_label { - let body = obligation.cause.body_id; + let body = obligation.cause.body_def_id; err.span_label(tcx.def_span(body), s); } @@ -689,7 +689,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { violations, ); if let hir::Node::Item(item) = - self.tcx.hir_node_by_def_id(obligation.cause.body_id) + self.tcx.hir_node_by_def_id(obligation.cause.body_def_id) && let hir::ItemKind::Impl(impl_) = item.kind && let None = impl_.of_trait && let hir::TyKind::TraitObject(_, tagged_ptr) = impl_.self_ty.kind @@ -949,7 +949,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } else if let ty::Param(param) = trait_ref.self_ty().skip_binder().kind() && let Some(generics) = - self.tcx.hir_node_by_def_id(main_obligation.cause.body_id).generics() + self.tcx.hir_node_by_def_id(main_obligation.cause.body_def_id).generics() { let constraint = ty::print::with_no_trimmed_paths!(format!( "[const] {}", @@ -1144,7 +1144,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } } - let hir_id = self.tcx.local_def_id_to_hir_id(obligation.cause.body_id); + let hir_id = self.tcx.local_def_id_to_hir_id(obligation.cause.body_def_id); let Some(body_id) = self.tcx.hir_node(hir_id).body_id() else { return (false, false) }; let ControlFlow::Break(expr) = (FindMethodSubexprOfTry { search_span: span }).visit_body(self.tcx.hir_body(body_id)) @@ -1382,7 +1382,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty: Ty<'tcx>, obligation: &PredicateObligation<'tcx>, ) -> Diag<'a> { - let def_id = obligation.cause.body_id; + let def_id = obligation.cause.body_def_id; let span = self.tcx.ty_span(def_id); let mut file = None; @@ -2869,7 +2869,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // message, and fall back to regular note otherwise. if !self.maybe_note_obligation_cause_for_async_await(err, obligation) { self.note_obligation_cause_code( - obligation.cause.body_id, + obligation.cause.body_def_id, err, obligation.predicate, obligation.param_env, @@ -2884,7 +2884,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { obligation.cause.code(), ); self.suggest_borrow_for_unsized_closure_return( - obligation.cause.body_id, + obligation.cause.body_def_id, err, obligation.predicate, ); @@ -3211,7 +3211,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { is_fn_trait: bool, suggested: bool, ) { - let body_def_id = obligation.cause.body_id; + let body_def_id = obligation.cause.body_def_id; let span = if let ObligationCauseCode::BinOp { rhs_span, .. } = obligation.cause.code() { *rhs_span } else { @@ -3242,7 +3242,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err, trait_predicate, None, - obligation.cause.body_id, + obligation.cause.body_def_id, ); } else if trait_def_id.is_local() && self.tcx.trait_impls_of(trait_def_id).is_empty() @@ -3798,7 +3798,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { { trait_item_def_id.as_local() } else { - Some(obligation.cause.body_id) + Some(obligation.cause.body_def_id) }; if let Some(suggestion_def_id) = suggestion_def_id && let Some(generics) = self.tcx.hir_get_generics(suggestion_def_id) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index e38ac4c447fcc..b50ace11bbd75 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -340,7 +340,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { | ObligationCauseCode::WhereClauseInExpr(..) = code { self.note_obligation_cause_code( - error.obligation.cause.body_id, + error.obligation.cause.body_def_id, &mut diag, error.obligation.predicate, error.obligation.param_env, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 53eebfd377171..138c53d013ebc 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -72,7 +72,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): HIR is not present for RPITITs, // but I guess we could synthesize one here. We don't see any errors that rely on // that yet, though. - let item_context = self.describe_enclosure(obligation.cause.body_id).unwrap_or(""); + let item_context = self.describe_enclosure(obligation.cause.body_def_id).unwrap_or(""); let direct = match obligation.cause.code() { ObligationCauseCode::BuiltinDerived(..) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs index df7f89266012e..a5377fc04acef 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs @@ -150,7 +150,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { suggest_increasing_limit, |err| { self.note_obligation_cause_code( - obligation.cause.body_id, + obligation.cause.body_def_id, err, predicate, obligation.param_env, 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 c4d04fe7d7f31..99b488740412b 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -285,7 +285,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } if !cause.span.is_dummy() - && let Some(body) = self.tcx.hir_maybe_body_owned_by(cause.body_id) + && let Some(body) = self.tcx.hir_maybe_body_owned_by(cause.body_def_id) { let mut expr_finder = FindExprBySpan::new(cause.span, self.tcx); expr_finder.visit_body(body); @@ -467,7 +467,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err: &mut Diag<'_>, trait_pred: ty::PolyTraitPredicate<'tcx>, associated_ty: Option<(&'static str, Ty<'tcx>)>, - mut body_id: LocalDefId, + mut body_def_id: LocalDefId, ) { if trait_pred.skip_binder().polarity != ty::PredicatePolarity::Positive { return; @@ -494,7 +494,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // FIXME: Add check for trait bound that is already present, particularly `?Sized` so we // don't suggest `T: Sized + ?Sized`. loop { - let node = self.tcx.hir_node_by_def_id(body_id); + let node = self.tcx.hir_node_by_def_id(body_def_id); match node { hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait { ident, generics, bounds, .. }, @@ -504,7 +504,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Restricting `Self` for a single method. suggest_restriction( self.tcx, - body_id, + body_def_id, generics, "`Self`", err, @@ -524,7 +524,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { assert!(param_ty); // Restricting `Self` for a single method. suggest_restriction( - self.tcx, body_id, generics, "`Self`", err, None, projection, trait_pred, + self.tcx, + body_def_id, + generics, + "`Self`", + err, + None, + projection, + trait_pred, None, ); return; @@ -547,7 +554,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Missing restriction on associated type of type parameter (unmet projection). suggest_restriction( self.tcx, - body_id, + body_def_id, generics, "the associated type", err, @@ -567,7 +574,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Missing restriction on associated type of type parameter (unmet projection). suggest_restriction( self.tcx, - body_id, + body_def_id, generics, "the associated type", err, @@ -687,7 +694,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { _ => {} } - body_id = self.tcx.local_parent(body_id); + body_def_id = self.tcx.local_parent(body_def_id); } } @@ -1024,7 +1031,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); let Some((def_id_or_name, output, inputs)) = - self.extract_callable_info(obligation.cause.body_id, obligation.param_env, self_ty) + self.extract_callable_info(obligation.cause.body_def_id, obligation.param_env, self_ty) else { return false; }; @@ -1232,7 +1239,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Wrap method receivers and `&`-references in parens. let suggestion = if self.tcx.sess.source_map().span_followed_by(span, ".").is_some() { parenthesized_cast(span) - } else if let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) { + } else if let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_def_id) { let mut expr_finder = FindExprBySpan::new(span, self.tcx); expr_finder.visit_expr(body.value); if let Some(expr) = expr_finder.result @@ -1271,7 +1278,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span.remove_mark(); } let mut expr_finder = FindExprBySpan::new(span, self.tcx); - let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else { + let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_def_id) else { return; }; expr_finder.visit_expr(body.value); @@ -1350,7 +1357,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ) -> bool { let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); self.enter_forall(self_ty, |ty: Ty<'_>| { - let Some(generics) = self.tcx.hir_get_generics(obligation.cause.body_id) else { + let Some(generics) = self.tcx.hir_get_generics(obligation.cause.body_def_id) else { return false; }; let ty::Ref(_, inner_ty, hir::Mutability::Not) = ty.kind() else { return false }; @@ -1444,7 +1451,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { /// because the callable type must also be well-formed to be called. pub fn extract_callable_info( &self, - body_id: LocalDefId, + body_def_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, found: Ty<'tcx>, ) -> Option<(DefIdOrName, Ty<'tcx>, Vec>)> { @@ -1526,7 +1533,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } }), ty::Param(param) => { - let generics = self.tcx.generics_of(body_id); + let generics = self.tcx.generics_of(body_def_id); let name = if generics.count() > param.index as usize && let def = generics.param_at(param.index as usize, self.tcx) && matches!(def.kind, ty::GenericParamDefKind::Type { .. }) @@ -1597,7 +1604,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; let (Some(typeck_results), Some(body)) = ( self.typeck_results.as_ref(), - self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id), + self.tcx.hir_maybe_body_owned_by(obligation.cause.body_def_id), ) else { return true; }; @@ -1859,7 +1866,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Issue #104961, we need to add parentheses properly for compound expressions // for example, `x.starts_with("hi".to_string() + "you")` // should be `x.starts_with(&("hi".to_string() + "you"))` - let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else { + let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_def_id) else { return false; }; let mut expr_finder = FindExprBySpan::new(span, self.tcx); @@ -2085,7 +2092,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span.remove_mark(); } let mut expr_finder = super::FindExprBySpan::new(span, self.tcx); - let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else { + let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_def_id) else { return false; }; expr_finder.visit_expr(body.value); @@ -2413,7 +2420,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span: Span, trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool { - let node = self.tcx.hir_node_by_def_id(obligation.cause.body_id); + let node = self.tcx.hir_node_by_def_id(obligation.cause.body_def_id); if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn {sig, body: body_id, .. }, .. }) = node && let hir::ExprKind::Block(blk, _) = &self.tcx.hir_body(*body_id).value.kind && sig.decl.output.span().overlaps(span) @@ -2449,7 +2456,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub(super) fn suggest_borrow_for_unsized_closure_return( &self, - body_id: LocalDefId, + body_def_id: LocalDefId, err: &mut Diag<'_, G>, predicate: ty::Predicate<'tcx>, ) { @@ -2463,10 +2470,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let Some(span) = err.span.primary_span() else { return; }; - let Some(node_body_id) = self.tcx.hir_node_by_def_id(body_id).body_id() else { + let Some(body_id) = self.tcx.hir_node_by_def_id(body_def_id).body_id() else { return; }; - let body = self.tcx.hir_body(node_body_id); + let body = self.tcx.hir_body(body_id); let mut expr_finder = FindExprBySpan::new(span, self.tcx); expr_finder.visit_expr(body.value); let Some(expr) = expr_finder.result else { @@ -2503,7 +2510,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub(super) fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option { let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig, .. }, .. }) = - self.tcx.hir_node_by_def_id(obligation.cause.body_id) + self.tcx.hir_node_by_def_id(obligation.cause.body_def_id) else { return None; }; @@ -2529,7 +2536,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(fn_sig, _), .. }) | Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(fn_sig, _), .. }) = - self.tcx.hir_node_by_def_id(obligation.cause.body_id) + self.tcx.hir_node_by_def_id(obligation.cause.body_def_id) && let hir::FnRetTy::Return(ty) = fn_sig.decl.output && let hir::TyKind::Path(qpath) = ty.kind && let hir::QPath::Resolved(None, path) = qpath @@ -2559,8 +2566,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut span = obligation.cause.span; let mut is_async_fn_return = false; - if let DefKind::Closure = self.tcx.def_kind(obligation.cause.body_id) - && let parent = self.tcx.local_parent(obligation.cause.body_id) + if let DefKind::Closure = self.tcx.def_kind(obligation.cause.body_def_id) + && let parent = self.tcx.local_parent(obligation.cause.body_def_id) && let DefKind::Fn | DefKind::AssocFn = self.tcx.def_kind(parent) && self.tcx.asyncness(parent).is_async() && let Node::Item(hir::Item { kind: hir::ItemKind::Fn { sig: fn_sig, .. }, .. }) @@ -2577,11 +2584,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { is_async_fn_return = true; err.span(span); } - let body = self.tcx.hir_body_owned_by(obligation.cause.body_id); + let body = self.tcx.hir_body_owned_by(obligation.cause.body_def_id); if !is_async_fn_return && let Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(closure), .. }) = - self.tcx.hir_node_by_def_id(obligation.cause.body_id) + self.tcx.hir_node_by_def_id(obligation.cause.body_def_id) && matches!(closure.fn_decl.output, hir::FnRetTy::DefaultReturn(_)) { return true; @@ -3447,7 +3454,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // bound that introduced the obligation (e.g. `T: Send`). debug!(?next_code); self.note_obligation_cause_code( - obligation.cause.body_id, + obligation.cause.body_def_id, err, obligation.predicate, obligation.param_env, @@ -3459,7 +3466,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub(super) fn note_obligation_cause_code( &self, - body_id: LocalDefId, + body_def_id: LocalDefId, err: &mut Diag<'_, G>, predicate: T, param_env: ty::ParamEnv<'tcx>, @@ -4125,7 +4132,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // #74711: avoid a stack overflow ensure_sufficient_stack(|| { self.note_obligation_cause_code( - body_id, + body_def_id, err, parent_predicate, param_env, @@ -4137,7 +4144,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } else { ensure_sufficient_stack(|| { self.note_obligation_cause_code( - body_id, + body_def_id, err, parent_predicate, param_env, @@ -4167,7 +4174,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Skip PinDerefMutHelper in suggestions, but still show downstream suggestions. ensure_sufficient_stack(|| { self.note_obligation_cause_code( - body_id, + body_def_id, err, parent_predicate, param_env, @@ -4321,7 +4328,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // #74711: avoid a stack overflow ensure_sufficient_stack(|| { self.note_obligation_cause_code( - body_id, + body_def_id, err, parent_predicate, param_env, @@ -4364,7 +4371,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } ensure_sufficient_stack(|| { self.note_obligation_cause_code( - body_id, + body_def_id, err, data.derived.parent_host_pred, param_env, @@ -4377,7 +4384,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ObligationCauseCode::BuiltinDerivedHost(ref data) => { ensure_sufficient_stack(|| { self.note_obligation_cause_code( - body_id, + body_def_id, err, data.parent_host_pred, param_env, @@ -4393,7 +4400,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // #74711: avoid a stack overflow ensure_sufficient_stack(|| { self.note_obligation_cause_code( - body_id, + body_def_id, err, parent_predicate, param_env, @@ -4407,7 +4414,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // #74711: avoid a stack overflow ensure_sufficient_stack(|| { self.note_obligation_cause_code( - body_id, + body_def_id, err, predicate, param_env, @@ -4427,7 +4434,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { arg_hir_id, call_hir_id, ref parent_code, .. } => { self.note_function_argument_obligation( - body_id, + body_def_id, err, arg_hir_id, parent_code, @@ -4437,7 +4444,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); ensure_sufficient_stack(|| { self.note_obligation_cause_code( - body_id, + body_def_id, err, predicate, param_env, @@ -4481,7 +4488,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info { let expr = tcx.hir_expect_expr(hir_id); (expr_ty, expr) - } else if let Some(body_id) = tcx.hir_node_by_def_id(body_id).body_id() + } else if let Some(body_id) = tcx.hir_node_by_def_id(body_def_id).body_id() && let body = tcx.hir_body(body_id) && let hir::ExprKind::Block(block, _) = body.value.kind && let Some(expr) = block.expr @@ -4579,7 +4586,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) && snippet.ends_with('?') { - match self.tcx.coroutine_kind(obligation.cause.body_id) { + match self.tcx.coroutine_kind(obligation.cause.body_def_id) { Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => { err.span_suggestion_verbose( span.with_hi(span.hi() - BytePos(1)).shrink_to_hi(), @@ -4591,7 +4598,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { _ => { let mut span: MultiSpan = span.with_lo(span.hi() - BytePos(1)).into(); span.push_span_label( - self.tcx.def_span(obligation.cause.body_id), + self.tcx.def_span(obligation.cause.body_def_id), "this is not `async`", ); err.span_note( @@ -4732,7 +4739,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn note_function_argument_obligation( &self, - body_id: LocalDefId, + body_def_id: LocalDefId, err: &mut Diag<'_, G>, arg_hir_id: HirId, parent_code: &ObligationCauseCode<'tcx>, @@ -4749,7 +4756,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let Some(failed_pred) = failed_pred.as_trait_clause() && let pred = failed_pred.map_bound(|pred| pred.with_replaced_self_ty(tcx, ty)) && self.predicate_must_hold_modulo_regions(&Obligation::misc( - tcx, expr.span, body_id, param_env, pred, + tcx, + expr.span, + body_def_id, + param_env, + pred, )) && expr.span.hi() != rcvr.span.hi() { @@ -4882,7 +4893,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { for (expected, actual) in zipped { self.probe(|_| { match self - .at(&ObligationCause::misc(expr.span, body_id), param_env) + .at(&ObligationCause::misc(expr.span, body_def_id), param_env) // Doesn't actually matter if we define opaque types here, this is just used for // diagnostics, and the result is never kept around. .eq(DefineOpaqueTypes::Yes, expected, actual) @@ -5880,7 +5891,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } - let node = self.tcx.hir_node_by_def_id(obligation.cause.body_id); + let node = self.tcx.hir_node_by_def_id(obligation.cause.body_def_id); if let Some((fn_decl, body_id)) = choose_suggest_items(self.tcx, node) && let hir::FnRetTy::DefaultReturn(ret_span) = fn_decl.output && self.tcx.is_diagnostic_item(sym::FromResidual, trait_pred.def_id()) diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs index 866be1e532661..cff2e64a0d1e3 100644 --- a/compiler/rustc_trait_selection/src/regions.rs +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -14,16 +14,16 @@ use crate::traits::outlives_bounds::InferCtxtExt; impl<'tcx> OutlivesEnvironment<'tcx> { fn new( infcx: &InferCtxt<'tcx>, - body_id: LocalDefId, + body_def_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, assumed_wf_tys: impl IntoIterator>, ) -> Self { - Self::new_with_implied_bounds_compat(infcx, body_id, param_env, assumed_wf_tys, false) + Self::new_with_implied_bounds_compat(infcx, body_def_id, param_env, assumed_wf_tys, false) } fn new_with_implied_bounds_compat( infcx: &InferCtxt<'tcx>, - body_id: LocalDefId, + body_def_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, assumed_wf_tys: impl IntoIterator>, disable_implied_bounds_hack: bool, @@ -60,7 +60,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> { param_env, bounds, infcx.implied_bounds_tys( - body_id, + body_def_id, param_env, assumed_wf_tys, disable_implied_bounds_hack, @@ -82,13 +82,13 @@ impl<'tcx> InferCtxt<'tcx> { /// This function assumes that all infer variables are already constrained. fn resolve_regions( &self, - body_id: LocalDefId, + body_def_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, assumed_wf_tys: impl IntoIterator>, ) -> Vec> { self.resolve_regions_with_outlives_env( - &OutlivesEnvironment::new(self, body_id, param_env, assumed_wf_tys), - self.tcx.def_span(body_id), + &OutlivesEnvironment::new(self, body_def_id, param_env, assumed_wf_tys), + self.tcx.def_span(body_def_id), ) } diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index 816bf7248f3bf..0c365e9dea707 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -258,10 +258,11 @@ impl<'tcx> BestObligation<'tcx> { ) -> ControlFlow> { let infcx = candidate.goal().infcx(); let param_env = candidate.goal().goal().param_env; - let body_id = self.obligation.cause.body_id; + let body_def_id = self.obligation.cause.body_def_id; - for obligation in wf::unnormalized_obligations(infcx, param_env, term, self.span(), body_id) - .into_flat_iter() + for obligation in + wf::unnormalized_obligations(infcx, param_env, term, self.span(), body_def_id) + .into_flat_iter() { let nested_goal = candidate.instantiate_proof_tree_for_nested_goal( GoalSource::Misc, diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index f6a7bbdc686ec..449fdbaca9abc 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -574,7 +574,7 @@ fn evaluate_host_effect_for_fn_goal<'tcx>( .map(|(c, span)| { let code = ObligationCauseCode::WhereClause(def, span); let cause = - ObligationCause::new(obligation.cause.span, obligation.cause.body_id, code); + ObligationCause::new(obligation.cause.span, obligation.cause.body_def_id, code); Obligation::new( tcx, cause, diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 6cddd79544906..1990ebd913eca 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -246,15 +246,15 @@ where /// will result in region constraints getting ignored. pub fn resolve_regions_and_report_errors( self, - body_id: LocalDefId, + body_def_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, assumed_wf_tys: impl IntoIterator>, ) -> Result<(), ErrorGuaranteed> { - let errors = self.infcx.resolve_regions(body_id, param_env, assumed_wf_tys); + let errors = self.infcx.resolve_regions(body_def_id, param_env, assumed_wf_tys); if errors.is_empty() { Ok(()) } else { - Err(self.infcx.err_ctxt().report_region_errors(body_id, &errors)) + Err(self.infcx.err_ctxt().report_region_errors(body_def_id, &errors)) } } @@ -265,11 +265,11 @@ where #[must_use] pub fn resolve_regions( self, - body_id: LocalDefId, + body_def_id: LocalDefId, param_env: ty::ParamEnv<'tcx>, assumed_wf_tys: impl IntoIterator>, ) -> Vec> { - self.infcx.resolve_regions(body_id, param_env, assumed_wf_tys) + self.infcx.resolve_regions(body_def_id, param_env, assumed_wf_tys) } } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 00ad863f38346..aa963b1bca749 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -611,7 +611,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { match wf::obligations( self.selcx.infcx, obligation.param_env, - obligation.cause.body_id, + obligation.cause.body_def_id, obligation.recursion_depth + 1, term, obligation.cause.span, diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 79f1a59d9884f..46616c84578cc 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -190,7 +190,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>( } // Check regions assuming the self type of the impl is WF - let errors = infcx.resolve_regions(parent_cause.body_id, param_env, [self_type]); + let errors = infcx.resolve_regions(parent_cause.body_def_id, param_env, [self_type]); if !errors.is_empty() { infringing_inner_tys.push((inner_ty, InfringingFieldsReason::Regions(errors))); continue; @@ -279,7 +279,7 @@ pub fn all_fields_implement_trait<'tcx>( } // Check regions assuming the self type of the impl is WF - let errors = infcx.resolve_regions(parent_cause.body_id, param_env, [self_type]); + let errors = infcx.resolve_regions(parent_cause.body_def_id, param_env, [self_type]); if !errors.is_empty() { infringing.push((field, ty, InfringingFieldsReason::Regions(errors))); } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 3abc79bd21304..92be8fdfaa20b 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -300,7 +300,7 @@ fn do_normalize_predicates<'tcx>( // // This is required by trait-system-refactor-initiative#166. The new solver encounters // this more frequently as we entirely ignore outlives predicates with the old solver. - let _errors = infcx.resolve_regions(cause.body_id, elaborated_env, []); + let _errors = infcx.resolve_regions(cause.body_def_id, elaborated_env, []); match infcx.fully_resolve(predicates) { Ok(predicates) => Ok(predicates), Err(fixup_err) => { diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index a171a0de9dd79..84cae1e7bfa0a 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -27,15 +27,15 @@ use crate::traits::ObligationCause; /// # Parameters /// /// - `param_env`, the where-clauses in scope -/// - `body_id`, the body-id to use when normalizing assoc types. +/// - `body_def_id`, the body_def_id to use when normalizing assoc types. /// Note that this may cause outlives obligations to be injected /// into the inference context with this body-id. /// - `ty`, the type that we are supposed to assume is WF. -#[instrument(level = "debug", skip(infcx, param_env, body_id), ret)] +#[instrument(level = "debug", skip(infcx, param_env, body_def_id), ret)] fn implied_outlives_bounds<'a, 'tcx>( infcx: &'a InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - body_id: LocalDefId, + body_def_id: LocalDefId, ty: Ty<'tcx>, disable_implied_bounds_hack: bool, ) -> Vec> { @@ -60,7 +60,7 @@ fn implied_outlives_bounds<'a, 'tcx>( }; let mut constraints = QueryRegionConstraints::default(); - let span = infcx.tcx.def_span(body_id); + let span = infcx.tcx.def_span(body_def_id); let Ok(InferOk { value: mut bounds, obligations }) = infcx .instantiate_nll_query_response_and_region_obligations( &ObligationCause::dummy_with_span(span), @@ -83,7 +83,7 @@ fn implied_outlives_bounds<'a, 'tcx>( // We otherwise would get spurious errors if normalizing an implied // outlives bound required proving some higher-ranked coroutine obl. let QueryRegionConstraints { constraints, assumptions: _ } = constraints; - let cause = ObligationCause::misc(span, body_id); + let cause = ObligationCause::misc(span, body_def_id); for &QueryRegionConstraint { constraint, visible_for_leak_check: vis, .. } in &constraints { match constraint { ty::RegionConstraint::Outlives(predicate) => { @@ -105,13 +105,13 @@ impl<'tcx> InferCtxt<'tcx> { /// instead if you're interested in the implied bounds for a given signature. fn implied_bounds_tys>>( &self, - body_id: LocalDefId, + body_def_id: LocalDefId, param_env: ParamEnv<'tcx>, tys: Tys, disable_implied_bounds_hack: bool, ) -> impl Iterator> { tys.into_iter().flat_map(move |ty| { - implied_outlives_bounds(self, param_env, body_id, ty, disable_implied_bounds_hack) + implied_outlives_bounds(self, param_env, body_def_id, ty, disable_implied_bounds_hack) }) } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index e2257703f5775..cc418ede7f5ed 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -230,7 +230,7 @@ fn project_and_unify_term<'cx, 'tcx>( let InferOk { value: actual, obligations: new } = selcx.infcx.replace_opaque_types_with_inference_vars( actual, - obligation.cause.body_id, + obligation.cause.body_def_id, obligation.cause.span, obligation.param_env, ); @@ -557,7 +557,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( let nested_cause = ObligationCause::new( cause.span, - cause.body_id, + cause.body_def_id, // FIXME(inherent_associated_types): Since we can't pass along the self type to the // cause code, inherent projections will be printed with identity instantiation in // diagnostics which is not ideal. @@ -2149,7 +2149,7 @@ fn assoc_term_own_obligations<'cx, 'tcx>( } else { ObligationCause::new( obligation.cause.span, - obligation.cause.body_id, + obligation.cause.body_def_id, ObligationCauseCode::WhereClause(def_id, span), ) }; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index f0a6ff9a58b51..440ed2b46320b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -727,7 +727,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match wf::obligations( self.infcx, obligation.param_env, - obligation.cause.body_id, + obligation.cause.body_def_id, obligation.recursion_depth + 1, term, obligation.cause.span, @@ -2557,7 +2557,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let cause = ObligationCause::new( obligation.cause.span, - obligation.cause.body_id, + obligation.cause.body_def_id, ObligationCauseCode::MatchImpl(obligation.cause.clone(), impl_def_id), ); diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index a47f933f5c25e..8ecea8279aac1 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -30,7 +30,7 @@ use crate::traits; pub fn obligations<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - body_id: LocalDefId, + body_def_id: LocalDefId, recursion_depth: usize, term: Term<'tcx>, span: Span, @@ -72,17 +72,17 @@ pub fn obligations<'tcx>( let mut wf = WfPredicates { infcx, param_env, - body_id, + body_def_id, span, out: PredicateObligations::new(), recursion_depth, item: None, }; wf.add_wf_preds_for_term(term); - debug!("wf::obligations({:?}, body_id={:?}) = {:?}", term, body_id, wf.out); + debug!("wf::obligations({:?}, body_def_id={:?}) = {:?}", term, body_def_id, wf.out); let result = wf.normalize(infcx); - debug!("wf::obligations({:?}, body_id={:?}) ~~> {:?}", term, body_id, result); + debug!("wf::obligations({:?}, body_def_id={:?}) ~~> {:?}", term, body_def_id, result); Some(result) } @@ -95,7 +95,7 @@ pub fn unnormalized_obligations<'tcx>( param_env: ty::ParamEnv<'tcx>, term: Term<'tcx>, span: Span, - body_id: LocalDefId, + body_def_id: LocalDefId, ) -> Option> { debug_assert_eq!(term, infcx.resolve_vars_if_possible(term)); @@ -109,7 +109,7 @@ pub fn unnormalized_obligations<'tcx>( let mut wf = WfPredicates { infcx, param_env, - body_id, + body_def_id, span, out: PredicateObligations::new(), recursion_depth: 0, @@ -126,7 +126,7 @@ pub fn unnormalized_obligations<'tcx>( pub fn trait_obligations<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - body_id: LocalDefId, + body_def_id: LocalDefId, trait_pred: ty::TraitPredicate<'tcx>, span: Span, item: &'tcx hir::Item<'tcx>, @@ -134,7 +134,7 @@ pub fn trait_obligations<'tcx>( let mut wf = WfPredicates { infcx, param_env, - body_id, + body_def_id, span, out: PredicateObligations::new(), recursion_depth: 0, @@ -154,14 +154,14 @@ pub fn trait_obligations<'tcx>( pub fn clause_obligations<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - body_id: LocalDefId, + body_def_id: LocalDefId, clause: ty::Clause<'tcx>, span: Span, ) -> PredicateObligations<'tcx> { let mut wf = WfPredicates { infcx, param_env, - body_id, + body_def_id, span, out: PredicateObligations::new(), recursion_depth: 0, @@ -205,7 +205,7 @@ pub fn clause_obligations<'tcx>( struct WfPredicates<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - body_id: LocalDefId, + body_def_id: LocalDefId, span: Span, out: PredicateObligations<'tcx>, recursion_depth: usize, @@ -334,7 +334,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } fn cause(&self, code: traits::ObligationCauseCode<'tcx>) -> traits::ObligationCause<'tcx> { - traits::ObligationCause::new(self.span, self.body_id, code) + traits::ObligationCause::new(self.span, self.body_def_id, code) } fn normalize(self, infcx: &InferCtxt<'tcx>) -> PredicateObligations<'tcx> { @@ -423,7 +423,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { .filter_map(|(i, arg)| arg.as_term().map(|t| (i, t))) .filter(|(_, term)| !term.has_escaping_bound_vars()) .map(|(i, term)| { - let mut cause = traits::ObligationCause::misc(self.span, self.body_id); + let mut cause = traits::ObligationCause::misc(self.span, self.body_def_id); // The first arg is the self ty - use the correct span for it. if i == 0 { if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) = diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 29bda55bbbaab..95bb37f20fa00 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -196,12 +196,11 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { )); } - let local_did = def_id.as_local(); + let local_did = def_id.as_local().unwrap_or(CRATE_DEF_ID); let unnormalized_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates)); - let body_id = local_did.unwrap_or(CRATE_DEF_ID); - let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); + let cause = traits::ObligationCause::misc(tcx.def_span(def_id), local_did); traits::normalize_param_env_or_error(tcx, unnormalized_env, cause) } diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 45b8b266a2671..e3785c92c8d0d 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1073,6 +1073,20 @@ pub const trait Destruct: PointeeSized {} #[rustc_dyn_incompatible_trait] pub trait Tuple {} +/// Creates a new style directly represented const argument. +/// ```ignore (cannot test this from within core yet) +/// type const BAR: usize = N; +/// type const FOO: usize = direct!(BAR::); +/// ``` +#[rustc_builtin_macro(direct_const_arg)] +#[unstable(feature = "min_generic_const_args", issue = "132980")] +#[macro_export] +macro_rules! direct_const_arg { + ($($arg:tt)*) => { + /* compiler built-in */ + }; +} + /// A marker for types which can be used as types of `const` generic parameters. /// /// These types must have a proper equivalence relation (`Eq`) and it must be automatically diff --git a/library/std/src/sys/fd/unix.rs b/library/std/src/sys/fd/unix.rs index 392e33a77dc50..a96df3972be6a 100644 --- a/library/std/src/sys/fd/unix.rs +++ b/library/std/src/sys/fd/unix.rs @@ -38,7 +38,10 @@ use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read}; use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; #[cfg(all(target_os = "android", target_pointer_width = "64"))] use crate::sys::pal::weak::syscall; -#[cfg(any(all(target_os = "android", target_pointer_width = "32"), target_vendor = "apple"))] +#[cfg(any( + all(target_os = "android", target_pointer_width = "32"), + all(target_vendor = "apple", not(all(target_os = "macos", target_arch = "aarch64"))) +))] use crate::sys::pal::weak::weak; use crate::sys::{AsInner, FromInner, IntoInner, cvt}; @@ -221,6 +224,7 @@ impl FileDesc { target_os = "linux", target_os = "netbsd", target_os = "openbsd", // OpenBSD 2.7 + all(target_os = "macos", target_arch = "aarch64"), ))] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { let ret = cvt(unsafe { @@ -309,14 +313,15 @@ impl FileDesc { // We support old MacOS, iOS, watchOS, tvOS and visionOS. `preadv` was added in the following // Apple OS versions: - // ios 14.0 - // tvos 14.0 - // macos 11.0 - // watchos 7.0 + // iOS 14.0 + // tvOS 14.0 + // macOS 11.0 + // watchOS 7.0 // - // These versions may be newer than the minimum supported versions of OS's we support so we must - // use "weak" linking. - #[cfg(target_vendor = "apple")] + // Since macOS 11.0 is also the first version with AArch64 support, we can + // `preadv` unconditionally there. But on all other targets we must use + // "weak" linking. + #[cfg(all(target_vendor = "apple", not(all(target_os = "macos", target_arch = "aarch64"))))] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { weak!( fn preadv( @@ -428,6 +433,7 @@ impl FileDesc { target_os = "linux", target_os = "netbsd", target_os = "openbsd", // OpenBSD 2.7 + all(target_os = "macos", target_arch = "aarch64"), ))] pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { let ret = cvt(unsafe { @@ -516,14 +522,15 @@ impl FileDesc { // We support old MacOS, iOS, watchOS, tvOS and visionOS. `pwritev` was added in the following // Apple OS versions: - // ios 14.0 - // tvos 14.0 - // macos 11.0 - // watchos 7.0 + // iOS 14.0 + // tvOS 14.0 + // macOS 11.0 + // watchOS 7.0 // - // These versions may be newer than the minimum supported versions of OS's we support so we must - // use "weak" linking. - #[cfg(target_vendor = "apple")] + // Since macOS 11.0 is also the first version with AArch64 support, we can + // `pwritev` unconditionally there. But on all other targets we must use + // "weak" linking. + #[cfg(all(target_vendor = "apple", not(all(target_os = "macos", target_arch = "aarch64")),))] pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { weak!( fn pwritev( diff --git a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile index a06331d88490b..f9a25a31c4930 100644 --- a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile @@ -47,7 +47,7 @@ RUN curl https://ci-mirrors.rust-lang.org/rustc/linux-4.14.336.tar.gz | \ # Compile an instance of busybox as this provides a lightweight system and init # binary which we will boot into. Only trick here is configuring busybox to # build static binaries. -RUN curl https://www.busybox.net/downloads/busybox-1.32.1.tar.bz2 | tar xjf - && \ +RUN curl https://ci-mirrors.rust-lang.org/rustc/busybox/busybox-1.32.1.tar.bz2 | tar xjf - && \ cd busybox-1.32.1 && \ make defconfig && \ sed -i 's/.*CONFIG_STATIC.*/CONFIG_STATIC=y/' .config && \ @@ -60,7 +60,7 @@ RUN curl https://www.busybox.net/downloads/busybox-1.32.1.tar.bz2 | tar xjf - && # Download the ubuntu rootfs, which we'll use as a chroot for all our tests. WORKDIR /tmp RUN mkdir rootfs/ubuntu -RUN curl https://cdimage.ubuntu.com/ubuntu-base/releases/22.04/release/ubuntu-base-22.04.2-base-armhf.tar.gz | \ +RUN curl https://ci-mirrors.rust-lang.org/rustc/ubuntu/ubuntu-base-22.04.2-base-armhf.tar.gz | \ tar xzf - -C rootfs/ubuntu && \ cd rootfs && mkdir proc sys dev etc etc/init.d diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index 7b642fcd4ff9a..24ccb99a7c6ee 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -536,6 +536,7 @@ fn ast_ty_search_pat(ty: &ast::Ty) -> (Pat, Pat) { // experimental | TyKind::Pat(..) | TyKind::FieldOf(..) + | TyKind::DirectConstArg(..) // unused | TyKind::CVarArgs diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index f194103ae2e88..cb0db1ed014fc 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -248,6 +248,7 @@ impl<'a> Sugg<'a> { | ast::ExprKind::Array(..) | ast::ExprKind::While(..) | ast::ExprKind::Await(..) + | ast::ExprKind::DirectConstArg(..) | ast::ExprKind::Err(_) | ast::ExprKind::Dummy | ast::ExprKind::UnsafeBinderCast(..) => Sugg::NonParen(snippet(expr.span)), diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index 8a3674bff1ca6..cc7fdaefc8fee 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -486,7 +486,8 @@ pub(crate) fn format_expr( | ast::ExprKind::Type(..) | ast::ExprKind::IncludedBytes(..) | ast::ExprKind::OffsetOf(..) - | ast::ExprKind::UnsafeBinderCast(..) => { + | ast::ExprKind::UnsafeBinderCast(..) + | ast::ExprKind::DirectConstArg(..) => { // These don't normally occur in the AST because macros aren't expanded. However, // rustfmt tries to parse macro arguments when formatting macros, so it's not totally // impossible for rustfmt to come across one of these nodes when formatting a file. diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 2dfb5e5b28f61..1a3e1f53c1504 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -1014,7 +1014,6 @@ impl Rewrite for ast::Ty { }) } ast::TyKind::CVarArgs => Ok("...".to_owned()), - ast::TyKind::Dummy | ast::TyKind::Err(_) => Ok(context.snippet(self.span).to_owned()), ast::TyKind::Pat(ref ty, ref pat) => { let ty = ty.rewrite_result(context, shape)?; let pat = pat.rewrite_result(context, shape)?; @@ -1054,6 +1053,14 @@ impl Rewrite for ast::Ty { result.push_str(&rewrite); Ok(result) } + ast::TyKind::DirectConstArg(..) => { + // These don't normally occur in the AST because macros aren't expanded. However, + // rustfmt tries to parse macro arguments when formatting macros, so it's not + // totally impossible for rustfmt to come across one of these nodes when formatting + // a file. Also, rustfmt might get passed the output from `-Zunpretty=expanded`. + Ok(context.snippet(self.span).to_owned()) + } + ast::TyKind::Dummy | ast::TyKind::Err(_) => Ok(context.snippet(self.span).to_owned()), } } } diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs index 1fcc59f2a1ea4..3e06f3899d1b3 100644 --- a/src/tools/rustfmt/src/utils.rs +++ b/src/tools/rustfmt/src/utils.rs @@ -532,9 +532,8 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr | ast::ExprKind::Index(_, ref expr, _) | ast::ExprKind::Unary(_, ref expr) | ast::ExprKind::Try(ref expr) - | ast::ExprKind::Yield(YieldKind::Prefix(Some(ref expr))) => { - is_block_expr(context, expr, repr) - } + | ast::ExprKind::Yield(YieldKind::Prefix(Some(ref expr))) + | ast::ExprKind::DirectConstArg(ref expr) => is_block_expr(context, expr, repr), ast::ExprKind::Closure(ref closure) => is_block_expr(context, &closure.body, repr), // This can only be a string lit ast::ExprKind::Lit(_) => { diff --git a/src/tools/rustfmt/tests/source/direct_const_arg.rs b/src/tools/rustfmt/tests/source/direct_const_arg.rs new file mode 100644 index 0000000000000..f6f9c25d9a0d8 --- /dev/null +++ b/src/tools/rustfmt/tests/source/direct_const_arg.rs @@ -0,0 +1,14 @@ +// direct_const_arg! is a built-in macro relevant to min_generic_const_args; its contents should be +// formatted as if its contents were passed through unchanged (the macro changes the semantics of +// the contained expression, the syntax is unchanged) + +#![feature(min_generic_const_args)] + +trait Trait { + type const TYPE_CONST: usize; +} + +struct S; + +fn parsed_as_expr_kind(_: S<{ core::direct_const_arg!( T :: TYPE_CONST ) }>) {} +fn parsed_as_ty_kind(_: S< core::direct_const_arg!( T :: TYPE_CONST ) >) {} diff --git a/src/tools/rustfmt/tests/target/direct_const_arg.rs b/src/tools/rustfmt/tests/target/direct_const_arg.rs new file mode 100644 index 0000000000000..1ebadae00ff05 --- /dev/null +++ b/src/tools/rustfmt/tests/target/direct_const_arg.rs @@ -0,0 +1,14 @@ +// direct_const_arg! is a built-in macro relevant to min_generic_const_args; its contents should be +// formatted as if its contents were passed through unchanged (the macro changes the semantics of +// the contained expression, the syntax is unchanged) + +#![feature(min_generic_const_args)] + +trait Trait { + type const TYPE_CONST: usize; +} + +struct S; + +fn parsed_as_expr_kind(_: S<{ core::direct_const_arg!(T::TYPE_CONST) }>) {} +fn parsed_as_ty_kind(_: S) {} diff --git a/tests/assembly-llvm/x86_64-windows-float-abi.rs b/tests/assembly-llvm/x86_64-windows-float-abi.rs index 51daff56789e6..b6ab9995fdb3e 100644 --- a/tests/assembly-llvm/x86_64-windows-float-abi.rs +++ b/tests/assembly-llvm/x86_64-windows-float-abi.rs @@ -3,6 +3,9 @@ //@ compile-flags: --target x86_64-pc-windows-msvc //@ needs-llvm-components: x86 //@ add-minicore +//@ revisions: LLVM22 LLVM23 +//@ [LLVM22] max-llvm-major-version: 22 +//@ [LLVM23] min-llvm-version: 23 #![feature(f16, f128)] #![feature(no_core)] @@ -37,8 +40,12 @@ pub extern "C" fn second_f64(_: f64, x: f64) -> f64 { } // CHECK-LABEL: second_f128 -// CHECK: movaps (%rdx), %xmm0 -// CHECK-NEXT: retq +// LLVM22: movaps (%rdx), %xmm0 +// LLVM22-NEXT: retq +// LLVM23: movq %rcx, %rax +// LLVM23-NEXT: movaps (%r8), %xmm0 +// LLVM23-NEXT: movaps %xmm0, (%rcx) +// LLVM23-NEXT: retq #[no_mangle] pub extern "C" fn second_f128(_: f128, x: f128) -> f128 { x diff --git a/tests/pretty/direct-const-arg.pp b/tests/pretty/direct-const-arg.pp new file mode 100644 index 0000000000000..a76ed9a480e71 --- /dev/null +++ b/tests/pretty/direct-const-arg.pp @@ -0,0 +1,15 @@ +#![feature(prelude_import)] +#![no_std] +//@ pretty-mode:expanded +//@ pp-exact:direct-const-arg.pp +#![feature(min_generic_const_args)] +extern crate std; +#[prelude_import] +use ::std::prelude::rust_2015::*; + +fn f() {} + +fn main() { + f::(); + f::<{ core::direct_const_arg! (2) }>(); +} diff --git a/tests/pretty/direct-const-arg.rs b/tests/pretty/direct-const-arg.rs new file mode 100644 index 0000000000000..330c1cac024de --- /dev/null +++ b/tests/pretty/direct-const-arg.rs @@ -0,0 +1,10 @@ +//@ pretty-mode:expanded +//@ pp-exact:direct-const-arg.pp +#![feature(min_generic_const_args)] + +fn f() {} + +fn main() { + f::(); + f::<{ core::direct_const_arg!(2) }>(); +} diff --git a/tests/run-make/autodiff/type-trees/iter/rmake.rs b/tests/run-make/autodiff/type-trees/iter/rmake.rs new file mode 100644 index 0000000000000..4aca0771b7ee8 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/iter/rmake.rs @@ -0,0 +1,25 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +// This test passes in release mode. If we run it in Debug mode and don't lower any MIR info to +// LLVM TypeTrees, then it fails on deducing the type of a memcpy. If we lower info it still fails, +// but at a later location based on an extractvalue call. We will fix this in a future PR. + +fn main() { + rustc() + .input("window.rs") + .arg("-Zautodiff=Enable,NoTT") + .arg("-Clto=fat") + .run_fail() + .assert_stderr_contains("Enzyme: Cannot deduce type of copy"); + rustc() + .input("window.rs") + .arg("-Zautodiff=Enable") + .arg("-Clto=fat") + .emit("llvm-ir") + .run_fail() + .assert_stderr_contains("Enzyme: Cannot deduce type of extract"); + rustc().input("window.rs").arg("-Zautodiff=Enable,NoTT").arg("-Clto=fat").arg("-O").run(); +} diff --git a/tests/run-make/autodiff/type-trees/iter/window.rs b/tests/run-make/autodiff/type-trees/iter/window.rs new file mode 100644 index 0000000000000..7a6a6239fc23d --- /dev/null +++ b/tests/run-make/autodiff/type-trees/iter/window.rs @@ -0,0 +1,53 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +// This tests verifies that Enzyme can differentiate the iterator and window version of the for +// loops given below. Iterators (especially the windows use here) cause a lot of extra abstractions +// and indirections. Without extra typetree hints, Enzyme failed to differentiate them in debug +// mode. + +//@revisions: tt no_tt +//@[tt] compile-flags: -Z autodiff=Enable +//@[no_tt] compile-flags: -Z autodiff=Enable,NoTT +//@[no_tt] build-fail + +#[unsafe(no_mangle)] +#[inline(never)] +#[autodiff_reverse(f_rev, 2, Duplicated, Const, Duplicated)] +fn f(x: &[f64; 3], args: &[f64; 3], y: &mut [f64; 2]) { + y[0] = x.iter().map(|i| args[0] * i.powi(2)).sum(); + y[1] = x + .windows(2) + .map(|w| (args[1] - w[0]).powi(2) + args[2] * (w[1] - w[0].powi(2)).powi(2)) + .sum(); + // The iterators above are equivalent to the two following for loops. + // for i in 0..3 { + // y[0] += args[0] * x[i].powi(2); + // } + // for i in 0..2 { + // y[1] += (args[1] - x[i]).powi(2) + args[2] * (x[i + 1] - x[i].powi(2)).powi(2); + // } +} + +// Not generally recommended, but since we rewrite llvm-ir, it should be good enough. +fn assert_abs_diff_eq(x: &[f64; N], y: &[f64; N]) { + for i in 0..N { + assert_eq!(x[i], y[i]); + } +} + +fn main() { + let x = [3.0, 5.0, 7.0]; + let args = [2.0, 1.0, 100.0]; + + let mut vjp = ([0.0; 3], [0.0; 3]); + let mut y = [0.0; 2]; + let mut dy = ([1.0, 0.0], [0.0, 1.0]); + + f_rev(&x, &mut vjp.0, &mut vjp.1, &args, &mut y, &mut dy.0, &mut dy.1); + + assert_abs_diff_eq::<2>(&y, &[166.0, 34020.0]); + assert_abs_diff_eq::<3>(&vjp.0, &[12.0, 20.0, 28.0]); + assert_abs_diff_eq::<3>(&vjp.1, &[4804.0, 35208.0, -3600.0]); +} diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index 6add008aa60fa..f0768b8953c5b 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -1,89 +1,89 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:8 + --> $DIR/unsupported.rs:42:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:39:22 + --> $DIR/unsupported.rs:44:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:43:8 + --> $DIR/unsupported.rs:48:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:45:8 + --> $DIR/unsupported.rs:50:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:48:8 + --> $DIR/unsupported.rs:53:8 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:50:24 + --> $DIR/unsupported.rs:55:24 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:54:8 + --> $DIR/unsupported.rs:59:8 | LL | extern "aapcs" {} | ^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:57:8 + --> $DIR/unsupported.rs:62:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:60:8 + --> $DIR/unsupported.rs:65:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/unsupported.rs:63:8 + --> $DIR/unsupported.rs:68:8 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:66:8 + --> $DIR/unsupported.rs:71:8 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:69:8 + --> $DIR/unsupported.rs:74:8 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:71:27 + --> $DIR/unsupported.rs:76:27 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:75:8 + --> $DIR/unsupported.rs:80:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:8 + --> $DIR/unsupported.rs:83:8 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^ @@ -91,7 +91,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:82:26 + --> $DIR/unsupported.rs:87:26 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^ @@ -99,7 +99,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:8 + --> $DIR/unsupported.rs:93:8 | LL | extern "stdcall" {} | ^^^^^^^^^ @@ -107,7 +107,7 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:92:8 + --> $DIR/unsupported.rs:97:8 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^ @@ -115,49 +115,49 @@ LL | extern "stdcall-unwind" {} = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:112:8 + --> $DIR/unsupported.rs:117:8 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:114:29 + --> $DIR/unsupported.rs:119:29 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:118:8 + --> $DIR/unsupported.rs:123:8 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:121:28 + --> $DIR/unsupported.rs:126:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:126:8 + --> $DIR/unsupported.rs:131:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:128:29 + --> $DIR/unsupported.rs:133:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:132:8 + --> $DIR/unsupported.rs:137:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:100:17 + --> $DIR/unsupported.rs:105:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -168,7 +168,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:105:1 + --> $DIR/unsupported.rs:110:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -178,7 +178,7 @@ LL | extern "cdecl" {} = note: for more information, see issue #137018 warning: "cdecl-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:108:1 + --> $DIR/unsupported.rs:113:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -188,7 +188,7 @@ LL | extern "cdecl-unwind" {} = note: for more information, see issue #137018 warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:97:1 + --> $DIR/unsupported.rs:102:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index ab345f9e42e96..dc50397601690 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -1,71 +1,71 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:8 + --> $DIR/unsupported.rs:42:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:39:22 + --> $DIR/unsupported.rs:44:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:43:8 + --> $DIR/unsupported.rs:48:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:45:8 + --> $DIR/unsupported.rs:50:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:57:8 + --> $DIR/unsupported.rs:62:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:60:8 + --> $DIR/unsupported.rs:65:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/unsupported.rs:63:8 + --> $DIR/unsupported.rs:68:8 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:66:8 + --> $DIR/unsupported.rs:71:8 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:69:8 + --> $DIR/unsupported.rs:74:8 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:71:27 + --> $DIR/unsupported.rs:76:27 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:75:8 + --> $DIR/unsupported.rs:80:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:8 + --> $DIR/unsupported.rs:83:8 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^ @@ -73,7 +73,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:82:26 + --> $DIR/unsupported.rs:87:26 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^ @@ -81,7 +81,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:8 + --> $DIR/unsupported.rs:93:8 | LL | extern "stdcall" {} | ^^^^^^^^^ @@ -89,7 +89,7 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:92:8 + --> $DIR/unsupported.rs:97:8 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^ @@ -97,49 +97,49 @@ LL | extern "stdcall-unwind" {} = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:112:8 + --> $DIR/unsupported.rs:117:8 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:114:29 + --> $DIR/unsupported.rs:119:29 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:118:8 + --> $DIR/unsupported.rs:123:8 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:121:28 + --> $DIR/unsupported.rs:126:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:126:8 + --> $DIR/unsupported.rs:131:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:128:29 + --> $DIR/unsupported.rs:133:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:132:8 + --> $DIR/unsupported.rs:137:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:100:17 + --> $DIR/unsupported.rs:105:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -150,7 +150,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:105:1 + --> $DIR/unsupported.rs:110:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -160,7 +160,7 @@ LL | extern "cdecl" {} = note: for more information, see issue #137018 warning: "cdecl-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:108:1 + --> $DIR/unsupported.rs:113:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -170,7 +170,7 @@ LL | extern "cdecl-unwind" {} = note: for more information, see issue #137018 warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:97:1 + --> $DIR/unsupported.rs:102:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index 0b29b557c6d48..65a8e44d06b4b 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -1,83 +1,83 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:8 + --> $DIR/unsupported.rs:42:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:39:22 + --> $DIR/unsupported.rs:44:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:43:8 + --> $DIR/unsupported.rs:48:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:45:8 + --> $DIR/unsupported.rs:50:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:48:8 + --> $DIR/unsupported.rs:53:8 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:50:24 + --> $DIR/unsupported.rs:55:24 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:54:8 + --> $DIR/unsupported.rs:59:8 | LL | extern "aapcs" {} | ^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:57:8 + --> $DIR/unsupported.rs:62:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:60:8 + --> $DIR/unsupported.rs:65:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/unsupported.rs:63:8 + --> $DIR/unsupported.rs:68:8 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:121:28 + --> $DIR/unsupported.rs:126:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:126:8 + --> $DIR/unsupported.rs:131:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:128:29 + --> $DIR/unsupported.rs:133:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:132:8 + --> $DIR/unsupported.rs:137:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr index e2ca35d6a50e2..de7f5e436154e 100644 --- a/tests/ui/abi/unsupported.riscv32.stderr +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -1,83 +1,83 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:8 + --> $DIR/unsupported.rs:42:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:39:22 + --> $DIR/unsupported.rs:44:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:43:8 + --> $DIR/unsupported.rs:48:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:45:8 + --> $DIR/unsupported.rs:50:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:48:8 + --> $DIR/unsupported.rs:53:8 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:50:24 + --> $DIR/unsupported.rs:55:24 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:54:8 + --> $DIR/unsupported.rs:59:8 | LL | extern "aapcs" {} | ^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:57:8 + --> $DIR/unsupported.rs:62:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:60:8 + --> $DIR/unsupported.rs:65:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:66:8 + --> $DIR/unsupported.rs:71:8 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:69:8 + --> $DIR/unsupported.rs:74:8 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:71:27 + --> $DIR/unsupported.rs:76:27 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:75:8 + --> $DIR/unsupported.rs:80:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:8 + --> $DIR/unsupported.rs:83:8 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^ @@ -85,7 +85,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:82:26 + --> $DIR/unsupported.rs:87:26 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^ @@ -93,7 +93,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:8 + --> $DIR/unsupported.rs:93:8 | LL | extern "stdcall" {} | ^^^^^^^^^ @@ -101,7 +101,7 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:92:8 + --> $DIR/unsupported.rs:97:8 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^ @@ -109,49 +109,49 @@ LL | extern "stdcall-unwind" {} = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:112:8 + --> $DIR/unsupported.rs:117:8 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:114:29 + --> $DIR/unsupported.rs:119:29 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:118:8 + --> $DIR/unsupported.rs:123:8 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:121:28 + --> $DIR/unsupported.rs:126:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:126:8 + --> $DIR/unsupported.rs:131:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:128:29 + --> $DIR/unsupported.rs:133:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:132:8 + --> $DIR/unsupported.rs:137:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:100:17 + --> $DIR/unsupported.rs:105:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -162,7 +162,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:105:1 + --> $DIR/unsupported.rs:110:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -172,7 +172,7 @@ LL | extern "cdecl" {} = note: for more information, see issue #137018 warning: "cdecl-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:108:1 + --> $DIR/unsupported.rs:113:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +182,7 @@ LL | extern "cdecl-unwind" {} = note: for more information, see issue #137018 warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:97:1 + --> $DIR/unsupported.rs:102:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr index e2ca35d6a50e2..de7f5e436154e 100644 --- a/tests/ui/abi/unsupported.riscv64.stderr +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -1,83 +1,83 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:8 + --> $DIR/unsupported.rs:42:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:39:22 + --> $DIR/unsupported.rs:44:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:43:8 + --> $DIR/unsupported.rs:48:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:45:8 + --> $DIR/unsupported.rs:50:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:48:8 + --> $DIR/unsupported.rs:53:8 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:50:24 + --> $DIR/unsupported.rs:55:24 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:54:8 + --> $DIR/unsupported.rs:59:8 | LL | extern "aapcs" {} | ^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:57:8 + --> $DIR/unsupported.rs:62:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:60:8 + --> $DIR/unsupported.rs:65:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:66:8 + --> $DIR/unsupported.rs:71:8 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:69:8 + --> $DIR/unsupported.rs:74:8 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:71:27 + --> $DIR/unsupported.rs:76:27 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:75:8 + --> $DIR/unsupported.rs:80:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:8 + --> $DIR/unsupported.rs:83:8 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^ @@ -85,7 +85,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:82:26 + --> $DIR/unsupported.rs:87:26 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^ @@ -93,7 +93,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:8 + --> $DIR/unsupported.rs:93:8 | LL | extern "stdcall" {} | ^^^^^^^^^ @@ -101,7 +101,7 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:92:8 + --> $DIR/unsupported.rs:97:8 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^ @@ -109,49 +109,49 @@ LL | extern "stdcall-unwind" {} = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:112:8 + --> $DIR/unsupported.rs:117:8 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:114:29 + --> $DIR/unsupported.rs:119:29 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:118:8 + --> $DIR/unsupported.rs:123:8 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:121:28 + --> $DIR/unsupported.rs:126:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:126:8 + --> $DIR/unsupported.rs:131:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:128:29 + --> $DIR/unsupported.rs:133:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:132:8 + --> $DIR/unsupported.rs:137:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:100:17 + --> $DIR/unsupported.rs:105:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -162,7 +162,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:105:1 + --> $DIR/unsupported.rs:110:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -172,7 +172,7 @@ LL | extern "cdecl" {} = note: for more information, see issue #137018 warning: "cdecl-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:108:1 + --> $DIR/unsupported.rs:113:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +182,7 @@ LL | extern "cdecl-unwind" {} = note: for more information, see issue #137018 warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:97:1 + --> $DIR/unsupported.rs:102:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs index 7f7963ea51e18..661691956cb5d 100644 --- a/tests/ui/abi/unsupported.rs +++ b/tests/ui/abi/unsupported.rs @@ -1,5 +1,5 @@ //@ add-minicore -//@ revisions: x64 x64_win i686 aarch64 arm riscv32 riscv64 +//@ revisions: x64 x64_win i686 aarch64 arm riscv32 riscv64 wasm32 wasm64 // //@ [x64] needs-llvm-components: x86 //@ [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib @@ -15,6 +15,10 @@ //@ [riscv32] compile-flags: --target=riscv32i-unknown-none-elf --crate-type=rlib //@ [riscv64] needs-llvm-components: riscv //@ [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf --crate-type=rlib +//@ [wasm32] needs-llvm-components: webassembly +//@ [wasm32] compile-flags: --target wasm32-unknown-unknown --crate-type=rlib +//@ [wasm64] needs-llvm-components: webassembly +//@ [wasm64] compile-flags: --target wasm64-unknown-unknown --crate-type=rlib //@ ignore-backends: gcc #![no_core] #![feature( @@ -28,7 +32,8 @@ abi_riscv_interrupt, abi_cmse_nonsecure_call, abi_vectorcall, - cmse_nonsecure_entry + cmse_nonsecure_entry, + abi_custom )] extern crate minicore; @@ -37,7 +42,7 @@ use minicore::*; extern "ptx-kernel" fn ptx() {} //~^ ERROR is not a supported ABI fn ptx_ptr(f: extern "ptx-kernel" fn()) { -//~^ ERROR is not a supported ABI + //~^ ERROR is not a supported ABI f() } extern "ptx-kernel" {} @@ -46,13 +51,13 @@ extern "gpu-kernel" fn gpu() {} //~^ ERROR is not a supported ABI extern "aapcs" fn aapcs() {} -//[x64,x64_win,i686,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,aarch64,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI fn aapcs_ptr(f: extern "aapcs" fn()) { - //[x64,x64_win,i686,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI + //[x64,x64_win,i686,aarch64,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI f() } extern "aapcs" {} -//[x64,x64_win,i686,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,aarch64,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI extern "msp430-interrupt" {} //~^ ERROR is not a supported ABI @@ -61,72 +66,72 @@ extern "avr-interrupt" {} //~^ ERROR is not a supported ABI extern "riscv-interrupt-m" {} -//[x64,x64_win,i686,arm,aarch64]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,arm,aarch64,wasm32,wasm64]~^ ERROR is not a supported ABI extern "x86-interrupt" {} -//[aarch64,arm,riscv32,riscv64]~^ ERROR is not a supported ABI +//[aarch64,arm,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI extern "thiscall" fn thiscall() {} -//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI +//[x64,x64_win,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI fn thiscall_ptr(f: extern "thiscall" fn()) { - //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI + //[x64,x64_win,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI f() } extern "thiscall" {} -//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI +//[x64,x64_win,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI extern "stdcall" fn stdcall() {} -//[x64,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI +//[x64,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI //[x64_win]~^^ WARN unsupported_calling_conventions //[x64_win]~^^^ WARN this was previously accepted fn stdcall_ptr(f: extern "stdcall" fn()) { - //[x64,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI + //[x64,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI //[x64_win]~^^ WARN unsupported_calling_conventions //[x64_win]~| WARN this was previously accepted f() } extern "stdcall" {} -//[x64,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI +//[x64,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI //[x64_win]~^^ WARN unsupported_calling_conventions //[x64_win]~^^^ WARN this was previously accepted extern "stdcall-unwind" {} -//[x64,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI +//[x64,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI //[x64_win]~^^ WARN unsupported_calling_conventions //[x64_win]~^^^ WARN this was previously accepted extern "cdecl" fn cdecl() {} -//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions -//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted +//[x64,x64_win,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ WARN unsupported_calling_conventions +//[x64,x64_win,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^^ WARN this was previously accepted fn cdecl_ptr(f: extern "cdecl" fn()) { - //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions - //[x64,x64_win,arm,aarch64,riscv32,riscv64]~| WARN this was previously accepted + //[x64,x64_win,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ WARN unsupported_calling_conventions + //[x64,x64_win,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~| WARN this was previously accepted f() } extern "cdecl" {} -//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions -//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted +//[x64,x64_win,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ WARN unsupported_calling_conventions +//[x64,x64_win,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^^ WARN this was previously accepted extern "cdecl-unwind" {} -//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions -//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted +//[x64,x64_win,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ WARN unsupported_calling_conventions +//[x64,x64_win,arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^^ WARN this was previously accepted extern "vectorcall" fn vectorcall() {} -//[arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI +//[arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI fn vectorcall_ptr(f: extern "vectorcall" fn()) { - //[arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI + //[arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI f() } extern "vectorcall" {} -//[arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI +//[arm,aarch64,riscv32,riscv64,wasm32,wasm64]~^ ERROR is not a supported ABI fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { -//~^ ERROR is not a supported ABI + //~^ ERROR is not a supported ABI f() } extern "cmse-nonsecure-entry" fn cmse_entry() {} //~^ ERROR is not a supported ABI fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { -//~^ ERROR is not a supported ABI + //~^ ERROR is not a supported ABI f() } extern "cmse-nonsecure-entry" {} @@ -137,3 +142,10 @@ extern "cmse-nonsecure-entry" {} extern "cdecl" {} //[x64_win]~^ WARN unsupported_calling_conventions //[x64_win]~^^ WARN this was previously accepted + +fn custom_ptr(f: extern "custom" fn()) { + //[wasm32,wasm64]~^ ERROR is not a supported ABI + let _ = f; +} +extern "custom" {} +//[wasm32,wasm64]~^ ERROR is not a supported ABI diff --git a/tests/ui/abi/unsupported.wasm32.stderr b/tests/ui/abi/unsupported.wasm32.stderr new file mode 100644 index 0000000000000..9314c287b8591 --- /dev/null +++ b/tests/ui/abi/unsupported.wasm32.stderr @@ -0,0 +1,214 @@ +error[E0570]: "ptx-kernel" is not a supported ABI for the current target + --> $DIR/unsupported.rs:42:8 + | +LL | extern "ptx-kernel" fn ptx() {} + | ^^^^^^^^^^^^ + +error[E0570]: "ptx-kernel" is not a supported ABI for the current target + --> $DIR/unsupported.rs:44:22 + | +LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { + | ^^^^^^^^^^^^ + +error[E0570]: "ptx-kernel" is not a supported ABI for the current target + --> $DIR/unsupported.rs:48:8 + | +LL | extern "ptx-kernel" {} + | ^^^^^^^^^^^^ + +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/unsupported.rs:50:8 + | +LL | extern "gpu-kernel" fn gpu() {} + | ^^^^^^^^^^^^ + +error[E0570]: "aapcs" is not a supported ABI for the current target + --> $DIR/unsupported.rs:53:8 + | +LL | extern "aapcs" fn aapcs() {} + | ^^^^^^^ + +error[E0570]: "aapcs" is not a supported ABI for the current target + --> $DIR/unsupported.rs:55:24 + | +LL | fn aapcs_ptr(f: extern "aapcs" fn()) { + | ^^^^^^^ + +error[E0570]: "aapcs" is not a supported ABI for the current target + --> $DIR/unsupported.rs:59:8 + | +LL | extern "aapcs" {} + | ^^^^^^^ + +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/unsupported.rs:62:8 + | +LL | extern "msp430-interrupt" {} + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/unsupported.rs:65:8 + | +LL | extern "avr-interrupt" {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/unsupported.rs:68:8 + | +LL | extern "riscv-interrupt-m" {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/unsupported.rs:71:8 + | +LL | extern "x86-interrupt" {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "thiscall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:74:8 + | +LL | extern "thiscall" fn thiscall() {} + | ^^^^^^^^^^ + +error[E0570]: "thiscall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:76:27 + | +LL | fn thiscall_ptr(f: extern "thiscall" fn()) { + | ^^^^^^^^^^ + +error[E0570]: "thiscall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:80:8 + | +LL | extern "thiscall" {} + | ^^^^^^^^^^ + +error[E0570]: "stdcall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:83:8 + | +LL | extern "stdcall" fn stdcall() {} + | ^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + +error[E0570]: "stdcall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:87:26 + | +LL | fn stdcall_ptr(f: extern "stdcall" fn()) { + | ^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + +error[E0570]: "stdcall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:93:8 + | +LL | extern "stdcall" {} + | ^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + +error[E0570]: "stdcall-unwind" is not a supported ABI for the current target + --> $DIR/unsupported.rs:97:8 + | +LL | extern "stdcall-unwind" {} + | ^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` + +error[E0570]: "vectorcall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:117:8 + | +LL | extern "vectorcall" fn vectorcall() {} + | ^^^^^^^^^^^^ + +error[E0570]: "vectorcall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:119:29 + | +LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { + | ^^^^^^^^^^^^ + +error[E0570]: "vectorcall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:123:8 + | +LL | extern "vectorcall" {} + | ^^^^^^^^^^^^ + +error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target + --> $DIR/unsupported.rs:126:28 + | +LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target + --> $DIR/unsupported.rs:131:8 + | +LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target + --> $DIR/unsupported.rs:133:29 + | +LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target + --> $DIR/unsupported.rs:137:8 + | +LL | extern "cmse-nonsecure-entry" {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "custom" is not a supported ABI for the current target + --> $DIR/unsupported.rs:146:25 + | +LL | fn custom_ptr(f: extern "custom" fn()) { + | ^^^^^^^^ + +error[E0570]: "custom" is not a supported ABI for the current target + --> $DIR/unsupported.rs:150:8 + | +LL | extern "custom" {} + | ^^^^^^^^ + +warning: "cdecl" is not a supported ABI for the current target + --> $DIR/unsupported.rs:105:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = help: use `extern "C"` instead + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: "cdecl" is not a supported ABI for the current target + --> $DIR/unsupported.rs:110:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = help: use `extern "C"` instead + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + +warning: "cdecl-unwind" is not a supported ABI for the current target + --> $DIR/unsupported.rs:113:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `extern "C-unwind"` instead + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + +warning: "cdecl" is not a supported ABI for the current target + --> $DIR/unsupported.rs:102:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `extern "C"` instead + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + +error: aborting due to 27 previous errors; 4 warnings emitted + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/unsupported.wasm64.stderr b/tests/ui/abi/unsupported.wasm64.stderr new file mode 100644 index 0000000000000..9314c287b8591 --- /dev/null +++ b/tests/ui/abi/unsupported.wasm64.stderr @@ -0,0 +1,214 @@ +error[E0570]: "ptx-kernel" is not a supported ABI for the current target + --> $DIR/unsupported.rs:42:8 + | +LL | extern "ptx-kernel" fn ptx() {} + | ^^^^^^^^^^^^ + +error[E0570]: "ptx-kernel" is not a supported ABI for the current target + --> $DIR/unsupported.rs:44:22 + | +LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { + | ^^^^^^^^^^^^ + +error[E0570]: "ptx-kernel" is not a supported ABI for the current target + --> $DIR/unsupported.rs:48:8 + | +LL | extern "ptx-kernel" {} + | ^^^^^^^^^^^^ + +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/unsupported.rs:50:8 + | +LL | extern "gpu-kernel" fn gpu() {} + | ^^^^^^^^^^^^ + +error[E0570]: "aapcs" is not a supported ABI for the current target + --> $DIR/unsupported.rs:53:8 + | +LL | extern "aapcs" fn aapcs() {} + | ^^^^^^^ + +error[E0570]: "aapcs" is not a supported ABI for the current target + --> $DIR/unsupported.rs:55:24 + | +LL | fn aapcs_ptr(f: extern "aapcs" fn()) { + | ^^^^^^^ + +error[E0570]: "aapcs" is not a supported ABI for the current target + --> $DIR/unsupported.rs:59:8 + | +LL | extern "aapcs" {} + | ^^^^^^^ + +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/unsupported.rs:62:8 + | +LL | extern "msp430-interrupt" {} + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/unsupported.rs:65:8 + | +LL | extern "avr-interrupt" {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/unsupported.rs:68:8 + | +LL | extern "riscv-interrupt-m" {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/unsupported.rs:71:8 + | +LL | extern "x86-interrupt" {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "thiscall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:74:8 + | +LL | extern "thiscall" fn thiscall() {} + | ^^^^^^^^^^ + +error[E0570]: "thiscall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:76:27 + | +LL | fn thiscall_ptr(f: extern "thiscall" fn()) { + | ^^^^^^^^^^ + +error[E0570]: "thiscall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:80:8 + | +LL | extern "thiscall" {} + | ^^^^^^^^^^ + +error[E0570]: "stdcall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:83:8 + | +LL | extern "stdcall" fn stdcall() {} + | ^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + +error[E0570]: "stdcall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:87:26 + | +LL | fn stdcall_ptr(f: extern "stdcall" fn()) { + | ^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + +error[E0570]: "stdcall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:93:8 + | +LL | extern "stdcall" {} + | ^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + +error[E0570]: "stdcall-unwind" is not a supported ABI for the current target + --> $DIR/unsupported.rs:97:8 + | +LL | extern "stdcall-unwind" {} + | ^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` + +error[E0570]: "vectorcall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:117:8 + | +LL | extern "vectorcall" fn vectorcall() {} + | ^^^^^^^^^^^^ + +error[E0570]: "vectorcall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:119:29 + | +LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { + | ^^^^^^^^^^^^ + +error[E0570]: "vectorcall" is not a supported ABI for the current target + --> $DIR/unsupported.rs:123:8 + | +LL | extern "vectorcall" {} + | ^^^^^^^^^^^^ + +error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target + --> $DIR/unsupported.rs:126:28 + | +LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target + --> $DIR/unsupported.rs:131:8 + | +LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target + --> $DIR/unsupported.rs:133:29 + | +LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target + --> $DIR/unsupported.rs:137:8 + | +LL | extern "cmse-nonsecure-entry" {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "custom" is not a supported ABI for the current target + --> $DIR/unsupported.rs:146:25 + | +LL | fn custom_ptr(f: extern "custom" fn()) { + | ^^^^^^^^ + +error[E0570]: "custom" is not a supported ABI for the current target + --> $DIR/unsupported.rs:150:8 + | +LL | extern "custom" {} + | ^^^^^^^^ + +warning: "cdecl" is not a supported ABI for the current target + --> $DIR/unsupported.rs:105:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = help: use `extern "C"` instead + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: "cdecl" is not a supported ABI for the current target + --> $DIR/unsupported.rs:110:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = help: use `extern "C"` instead + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + +warning: "cdecl-unwind" is not a supported ABI for the current target + --> $DIR/unsupported.rs:113:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `extern "C-unwind"` instead + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + +warning: "cdecl" is not a supported ABI for the current target + --> $DIR/unsupported.rs:102:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `extern "C"` instead + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + +error: aborting due to 27 previous errors; 4 warnings emitted + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 41842eecbd020..a1233e2c13cf3 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -1,83 +1,83 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:8 + --> $DIR/unsupported.rs:42:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:39:22 + --> $DIR/unsupported.rs:44:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:43:8 + --> $DIR/unsupported.rs:48:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:45:8 + --> $DIR/unsupported.rs:50:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:48:8 + --> $DIR/unsupported.rs:53:8 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:50:24 + --> $DIR/unsupported.rs:55:24 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:54:8 + --> $DIR/unsupported.rs:59:8 | LL | extern "aapcs" {} | ^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:57:8 + --> $DIR/unsupported.rs:62:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:60:8 + --> $DIR/unsupported.rs:65:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/unsupported.rs:63:8 + --> $DIR/unsupported.rs:68:8 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:69:8 + --> $DIR/unsupported.rs:74:8 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:71:27 + --> $DIR/unsupported.rs:76:27 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:75:8 + --> $DIR/unsupported.rs:80:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:8 + --> $DIR/unsupported.rs:83:8 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^ @@ -85,7 +85,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:82:26 + --> $DIR/unsupported.rs:87:26 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^ @@ -93,7 +93,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:8 + --> $DIR/unsupported.rs:93:8 | LL | extern "stdcall" {} | ^^^^^^^^^ @@ -101,7 +101,7 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:92:8 + --> $DIR/unsupported.rs:97:8 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^ @@ -109,31 +109,31 @@ LL | extern "stdcall-unwind" {} = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:121:28 + --> $DIR/unsupported.rs:126:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:126:8 + --> $DIR/unsupported.rs:131:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:128:29 + --> $DIR/unsupported.rs:133:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:132:8 + --> $DIR/unsupported.rs:137:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:100:17 + --> $DIR/unsupported.rs:105:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:105:1 + --> $DIR/unsupported.rs:110:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | extern "cdecl" {} = note: for more information, see issue #137018 warning: "cdecl-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:108:1 + --> $DIR/unsupported.rs:113:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -164,7 +164,7 @@ LL | extern "cdecl-unwind" {} = note: for more information, see issue #137018 warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:97:1 + --> $DIR/unsupported.rs:102:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.x64_win.stderr b/tests/ui/abi/unsupported.x64_win.stderr index 79938f04c5996..a011fcf4a06fb 100644 --- a/tests/ui/abi/unsupported.x64_win.stderr +++ b/tests/ui/abi/unsupported.x64_win.stderr @@ -1,107 +1,107 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:8 + --> $DIR/unsupported.rs:42:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:39:22 + --> $DIR/unsupported.rs:44:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:43:8 + --> $DIR/unsupported.rs:48:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:45:8 + --> $DIR/unsupported.rs:50:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:48:8 + --> $DIR/unsupported.rs:53:8 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:50:24 + --> $DIR/unsupported.rs:55:24 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:54:8 + --> $DIR/unsupported.rs:59:8 | LL | extern "aapcs" {} | ^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:57:8 + --> $DIR/unsupported.rs:62:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:60:8 + --> $DIR/unsupported.rs:65:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/unsupported.rs:63:8 + --> $DIR/unsupported.rs:68:8 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:69:8 + --> $DIR/unsupported.rs:74:8 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:71:27 + --> $DIR/unsupported.rs:76:27 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:75:8 + --> $DIR/unsupported.rs:80:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:121:28 + --> $DIR/unsupported.rs:126:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:126:8 + --> $DIR/unsupported.rs:131:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:128:29 + --> $DIR/unsupported.rs:133:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:132:8 + --> $DIR/unsupported.rs:137:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:82:19 + --> $DIR/unsupported.rs:87:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -112,7 +112,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default warning: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:93:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #137018 warning: "stdcall-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:92:1 + --> $DIR/unsupported.rs:97:1 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,7 +132,7 @@ LL | extern "stdcall-unwind" {} = note: for more information, see issue #137018 warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:100:17 + --> $DIR/unsupported.rs:105:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -142,7 +142,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: for more information, see issue #137018 warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:105:1 + --> $DIR/unsupported.rs:110:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -152,7 +152,7 @@ LL | extern "cdecl" {} = note: for more information, see issue #137018 warning: "cdecl-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:108:1 + --> $DIR/unsupported.rs:113:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -162,7 +162,7 @@ LL | extern "cdecl-unwind" {} = note: for more information, see issue #137018 warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:137:1 + --> $DIR/unsupported.rs:142:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -172,7 +172,7 @@ LL | extern "cdecl" {} = note: for more information, see issue #137018 warning: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:83:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +182,7 @@ LL | extern "stdcall" fn stdcall() {} = note: for more information, see issue #137018 warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:97:1 + --> $DIR/unsupported.rs:102:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs index 55f2f552ad31c..a6ed7d69a0866 100644 --- a/tests/ui/asm/naked-functions.rs +++ b/tests/ui/asm/naked-functions.rs @@ -3,7 +3,7 @@ //@ ignore-spirv //@ reference: attributes.codegen.naked.body -#![feature(asm_unwind, linkage, rustc_attrs, cfg_target_object_format)] +#![feature(asm_unwind, linkage, rustc_attrs, cfg_target_object_format, abi_custom)] #![crate_type = "lib"] use std::arch::{asm, naked_asm}; @@ -241,3 +241,10 @@ pub extern "C" fn rustc_std_internal_symbol() { pub extern "C" fn rustfmt_skip() { naked_asm!("", options(raw)); } + +/// This is here to ensure that for any new target that adds assembly support, we +/// check whether it can/does support `extern "custom"`. +#[unsafe(naked)] +unsafe extern "custom" fn abi_custom() { + naked_asm!("") +} diff --git a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr index 62bebd53b14a6..6cf4e881adae8 100644 --- a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr +++ b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr @@ -1,8 +1,8 @@ error: unconstrained generic constant - --> $DIR/doesnt_unify_evaluatable.rs:9:13 + --> $DIR/doesnt_unify_evaluatable.rs:9:11 | LL | bar::<{ T::ASSOC }>(); - | ^^^^^^^^ + | ^^^^^^^^^^^^ | help: try adding a `where` bound | diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs b/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs index 8470b933cadd2..b09d17fb11262 100644 --- a/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs +++ b/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs @@ -10,7 +10,6 @@ use Option::Some; fn foo>() {} - trait Trait { type const ASSOC: u32; } @@ -26,7 +25,7 @@ fn bar() { // this on the other hand is not allowed as `N + 1` is not a legal // const argument - foo::<{ Some:: { 0: N + 1 } }>(); + foo::<{ core::direct_const_arg!(Some:: { 0: N + 1 }) }>(); //~^ ERROR: complex const arguments must be placed inside of a `const` block // this also is not allowed as generic parameters cannot be used diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr index 0060c94875b5c..8f02ce0f82315 100644 --- a/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr +++ b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr @@ -1,11 +1,11 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/adt_expr_arg_simple.rs:29:30 + --> $DIR/adt_expr_arg_simple.rs:28:54 | -LL | foo::<{ Some:: { 0: N + 1 } }>(); - | ^^^^^ +LL | foo::<{ core::direct_const_arg!(Some:: { 0: N + 1 }) }>(); + | ^^^^^ error: generic parameters may not be used in const operations - --> $DIR/adt_expr_arg_simple.rs:34:38 + --> $DIR/adt_expr_arg_simple.rs:33:38 | LL | foo::<{ Some:: { 0: const { N + 1 } } }>(); | ^ diff --git a/tests/ui/const-generics/mgca/array-expr-complex.r1.stderr b/tests/ui/const-generics/mgca/array-expr-complex.r1.stderr index 0c931af8d8b1c..a226d7ff0c225 100644 --- a/tests/ui/const-generics/mgca/array-expr-complex.r1.stderr +++ b/tests/ui/const-generics/mgca/array-expr-complex.r1.stderr @@ -1,8 +1,8 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/array-expr-complex.rs:11:28 + --> $DIR/array-expr-complex.rs:11:52 | -LL | takes_array::<{ [1, 2, 1 + 2] }>(); - | ^^^^^ +LL | takes_array::<{ core::direct_const_arg!([1, 2, 1 + 2]) }>(); + | ^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/array-expr-complex.r2.stderr b/tests/ui/const-generics/mgca/array-expr-complex.r2.stderr index 335af9235e0c9..cc1e70c1d9a7a 100644 --- a/tests/ui/const-generics/mgca/array-expr-complex.r2.stderr +++ b/tests/ui/const-generics/mgca/array-expr-complex.r2.stderr @@ -1,8 +1,8 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/array-expr-complex.rs:14:21 + --> $DIR/array-expr-complex.rs:14:45 | -LL | takes_array::<{ [X; 3] }>(); - | ^^^^^^ +LL | takes_array::<{ core::direct_const_arg!([X; 3]) }>(); + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/array-expr-complex.r3.stderr b/tests/ui/const-generics/mgca/array-expr-complex.r3.stderr index 02d74c1b5d0c5..cc52abe0e8fb8 100644 --- a/tests/ui/const-generics/mgca/array-expr-complex.r3.stderr +++ b/tests/ui/const-generics/mgca/array-expr-complex.r3.stderr @@ -1,8 +1,8 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/array-expr-complex.rs:17:21 + --> $DIR/array-expr-complex.rs:17:45 | -LL | takes_array::<{ [0; Y] }>(); - | ^^^^^^ +LL | takes_array::<{ core::direct_const_arg!([0; Y]) }>(); + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/array-expr-complex.rs b/tests/ui/const-generics/mgca/array-expr-complex.rs index 26f4700b5885c..7f5a77fdff3df 100644 --- a/tests/ui/const-generics/mgca/array-expr-complex.rs +++ b/tests/ui/const-generics/mgca/array-expr-complex.rs @@ -8,13 +8,13 @@ fn takes_array() {} fn generic_caller() { // not supported yet #[cfg(r1)] - takes_array::<{ [1, 2, 1 + 2] }>(); + takes_array::<{ core::direct_const_arg!([1, 2, 1 + 2]) }>(); //[r1]~^ ERROR: complex const arguments must be placed inside of a `const` block #[cfg(r2)] - takes_array::<{ [X; 3] }>(); + takes_array::<{ core::direct_const_arg!([X; 3]) }>(); //[r2]~^ ERROR: complex const arguments must be placed inside of a `const` block #[cfg(r3)] - takes_array::<{ [0; Y] }>(); + takes_array::<{ core::direct_const_arg!([0; Y]) }>(); //[r3]~^ ERROR: complex const arguments must be placed inside of a `const` block } diff --git a/tests/ui/const-generics/mgca/array_expr_arg_complex.rs b/tests/ui/const-generics/mgca/array_expr_arg_complex.rs index 6d57e4f4b9686..4adb2bf6e429d 100644 --- a/tests/ui/const-generics/mgca/array_expr_arg_complex.rs +++ b/tests/ui/const-generics/mgca/array_expr_arg_complex.rs @@ -9,8 +9,8 @@ fn takes_array() {} fn takes_tuple_with_array() {} fn generic_caller() { - takes_array::<{ [N, N + 1] }>(); //~ ERROR complex const arguments must be placed inside of a `const` block - takes_tuple_with_array::<{ ([N, N + 1], N) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + takes_array::<{ core::direct_const_arg!([N, N + 1]) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + takes_tuple_with_array::<{ core::direct_const_arg!(([N, N + 1], N)) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block } fn main() {} diff --git a/tests/ui/const-generics/mgca/array_expr_arg_complex.stderr b/tests/ui/const-generics/mgca/array_expr_arg_complex.stderr index f40d4b5035d86..c7b13351d453c 100644 --- a/tests/ui/const-generics/mgca/array_expr_arg_complex.stderr +++ b/tests/ui/const-generics/mgca/array_expr_arg_complex.stderr @@ -1,14 +1,14 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/array_expr_arg_complex.rs:12:25 + --> $DIR/array_expr_arg_complex.rs:12:49 | -LL | takes_array::<{ [N, N + 1] }>(); - | ^^^^^ +LL | takes_array::<{ core::direct_const_arg!([N, N + 1]) }>(); + | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/array_expr_arg_complex.rs:13:37 + --> $DIR/array_expr_arg_complex.rs:13:61 | -LL | takes_tuple_with_array::<{ ([N, N + 1], N) }>(); - | ^^^^^ +LL | takes_tuple_with_array::<{ core::direct_const_arg!(([N, N + 1], N)) }>(); + | ^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/auxiliary/anon-const-def-id-on-const-arg-with-anon.rs b/tests/ui/const-generics/mgca/auxiliary/anon-const-def-id-on-const-arg-with-anon.rs new file mode 100644 index 0000000000000..c1ebfc18e0816 --- /dev/null +++ b/tests/ui/const-generics/mgca/auxiliary/anon-const-def-id-on-const-arg-with-anon.rs @@ -0,0 +1,11 @@ +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] +pub struct S; +// this is a directly represented anon const... it's a bit weird. +// imagine `S<{ (2, const { 1 + 1 }) }>`. a directly represented tuple, containing an anon const. +// now, replace `(2, _)` with `_`. it's a directly represented anon const. +// this is different from const argument lowering failing to represent an argument directly and +// falling back to representing it as an anon const instead. +pub fn f() -> S<{ const { 1 + 1 } }> { + S +} diff --git a/tests/ui/const-generics/mgca/bad-const-arg-fn-154539.rs b/tests/ui/const-generics/mgca/bad-const-arg-fn-154539.rs index 7c7ffd9a9bd5f..e3d1f577d4f60 100644 --- a/tests/ui/const-generics/mgca/bad-const-arg-fn-154539.rs +++ b/tests/ui/const-generics/mgca/bad-const-arg-fn-154539.rs @@ -2,10 +2,11 @@ trait Iter< const FN: fn() = { - || { //~ ERROR complex const arguments must be placed inside of a `const` block + core::direct_const_arg!(|| { + //~^ ERROR complex const arguments must be placed inside of a `const` block use std::io::*; write!(_, "") - } + }) }, > { diff --git a/tests/ui/const-generics/mgca/bad-const-arg-fn-154539.stderr b/tests/ui/const-generics/mgca/bad-const-arg-fn-154539.stderr index 60774c4a3efea..96fcea9e906cf 100644 --- a/tests/ui/const-generics/mgca/bad-const-arg-fn-154539.stderr +++ b/tests/ui/const-generics/mgca/bad-const-arg-fn-154539.stderr @@ -1,10 +1,12 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/bad-const-arg-fn-154539.rs:5:9 + --> $DIR/bad-const-arg-fn-154539.rs:5:33 | -LL | / || { +LL | core::direct_const_arg!(|| { + | _________________________________^ +LL | | LL | | use std::io::*; LL | | write!(_, "") -LL | | } +LL | | }) | |_________^ error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/bad-direct-const-arg.rs b/tests/ui/const-generics/mgca/bad-direct-const-arg.rs new file mode 100644 index 0000000000000..451806ca6e1db --- /dev/null +++ b/tests/ui/const-generics/mgca/bad-direct-const-arg.rs @@ -0,0 +1,8 @@ +//! Simple error message test, nothing special here +#![feature(min_generic_const_args)] + +fn main(x: core::direct_const_arg!(2)) { + //~^ ERROR expected type, found `direct_const_arg!()` constant + let _ = core::direct_const_arg!(2); + //~^ ERROR expected expression, found `direct_const_arg!()` constant +} diff --git a/tests/ui/const-generics/mgca/bad-direct-const-arg.stderr b/tests/ui/const-generics/mgca/bad-direct-const-arg.stderr new file mode 100644 index 0000000000000..b77791ad5b3ee --- /dev/null +++ b/tests/ui/const-generics/mgca/bad-direct-const-arg.stderr @@ -0,0 +1,14 @@ +error: expected expression, found `direct_const_arg!()` constant + --> $DIR/bad-direct-const-arg.rs:6:13 + | +LL | let _ = core::direct_const_arg!(2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected type, found `direct_const_arg!()` constant + --> $DIR/bad-direct-const-arg.rs:4:12 + | +LL | fn main(x: core::direct_const_arg!(2)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/direct-const-arg-feature-gate.rs b/tests/ui/const-generics/mgca/direct-const-arg-feature-gate.rs new file mode 100644 index 0000000000000..16ba349a29be6 --- /dev/null +++ b/tests/ui/const-generics/mgca/direct-const-arg-feature-gate.rs @@ -0,0 +1,5 @@ +fn foo(_: [(); core::direct_const_arg!(N)]) {} +//~^ ERROR use of unstable library feature `min_generic_const_args` +//~| ERROR expected expression, found `direct_const_arg!()` constant +//~| ERROR generic parameters may not be used in const operations +fn main() {} diff --git a/tests/ui/const-generics/mgca/direct-const-arg-feature-gate.stderr b/tests/ui/const-generics/mgca/direct-const-arg-feature-gate.stderr new file mode 100644 index 0000000000000..f5dc211c2f71a --- /dev/null +++ b/tests/ui/const-generics/mgca/direct-const-arg-feature-gate.stderr @@ -0,0 +1,28 @@ +error[E0658]: use of unstable library feature `min_generic_const_args` + --> $DIR/direct-const-arg-feature-gate.rs:1:32 + | +LL | fn foo(_: [(); core::direct_const_arg!(N)]) {} + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: generic parameters may not be used in const operations + --> $DIR/direct-const-arg-feature-gate.rs:1:56 + | +LL | fn foo(_: [(); core::direct_const_arg!(N)]) {} + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments here, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: expected expression, found `direct_const_arg!()` constant + --> $DIR/direct-const-arg-feature-gate.rs:1:32 + | +LL | fn foo(_: [(); core::direct_const_arg!(N)]) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/mgca/direct-const-arg-multiple-exprs.rs b/tests/ui/const-generics/mgca/direct-const-arg-multiple-exprs.rs new file mode 100644 index 0000000000000..8c802e563db7c --- /dev/null +++ b/tests/ui/const-generics/mgca/direct-const-arg-multiple-exprs.rs @@ -0,0 +1,5 @@ +#![feature(min_generic_const_args)] +struct S; +fn foo(_: S) {} +//~^ ERROR direct_const_arg! takes 1 argument +fn main() {} diff --git a/tests/ui/const-generics/mgca/direct-const-arg-multiple-exprs.stderr b/tests/ui/const-generics/mgca/direct-const-arg-multiple-exprs.stderr new file mode 100644 index 0000000000000..6f54a563ffbfc --- /dev/null +++ b/tests/ui/const-generics/mgca/direct-const-arg-multiple-exprs.stderr @@ -0,0 +1,8 @@ +error: direct_const_arg! takes 1 argument + --> $DIR/direct-const-arg-multiple-exprs.rs:3:45 + | +LL | fn foo(_: S) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/double-wrapped-path-not-accidentally-stabilized.rs b/tests/ui/const-generics/mgca/double-wrapped-path-not-accidentally-stabilized.rs new file mode 100644 index 0000000000000..09bce5c7f9aa2 --- /dev/null +++ b/tests/ui/const-generics/mgca/double-wrapped-path-not-accidentally-stabilized.rs @@ -0,0 +1,15 @@ +//! When doing some refactorings in mGCA, it was easy to accidentally stabilize doubly-brace-wrapped +//! paths. Check to make sure we don't accidentally do so. +//! +//! Feel free to delete this test if/when mGCA is stabilized and we support this syntax on stable, +//! it's testing nothing useful beyond that point. + +fn f() {} + +fn g() { + f::<{ N }>(); // ok + f::<{ { N } }>(); + //~^ ERROR: generic parameters may not be used in const operations +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/double-wrapped-path-not-accidentally-stabilized.stderr b/tests/ui/const-generics/mgca/double-wrapped-path-not-accidentally-stabilized.stderr new file mode 100644 index 0000000000000..6168ec242a38c --- /dev/null +++ b/tests/ui/const-generics/mgca/double-wrapped-path-not-accidentally-stabilized.stderr @@ -0,0 +1,11 @@ +error: generic parameters may not be used in const operations + --> $DIR/double-wrapped-path-not-accidentally-stabilized.rs:11:13 + | +LL | f::<{ { N } }>(); + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments here, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.rs b/tests/ui/const-generics/mgca/explicit_anon_consts.rs index 2b9909b43dfbb..9b642b286fa3e 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.rs +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.rs @@ -10,7 +10,7 @@ type Adt1 = Foo; type Adt2 = Foo<{ N }>; type Adt3 = Foo; //~^ ERROR: generic parameters may not be used in const operations -type Adt4 = Foo<{ 1 + 1 }>; +type Adt4 = Foo; //~^ ERROR: complex const arguments must be placed inside of a `const` block type Adt5 = Foo; @@ -18,7 +18,7 @@ type Arr = [(); N]; type Arr2 = [(); { N }]; type Arr3 = [(); const { N }]; //~^ ERROR: generic parameters may not be used in const operations -type Arr4 = [(); 1 + 1]; +type Arr4 = [(); core::direct_const_arg!(1 + 1)]; //~^ ERROR: complex const arguments must be placed inside of a `const` block type Arr5 = [(); const { 1 + 1 }]; @@ -27,7 +27,7 @@ fn repeats() -> [(); N] { let _2 = [(); { N }]; let _3 = [(); const { N }]; //~^ ERROR: generic parameters may not be used in const operations - let _4 = [(); 1 + 1]; + let _4 = [(); core::direct_const_arg!(1 + 1)]; //~^ ERROR: complex const arguments must be placed inside of a `const` block let _5 = [(); const { 1 + 1 }]; let _6: [(); const { N }] = todo!(); @@ -42,10 +42,10 @@ type const ITEM2: usize = { N }; type const ITEM3: usize = const { N }; //~^ ERROR: generic parameters may not be used in const operations -type const ITEM4: usize = { 1 + 1 }; +type const ITEM4: usize = core::direct_const_arg!(1 + 1); //~^ ERROR: complex const arguments must be placed inside of a `const` block -type const ITEM5: usize = const { 1 + 1}; +type const ITEM5: usize = const { 1 + 1 }; trait Trait { @@ -59,7 +59,7 @@ fn ace_bounds< T2: Trait, T3: Trait, //~^ ERROR: generic parameters may not be used in const operations - T4: Trait, + T4: Trait, //~^ ERROR: complex const arguments must be placed inside of a `const` block T5: Trait, >() {} @@ -68,6 +68,6 @@ struct Default1; struct Default2; struct Default3; //~^ ERROR: generic parameters may not be used in const operations -struct Default4; +struct Default4; //~^ ERROR: complex const arguments must be placed inside of a `const` block -struct Default5; +struct Default5; diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr index f634ec1cf12e4..9ab6af010bf21 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr @@ -1,38 +1,38 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:13:35 + --> $DIR/explicit_anon_consts.rs:13:57 | -LL | type Adt4 = Foo<{ 1 + 1 }>; - | ^^^^^ +LL | type Adt4 = Foo; + | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:21:34 + --> $DIR/explicit_anon_consts.rs:21:58 | -LL | type Arr4 = [(); 1 + 1]; - | ^^^^^ +LL | type Arr4 = [(); core::direct_const_arg!(1 + 1)]; + | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:30:19 + --> $DIR/explicit_anon_consts.rs:30:43 | -LL | let _4 = [(); 1 + 1]; - | ^^^^^ +LL | let _4 = [(); core::direct_const_arg!(1 + 1)]; + | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:45:45 + --> $DIR/explicit_anon_consts.rs:45:67 | -LL | type const ITEM4: usize = { 1 + 1 }; - | ^^^^^ +LL | type const ITEM4: usize = core::direct_const_arg!(1 + 1); + | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:62:25 + --> $DIR/explicit_anon_consts.rs:62:49 | -LL | T4: Trait, - | ^^^^^ +LL | T4: Trait, + | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:71:52 + --> $DIR/explicit_anon_consts.rs:71:76 | -LL | struct Default4; - | ^^^^^ +LL | struct Default4; + | ^^^^^ error: generic parameters may not be used in const operations --> $DIR/explicit_anon_consts.rs:42:51 diff --git a/tests/ui/const-generics/mgca/mixed-direct-anon-expression-diagnostics.rs b/tests/ui/const-generics/mgca/mixed-direct-anon-expression-diagnostics.rs new file mode 100644 index 0000000000000..1653fd63ed3f8 --- /dev/null +++ b/tests/ui/const-generics/mgca/mixed-direct-anon-expression-diagnostics.rs @@ -0,0 +1,17 @@ +//! Diagnostics for expressions that contain things that must be a mGCA direct expression, *and* +//! things that must be an anon const, are currently less than ideal. This test merely asserts the +//! current (bad) state of diagnostics, so we can track improvements over time. + +#![feature(min_generic_const_args, min_adt_const_params)] +#![allow(incomplete_features)] + +fn f() {} + +fn g() { + f::<{ (N, 1 + 1) }>(); + //~^ ERROR: generic parameters may not be used in const operations + f::<{ core::direct_const_arg!((N, 1 + 1)) }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/mixed-direct-anon-expression-diagnostics.stderr b/tests/ui/const-generics/mgca/mixed-direct-anon-expression-diagnostics.stderr new file mode 100644 index 0000000000000..ae297de108493 --- /dev/null +++ b/tests/ui/const-generics/mgca/mixed-direct-anon-expression-diagnostics.stderr @@ -0,0 +1,16 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/mixed-direct-anon-expression-diagnostics.rs:13:39 + | +LL | f::<{ core::direct_const_arg!((N, 1 + 1)) }>(); + | ^^^^^ + +error: generic parameters may not be used in const operations + --> $DIR/mixed-direct-anon-expression-diagnostics.rs:11:12 + | +LL | f::<{ (N, 1 + 1) }>(); + | ^ + | + = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/serialized-direct-const-with-anon-const-body.rs b/tests/ui/const-generics/mgca/serialized-direct-const-with-anon-const-body.rs new file mode 100644 index 0000000000000..985e14fddb676 --- /dev/null +++ b/tests/ui/const-generics/mgca/serialized-direct-const-with-anon-const-body.rs @@ -0,0 +1,16 @@ +//@ check-pass +//@ aux-build:anon-const-def-id-on-const-arg-with-anon.rs +//! The DefCollector sometimes generates "fake" DefKind::AnonConst DefIds for AST AnonConsts that +//! are not actually lowered to HIR AnonConsts, and so the DefId is placed on a hir::Node::ConstArg +//! (just to place it *somewhere*). These "fake" DefIds should not be serialized. Previously, the +//! logic to skip serializing them was incorrect (we were still serializing fake DefIds for +//! `ConstArg(ConstArgKind::Anon)` if the directly represented expression contained within it +//! *another*, unrelated, anon const). This test checks that case, a directly-represented +//! fake-anon-const directly containing another anon const. + +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] +extern crate anon_const_def_id_on_const_arg_with_anon; +fn main() { + anon_const_def_id_on_const_arg_with_anon::f(); +} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.rs b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.rs index 2e39f8952b11d..460c8af840a1c 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.rs +++ b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.rs @@ -9,7 +9,7 @@ struct Point(u32, u32); fn with_point() {} fn test() { - with_point::<{ Point(N + 1, N) }>(); + with_point::<{ core::direct_const_arg!(Point(N + 1, N)) }>(); //~^ ERROR complex const arguments must be placed inside of a `const` block with_point::<{ Point(const { N + 1 }, N) }>(); diff --git a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr index 3a873ec33fb19..a4e7cb94c57c3 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr +++ b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr @@ -1,8 +1,8 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/tuple_ctor_complex_args.rs:12:26 + --> $DIR/tuple_ctor_complex_args.rs:12:50 | -LL | with_point::<{ Point(N + 1, N) }>(); - | ^^^^^ +LL | with_point::<{ core::direct_const_arg!(Point(N + 1, N)) }>(); + | ^^^^^ error: generic parameters may not be used in const operations --> $DIR/tuple_ctor_complex_args.rs:15:34 diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs index d7cab17bad124..0d99b8ae345d6 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs @@ -9,11 +9,11 @@ fn takes_tuple() {} fn takes_nested_tuple() {} fn generic_caller() { - takes_tuple::<{ (N, N + 1) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block - takes_tuple::<{ (N, T::ASSOC + 1) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + takes_tuple::<{ core::direct_const_arg!((N, N + 1)) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + takes_tuple::<{ core::direct_const_arg!((N, T::ASSOC + 1)) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block - takes_nested_tuple::<{ (N, (N, N + 1)) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block - takes_nested_tuple::<{ (N, (N, const { N + 1 })) }>(); //~ ERROR generic parameters may not be used in const operations + takes_nested_tuple::<{ core::direct_const_arg!((N, (N, N + 1))) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + takes_nested_tuple::<{ core::direct_const_arg!((N, (N, const { N + 1 }))) }>(); //~ ERROR generic parameters may not be used in const operations } fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr index a9d412964da29..4bed120284c08 100644 --- a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr @@ -1,26 +1,26 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/tuple_expr_arg_complex.rs:12:25 + --> $DIR/tuple_expr_arg_complex.rs:12:49 | -LL | takes_tuple::<{ (N, N + 1) }>(); - | ^^^^^ +LL | takes_tuple::<{ core::direct_const_arg!((N, N + 1)) }>(); + | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/tuple_expr_arg_complex.rs:13:25 + --> $DIR/tuple_expr_arg_complex.rs:13:49 | -LL | takes_tuple::<{ (N, T::ASSOC + 1) }>(); - | ^^^^^^^^^^^^ +LL | takes_tuple::<{ core::direct_const_arg!((N, T::ASSOC + 1)) }>(); + | ^^^^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/tuple_expr_arg_complex.rs:15:36 + --> $DIR/tuple_expr_arg_complex.rs:15:60 | -LL | takes_nested_tuple::<{ (N, (N, N + 1)) }>(); - | ^^^^^ +LL | takes_nested_tuple::<{ core::direct_const_arg!((N, (N, N + 1))) }>(); + | ^^^^^ error: generic parameters may not be used in const operations - --> $DIR/tuple_expr_arg_complex.rs:16:44 + --> $DIR/tuple_expr_arg_complex.rs:16:68 | -LL | takes_nested_tuple::<{ (N, (N, const { N + 1 })) }>(); - | ^ +LL | takes_nested_tuple::<{ core::direct_const_arg!((N, (N, const { N + 1 }))) }>(); + | ^ | = help: add `#![feature(generic_const_args)]` to allow generic expressions as the RHS of const items diff --git a/tests/ui/const-generics/mgca/type-const-free-anon-const-mismatch.stderr b/tests/ui/const-generics/mgca/type-const-free-anon-const-mismatch.stderr index d0339d09cdc7a..52ef108a84dbf 100644 --- a/tests/ui/const-generics/mgca/type-const-free-anon-const-mismatch.stderr +++ b/tests/ui/const-generics/mgca/type-const-free-anon-const-mismatch.stderr @@ -4,7 +4,7 @@ error[E0284]: type annotations needed LL | type const X: usize = const { N }; | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` | - = note: cannot satisfy `X::{constant#0} == _` + = note: cannot satisfy `X::{constant#0}::{constant#0} == _` error: the constant `"this isn't a usize"` is not of type `usize` --> $DIR/type-const-free-anon-const-mismatch.rs:8:1 diff --git a/tests/ui/const-generics/mgca/type-const-free-value-type-mismatch.next.stderr b/tests/ui/const-generics/mgca/type-const-free-value-type-mismatch.next.stderr index d96726829ee0b..3ef6ede90d933 100644 --- a/tests/ui/const-generics/mgca/type-const-free-value-type-mismatch.next.stderr +++ b/tests/ui/const-generics/mgca/type-const-free-value-type-mismatch.next.stderr @@ -10,7 +10,7 @@ error[E0284]: type annotations needed LL | fn f() -> [u8; const { N }] {} | ^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` | - = note: cannot satisfy `f::{constant#0} == _` + = note: cannot satisfy `f::{constant#0}::{constant#0} == _` error[E0308]: mismatched types --> $DIR/type-const-free-value-type-mismatch.rs:11:11 diff --git a/tests/ui/const-generics/mgca/type-const-inherent-value-type-mismatch.next.stderr b/tests/ui/const-generics/mgca/type-const-inherent-value-type-mismatch.next.stderr index eeabde2d06320..551a1d496e910 100644 --- a/tests/ui/const-generics/mgca/type-const-inherent-value-type-mismatch.next.stderr +++ b/tests/ui/const-generics/mgca/type-const-inherent-value-type-mismatch.next.stderr @@ -4,7 +4,7 @@ error[E0284]: type annotations needed LL | fn f() -> [u8; const { Struct::N }] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` | - = note: cannot satisfy `f::{constant#0} == _` + = note: cannot satisfy `f::{constant#0}::{constant#0} == _` error: the constant `"this isn't a usize"` is not of type `usize` --> $DIR/type-const-inherent-value-type-mismatch.rs:13:5 diff --git a/tests/ui/const-generics/mgca/type-const-value-type-mismatch.next.stderr b/tests/ui/const-generics/mgca/type-const-value-type-mismatch.next.stderr index 123c442a3938d..748ffe1294e0a 100644 --- a/tests/ui/const-generics/mgca/type-const-value-type-mismatch.next.stderr +++ b/tests/ui/const-generics/mgca/type-const-value-type-mismatch.next.stderr @@ -16,7 +16,7 @@ error[E0284]: type annotations needed LL | fn arr() -> [u8; const { Self::LEN }] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` | - = note: cannot satisfy `::arr::{constant#0} == _` + = note: cannot satisfy `::arr::{constant#0}::{constant#0} == _` error[E0308]: mismatched types --> $DIR/type-const-value-type-mismatch.rs:21:17 diff --git a/tests/ui/delegation/bad-resolve.rs b/tests/ui/delegation/bad-resolve.rs index 2c2c622e09006..3700b04160292 100644 --- a/tests/ui/delegation/bad-resolve.rs +++ b/tests/ui/delegation/bad-resolve.rs @@ -33,6 +33,7 @@ impl Trait for S { reuse foo { &self.0 } //~^ ERROR cannot find function `foo` in this scope + //~| ERROR: method `foo` has a `&self` declaration in the trait, but not in the impl reuse Trait::foo2 { self.0 } //~^ ERROR cannot find function `foo2` in trait `Trait` //~| ERROR method `foo2` is not a member of trait `Trait` diff --git a/tests/ui/delegation/bad-resolve.stderr b/tests/ui/delegation/bad-resolve.stderr index d1b3974e77081..29460e0ce982f 100644 --- a/tests/ui/delegation/bad-resolve.stderr +++ b/tests/ui/delegation/bad-resolve.stderr @@ -26,7 +26,7 @@ LL | reuse ::baz; | not a member of trait `Trait` error[E0407]: method `foo2` is not a member of trait `Trait` - --> $DIR/bad-resolve.rs:36:5 + --> $DIR/bad-resolve.rs:37:5 | LL | reuse Trait::foo2 { self.0 } | ^^^^^^^^^^^^^----^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL | reuse foo { &self.0 } | ^^^ not found in this scope error[E0425]: cannot find function `foo2` in trait `Trait` - --> $DIR/bad-resolve.rs:36:18 + --> $DIR/bad-resolve.rs:37:18 | LL | fn foo(&self, x: i32) -> i32 { x } | ---------------------------- similarly named associated function `foo` defined here @@ -83,11 +83,20 @@ LL + reuse Trait::foo { self.0 } | error[E0423]: expected function, found module `prefix::self` - --> $DIR/bad-resolve.rs:43:7 + --> $DIR/bad-resolve.rs:44:7 | LL | reuse prefix::{self, super, crate}; | ^^^^^^ not a function +error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl + --> $DIR/bad-resolve.rs:34:11 + | +LL | fn foo(&self, x: i32) -> i32 { x } + | ---------------------------- `&self` used in trait +... +LL | reuse foo { &self.0 } + | ^^^ expected `&self` in impl + error[E0046]: not all trait items implemented, missing: `Type` --> $DIR/bad-resolve.rs:21:1 | @@ -98,7 +107,7 @@ LL | impl Trait for S { | ^^^^^^^^^^^^^^^^ missing `Type` in implementation error[E0433]: cannot find module or crate `unresolved_prefix` in this scope - --> $DIR/bad-resolve.rs:42:7 + --> $DIR/bad-resolve.rs:43:7 | LL | reuse unresolved_prefix::{a, b, c}; | ^^^^^^^^^^^^^^^^^ use of unresolved module or unlinked crate `unresolved_prefix` @@ -106,12 +115,12 @@ LL | reuse unresolved_prefix::{a, b, c}; = help: you might be missing a crate named `unresolved_prefix` error[E0433]: `crate` in paths can only be used in start position - --> $DIR/bad-resolve.rs:43:29 + --> $DIR/bad-resolve.rs:44:29 | LL | reuse prefix::{self, super, crate}; | ^^^^^ can only be used in path start position -error: aborting due to 13 previous errors +error: aborting due to 14 previous errors -Some errors have detailed explanations: E0046, E0324, E0407, E0423, E0425, E0433, E0575, E0576. +Some errors have detailed explanations: E0046, E0186, E0324, E0407, E0423, E0425, E0433, E0575, E0576. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/delegation/constraints-in-generic-args-ice-158812.rs b/tests/ui/delegation/constraints-in-generic-args-ice-158812.rs new file mode 100644 index 0000000000000..1764a9d979992 --- /dev/null +++ b/tests/ui/delegation/constraints-in-generic-args-ice-158812.rs @@ -0,0 +1,13 @@ +#![feature(fn_delegation)] + +pub trait Trait<'a> { + fn foo(&self); +} + +pub struct S<'a, A>(&'a A); +impl<'a, A> Trait<'a> for S<'a, A> { + reuse Trait::::foo; + //~^ ERROR: associated item constraints are not allowed here +} + +fn main() {} diff --git a/tests/ui/delegation/constraints-in-generic-args-ice-158812.stderr b/tests/ui/delegation/constraints-in-generic-args-ice-158812.stderr new file mode 100644 index 0000000000000..1d4b02ef87a6c --- /dev/null +++ b/tests/ui/delegation/constraints-in-generic-args-ice-158812.stderr @@ -0,0 +1,9 @@ +error[E0229]: associated item constraints are not allowed here + --> $DIR/constraints-in-generic-args-ice-158812.rs:9:19 + | +LL | reuse Trait::::foo; + | ^^^^^^ associated item constraint not allowed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0229`. diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155125.stderr b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155125.stderr index d2f0e87ecb593..6675831bddc86 100644 --- a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155125.stderr +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155125.stderr @@ -9,13 +9,14 @@ LL | reuse foo; = note: `foo` must be defined only once in the value namespace of this block error: complex const arguments must be placed inside of a `const` block - --> $DIR/hir-crate-items-before-lowering-ices.rs:10:13 + --> $DIR/hir-crate-items-before-lowering-ices.rs:10:37 | -LL | / { +LL | core::direct_const_arg!({ + | _____________________________________^ LL | | fn foo() {} LL | | reuse foo; LL | | 2 -LL | | }, +LL | | }), | |_____________^ error: aborting due to 2 previous errors diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155164.stderr b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155164.stderr index 34d1a92ccd225..6164dabe74bff 100644 --- a/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155164.stderr +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155164.stderr @@ -1,12 +1,13 @@ error: complex const arguments must be placed inside of a `const` block - --> $DIR/hir-crate-items-before-lowering-ices.rs:47:13 + --> $DIR/hir-crate-items-before-lowering-ices.rs:47:37 | -LL | / { +LL | core::direct_const_arg!({ + | _____________________________________^ LL | | LL | | struct W; LL | | impl W { ... | -LL | | }, +LL | | }), | |_____________^ error: aborting due to 1 previous error diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs b/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs index b9a7a73732cf3..07f5a1ad1712f 100644 --- a/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs @@ -7,11 +7,11 @@ mod ice_155125 { struct S; impl S< - { //[ice_155125]~ ERROR: complex const arguments must be placed inside of a `const` block + core::direct_const_arg!({ //[ice_155125]~ ERROR: complex const arguments must be placed inside of a `const` block fn foo() {} reuse foo; //[ice_155125]~ ERROR: the name `foo` is defined multiple times 2 - }, + }), > { } @@ -44,13 +44,13 @@ mod ice_155128 { mod ice_155164 { struct X { inner: std::iter::Map< - { + core::direct_const_arg!({ //[ice_155164]~^ ERROR: complex const arguments must be placed inside of a `const` block struct W; impl W { reuse Iterator::fold; } - }, + }), F, >, } diff --git a/tests/ui/delegation/inside-const-body-ice-155300.rs b/tests/ui/delegation/inside-const-body-ice-155300.rs index 06addf7e5412d..2d13007bc807b 100644 --- a/tests/ui/delegation/inside-const-body-ice-155300.rs +++ b/tests/ui/delegation/inside-const-body-ice-155300.rs @@ -5,12 +5,13 @@ pub struct S; impl S< - { //~ ERROR: complex const arguments must be placed inside of a `const` block + core::direct_const_arg!({ + //~^ ERROR: complex const arguments must be placed inside of a `const` block fn foo() {} reuse foo::<> as bar; reuse bar; //~^ ERROR: the name `bar` is defined multiple times - }, + }), > { } diff --git a/tests/ui/delegation/inside-const-body-ice-155300.stderr b/tests/ui/delegation/inside-const-body-ice-155300.stderr index 0d2020c997200..f0cb830109f8a 100644 --- a/tests/ui/delegation/inside-const-body-ice-155300.stderr +++ b/tests/ui/delegation/inside-const-body-ice-155300.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `bar` is defined multiple times - --> $DIR/inside-const-body-ice-155300.rs:11:13 + --> $DIR/inside-const-body-ice-155300.rs:12:13 | LL | reuse foo::<> as bar; | --------------------- previous definition of the value `bar` here @@ -9,14 +9,15 @@ LL | reuse bar; = note: `bar` must be defined only once in the value namespace of this block error: complex const arguments must be placed inside of a `const` block - --> $DIR/inside-const-body-ice-155300.rs:8:9 + --> $DIR/inside-const-body-ice-155300.rs:8:33 | -LL | / { +LL | core::direct_const_arg!({ + | _________________________________^ +LL | | LL | | fn foo() {} LL | | reuse foo::<> as bar; -LL | | reuse bar; -LL | | -LL | | }, +... | +LL | | }), | |_________^ error: aborting due to 2 previous errors diff --git a/tests/ui/delegation/self-mapping-arguments-errors.rs b/tests/ui/delegation/self-mapping-arguments-errors.rs new file mode 100644 index 0000000000000..c7789c69be805 --- /dev/null +++ b/tests/ui/delegation/self-mapping-arguments-errors.rs @@ -0,0 +1,47 @@ +#![feature(fn_delegation)] + +mod target_expr_doesnt_relower_when_defs_inside { + trait MyAdd { + fn add(self, other: Self) -> Self; + } + + impl MyAdd for usize { + fn add(self, other: usize) -> usize { self + other } + } + + #[derive(Eq, PartialEq, Debug)] + struct W(usize); + reuse impl MyAdd for W { + //~^ ERROR: attempted to lower target expression with definitions more than once while mapping argument + //~| ERROR: method `add` has a `self` declaration in the trait, but not in the impl + //~| ERROR: the trait bound `(): target_expr_doesnt_relower_when_defs_inside::MyAdd` is not satisfied + //~| ERROR: this function takes 2 arguments but 1 argument was supplied + println!("{self:?}"); + fn foo() { + println!("hello"); + } + + reuse foo as bar; + bar(); + bar(); + + self.0 + } +} + +mod complex_Self_doesnt_map { + trait MyAdd { + fn add(self, other: Box) -> Self; + } + + impl MyAdd for usize { + fn add(self, other: Box) -> usize { self + *other.as_ref() } + } + + #[derive(Eq, PartialEq, Debug)] + struct W(usize); + reuse impl MyAdd for W { self.0 } + //~^ ERROR: mismatched types +} + +fn main() {} diff --git a/tests/ui/delegation/self-mapping-arguments-errors.stderr b/tests/ui/delegation/self-mapping-arguments-errors.stderr new file mode 100644 index 0000000000000..6208a1463c443 --- /dev/null +++ b/tests/ui/delegation/self-mapping-arguments-errors.stderr @@ -0,0 +1,98 @@ +error: attempted to lower target expression with definitions more than once while mapping argument + --> $DIR/self-mapping-arguments-errors.rs:14:5 + | +LL | / reuse impl MyAdd for W { +... | +LL | | self.0 +LL | | } + | |_____^ + +error[E0186]: method `add` has a `self` declaration in the trait, but not in the impl + --> $DIR/self-mapping-arguments-errors.rs:14:5 + | +LL | fn add(self, other: Self) -> Self; + | ---------------------------------- `self` used in trait +... +LL | / reuse impl MyAdd for W { +... | +LL | | self.0 +LL | | } + | |_____^ expected `self` in impl + +error[E0277]: the trait bound `(): target_expr_doesnt_relower_when_defs_inside::MyAdd` is not satisfied + --> $DIR/self-mapping-arguments-errors.rs:14:5 + | +LL | / reuse impl MyAdd for W { +... | +LL | | self.0 +LL | | } + | |_____^ the trait `target_expr_doesnt_relower_when_defs_inside::MyAdd` is not implemented for `()` + | +help: the following other types implement trait `target_expr_doesnt_relower_when_defs_inside::MyAdd` + --> $DIR/self-mapping-arguments-errors.rs:8:5 + | +LL | impl MyAdd for usize { + | ^^^^^^^^^^^^^^^^^^^^ `usize` +... +LL | reuse impl MyAdd for W { + | ^^^^^^^^^^^^^^^^^^^^^^ `target_expr_doesnt_relower_when_defs_inside::W` + +error[E0061]: this function takes 2 arguments but 1 argument was supplied + --> $DIR/self-mapping-arguments-errors.rs:14:5 + | +LL | / reuse impl MyAdd for W { +... | +LL | | self.0 +LL | | } + | | ^ + | | | + | |_____argument #2 of type `()` is missing + | this implicit `()` return type influences the call expression's return type + | +note: method defined here + --> $DIR/self-mapping-arguments-errors.rs:5:12 + | +LL | fn add(self, other: Self) -> Self; + | ^^^ ----- +help: provide the argument + | +LL ~ }({ +LL + +LL + +LL + +LL + +LL + println!("{self:?}"); +LL + fn foo() { +LL + println!("hello"); +LL + } +LL + +LL + reuse foo as bar; +LL + bar(); +LL + bar(); +LL + +LL + self.0 +LL + }, ()) + | + +error[E0308]: mismatched types + --> $DIR/self-mapping-arguments-errors.rs:43:5 + | +LL | reuse impl MyAdd for W { self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected `Box`, found `Box` + | arguments to this function are incorrect + | this return type influences the call expression's return type + | + = note: expected struct `Box` + found struct `Box` +note: method defined here + --> $DIR/self-mapping-arguments-errors.rs:34:12 + | +LL | fn add(self, other: Box) -> Self; + | ^^^ ----- + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0061, E0186, E0277, E0308. +For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/self-mapping-arguments.rs b/tests/ui/delegation/self-mapping-arguments.rs new file mode 100644 index 0000000000000..f1b5279927af7 --- /dev/null +++ b/tests/ui/delegation/self-mapping-arguments.rs @@ -0,0 +1,59 @@ +//@ run-pass +//@ check-run-results + +#![feature(fn_delegation)] + + +mod default_test { + trait MyAdd { + fn add(self, other: Self) -> Self; + } + + impl MyAdd for usize { + fn add(self, other: usize) -> usize { self + other } + } + + #[derive(Eq, PartialEq, Debug)] + struct W(usize); + reuse impl MyAdd for W { + println!("{self:?}"); + let _x = 213; + + self.0 + } + + pub fn check() { + assert_eq!(W(1).add(W(2)), W(3)) + } +} + +mod arguments_mapping_works_without_return_self { + trait MyAdd { + fn add(self, other: Self); + } + + impl MyAdd for usize { + fn add(self, other: usize) { + let result = self + other; + println!("{result}"); + } + } + + #[derive(Eq, PartialEq, Debug)] + struct W(usize); + reuse impl MyAdd for W { + println!("{self:?}"); + let _x = 213; + + self.0 + } + + pub fn check() { + W(2).add(W(10)); + } +} + +fn main() { + default_test::check(); + arguments_mapping_works_without_return_self::check(); +} diff --git a/tests/ui/delegation/self-mapping-arguments.run.stdout b/tests/ui/delegation/self-mapping-arguments.run.stdout new file mode 100644 index 0000000000000..d8177420647a8 --- /dev/null +++ b/tests/ui/delegation/self-mapping-arguments.run.stdout @@ -0,0 +1,5 @@ +W(1) +W(2) +W(2) +W(10) +12 diff --git a/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.rs b/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.rs index a1d0e540b398d..bc7efac9dfccd 100644 --- a/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.rs +++ b/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.rs @@ -1,7 +1,7 @@ // Regression test for #152335. // The compiler used to ICE in `generics_of` when `note_and_explain_type_err` // was called with `CRATE_DEF_ID` as the body owner during dyn-compatibility -// checking. This happened because `ObligationCause::dummy()` sets `body_id` +// checking. This happened because `ObligationCause::dummy()` sets `body_def_id` // to `CRATE_DEF_ID`, and error reporting tried to look up generics on it. struct ActuallySuper; diff --git a/tests/ui/lint/unused-braces-macro-arg-issue-158747.fixed b/tests/ui/lint/unused-braces-macro-arg-issue-158747.fixed new file mode 100644 index 0000000000000..840b33352939c --- /dev/null +++ b/tests/ui/lint/unused-braces-macro-arg-issue-158747.fixed @@ -0,0 +1,40 @@ +//@ check-pass +//@ run-rustfix + +// Removing block braces can change how macro-generated calls match macro arguments. + +#![warn(unused_braces)] + +macro_rules! type_or_expr { + ($x:ty) => { + identity(stringify!($x)) + }; + ($x:expr) => { + identity($x) + }; +} + +macro_rules! call_expr { + ($e:expr) => { + identity($e) + }; +} + +macro_rules! call_block { + ($b:block) => { + identity($b) + }; +} + +fn identity(x: T) -> T { + x +} + +fn main() { + // should not warn + let _ = type_or_expr!({ format!("{}", 1) }); + // should not warn + let _ = call_expr!(1); + //~^ WARN unnecessary braces around function argument + let _ = call_block!({ 1 }); +} diff --git a/tests/ui/lint/unused-braces-macro-arg-issue-158747.rs b/tests/ui/lint/unused-braces-macro-arg-issue-158747.rs new file mode 100644 index 0000000000000..3d03ce38fddaa --- /dev/null +++ b/tests/ui/lint/unused-braces-macro-arg-issue-158747.rs @@ -0,0 +1,40 @@ +//@ check-pass +//@ run-rustfix + +// Removing block braces can change how macro-generated calls match macro arguments. + +#![warn(unused_braces)] + +macro_rules! type_or_expr { + ($x:ty) => { + identity(stringify!($x)) + }; + ($x:expr) => { + identity($x) + }; +} + +macro_rules! call_expr { + ($e:expr) => { + identity($e) + }; +} + +macro_rules! call_block { + ($b:block) => { + identity($b) + }; +} + +fn identity(x: T) -> T { + x +} + +fn main() { + // should not warn + let _ = type_or_expr!({ format!("{}", 1) }); + // should not warn + let _ = call_expr!({ 1 }); + //~^ WARN unnecessary braces around function argument + let _ = call_block!({ 1 }); +} diff --git a/tests/ui/lint/unused-braces-macro-arg-issue-158747.stderr b/tests/ui/lint/unused-braces-macro-arg-issue-158747.stderr new file mode 100644 index 0000000000000..4c6ed914cc6a4 --- /dev/null +++ b/tests/ui/lint/unused-braces-macro-arg-issue-158747.stderr @@ -0,0 +1,19 @@ +warning: unnecessary braces around function argument + --> $DIR/unused-braces-macro-arg-issue-158747.rs:37:24 + | +LL | let _ = call_expr!({ 1 }); + | ^^ ^^ + | +note: the lint level is defined here + --> $DIR/unused-braces-macro-arg-issue-158747.rs:6:9 + | +LL | #![warn(unused_braces)] + | ^^^^^^^^^^^^^ +help: remove these braces + | +LL - let _ = call_expr!({ 1 }); +LL + let _ = call_expr!(1); + | + +warning: 1 warning emitted +