diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 9ee8ece414b7c..14b317199996f 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -62,7 +62,7 @@ impl HasNodeId for Box { } /// A trait for AST nodes having (or not having) collected tokens. -pub trait HasTokens { +pub trait HasTokens: HasAttrs { fn tokens(&self) -> Option<&LazyAttrTokenStream>; fn tokens_mut(&mut self) -> Option<&mut Option>; } @@ -109,7 +109,7 @@ impl_has_tokens_none!( WherePredicate ); -impl HasTokens for WithTokens { +impl HasTokens for WithTokens { fn tokens(&self) -> Option<&LazyAttrTokenStream> { self.tokens.as_ref() } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 2e54e1a7c320c..9774173f24780 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -7,7 +7,7 @@ use std::fmt::Debug; use std::sync::atomic::{AtomicU32, Ordering}; use rustc_index::bit_set::GrowableBitSet; -use rustc_span::{Ident, Span, Symbol, sym}; +use rustc_span::{Ident, Span, Symbol, kw, sym}; use smallvec::{SmallVec, smallvec}; use thin_vec::{ThinVec, thin_vec}; @@ -21,7 +21,8 @@ use crate::token::{ self, CommentKind, Delimiter, DocFragmentKind, InvisibleOrigin, MetaVarKind, Token, }; use crate::tokenstream::{ - DelimSpan, LazyAttrTokenStream, Spacing, TokenStream, TokenStreamIter, TokenTree, + AttrTokenStream, AttrTokenTree, DelimSpacing, DelimSpan, LazyAttrTokenStream, Spacing, + TokenStream, TokenStreamIter, TokenTree, }; use crate::util::comments; use crate::util::literal::escape_string_symbol; @@ -737,23 +738,6 @@ pub fn mk_doc_comment( Attribute { kind: AttrKind::DocComment(comment_kind, data), id: g.mk_attr_id(), style, span } } -fn mk_attr( - g: &AttrIdGenerator, - style: AttrStyle, - unsafety: Safety, - path: Path, - args: AttrArgs, - span: Span, -) -> Attribute { - mk_attr_from_item( - g, - AttrItem { unsafety, path, args: AttrItemKind::Unparsed(args) }, - None, - style, - span, - ) -} - pub fn mk_attr_from_item( g: &AttrIdGenerator, item: AttrItem, @@ -769,6 +753,50 @@ pub fn mk_attr_from_item( } } +fn mk_attr_tokens( + style: AttrStyle, + unsafety: Safety, + item_tokens: AttrTokenStream, + span: Span, +) -> LazyAttrTokenStream { + let safety_kw = match unsafety { + Safety::Default => None, + Safety::Unsafe(span) => Some((kw::Unsafe, span)), + Safety::Safe(span) => Some((kw::Safe, span)), + }; + let item_tokens = if let Some((kw, kw_span)) = safety_kw { + AttrTokenStream::new(vec![ + AttrTokenTree::Token(Token::from_ast_ident(Ident::new(kw, kw_span)), Spacing::Alone), + AttrTokenTree::Delimited( + DelimSpan::from_single(span), + DelimSpacing::new(Spacing::JointHidden, Spacing::Alone), + Delimiter::Parenthesis, + item_tokens, + ), + ]) + } else { + item_tokens + }; + + let mut tokens = match style { + AttrStyle::Outer => { + vec![AttrTokenTree::Token(Token::new(token::Pound, span), Spacing::JointHidden)] + } + AttrStyle::Inner => vec![ + AttrTokenTree::Token(Token::new(token::Pound, span), Spacing::Joint), + AttrTokenTree::Token(Token::new(token::Bang, span), Spacing::JointHidden), + ], + }; + tokens.push(AttrTokenTree::Delimited( + DelimSpan::from_single(span), + DelimSpacing::new(Spacing::JointHidden, Spacing::Alone), + Delimiter::Bracket, + item_tokens, + )); + + LazyAttrTokenStream::new_direct(AttrTokenStream::new(tokens)) +} + pub fn mk_attr_word( g: &AttrIdGenerator, style: AttrStyle, @@ -778,7 +806,24 @@ pub fn mk_attr_word( ) -> Attribute { let path = Path::from_ident(Ident::new(name, span)); let args = AttrArgs::Empty; - mk_attr(g, style, unsafety, path, args, span) + + let tokens = Some(mk_attr_tokens( + style, + unsafety, + AttrTokenStream::new(vec![AttrTokenTree::Token( + Token::from_ast_ident(Ident::new(name, span)), + Spacing::Alone, + )]), + span, + )); + + mk_attr_from_item( + g, + AttrItem { unsafety, path, args: AttrItemKind::Unparsed(args) }, + tokens, + style, + span, + ) } pub fn mk_attr_nested_word( @@ -800,7 +845,32 @@ pub fn mk_attr_nested_word( delim: Delimiter::Parenthesis, tokens: inner_tokens, }); - mk_attr(g, style, unsafety, path, attr_args, span) + + let tokens = Some(mk_attr_tokens( + style, + unsafety, + AttrTokenStream::new(vec![ + AttrTokenTree::Token(Token::from_ast_ident(Ident::new(outer, span)), Spacing::Alone), + AttrTokenTree::Delimited( + DelimSpan::from_single(span), + DelimSpacing::new(Spacing::JointHidden, Spacing::Alone), + Delimiter::Parenthesis, + AttrTokenStream::new(vec![AttrTokenTree::Token( + Token::from_ast_ident(Ident::new(inner, span)), + Spacing::Alone, + )]), + ), + ]), + span, + )); + + mk_attr_from_item( + g, + AttrItem { unsafety, path, args: AttrItemKind::Unparsed(attr_args) }, + tokens, + style, + span, + ) } pub fn mk_attr_name_value_str( @@ -821,7 +891,28 @@ pub fn mk_attr_name_value_str( }); let path = Path::from_ident(Ident::new(name, span)); let args = AttrArgs::Eq { eq_span: span, expr }; - mk_attr(g, style, unsafety, path, args, span) + + let tokens = Some(mk_attr_tokens( + style, + unsafety, + AttrTokenStream::new(vec![ + AttrTokenTree::Token(Token::from_ast_ident(Ident::new(name, span)), Spacing::Alone), + AttrTokenTree::Token(Token::new(token::Eq, span), Spacing::Alone), + AttrTokenTree::Token( + Token::new(token::TokenKind::lit(lit.kind, lit.symbol, lit.suffix), span), + Spacing::Alone, + ), + ]), + span, + )); + + mk_attr_from_item( + g, + AttrItem { unsafety, path, args: AttrItemKind::Unparsed(args) }, + tokens, + style, + span, + ) } pub fn filter_by_name(attrs: &[Attribute], name: Symbol) -> impl Iterator { diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index b37d5fd9dc9c1..19ac92aa66fe7 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -18,7 +18,7 @@ use rustc_span::{DUMMY_SP, Span, SpanDecoder, SpanEncoder, Symbol, sym}; use thin_vec::ThinVec; use crate::ast::AttrStyle; -use crate::ast_traits::{HasAttrs, HasTokens}; +use crate::ast_traits::HasTokens; use crate::token::{self, Delimiter, Token, TokenKind}; use crate::{AttrVec, Attribute}; @@ -653,7 +653,7 @@ impl TokenStream { TokenStream::new(vec![TokenTree::token_alone(kind, span)]) } - pub fn from_ast(node: &(impl HasAttrs + HasTokens + fmt::Debug)) -> TokenStream { + pub fn from_ast(node: &(impl HasTokens + fmt::Debug)) -> TokenStream { let tokens = node.tokens().unwrap_or_else(|| panic!("missing tokens for node: {:?}", node)); let mut tts = vec![]; attrs_and_tokens_to_token_trees(node.attrs(), tokens, &mut tts); diff --git a/compiler/rustc_ast_lowering/src/expr/closure.rs b/compiler/rustc_ast_lowering/src/expr/closure.rs index cc2c6ae2879c1..32e2e5d40d132 100644 --- a/compiler/rustc_ast_lowering/src/expr/closure.rs +++ b/compiler/rustc_ast_lowering/src/expr/closure.rs @@ -38,6 +38,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &closure.body, closure.fn_decl_span, closure.fn_arg_span, + attrs, ), span: self.lower_span(e.span), }, @@ -240,7 +241,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn_decl_span: self.lower_span(fn_decl_span), fn_arg_span: Some(self.lower_span(fn_arg_span)), kind: closure_kind, - constness: self.lower_constness(constness), + constness: self.lower_constness(attrs, constness), explicit_captures, }); @@ -308,6 +309,7 @@ impl<'hir> LoweringContext<'_, 'hir> { body: &Expr, fn_decl_span: Span, fn_arg_span: Span, + attrs: &[hir::Attribute], ) -> hir::ExprKind<'hir> { let closure_def_id = self.local_def_id(closure_id); let (binder_clause, generic_params) = self.lower_closure_binder(binder); @@ -369,7 +371,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // knows that a `FnDecl` output type like `-> &str` actually means // "coroutine that returns &str", rather than directly returning a `&str`. kind: hir::ClosureKind::CoroutineClosure(coroutine_desugaring), - constness: self.lower_constness(constness), + constness: self.lower_constness(attrs, constness), explicit_captures: &[], }); hir::ExprKind::Closure(c) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 692c178a6875c..8d5bd34f13444 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -479,7 +479,7 @@ impl<'hir> LoweringContext<'_, 'hir> { .arena .alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item))); - let constness = self.lower_constness(*constness); + let constness = self.lower_constness(attrs, *constness); hir::ItemKind::Impl(hir::Impl { generics, @@ -499,7 +499,7 @@ impl<'hir> LoweringContext<'_, 'hir> { bounds, items, }) => { - let constness = self.lower_constness(*constness); + let constness = self.lower_constness(attrs, *constness); let impl_restriction = self.lower_impl_restriction(impl_restriction); let ident = self.lower_ident(*ident); let (generics, (safety, items, bounds)) = self.lower_generics( @@ -530,7 +530,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } ItemKind::TraitAlias(TraitAlias { constness, ident, generics, bounds }) => { - let constness = self.lower_constness(*constness); + let constness = self.lower_constness(attrs, *constness); let ident = self.lower_ident(*ident); let (generics, bounds) = self.lower_generics( generics, @@ -1702,21 +1702,7 @@ impl<'hir> LoweringContext<'_, 'hir> { safety.into() }; - let mut constness = self.lower_constness(h.constness); - if let Some(&attr_span) = find_attr!(attrs, RustcComptime(span) => span) { - match std::mem::replace(&mut constness, rustc_hir::Constness::Const { always: true }) { - rustc_hir::Constness::Const { always: true } => { - unreachable!("lower_constness cannot produce comptime") - } - // A function can't be `const` and `comptime` at the same time - rustc_hir::Constness::Const { always: false } => { - let Const::Yes(span) = h.constness else { unreachable!() }; - self.dcx().emit_err(ConstComptimeFn { span, attr_span }); - } - // Good - rustc_hir::Constness::NotConst => {} - } - } + let constness = self.lower_constness(attrs, h.constness); hir::FnHeader { safety, asyncness, constness, abi: self.lower_extern(h.ext) } } @@ -1778,11 +1764,30 @@ impl<'hir> LoweringContext<'_, 'hir> { }); } - pub(super) fn lower_constness(&mut self, c: Const) -> hir::Constness { - match c { + /// Lowers constness or comptime attribute. + /// Whether `const` is allowed here is checked by ast validation. + /// Whether `comptime` is allowed here is checked by the `comptime` attribute parser. + pub(super) fn lower_constness(&mut self, attrs: &[hir::Attribute], c: Const) -> hir::Constness { + let mut constness = match c { Const::Yes(_) => hir::Constness::Const { always: false }, Const::No => hir::Constness::NotConst, + }; + + if let Some(&attr_span) = find_attr!(attrs, RustcComptime(span) => span) { + match std::mem::replace(&mut constness, hir::Constness::Const { always: true }) { + hir::Constness::Const { always: true } => { + unreachable!("lower_constness cannot produce comptime") + } + // A function can't be `const` and `comptime` at the same time + hir::Constness::Const { always: false } => { + let Const::Yes(span) = c else { unreachable!() }; + self.dcx().emit_err(ConstComptimeFn { span, attr_span }); + } + // Good + hir::Constness::NotConst => {} + } } + constness } pub(super) fn lower_safety(&self, s: Safety, default: hir::Safety) -> hir::Safety { diff --git a/compiler/rustc_attr_parsing/src/attributes/semantics.rs b/compiler/rustc_attr_parsing/src/attributes/semantics.rs index cdcb8e95da726..fa19d51c397eb 100644 --- a/compiler/rustc_attr_parsing/src/attributes/semantics.rs +++ b/compiler/rustc_attr_parsing/src/attributes/semantics.rs @@ -23,6 +23,7 @@ impl NoArgsAttributeParser for ComptimeParser { const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Fn), + Allow(Target::Impl { of_trait: false }), ]); const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcComptime; diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 9f032fa588195..60854d67ec946 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -3,7 +3,7 @@ use core::ops::ControlFlow; use rustc_ast as ast; use rustc_ast::mut_visit::MutVisitor; use rustc_ast::visit::{AssocCtxt, Visitor}; -use rustc_ast::{Attribute, HasAttrs, HasTokens, NodeId, mut_visit, visit}; +use rustc_ast::{Attribute, HasTokens, NodeId, mut_visit, visit}; use rustc_errors::PResult; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_expand::config::StripUnconfigured; @@ -67,7 +67,7 @@ fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool { } impl CfgEval<'_> { - fn configure(&mut self, node: T) -> Option { + fn configure(&mut self, node: T) -> Option { self.0.configure(node) } diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 4871e80a75645..478f5d30a255c 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -440,18 +440,6 @@ pub(crate) fn codegen_terminator_call<'tcx>( } } - if fx.tcx.symbol_name(instance).name.starts_with("llvm.") { - crate::intrinsics::codegen_llvm_intrinsic_call( - fx, - fx.tcx.symbol_name(instance).name, - args, - ret_place, - target, - source_info.span, - ); - return; - } - match instance.def { InstanceKind::Intrinsic(_) => { match crate::intrinsics::codegen_intrinsic_call( @@ -466,6 +454,17 @@ pub(crate) fn codegen_terminator_call<'tcx>( Err(instance) => Some(instance), } } + InstanceKind::LlvmIntrinsic(_) => { + crate::intrinsics::codegen_llvm_intrinsic_call( + fx, + fx.tcx.symbol_name(instance).name, + args, + ret_place, + target, + source_info.span, + ); + return; + } // We don't need AsyncDropGlueCtorShim here because it is not `noop func`, // it is `func returning noop future` InstanceKind::Shim(ShimKind::DropGlue(_, None)) => { diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index ec325319db401..028cd8c792349 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -892,12 +892,8 @@ pub fn is_call_from_compiler_builtins_to_upstream_monomorphization<'tcx>( tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, ) -> bool { - fn is_llvm_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - if let Some(name) = tcx.codegen_fn_attrs(def_id).symbol_name { - name.as_str().starts_with("llvm.") - } else { - false - } + if let ty::InstanceKind::LlvmIntrinsic(_) = instance.def { + return false; } fn is_extern_call_to_local_crate<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool { @@ -910,7 +906,6 @@ pub fn is_call_from_compiler_builtins_to_upstream_monomorphization<'tcx>( let def_id = instance.def_id(); !def_id.is_local() && tcx.is_compiler_builtins(LOCAL_CRATE) - && !is_llvm_intrinsic(tcx, def_id) && !tcx.should_codegen_locally(instance) && !is_extern_call_to_local_crate(tcx, instance) } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index ae2e6a2b14a33..cf59a0aeb24ab 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1112,8 +1112,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; if let Some(instance) = instance + && let ty::InstanceKind::LlvmIntrinsic(_) = instance.def && let Some(name) = bx.tcx().codegen_fn_attrs(instance.def_id()).symbol_name - && name.as_str().starts_with("llvm.") // This is the only LLVM intrinsic we use that unwinds // FIXME either add unwind support to codegen_llvm_intrinsic_call or replace usage of // this intrinsic with something else diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index c8e404ed3236f..15e800666129a 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -594,7 +594,7 @@ impl<'tcx> NonConstOp<'tcx> for LiveDrop<'tcx> { } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { - if self.needs_non_const_drop { + let mut err = if self.needs_non_const_drop { ccx.dcx().create_err(diagnostics::LiveDrop { span, dropped_ty: self.dropped_ty, @@ -611,7 +611,30 @@ impl<'tcx> NonConstOp<'tcx> for LiveDrop<'tcx> { }, sym::const_destruct, ) + }; + + // If the dropped type is a type parameter, suggest adding a `[const] Destruct` bound. + // The suggestion is only offered on nightly, since `[const]` bounds are unstable. + if let Param(param_ty) = self.dropped_ty.kind() + && ccx.tcx.sess.is_nightly_build() + { + let tcx = ccx.tcx; + let caller = ccx.def_id(); + if let Some(generics) = tcx.hir_node_by_def_id(caller).generics() { + let destruct_def_id = tcx.lang_items().destruct_trait(); + suggest_constraining_type_param( + tcx, + generics, + &mut err, + param_ty.name.as_str(), + "[const] Destruct", + destruct_def_id, + None, + ); + } } + + err } } diff --git a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs index 7c5f867929f04..b4f54f4c79f51 100644 --- a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs @@ -105,6 +105,16 @@ impl<'tcx> interpret::Machine<'tcx> for DummyMachine { unimplemented!() } + fn call_llvm_intrinsic( + _ecx: &mut InterpCx<'tcx, Self>, + _instance: ty::Instance<'tcx>, + _args: &[interpret::OpTy<'tcx, Self::Provenance>], + _destination: &interpret::PlaceTy<'tcx, Self::Provenance>, + _target: Option, + ) -> interpret::InterpResult<'tcx> { + unimplemented!() + } + fn assert_panic( _ecx: &mut InterpCx<'tcx, Self>, _msg: &rustc_middle::mir::AssertMessage<'tcx>, diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index c5da3253ef2c7..545a3a3ff523a 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -745,6 +745,18 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { interp_ok(None) } + fn call_llvm_intrinsic( + ecx: &mut InterpCx<'tcx, Self>, + instance: ty::Instance<'tcx>, + _args: &[OpTy<'tcx>], + _dest: &PlaceTy<'tcx, Self::Provenance>, + _target: Option, + ) -> InterpResult<'tcx> { + let intrinsic_name = ecx.tcx.codegen_fn_attrs(instance.def_id()).symbol_name.unwrap(); + + throw_unsup_format!("LLVM intrinsic `{intrinsic_name}` is not supported at compile-time"); + } + fn assert_panic( ecx: &mut InterpCx<'tcx, Self>, msg: &AssertMessage<'tcx>, diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index e2fe8c3a79690..80cd892c799cd 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -652,6 +652,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(()) } } + ty::InstanceKind::LlvmIntrinsic(_) => { + // FIXME: Should `InPlace` arguments be reset to uninit? + M::call_llvm_intrinsic( + self, + instance, + &Self::copy_fn_args(args), + destination, + target, + ) + } ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) | ty::InstanceKind::Shim(ty::ShimKind::Reify(..)) | ty::InstanceKind::Shim(ty::ShimKind::ClosureOnce { .. }) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index debcc2ac338b5..40251cbc8155b 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -247,6 +247,16 @@ pub trait Machine<'tcx>: Sized { unwind: mir::UnwindAction, ) -> InterpResult<'tcx, Option>>; + /// Directly process an LLVM intrinsic without pushing a stack frame. It is the hook's + /// responsibility to advance the instruction pointer as appropriate. + fn call_llvm_intrinsic( + ecx: &mut InterpCx<'tcx, Self>, + instance: ty::Instance<'tcx>, + args: &[OpTy<'tcx, Self::Provenance>], + destination: &PlaceTy<'tcx, Self::Provenance>, + target: Option, + ) -> InterpResult<'tcx>; + /// Check whether the given function may be executed on the current machine, in terms of the /// target features is requires. fn check_fn_target_features( diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 3127fd9b49789..b03f294c4af13 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -167,7 +167,7 @@ macro_rules! configure { } impl<'a> StripUnconfigured<'a> { - pub fn configure(&self, mut node: T) -> Option { + pub fn configure(&self, mut node: T) -> Option { self.process_cfg_attrs(&mut node); self.in_cfg(node.attrs()).then(|| { self.try_configure_tokens(&mut node); diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 783829b356369..494a6f2903a07 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -601,8 +601,6 @@ pub(crate) struct BuiltinDerefNullptr { pub label: Span, } -// FIXME: migrate fluent::lint::builtin_asm_labels - #[derive(Diagnostic)] pub(crate) enum BuiltinSpecialModuleNameUsed { #[diag("found module declaration for lib.rs")] diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 22f2d5c1afcac..56f6ac4368d5f 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -347,6 +347,7 @@ macro_rules! make_mir_visitor { ty::InstanceKind::Item(_def_id) => {} ty::InstanceKind::Intrinsic(_def_id) + | ty::InstanceKind::LlvmIntrinsic(_def_id) | ty::InstanceKind::Shim(ty::ShimKind::VTable(_def_id)) | ty::InstanceKind::Shim(ty::ShimKind::Reify(_def_id, _)) | ty::InstanceKind::Virtual(_def_id, _) diff --git a/compiler/rustc_middle/src/mono.rs b/compiler/rustc_middle/src/mono.rs index 6df67257a2ea7..bad6986a2630c 100644 --- a/compiler/rustc_middle/src/mono.rs +++ b/compiler/rustc_middle/src/mono.rs @@ -524,6 +524,7 @@ impl<'tcx> CodegenUnit<'tcx> { MonoItem::Fn(ref instance) => match instance.def { InstanceKind::Item(def) => def.as_local().map(|_| def), InstanceKind::Intrinsic(..) + | InstanceKind::LlvmIntrinsic(..) | InstanceKind::Virtual(..) | InstanceKind::Shim(ShimKind::VTable(..)) | InstanceKind::Shim(ShimKind::Reify(..)) diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index c59e71b19be78..6a04357827360 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -70,11 +70,18 @@ pub enum InstanceKind<'tcx> { /// An intrinsic `fn` item (with`#[rustc_intrinsic]`). /// - /// Alongside `Virtual`, this is the only `InstanceKind` that does not have its own callable MIR. - /// Instead, codegen and const eval "magically" evaluate calls to intrinsics purely in the - /// caller. + /// Alongside `LlvmIntrinsic` and `Virtual`, this is the only `InstanceKind` + /// that does not have its own callable MIR. Instead, codegen and const eval + /// "magically" evaluate calls to intrinsics purely in the caller. Intrinsic(DefId), + /// An LLVM intrinsic `fn` item (with `extern "unadjusted"`). + /// + /// Alongside `Intrinsic` and `Virtual`, this is the only `InstanceKind` + /// that does not have its own callable MIR. Instead, codegen and const eval + /// "magically" evaluate calls to LLVM intrinsics purely in the caller. + LlvmIntrinsic(DefId), + /// Dynamic dispatch to `::fn`. /// /// This `InstanceKind` may have a callable MIR as the default implementation. @@ -253,7 +260,8 @@ impl<'tcx> InstanceKind<'tcx> { match self { InstanceKind::Item(def_id) | InstanceKind::Virtual(def_id, _) - | InstanceKind::Intrinsic(def_id) => def_id, + | InstanceKind::Intrinsic(def_id) + | InstanceKind::LlvmIntrinsic(def_id) => def_id, InstanceKind::Shim(shim) => shim.def_id(), } } @@ -262,7 +270,9 @@ impl<'tcx> InstanceKind<'tcx> { pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option { match self { InstanceKind::Item(def) => Some(def), - InstanceKind::Virtual(..) | InstanceKind::Intrinsic(..) => None, + InstanceKind::Virtual(..) + | InstanceKind::Intrinsic(..) + | InstanceKind::LlvmIntrinsic(..) => None, InstanceKind::Shim(shim) => shim.def_id_if_not_guaranteed_local_codegen(), } } @@ -280,7 +290,9 @@ impl<'tcx> InstanceKind<'tcx> { DefPathData::Ctor | DefPathData::Closure ), InstanceKind::Shim(shim) => shim.requires_inline(), - InstanceKind::Virtual(..) | InstanceKind::Intrinsic(..) => true, + InstanceKind::Virtual(..) + | InstanceKind::Intrinsic(..) + | InstanceKind::LlvmIntrinsic(..) => true, } } @@ -308,7 +320,10 @@ impl<'tcx> InstanceKind<'tcx> { /// body should perform necessary instantiations. pub fn has_polymorphic_mir_body(&self) -> bool { match *self { - InstanceKind::Item(_) | InstanceKind::Intrinsic(..) | InstanceKind::Virtual(..) => true, + InstanceKind::Item(_) + | InstanceKind::Intrinsic(..) + | InstanceKind::LlvmIntrinsic(..) + | InstanceKind::Virtual(..) => true, InstanceKind::Shim(shim) => shim.has_polymorphic_mir_body(), } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c482e6bb87345..4c14858101bf1 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1833,7 +1833,9 @@ impl<'tcx> TyCtxt<'tcx> { _ => self.optimized_mir(def), } } - ty::InstanceKind::Intrinsic(..) => bug!("intrinsics have no instance MIR"), + ty::InstanceKind::Intrinsic(..) | ty::InstanceKind::LlvmIntrinsic(..) => { + bug!("intrinsics have no instance MIR") + } ty::InstanceKind::Virtual(..) => bug!("virtual dispatches have no instance MIR"), ty::InstanceKind::Shim(shim) => self.mir_shims(shim), }; diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index bec1ffc642769..ccdac57cc8dcd 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -368,6 +368,7 @@ impl<'tcx, P: Printer<'tcx> + std::fmt::Write> Print

for ty::Instance<'tcx> { match self.def { ty::InstanceKind::Item(_) => {} ty::InstanceKind::Intrinsic(_) => cx.write_str(" - intrinsic")?, + ty::InstanceKind::LlvmIntrinsic(_) => cx.write_str(" - LLVM intrinsic")?, ty::InstanceKind::Virtual(_, num) => cx.write_str(&format!(" - virtual#{num}"))?, ty::InstanceKind::Shim(shim) => { cx.write_str(" - ")?; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 7d7ca37ff3243..69def782bb67b 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2359,7 +2359,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { { // We only truncate types that we know are likely to be much longer than 3 chars. // There's no point in replacing `i32` or `!`. - write!(self, "...")?; + write!(self, "_")?; Ok(()) } _ => { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 3249f196cc56d..0e6aaf3ccf220 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -732,7 +732,7 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>( } } // These have no own callable MIR. - InstanceKind::Intrinsic(_) | InstanceKind::Virtual(..) => { + InstanceKind::Intrinsic(_) | InstanceKind::LlvmIntrinsic(_) | InstanceKind::Virtual(..) => { debug!("instance without MIR (intrinsic / virtual)"); return Err("implementation limitation -- cannot inline intrinsic"); } diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 8c33b0930d438..22529d7fcd56f 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -21,7 +21,9 @@ fn should_recurse<'tcx>(tcx: TyCtxt<'tcx>, callee: ty::Instance<'tcx>) -> bool { } // These have no own callable MIR. - InstanceKind::Intrinsic(_) | InstanceKind::Virtual(..) => return false, + InstanceKind::Intrinsic(_) | InstanceKind::LlvmIntrinsic(_) | InstanceKind::Virtual(..) => { + return false; + } // These have MIR and if that MIR is inlined, instantiated and then inlining is run // again, a function item can end up getting inlined. Thus we'll be able to cause diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index f7c10a6ffed7c..631d28d6cef00 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1019,7 +1019,9 @@ fn visit_instance_use<'tcx>( } match instance.def { - ty::InstanceKind::Virtual(..) | ty::InstanceKind::Intrinsic(_) => { + ty::InstanceKind::Virtual(..) + | ty::InstanceKind::Intrinsic(_) + | ty::InstanceKind::LlvmIntrinsic(_) => { if !is_direct_call { bug!("{:?} being reified", instance); } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index bf4a2bdd15107..1e8e1486f107f 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -631,6 +631,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( let def_id = match instance.def { ty::InstanceKind::Item(def) => def, ty::InstanceKind::Intrinsic(..) + | ty::InstanceKind::LlvmIntrinsic(..) | ty::InstanceKind::Virtual(..) | ty::InstanceKind::Shim(ty::ShimKind::VTable(..)) | ty::InstanceKind::Shim(ty::ShimKind::Reify(..)) @@ -810,6 +811,7 @@ fn mono_item_visibility<'tcx>( | InstanceKind::Shim(ShimKind::FnPtr(..)) | InstanceKind::Virtual(..) | InstanceKind::Intrinsic(..) + | InstanceKind::LlvmIntrinsic(..) | InstanceKind::Shim(ShimKind::ClosureOnce { .. }) | InstanceKind::Shim(ShimKind::ConstructCoroutineInClosure { .. }) | InstanceKind::Shim(ShimKind::DropGlue(..)) diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index d83320f5fe800..3a98abf06a342 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -870,7 +870,7 @@ where ( RerunCondition::OpaqueInStorageOrAnyOpaqueHasInferAsHidden(_), TypingMode::PostAnalysis | TypingMode::Codegen, - ) => RerunDecision::No, + ) => RerunDecision::Yes, ( RerunCondition::OpaqueInStorageOrAnyOpaqueHasInferAsHidden(defids), TypingMode::Typeck { defining_opaque_types_and_generators: opaques }, diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index e04178645fdd8..6397fc855b86c 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -5,7 +5,7 @@ use rustc_ast::token::Token; use rustc_ast::tokenstream::{ AttrsTarget, LazyAttrTokenStream, NodeRange, ParserRange, Spacing, TokenCursor, }; -use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, HasTokens}; +use rustc_ast::{self as ast, AttrVec, Attribute, HasTokens}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::PResult; use rustc_session::parse::ParseSess; @@ -137,7 +137,7 @@ impl<'a> Parser<'a> { /// } // 32..33 /// } // 33..34 /// ``` - pub(super) fn collect_tokens( + pub(super) fn collect_tokens( &mut self, pre_attr_pos: Option, attrs: AttrWrapper, diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index ecd78fef6e142..09ac1acb74f51 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -36,9 +36,8 @@ use rustc_ast::util::case::Case; 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, - MutRestriction, Mutability, Recovered, RestrictionKind, Safety, StrLit, Visibility, - VisibilityKind, + DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, Extern, HasTokens, ImplRestriction, MutRestriction, + Mutability, Recovered, RestrictionKind, Safety, StrLit, Visibility, VisibilityKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; @@ -1662,7 +1661,7 @@ impl<'a> Parser<'a> { } } - fn collect_tokens_no_attrs( + fn collect_tokens_no_attrs( &mut self, f: impl FnOnce(&mut Self) -> PResult<'a, R>, ) -> PResult<'a, R> { diff --git a/compiler/rustc_public/src/mir/mono.rs b/compiler/rustc_public/src/mir/mono.rs index ab939a5535149..b3caee5095733 100644 --- a/compiler/rustc_public/src/mir/mono.rs +++ b/compiler/rustc_public/src/mir/mono.rs @@ -32,6 +32,8 @@ pub enum InstanceKind { Item, /// A compiler intrinsic function. Intrinsic, + /// An LLVM intrinsic function. + LlvmIntrinsic, /// A virtual function definition stored in a VTable. /// The `idx` field indicates the position in the VTable for this instance. Virtual { idx: usize }, @@ -113,7 +115,10 @@ impl Instance { InstanceKind::Intrinsic => { Some(with(|context| context.intrinsic(self.def.def_id()).unwrap().fn_name())) } - InstanceKind::Item | InstanceKind::Virtual { .. } | InstanceKind::Shim => None, + InstanceKind::LlvmIntrinsic + | InstanceKind::Item + | InstanceKind::Virtual { .. } + | InstanceKind::Shim => None, } } diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index f463507870fa7..17edd29dcbb42 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -972,6 +972,7 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> { let kind = match self.def { ty::InstanceKind::Item(..) => crate::mir::mono::InstanceKind::Item, ty::InstanceKind::Intrinsic(..) => crate::mir::mono::InstanceKind::Intrinsic, + ty::InstanceKind::LlvmIntrinsic(..) => crate::mir::mono::InstanceKind::LlvmIntrinsic, ty::InstanceKind::Virtual(_def_id, idx) => { crate::mir::mono::InstanceKind::Virtual { idx } } diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index fb44b3b9a9988..1d5c657cb6723 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -601,7 +601,8 @@ fn evaluate_host_effect_from_selection_candidate<'tcx>( match tcx.impl_trait_header(impl_.impl_def_id).constness { rustc_hir::Constness::Const { always } => { if always { - unimplemented!() + // FIXME(comptime): just bailing for now to avoid an ICE in a test. + return Err(EvaluationFailure::NoSolution); } } rustc_hir::Constness::NotConst => { diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 34a3a96f89c40..d9069ac127729 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -1,5 +1,6 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::LangItem; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; @@ -91,6 +92,12 @@ fn resolve_instance_raw<'tcx>( } else if tcx.is_async_drop_in_place_coroutine(def_id) { let ty = args.type_at(0); ty::InstanceKind::Shim(ty::ShimKind::AsyncDropGlue(def_id, ty)) + } else if tcx.def_kind(def_id) == DefKind::Fn + && let Some(name) = tcx.codegen_fn_attrs(def_id).symbol_name + && name.as_str().starts_with("llvm.") + { + debug!(" => LLVM intrinsic"); + ty::InstanceKind::LlvmIntrinsic(def_id) } else { debug!(" => free item"); ty::InstanceKind::Item(def_id) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index c050f240f2dce..3d636b689af42 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -906,16 +906,12 @@ impl [T] { #[inline] #[track_caller] pub const fn swap(&mut self, a: usize, b: usize) { - // FIXME: use swap_unchecked here (https://github.com/rust-lang/rust/pull/88540#issuecomment-944344343) - // Can't take two mutable loans from one vector, so instead use raw pointers. - let pa = &raw mut self[a]; - let pb = &raw mut self[b]; - // SAFETY: `pa` and `pb` have been created from safe mutable references and refer - // to elements in the slice and therefore are guaranteed to be valid and aligned. - // Note that accessing the elements behind `a` and `b` is checked and will - // panic when out of bounds. + // Bounds checks that panic exactly like indexing would. + let _ = &self[a]; + let _ = &self[b]; + // SAFETY: `a` and `b` were checked to be in bounds above. unsafe { - ptr::swap(pa, pb); + self.swap_unchecked(a, b); } } diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs index 2556d1897b642..d37e57e399660 100644 --- a/library/std/src/sync/once.rs +++ b/library/std/src/sync/once.rs @@ -296,6 +296,7 @@ impl Once { /// If this [`Once`] has been poisoned because an initialization closure has /// panicked, this method will also panic. Use [`wait_force`](Self::wait_force) /// if this behavior is not desired. + #[inline] #[stable(feature = "once_wait", since = "1.86.0")] #[rustc_should_not_be_called_on_const_items] pub fn wait(&self) { @@ -309,6 +310,7 @@ impl Once { /// /// If this [`Once`] has been poisoned, this function blocks until it /// becomes completed, unlike [`Once::wait()`], which panics in this case. + #[inline] #[stable(feature = "once_wait", since = "1.86.0")] #[rustc_should_not_be_called_on_const_items] pub fn wait_force(&self) { diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 9d958f7d10078..002b46cb7fbec 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -5,7 +5,7 @@ use std::path::{Path, PathBuf}; use crate::core::build_steps::compile::{ ArtifactKeepMode, add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, - std_crates_for_run_make, + std_crates_for_make_run, }; use crate::core::build_steps::tool; use crate::core::build_steps::tool::{ @@ -68,7 +68,7 @@ impl Step for Std { // Explicitly pass -p for all dependencies crates -- this will force cargo // to also check the tests/benches/examples for these crates, rather // than just the leaf crate. - let crates = std_crates_for_run_make(&run); + let crates = std_crates_for_make_run(&run); run.builder.ensure(Std { build_compiler: prepare_compiler_for_check(run.builder, run.target, Mode::Std) .build_compiler(), diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index f03ae75c4bbf2..09ccd14ab88c3 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -13,11 +13,12 @@ //! to pass a prebuilt Clippy from the outside when running `cargo clippy`, but that would be //! (as usual) a massive undertaking/refactoring. -use super::compile::{ArtifactKeepMode, run_cargo, rustc_cargo, std_cargo}; use super::tool::{SourceType, prepare_tool_cargo}; use crate::builder::{Builder, ShouldRun}; use crate::core::build_steps::check::{CompilerForCheck, prepare_compiler_for_check}; -use crate::core::build_steps::compile::std_crates_for_run_make; +use crate::core::build_steps::compile::{ + ArtifactKeepMode, run_cargo, rustc_cargo, std_cargo, std_crates_for_make_run, +}; use crate::core::builder; use crate::core::builder::{Alias, Kind, RunConfig, Step, StepMetadata, crate_description}; use crate::utils::build_stamp::{self, BuildStamp}; @@ -178,7 +179,7 @@ impl Step for Std { } fn make_run(run: RunConfig<'_>) { - let crates = std_crates_for_run_make(&run); + let crates = std_crates_for_make_run(&run); let config = LintConfig::new(run.builder); run.builder.ensure(Std::new(run.builder, run.target, config, crates)); } diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 54f93d8f72bf8..1248438e93605 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -122,7 +122,7 @@ impl Step for Std { } fn make_run(run: RunConfig<'_>) { - let crates = std_crates_for_run_make(&run); + let crates = std_crates_for_make_run(&run); let builder = run.builder; // Force compilation of the standard library from source if the `library` is modified. This allows @@ -479,9 +479,9 @@ fn copy_self_contained_objects( target_deps } -/// Resolves standard library crates for `Std::run_make` for any build kind (like check, doc, +/// Resolves standard library crates for [`Std::make_run`] for any build kind (like check, doc, /// build, clippy, etc.). -pub fn std_crates_for_run_make(run: &RunConfig<'_>) -> Vec { +pub fn std_crates_for_make_run(run: &RunConfig<'_>) -> Vec { let mut crates = run.make_run_crates(builder::Alias::Library); // For no_std targets, we only want to check core and alloc diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 0f051232757e8..847282ee62719 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -667,7 +667,7 @@ impl Step for Std { } fn make_run(run: RunConfig<'_>) { - let crates = compile::std_crates_for_run_make(&run); + let crates = compile::std_crates_for_make_run(&run); let target_is_no_std = run.builder.no_std(run.target).unwrap_or(false); if crates.is_empty() && target_is_no_std { return; diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 6b232cc039492..9ebe3191db40f 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1085,10 +1085,12 @@ impl Step for IntrinsicTest { cmd.env("CFLAGS", cflags); // intrinsic-test shells out to `cargo` and `rustfmt` make bootstrap's // managed binaries findable by prepending their dirs to PATH. - let rustfmt_path = builder.config.initial_rustfmt.clone().unwrap_or_else(|| { - eprintln!("intrinsic-test: rustfmt is required but not available on this channel"); - crate::exit!(1); - }); + let Some(rustfmt_path) = builder.config.initial_rustfmt.clone() else { + eprintln!( + "WARNING: intrinsic-test skipped because rustfmt is required but not available on this channel" + ); + return; + }; let mut path_dirs: Vec = Vec::new(); if let Some(cargo_dir) = builder.initial_cargo.parent() { diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index bc171f8fdb87c..7d7f4e6be7fc3 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -10,7 +10,7 @@ pub use self::atomic::AtomicRmwOp; use rand::RngExt; use rustc_abi::Size; use rustc_middle::{mir, ty}; -use rustc_span::Symbol; +use rustc_span::{Symbol, sym}; use self::atomic::EvalContextExt as _; use self::math::EvalContextExt as _; diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index cc6a15d3f7115..cdf7dcda2444f 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1300,6 +1300,17 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { ecx.call_intrinsic(instance, args, dest, ret, unwind) } + #[inline(always)] + fn call_llvm_intrinsic( + ecx: &mut MiriInterpCx<'tcx>, + instance: ty::Instance<'tcx>, + args: &[OpTy<'tcx>], + dest: &PlaceTy<'tcx>, + ret: Option, + ) -> InterpResult<'tcx, ()> { + ecx.call_llvm_intrinsic(instance, args, dest, ret) + } + #[inline(always)] fn assert_panic( ecx: &mut MiriInterpCx<'tcx>, diff --git a/src/tools/miri/src/shims/aarch64.rs b/src/tools/miri/src/shims/aarch64.rs index 290b8e108f3e6..afaace872b52b 100644 --- a/src/tools/miri/src/shims/aarch64.rs +++ b/src/tools/miri/src/shims/aarch64.rs @@ -13,7 +13,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); // Prefix should have already been checked. let unprefixed_name = link_name.as_str().strip_prefix("llvm.aarch64.").unwrap(); @@ -273,8 +273,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_u128(result), &dest)?; } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index a1a341ffff3e0..cef23e6648964 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -241,6 +241,109 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Some(instance) => interp_ok(Some((this.load_mir(instance.def, None)?, instance))), } } + + // FIXME move this and the LLVM intrinsic impls to the intrinsics module + fn call_llvm_intrinsic( + &mut self, + instance: ty::Instance<'tcx>, + args: &[OpTy<'tcx>], + dest: &PlaceTy<'tcx>, + ret: Option, + ) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + + let link_name = this.tcx.codegen_fn_attrs(instance.def_id()).symbol_name.unwrap(); + + // FIXME: avoid allocating memory + let dest = this.force_allocation(dest)?; + + let handled = match link_name.as_str() { + // LLVM intrinsics + "llvm.prefetch.p0" => { + let [p, rw, loc, ty] = this.check_shim_sig_unadjusted(link_name, args)?; + + let _ = this.read_pointer(p)?; + let rw = this.read_scalar(rw)?.to_i32()?; + let loc = this.read_scalar(loc)?.to_i32()?; + let ty = this.read_scalar(ty)?.to_i32()?; + + if ty == 1 { + // Data cache prefetch. + // Notably, we do not have to check the pointer, this operation is never UB! + + if !matches!(rw, 0 | 1) { + throw_unsup_format!("invalid `rw` value passed to `llvm.prefetch`: {}", rw); + } + if !matches!(loc, 0..=3) { + throw_unsup_format!( + "invalid `loc` value passed to `llvm.prefetch`: {}", + loc + ); + } + } else { + throw_unsup_format!("unsupported `llvm.prefetch` type argument: {}", ty); + } + + true + } + // Used to implement the x86 `_mm{,256,512}_popcnt_epi{8,16,32,64}` and wasm + // `{i,u}8x16_popcnt` functions. + name if name.starts_with("llvm.ctpop.v") + && this.tcx.sess.target.endian == Endian::Little => + { + let [op] = this.check_shim_sig_unadjusted(link_name, args)?; + + let (op, op_len) = this.project_to_simd(op)?; + let (dest, dest_len) = this.project_to_simd(&dest)?; + + assert_eq!(dest_len, op_len); + + for i in 0..dest_len { + let op = this.read_immediate(&this.project_index(&op, i)?)?; + // Use `to_uint` to get a zero-extended `u128`. Those + // extra zeros will not affect `count_ones`. + let res = op.to_scalar().to_uint(op.layout.size)?.count_ones(); + + this.write_scalar( + Scalar::from_uint(res, op.layout.size), + &this.project_index(&dest, i)?, + )?; + } + + true + } + + // Target-specific shims + name if name.starts_with("llvm.x86.") + && matches!(this.tcx.sess.target.arch, Arch::X86 | Arch::X86_64) + && this.tcx.sess.target.endian == Endian::Little => + shims::x86::EvalContextExt::emulate_x86_intrinsic(this, link_name, args, &dest)?, + name if name.starts_with("llvm.aarch64.") + && this.tcx.sess.target.arch == Arch::AArch64 + && this.tcx.sess.target.endian == Endian::Little => + shims::aarch64::EvalContextExt::emulate_aarch64_intrinsic( + this, link_name, args, &dest, + )?, + name if name.starts_with("llvm.loongarch.") + && matches!(this.tcx.sess.target.arch, Arch::LoongArch32 | Arch::LoongArch64) + && this.tcx.sess.target.endian == Endian::Little => + shims::loongarch::EvalContextExt::emulate_loongarch_intrinsic( + this, link_name, args, &dest, + )?, + _ => false, + }; + + // The rest either implements the logic, or falls back to `lookup_exported_symbol`. + if handled { + trace!("{:?}", this.dump_place(&dest.clone().into())); + this.return_to_block(ret) + } else { + throw_machine_stop!(TerminationInfo::UnsupportedForeignItem(format!( + "can't call LLVM intrinsic `{link_name}` on architecture `{arch}`", + arch = this.tcx.sess.target.arch, + ))); + } + } } impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} @@ -803,83 +906,6 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(ptr_dest, dest)?; } - // LLVM intrinsics - "llvm.prefetch.p0" => { - let [p, rw, loc, ty] = this.check_shim_sig_unadjusted(link_name, args)?; - - let _ = this.read_pointer(p)?; - let rw = this.read_scalar(rw)?.to_i32()?; - let loc = this.read_scalar(loc)?.to_i32()?; - let ty = this.read_scalar(ty)?.to_i32()?; - - if ty == 1 { - // Data cache prefetch. - // Notably, we do not have to check the pointer, this operation is never UB! - - if !matches!(rw, 0 | 1) { - throw_unsup_format!("invalid `rw` value passed to `llvm.prefetch`: {}", rw); - } - if !matches!(loc, 0..=3) { - throw_unsup_format!( - "invalid `loc` value passed to `llvm.prefetch`: {}", - loc - ); - } - } else { - throw_unsup_format!("unsupported `llvm.prefetch` type argument: {}", ty); - } - } - // Used to implement the x86 `_mm{,256,512}_popcnt_epi{8,16,32,64}` and wasm - // `{i,u}8x16_popcnt` functions. - name if name.starts_with("llvm.ctpop.v") - && this.tcx.sess.target.endian == Endian::Little => - { - let [op] = this.check_shim_sig_unadjusted(link_name, args)?; - - let (op, op_len) = this.project_to_simd(op)?; - let (dest, dest_len) = this.project_to_simd(dest)?; - - assert_eq!(dest_len, op_len); - - for i in 0..dest_len { - let op = this.read_immediate(&this.project_index(&op, i)?)?; - // Use `to_uint` to get a zero-extended `u128`. Those - // extra zeros will not affect `count_ones`. - let res = op.to_scalar().to_uint(op.layout.size)?.count_ones(); - - this.write_scalar( - Scalar::from_uint(res, op.layout.size), - &this.project_index(&dest, i)?, - )?; - } - } - - // Target-specific shims - name if name.starts_with("llvm.x86.") - && matches!(this.tcx.sess.target.arch, Arch::X86 | Arch::X86_64) - && this.tcx.sess.target.endian == Endian::Little => - { - return shims::x86::EvalContextExt::emulate_x86_intrinsic( - this, link_name, args, dest, - ); - } - name if name.starts_with("llvm.aarch64.") - && this.tcx.sess.target.arch == Arch::AArch64 - && this.tcx.sess.target.endian == Endian::Little => - { - return shims::aarch64::EvalContextExt::emulate_aarch64_intrinsic( - this, link_name, args, dest, - ); - } - name if name.starts_with("llvm.loongarch.") - && matches!(this.tcx.sess.target.arch, Arch::LoongArch32 | Arch::LoongArch64) - && this.tcx.sess.target.endian == Endian::Little => - { - return shims::loongarch::EvalContextExt::emulate_loongarch_intrinsic( - this, link_name, args, dest, - ); - } - // Fallback to shims in submodules. _ => { // Math shims diff --git a/src/tools/miri/src/shims/loongarch.rs b/src/tools/miri/src/shims/loongarch.rs index 461dd08dd2157..d45581c4c09f9 100644 --- a/src/tools/miri/src/shims/loongarch.rs +++ b/src/tools/miri/src/shims/loongarch.rs @@ -11,7 +11,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); // Prefix should have already been checked. let unprefixed_name = link_name.as_str().strip_prefix("llvm.loongarch.").unwrap(); @@ -67,8 +67,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = compute_crc32(crc, data, bit_size, polynomial); this.write_scalar(Scalar::from_u32(result), dest)?; } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/aesni.rs b/src/tools/miri/src/shims/x86/aesni.rs index 0ae76b62d2624..b706639c75ead 100644 --- a/src/tools/miri/src/shims/x86/aesni.rs +++ b/src/tools/miri/src/shims/x86/aesni.rs @@ -10,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); this.expect_target_feature_for_intrinsic(link_name, "aes")?; // Prefix should have already been checked. @@ -112,9 +112,9 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // TODO: Implement the `llvm.x86.aesni.aeskeygenassist` when possible // with an external crate. - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs index 25fe93a20f9db..aad278948338f 100644 --- a/src/tools/miri/src/shims/x86/avx.rs +++ b/src/tools/miri/src/shims/x86/avx.rs @@ -14,7 +14,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); this.expect_target_feature_for_intrinsic(link_name, "avx")?; // Prefix should have already been checked. @@ -243,8 +243,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // The only thing that needs to be ensured is the correct calling convention. let [] = this.check_shim_sig_unadjusted(link_name, args)?; } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index 160bce2dec98b..3ee66862cc5cf 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -14,7 +14,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); this.expect_target_feature_for_intrinsic(link_name, "avx2")?; // Prefix should have already been checked. @@ -216,8 +216,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { pmaddwd(this, left, right, dest)?; } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/avx512.rs b/src/tools/miri/src/shims/x86/avx512.rs index 6dde7558d829c..d69b1ff112753 100644 --- a/src/tools/miri/src/shims/x86/avx512.rs +++ b/src/tools/miri/src/shims/x86/avx512.rs @@ -12,7 +12,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); // Prefix should have already been checked. let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.avx512.").unwrap(); @@ -178,9 +178,9 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { packusdw(this, a, b, dest)?; } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/bmi.rs b/src/tools/miri/src/shims/x86/bmi.rs index b14d69199ab6b..4e82d7a6693fa 100644 --- a/src/tools/miri/src/shims/x86/bmi.rs +++ b/src/tools/miri/src/shims/x86/bmi.rs @@ -10,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); // Prefix should have already been checked. @@ -29,7 +29,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.expect_target_feature_for_intrinsic(link_name, target_feature)?; if is_64_bit && this.tcx.sess.target.arch != Arch::X86_64 { - return interp_ok(EmulateItemResult::NotSupported); + return interp_ok(false); } let [left, right] = this.check_shim_sig_unadjusted(link_name, args)?; @@ -92,7 +92,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } result } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), }; let result = if is_64_bit { @@ -102,6 +102,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { }; this.write_scalar(result, dest)?; - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/gfni.rs b/src/tools/miri/src/shims/x86/gfni.rs index 562d9f76ffc6e..71ba283992c62 100644 --- a/src/tools/miri/src/shims/x86/gfni.rs +++ b/src/tools/miri/src/shims/x86/gfni.rs @@ -9,7 +9,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); // Prefix should have already been checked. @@ -58,9 +58,9 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_u8(gf2p8_mul(left, right)), &dest)?; } } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index d76d35cb722bc..c320d5af9b976 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -30,7 +30,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); // Prefix should have already been checked. let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.").unwrap(); @@ -42,7 +42,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/subborrow-u32-subborrow-u64.html "addcarry.32" | "addcarry.64" | "subborrow.32" | "subborrow.64" => { if unprefixed_name.ends_with("64") && this.tcx.sess.target.arch != Arch::X86_64 { - return interp_ok(EmulateItemResult::NotSupported); + return interp_ok(false); } let [cb_in, a, b] = this.check_shim_sig_unadjusted(link_name, args)?; @@ -147,9 +147,9 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/sha.rs b/src/tools/miri/src/shims/x86/sha.rs index 982e3a08e4826..3809e23ce8bb4 100644 --- a/src/tools/miri/src/shims/x86/sha.rs +++ b/src/tools/miri/src/shims/x86/sha.rs @@ -15,7 +15,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); this.expect_target_feature_for_intrinsic(link_name, "sha")?; // Prefix should have already been checked. @@ -104,9 +104,9 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = sha256msg2(a, b); write(this, &dest, result)?; } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs index 81078bda99c8c..c6e0c7d9a7b59 100644 --- a/src/tools/miri/src/shims/x86/sse.rs +++ b/src/tools/miri/src/shims/x86/sse.rs @@ -14,7 +14,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); this.expect_target_feature_for_intrinsic(link_name, "sse")?; // Prefix should have already been checked. @@ -171,8 +171,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_immediate(*res, dest)?; } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index 2ee4d276a3af6..f0017b443d0a3 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -14,7 +14,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); this.expect_target_feature_for_intrinsic(link_name, "sse2")?; // Prefix should have already been checked. @@ -272,8 +272,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { pmaddwd(this, left, right, dest)?; } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/sse3.rs b/src/tools/miri/src/shims/x86/sse3.rs index 5890af49088df..c470ad54b20a4 100644 --- a/src/tools/miri/src/shims/x86/sse3.rs +++ b/src/tools/miri/src/shims/x86/sse3.rs @@ -9,7 +9,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); this.expect_target_feature_for_intrinsic(link_name, "sse3")?; // Prefix should have already been checked. @@ -28,8 +28,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.mem_copy(src_ptr, dest.ptr(), dest.layout.size, /*nonoverlapping*/ true)?; } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs index aee2e115a0ac5..68aa0f71160e2 100644 --- a/src/tools/miri/src/shims/x86/sse41.rs +++ b/src/tools/miri/src/shims/x86/sse41.rs @@ -10,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); this.expect_target_feature_for_intrinsic(link_name, "sse4.1")?; // Prefix should have already been checked. @@ -155,8 +155,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_i32(res.into()), dest)?; } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/sse42.rs b/src/tools/miri/src/shims/x86/sse42.rs index f6152c60f8370..af28897305bb9 100644 --- a/src/tools/miri/src/shims/x86/sse42.rs +++ b/src/tools/miri/src/shims/x86/sse42.rs @@ -279,7 +279,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); this.expect_target_feature_for_intrinsic(link_name, "sse4.2")?; // Prefix should have already been checked. @@ -428,7 +428,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { }; if bit_size == 64 && this.tcx.sess.target.arch != Arch::X86_64 { - return interp_ok(EmulateItemResult::NotSupported); + return interp_ok(false); } let [left, right] = this.check_shim_sig_unadjusted(link_name, args)?; @@ -460,8 +460,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs index 5b4746e5b1a04..dadd0cc7315a8 100644 --- a/src/tools/miri/src/shims/x86/ssse3.rs +++ b/src/tools/miri/src/shims/x86/ssse3.rs @@ -11,7 +11,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { + ) -> InterpResult<'tcx, bool> { let this = self.eval_context_mut(); this.expect_target_feature_for_intrinsic(link_name, "ssse3")?; // Prefix should have already been checked. @@ -67,8 +67,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { psign(this, left, right, dest)?; } - _ => return interp_ok(EmulateItemResult::NotSupported), + _ => return interp_ok(false), } - interp_ok(EmulateItemResult::NeedsReturn) + interp_ok(true) } } diff --git a/src/tools/rustc-perf b/src/tools/rustc-perf index dec492af8eb74..a134d7f67336c 160000 --- a/src/tools/rustc-perf +++ b/src/tools/rustc-perf @@ -1 +1 @@ -Subproject commit dec492af8eb74903879bd356648fc42d7aaf8555 +Subproject commit a134d7f67336c1178aa28b09063f86e28bb42cd6 diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 60b321641ad76..aeaea8ca9bb5b 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -242,11 +242,17 @@ const EXCEPTIONS_RUST_ANALYZER: ExceptionList = &[ const EXCEPTIONS_RUSTC_PERF: ExceptionList = &[ // tidy-alphabetical-start + ("aws-lc-rs", "ISC AND (Apache-2.0 OR ISC)"), + ( + "aws-lc-sys", + "ISC AND (Apache-2.0 OR ISC) AND Apache-2.0 AND MIT AND BSD-3-Clause AND (Apache-2.0 OR ISC OR MIT) AND (Apache-2.0 OR ISC OR MIT-0)", + ), + ("brotli", "BSD-3-Clause AND MIT"), + ("fast-srgb8", "MIT OR Apache-2.0 OR CC0-1.0"), ("inferno", "CDDL-1.0"), ("option-ext", "MPL-2.0"), - ("terminfo", "WTFPL"), ("wasite", "Apache-2.0 OR BSL-1.0 OR MIT"), - ("wezterm-bidi", "MIT AND Unicode-DFS-2016"), + ("webpki-root-certs", "CDLA-Permissive-2.0"), ("whoami", "Apache-2.0 OR BSL-1.0 OR MIT"), // tidy-alphabetical-end ]; diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index 7999386a3c298..79b562270f7ce 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -10,7 +10,7 @@ use crate::diagnostics::TidyCtx; const ALLOWED_SOURCES: &[&str] = &[ r#""registry+https://github.com/rust-lang/crates.io-index""#, // This is `rust_team_data` used by `site` in src/tools/rustc-perf, - r#""git+https://github.com/rust-lang/team#a5260e76d3aa894c64c56e6ddc8545b9a98043ec""#, + r#""git+https://github.com/rust-lang/team#db2c1ed9fbc0216e533db954cd249045c01c7406""#, ]; /// Checks for external package sources. `root` is the path to the directory that contains the diff --git a/tests/codegen-llvm/issues/rem-match-unreachable.rs b/tests/codegen-llvm/issues/rem-match-unreachable.rs new file mode 100644 index 0000000000000..cd4f0579f0a4a --- /dev/null +++ b/tests/codegen-llvm/issues/rem-match-unreachable.rs @@ -0,0 +1,32 @@ +// Matching every possible result of `x % 5` should not keep unreachable +// fallback panic code. + +//@ compile-flags: -Copt-level=3 +//@ only-64bit + +#![crate_type = "lib"] + +unsafe extern "C" { + fn rem_arm0(x: usize) -> usize; + fn rem_arm1(x: usize) -> usize; + fn rem_arm2(x: usize) -> usize; + fn rem_arm3(x: usize) -> usize; + fn rem_arm4(x: usize) -> usize; +} + +// CHECK-LABEL: @rem_match_unreachable +// CHECK-NOT: core::panicking::panic +// CHECK-NOT: entered unreachable code +#[no_mangle] +pub fn rem_match_unreachable(x: usize) -> usize { + unsafe { + match x % 5 { + 0 => rem_arm0(x), + 1 => rem_arm1(x), + 2 => rem_arm2(x), + 3 => rem_arm3(x), + 4 => rem_arm4(x), + _ => unreachable!(), + } + } +} diff --git a/tests/codegen-llvm/range-len-try-from.rs b/tests/codegen-llvm/range-len-try-from.rs index e8f204b45e81b..9e23fd67bcd9c 100644 --- a/tests/codegen-llvm/range-len-try-from.rs +++ b/tests/codegen-llvm/range-len-try-from.rs @@ -4,6 +4,7 @@ //@ compile-flags: -Copt-level=3 //@ only-64bit +//@ ignore-s390x OPT missing on s390x https://github.com/llvm/llvm-project/issues/208712 #![crate_type = "lib"] diff --git a/tests/run-make/const-destruct-stable-toolchain/const-drop-nightly.stderr b/tests/run-make/const-destruct-stable-toolchain/const-drop-nightly.stderr new file mode 100644 index 0000000000000..52f68743b6275 --- /dev/null +++ b/tests/run-make/const-destruct-stable-toolchain/const-drop-nightly.stderr @@ -0,0 +1,16 @@ +error[E0493]: destructor of `T` cannot be evaluated at compile-time + --> const-drop.rs:1:24 + | +LL | const fn const_drop(_: T) {} + | ^ - value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions + | +help: consider restricting type parameter `T` with unstable trait `Destruct` + | +LL | const fn const_drop(_: T) {} + | ++++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/run-make/const-destruct-stable-toolchain/const-drop-stable.stderr b/tests/run-make/const-destruct-stable-toolchain/const-drop-stable.stderr new file mode 100644 index 0000000000000..dc37d840658fd --- /dev/null +++ b/tests/run-make/const-destruct-stable-toolchain/const-drop-stable.stderr @@ -0,0 +1,11 @@ +error[E0493]: destructor of `T` cannot be evaluated at compile-time + --> const-drop.rs:1:24 + | +1 | const fn const_drop(_: T) {} + | ^ - value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/run-make/const-destruct-stable-toolchain/const-drop.rs b/tests/run-make/const-destruct-stable-toolchain/const-drop.rs new file mode 100644 index 0000000000000..6479498281fe5 --- /dev/null +++ b/tests/run-make/const-destruct-stable-toolchain/const-drop.rs @@ -0,0 +1,3 @@ +const fn const_drop(_: T) {} + +fn main() {} diff --git a/tests/run-make/const-destruct-stable-toolchain/rmake.rs b/tests/run-make/const-destruct-stable-toolchain/rmake.rs new file mode 100644 index 0000000000000..c1ff48b3214f0 --- /dev/null +++ b/tests/run-make/const-destruct-stable-toolchain/rmake.rs @@ -0,0 +1,26 @@ +//@ needs-target-std +// +// Test that the suggestion to constrain a type parameter that is dropped in a const +// function with a `[const] Destruct` bound is only offered on nightly, since the bound +// requires an unstable feature. + +use run_make_support::{diff, rustc}; + +fn main() { + let out = rustc() + .input("const-drop.rs") + .env("RUSTC_BOOTSTRAP", "-1") + .run_fail() + .assert_stderr_not_contains("consider restricting type parameter `T`") + .stderr_utf8(); + diff().expected_file("const-drop-stable.stderr").actual_text("(rustc)", &out).run(); + let out = rustc() + .input("const-drop.rs") + .ui_testing() + .run_fail() + .assert_stderr_contains( + "consider restricting type parameter `T` with unstable trait `Destruct`", + ) + .stderr_utf8(); + diff().expected_file("const-drop-nightly.stderr").actual_text("(rustc)", &out).run(); +} diff --git a/tests/ui/codegen/overflow-during-mono.stderr b/tests/ui/codegen/overflow-during-mono.stderr index 1559de757e7ba..4d631e255afe5 100644 --- a/tests/ui/codegen/overflow-during-mono.stderr +++ b/tests/ui/codegen/overflow-during-mono.stderr @@ -3,8 +3,8 @@ error[E0275]: overflow evaluating the requirement `for<'a> {closure@$DIR/overflo = help: consider increasing the recursion limit by adding a `#![recursion_limit = "64"]` attribute to your crate (`overflow_during_mono`) = note: required for `Filter, {closure@overflow-during-mono.rs:14:41}>` to implement `Iterator` = note: 31 redundant requirements hidden - = note: required for `Filter, ...>, ...>, ...>, ...>` to implement `Iterator` - = note: required for `Filter, ...>, ...>, ...>, ...>` to implement `IntoIterator` + = note: required for `Filter, _>, _>, _>, _>, _>` to implement `Iterator` + = note: required for `Filter, _>, _>, _>, _>, _>` to implement `IntoIterator` = note: the full name for the type has been written to '$TEST_BUILD_DIR/overflow-during-mono.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/coercion/hr_alias_normalization_leaking_vars.stderr b/tests/ui/coercion/hr_alias_normalization_leaking_vars.stderr index 54da352c65039..c549748f2d0d1 100644 --- a/tests/ui/coercion/hr_alias_normalization_leaking_vars.stderr +++ b/tests/ui/coercion/hr_alias_normalization_leaking_vars.stderr @@ -16,7 +16,7 @@ error[E0308]: mismatched types --> $DIR/hr_alias_normalization_leaking_vars.rs:34:36 | LL | LendingIterator::for_each(&(), f); - | ------------------------- ^ expected `Box`, found fn item + | ------------------------- ^ expected `Box`, found fn item | | | arguments to this function are incorrect | diff --git a/tests/ui/comptime/comptime_closure.rs b/tests/ui/comptime/comptime_closure.rs new file mode 100644 index 0000000000000..bc3d58104cbc6 --- /dev/null +++ b/tests/ui/comptime/comptime_closure.rs @@ -0,0 +1,13 @@ +#![feature(rustc_attrs, stmt_expr_attributes)] + +const _: () = { + let f = #[rustc_comptime] + //~^ ERROR: `#[rustc_comptime]` attribute cannot be used on closures + || (); + + // FIXME(comptime): closures should work, too. + f(); + //~^ ERROR: cannot call non-const closure in constants +}; + +fn main() {} diff --git a/tests/ui/comptime/comptime_closure.stderr b/tests/ui/comptime/comptime_closure.stderr new file mode 100644 index 0000000000000..602f88e64b7ad --- /dev/null +++ b/tests/ui/comptime/comptime_closure.stderr @@ -0,0 +1,20 @@ +error: `#[rustc_comptime]` attribute cannot be used on closures + --> $DIR/comptime_closure.rs:4:13 + | +LL | let f = #[rustc_comptime] + | ^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_comptime]` can be applied to functions, inherent impl blocks, and inherent methods + +error[E0015]: cannot call non-const closure in constants + --> $DIR/comptime_closure.rs:9:5 + | +LL | f(); + | ^^^ + | + = note: closures need an RFC before allowed to be called in constants + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/comptime/comptime_impl.rs b/tests/ui/comptime/comptime_impl.rs new file mode 100644 index 0000000000000..6e8768aaed109 --- /dev/null +++ b/tests/ui/comptime/comptime_impl.rs @@ -0,0 +1,35 @@ +#![feature(rustc_attrs, const_trait_impl)] + +const trait Foo { + fn foo(&self); + + fn bar(&self) {} +} + +struct Bar; + +#[rustc_comptime] +impl Bar { + fn boo(&self) {} +} + +#[rustc_comptime] +//~^ ERROR: cannot be used on trait impl +impl Foo for Bar { + fn foo(&self) { + comptime_fn(); + } +} + +#[rustc_comptime] +fn comptime_fn() {} + +const _: () = { + Bar.boo(); + Bar.foo(); + //~^ ERROR: `Bar: const Foo` is not satisfied + Bar.bar(); + //~^ ERROR: `Bar: const Foo` is not satisfied +}; + +fn main() {} diff --git a/tests/ui/comptime/comptime_impl.stderr b/tests/ui/comptime/comptime_impl.stderr new file mode 100644 index 0000000000000..25f5e878b57f6 --- /dev/null +++ b/tests/ui/comptime/comptime_impl.stderr @@ -0,0 +1,33 @@ +error: `#[rustc_comptime]` attribute cannot be used on trait impl blocks + --> $DIR/comptime_impl.rs:16:1 + | +LL | #[rustc_comptime] + | ^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_comptime]` can be applied to functions and inherent impl blocks + +error[E0277]: the trait bound `Bar: const Foo` is not satisfied + --> $DIR/comptime_impl.rs:29:9 + | +LL | Bar.foo(); + | ^^^ + | +help: make the `impl` of trait `Foo` `const` + | +LL | impl const Foo for Bar { + | +++++ + +error[E0277]: the trait bound `Bar: const Foo` is not satisfied + --> $DIR/comptime_impl.rs:31:9 + | +LL | Bar.bar(); + | ^^^ + | +help: make the `impl` of trait `Foo` `const` + | +LL | impl const Foo for Bar { + | +++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/comptime/comptime_method.rs b/tests/ui/comptime/comptime_method.rs new file mode 100644 index 0000000000000..a55c950b01680 --- /dev/null +++ b/tests/ui/comptime/comptime_method.rs @@ -0,0 +1,17 @@ +#![feature(rustc_attrs)] + +struct Bar; + +#[rustc_comptime] +impl Bar { + fn boo(&self) {} +} + +const _: () = { + Bar.boo(); +}; + +fn main() { + Bar.boo(); + //~^ ERROR: comptime fns can only be called at compile time +} diff --git a/tests/ui/comptime/comptime_method.stderr b/tests/ui/comptime/comptime_method.stderr new file mode 100644 index 0000000000000..f188ab7e4be58 --- /dev/null +++ b/tests/ui/comptime/comptime_method.stderr @@ -0,0 +1,8 @@ +error: comptime fns can only be called at compile time + --> $DIR/comptime_method.rs:15:5 + | +LL | Bar.boo(); + | ^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/comptime/comptime_method_bounds.rs b/tests/ui/comptime/comptime_method_bounds.rs new file mode 100644 index 0000000000000..993fd28abd1f1 --- /dev/null +++ b/tests/ui/comptime/comptime_method_bounds.rs @@ -0,0 +1,24 @@ +//@check-pass + +#![feature(rustc_attrs, const_trait_impl)] + +struct Bar(T); + +const trait Trait { + fn method(&self) {} +} + +#[rustc_comptime] +impl Bar { + fn boo(&self) { + self.0.method() + } +} + +const impl Trait for () {} + +const _: () = { + Bar(()).boo(); +}; + +fn main() {} diff --git a/tests/ui/comptime/comptime_trait.rs b/tests/ui/comptime/comptime_trait.rs new file mode 100644 index 0000000000000..6f7b601149191 --- /dev/null +++ b/tests/ui/comptime/comptime_trait.rs @@ -0,0 +1,32 @@ +#![feature(rustc_attrs, const_trait_impl, trait_alias)] + +#[rustc_comptime] +//~^ ERROR: `#[rustc_comptime]` attribute cannot be used on traits +trait Trait { + fn method(&self) {} +} + +const impl Trait for () {} + +#[rustc_comptime] +//~^ ERROR: `#[rustc_comptime]` attribute cannot be used on trait impl +impl Trait for u32 { + fn method(&self) { + comptime_fn(); + } +} + +#[rustc_comptime] +fn comptime_fn() {} + +#[rustc_comptime] +//~^ ERROR: `#[rustc_comptime]` attribute cannot be used on trait aliases +trait TraitAlias = const Trait; + +#[rustc_comptime] +fn func(t: &T) { + t.method() + //~^ ERROR: cannot call non-const method `::method` in constants +} + +fn main() {} diff --git a/tests/ui/comptime/comptime_trait.stderr b/tests/ui/comptime/comptime_trait.stderr new file mode 100644 index 0000000000000..8e9272e238fe1 --- /dev/null +++ b/tests/ui/comptime/comptime_trait.stderr @@ -0,0 +1,35 @@ +error: `#[rustc_comptime]` attribute cannot be used on traits + --> $DIR/comptime_trait.rs:3:1 + | +LL | #[rustc_comptime] + | ^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_comptime]` can be applied to functions and inherent impl blocks + +error: `#[rustc_comptime]` attribute cannot be used on trait impl blocks + --> $DIR/comptime_trait.rs:11:1 + | +LL | #[rustc_comptime] + | ^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_comptime]` can be applied to functions and inherent impl blocks + +error: `#[rustc_comptime]` attribute cannot be used on trait aliases + --> $DIR/comptime_trait.rs:22:1 + | +LL | #[rustc_comptime] + | ^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_comptime]` can be applied to functions and inherent impl blocks + +error[E0015]: cannot call non-const method `::method` in constants + --> $DIR/comptime_trait.rs:28:7 + | +LL | t.method() + | ^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/comptime/trait_comptime.stderr b/tests/ui/comptime/trait_comptime.stderr index 06e982288471d..0ff981e290b17 100644 --- a/tests/ui/comptime/trait_comptime.stderr +++ b/tests/ui/comptime/trait_comptime.stderr @@ -4,7 +4,7 @@ error: `#[rustc_comptime]` attribute cannot be used on required trait methods LL | #[rustc_comptime] | ^^^^^^^^^^^^^^^^^ | - = help: `#[rustc_comptime]` can only be applied to functions with a body + = help: `#[rustc_comptime]` can be applied to functions with a body and inherent impl blocks error: `#[rustc_comptime]` attribute cannot be used on provided trait methods --> $DIR/trait_comptime.rs:8:5 @@ -12,7 +12,7 @@ error: `#[rustc_comptime]` attribute cannot be used on provided trait methods LL | #[rustc_comptime] | ^^^^^^^^^^^^^^^^^ | - = help: `#[rustc_comptime]` can be applied to functions and inherent methods + = help: `#[rustc_comptime]` can be applied to functions, inherent impl blocks, and inherent methods error: `#[rustc_comptime]` attribute cannot be used on trait methods in impl blocks --> $DIR/trait_comptime.rs:21:5 @@ -20,7 +20,7 @@ error: `#[rustc_comptime]` attribute cannot be used on trait methods in impl blo LL | #[rustc_comptime] | ^^^^^^^^^^^^^^^^^ | - = help: `#[rustc_comptime]` can be applied to functions and inherent methods + = help: `#[rustc_comptime]` can be applied to functions, inherent impl blocks, and inherent methods error: aborting due to 3 previous errors diff --git a/tests/ui/consts/min_const_fn/min_const_fn.stderr b/tests/ui/consts/min_const_fn/min_const_fn.stderr index 0e939e5121aa9..0904de2af0d46 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn.stderr +++ b/tests/ui/consts/min_const_fn/min_const_fn.stderr @@ -73,6 +73,11 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {} | ^^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions + | +help: consider restricting opaque type `impl std::fmt::Debug` with unstable trait `Destruct` + | +LL | const fn no_apit(_x: impl std::fmt::Debug + [const] Destruct) {} + | ++++++++++++++++++ error: aborting due to 9 previous errors diff --git a/tests/ui/consts/unstable-const-fn-in-libcore.stderr b/tests/ui/consts/unstable-const-fn-in-libcore.stderr index 16db7791cd849..9dcd2b0ac0326 100644 --- a/tests/ui/consts/unstable-const-fn-in-libcore.stderr +++ b/tests/ui/consts/unstable-const-fn-in-libcore.stderr @@ -6,6 +6,11 @@ LL | const fn unwrap_or_else T>(self, f: F) -> T { ... LL | } | - value is dropped here + | +help: consider further restricting type parameter `F` with unstable trait `Destruct` + | +LL | const fn unwrap_or_else T + [const] Destruct>(self, f: F) -> T { + | ++++++++++++++++++ error[E0493]: destructor of `Opt` cannot be evaluated at compile-time --> $DIR/unstable-const-fn-in-libcore.rs:19:55 diff --git a/tests/ui/diagnostic-width/E0271.ascii.stderr b/tests/ui/diagnostic-width/E0271.ascii.stderr index ad5f53e44beab..f1e9a9366925a 100644 --- a/tests/ui/diagnostic-width/E0271.ascii.stderr +++ b/tests/ui/diagnostic-width/E0271.ascii.stderr @@ -1,4 +1,4 @@ -error[E0271]: type mismatch resolving ` as Future>::Error == Foo` +error[E0271]: type mismatch resolving ` as Future>::Error == Foo` --> $DIR/E0271.rs:19:5 | LL | / Box::new( @@ -7,14 +7,14 @@ LL | | Err::<(), _>( LL | | Ok::<_, ()>( ... | LL | | ) - | |_____^ type mismatch resolving ` as Future>::Error == Foo` + | |_____^ type mismatch resolving ` as Future>::Error == Foo` | note: expected this to be `Foo` --> $DIR/E0271.rs:9:18 | LL | type Error = E; | ^ - = note: required for the cast from `Box>` to `Box<...>` + = note: required for the cast from `Box>` to `Box<_>` = note: the full name for the type has been written to '$TEST_BUILD_DIR/E0271.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/diagnostic-width/E0271.unicode.stderr b/tests/ui/diagnostic-width/E0271.unicode.stderr index 91adf83410163..ecb09c53a76c6 100644 --- a/tests/ui/diagnostic-width/E0271.unicode.stderr +++ b/tests/ui/diagnostic-width/E0271.unicode.stderr @@ -1,4 +1,4 @@ -error[E0271]: type mismatch resolving ` as Future>::Error == Foo` +error[E0271]: type mismatch resolving ` as Future>::Error == Foo` ╭▸ $DIR/E0271.rs:19:5 │ LL │ ┏ Box::new( @@ -7,14 +7,14 @@ LL │ ┃ Err::<(), _>( LL │ ┃ Ok::<_, ()>( ‡ ┃ LL │ ┃ ) - │ ┗━━━━━┛ type mismatch resolving ` as Future>::Error == Foo` + │ ┗━━━━━┛ type mismatch resolving ` as Future>::Error == Foo` ╰╴ note: expected this to be `Foo` ╭▸ $DIR/E0271.rs:9:18 │ LL │ type Error = E; │ ━ - ├ note: required for the cast from `Box>` to `Box<...>` + ├ note: required for the cast from `Box>` to `Box<_>` ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/E0271.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/diagnostic-width/binop.rs b/tests/ui/diagnostic-width/binop.rs index 9e4e837f38698..fc6e47b0fdecc 100644 --- a/tests/ui/diagnostic-width/binop.rs +++ b/tests/ui/diagnostic-width/binop.rs @@ -5,11 +5,11 @@ type C = (B, B, B, B); type D = (C, C, C, C); fn foo(x: D) { - x + x; //~ ERROR cannot add `(... + x + x; //~ ERROR cannot add `((_ } fn bar(x: D) { - !x; //~ ERROR cannot apply unary operator `!` to type `(... + !x; //~ ERROR cannot apply unary operator `!` to type `((_ } fn main() {} diff --git a/tests/ui/diagnostic-width/binop.stderr b/tests/ui/diagnostic-width/binop.stderr index 92723df5a9b35..adf168ffb06f1 100644 --- a/tests/ui/diagnostic-width/binop.stderr +++ b/tests/ui/diagnostic-width/binop.stderr @@ -1,15 +1,15 @@ -error[E0369]: cannot add `(..., ..., ..., ...)` to `(..., ..., ..., ...)` +error[E0369]: cannot add `((_, _, _, _), _, _, _)` to `((_, _, _, _), _, _, _)` --> $DIR/binop.rs:8:7 | LL | x + x; - | - ^ - (..., ..., ..., ...) + | - ^ - ((_, _, _, _), _, _, _) | | - | (..., ..., ..., ...) + | ((_, _, _, _), _, _, _) | = note: the full name for the type has been written to '$TEST_BUILD_DIR/binop.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console -error[E0600]: cannot apply unary operator `!` to type `(..., ..., ..., ...)` +error[E0600]: cannot apply unary operator `!` to type `((_, _, _, _), _, _, _)` --> $DIR/binop.rs:12:5 | LL | !x; diff --git a/tests/ui/diagnostic-width/long-E0308.ascii.stderr b/tests/ui/diagnostic-width/long-E0308.ascii.stderr index d1fdd6c443352..3acf3829c352e 100644 --- a/tests/ui/diagnostic-width/long-E0308.ascii.stderr +++ b/tests/ui/diagnostic-width/long-E0308.ascii.stderr @@ -16,10 +16,10 @@ LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok... LL | | Ok("") LL | | )))))))))))))))))))))))))))))) LL | | )))))))))))))))))))))))))))))); - | |__________________________________^ expected `Atype, i32>, i32>`, found `Result, _>, _>` + | |__________________________________^ expected `Atype, i32>, i32>`, found `Result, _>, _>` | - = note: expected struct `Atype, i32>` - found enum `Result, _>` + = note: expected struct `Atype, i32>` + found enum `Result, _>` = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console @@ -32,10 +32,10 @@ LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(... LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(""))))))) LL | | )))))))))))))))))))))))))))))) LL | | )))))))))))))))))))))))); - | |____________________________^ expected `Option>, _>>`, found `Result, _>, _>` + | |____________________________^ expected `Option>, _>>`, found `Result, _>, _>` | - = note: expected enum `Option, _>>` - found enum `Result, _>` + = note: expected enum `Option, _>>` + found enum `Result, _>` = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console @@ -50,11 +50,11 @@ LL | | Atype< ... | LL | | i32 LL | | > = (); - | | - ^^ expected `Atype, i32>, i32>`, found `()` + | | - ^^ expected `Atype, i32>, i32>`, found `()` | |_____| | expected due to this | - = note: expected struct `Atype, i32>` + = note: expected struct `Atype, i32>` found unit type `()` = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console @@ -70,10 +70,10 @@ LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(... LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(""))))))) LL | | )))))))))))))))))))))))))))))) LL | | )))))))))))))))))))))))); - | |____________________________^ expected `()`, found `Result, _>, _>` + | |____________________________^ expected `()`, found `Result, _>, _>` | = note: expected unit type `()` - found enum `Result, _>` + found enum `Result, _>` = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/diagnostic-width/long-E0308.unicode.stderr b/tests/ui/diagnostic-width/long-E0308.unicode.stderr index 69e5ca100671e..4cd09b66eee90 100644 --- a/tests/ui/diagnostic-width/long-E0308.unicode.stderr +++ b/tests/ui/diagnostic-width/long-E0308.unicode.stderr @@ -16,10 +16,10 @@ LL │ ┃ Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O… LL │ ┃ Ok("") LL │ ┃ )))))))))))))))))))))))))))))) LL │ ┃ )))))))))))))))))))))))))))))); - │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Atype, i32>, i32>`, found `Result, _>, _>` + │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Atype, i32>, i32>`, found `Result, _>, _>` │ - ├ note: expected struct `Atype, i32>` - │ found enum `Result, _>` + ├ note: expected struct `Atype, i32>` + │ found enum `Result, _>` ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console @@ -32,10 +32,10 @@ LL │ ┃ Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok… LL │ ┃ Ok(Ok(Ok(Ok(Ok(Ok(Ok(""))))))) LL │ ┃ )))))))))))))))))))))))))))))) LL │ ┃ )))))))))))))))))))))))); - │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Option>, _>>`, found `Result, _>, _>` + │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Option>, _>>`, found `Result, _>, _>` │ - ├ note: expected enum `Option, _>>` - │ found enum `Result, _>` + ├ note: expected enum `Option, _>>` + │ found enum `Result, _>` ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console @@ -50,11 +50,11 @@ LL │ │ Atype< ‡ │ LL │ │ i32 LL │ │ > = (); - │ │ │ ━━ expected `Atype, i32>, i32>`, found `()` + │ │ │ ━━ expected `Atype, i32>, i32>`, found `()` │ └─────┤ │ expected due to this │ - ├ note: expected struct `Atype, i32>` + ├ note: expected struct `Atype, i32>` │ found unit type `()` ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console @@ -70,10 +70,10 @@ LL │ ┃ Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok… LL │ ┃ Ok(Ok(Ok(Ok(Ok(Ok(Ok(""))))))) LL │ ┃ )))))))))))))))))))))))))))))) LL │ ┃ )))))))))))))))))))))))); - │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `()`, found `Result, _>, _>` + │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `()`, found `Result, _>, _>` │ ├ note: expected unit type `()` - │ found enum `Result, _>` + │ found enum `Result, _>` ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt' ╰ note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/diagnostic-width/long-E0529.rs b/tests/ui/diagnostic-width/long-E0529.rs index 4146d3be40fe0..3930c1aa303d8 100644 --- a/tests/ui/diagnostic-width/long-E0529.rs +++ b/tests/ui/diagnostic-width/long-E0529.rs @@ -7,8 +7,8 @@ type C = (B, B, B, B); type D = (C, C, C, C); fn foo(x: D) { - let [] = x; //~ ERROR expected an array or slice, found `(... - //~^ NOTE pattern cannot match with input type `(... + let [] = x; //~ ERROR expected an array or slice, found `((_ + //~^ NOTE pattern cannot match with input type `((_ } fn main() {} diff --git a/tests/ui/diagnostic-width/long-E0529.stderr b/tests/ui/diagnostic-width/long-E0529.stderr index e5b82b592712f..bd0ba90fa930e 100644 --- a/tests/ui/diagnostic-width/long-E0529.stderr +++ b/tests/ui/diagnostic-width/long-E0529.stderr @@ -1,8 +1,8 @@ -error[E0529]: expected an array or slice, found `(..., ..., ..., ...)` +error[E0529]: expected an array or slice, found `((_, _, _, _), _, _, _)` --> $DIR/long-E0529.rs:10:9 | LL | let [] = x; - | ^^ pattern cannot match with input type `(..., ..., ..., ...)` + | ^^ pattern cannot match with input type `((_, _, _, _), _, _, _)` | = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0529.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/diagnostic-width/long-E0609.rs b/tests/ui/diagnostic-width/long-E0609.rs index a26d16ad12e78..d9c4417ad93cc 100644 --- a/tests/ui/diagnostic-width/long-E0609.rs +++ b/tests/ui/diagnostic-width/long-E0609.rs @@ -6,7 +6,7 @@ type C = (B, B, B, B); type D = (C, C, C, C); fn foo(x: D) { - x.field; //~ ERROR no field `field` on type `(... + x.field; //~ ERROR no field `field` on type `((_ } fn main() {} diff --git a/tests/ui/diagnostic-width/long-E0609.stderr b/tests/ui/diagnostic-width/long-E0609.stderr index 70092ea34bc13..894f7ef131eef 100644 --- a/tests/ui/diagnostic-width/long-E0609.stderr +++ b/tests/ui/diagnostic-width/long-E0609.stderr @@ -1,4 +1,4 @@ -error[E0609]: no field `field` on type `(..., ..., ..., ...)` +error[E0609]: no field `field` on type `((_, _, _, _), _, _, _)` --> $DIR/long-E0609.rs:9:7 | LL | x.field; diff --git a/tests/ui/diagnostic-width/long-E0614.rs b/tests/ui/diagnostic-width/long-E0614.rs index 5e8b3324dd17d..81e1a5cb4a4c3 100644 --- a/tests/ui/diagnostic-width/long-E0614.rs +++ b/tests/ui/diagnostic-width/long-E0614.rs @@ -6,7 +6,7 @@ type C = (B, B, B, B); type D = (C, C, C, C); fn foo(x: D) { - *x; //~ ERROR type `(... + *x; //~ ERROR type `((_ } fn main() {} diff --git a/tests/ui/diagnostic-width/long-E0614.stderr b/tests/ui/diagnostic-width/long-E0614.stderr index 18da20da9453e..16c2f0f567a32 100644 --- a/tests/ui/diagnostic-width/long-E0614.stderr +++ b/tests/ui/diagnostic-width/long-E0614.stderr @@ -1,4 +1,4 @@ -error[E0614]: type `(..., ..., ..., ...)` cannot be dereferenced +error[E0614]: type `((_, _, _, _), _, _, _)` cannot be dereferenced --> $DIR/long-E0614.rs:9:5 | LL | *x; diff --git a/tests/ui/diagnostic-width/long-E0618.rs b/tests/ui/diagnostic-width/long-E0618.rs index 247061d17f836..c6ee331ba2387 100644 --- a/tests/ui/diagnostic-width/long-E0618.rs +++ b/tests/ui/diagnostic-width/long-E0618.rs @@ -6,8 +6,8 @@ type B = (A, A, A, A); type C = (B, B, B, B); type D = (C, C, C, C); -fn foo(x: D) { //~ NOTE `x` has type `(... - x(); //~ ERROR expected function, found `(... +fn foo(x: D) { //~ NOTE `x` has type `((_ + x(); //~ ERROR expected function, found `((_ } fn main() {} diff --git a/tests/ui/diagnostic-width/long-E0618.stderr b/tests/ui/diagnostic-width/long-E0618.stderr index 7d92b94faf8fe..2a2d13db35332 100644 --- a/tests/ui/diagnostic-width/long-E0618.stderr +++ b/tests/ui/diagnostic-width/long-E0618.stderr @@ -1,8 +1,8 @@ -error[E0618]: expected function, found `(..., ..., ..., ...)` +error[E0618]: expected function, found `((_, _, _, _), _, _, _)` --> $DIR/long-E0618.rs:10:5 | LL | fn foo(x: D) { - | - `x` has type `(..., ..., ..., ...)` + | - `x` has type `((_, _, _, _), _, _, _)` LL | x(); | ^-- | | diff --git a/tests/ui/diagnostic-width/long-e0277.rs b/tests/ui/diagnostic-width/long-e0277.rs index 369fd8daea78c..7c6a3f56c313f 100644 --- a/tests/ui/diagnostic-width/long-e0277.rs +++ b/tests/ui/diagnostic-width/long-e0277.rs @@ -9,5 +9,5 @@ trait Trait {} fn require_trait() {} fn main() { - require_trait::(); //~ ERROR the trait bound `(... + require_trait::(); //~ ERROR the trait bound `((_ } diff --git a/tests/ui/diagnostic-width/long-e0277.stderr b/tests/ui/diagnostic-width/long-e0277.stderr index ff8971511653c..130ff1228aa7d 100644 --- a/tests/ui/diagnostic-width/long-e0277.stderr +++ b/tests/ui/diagnostic-width/long-e0277.stderr @@ -1,10 +1,10 @@ -error[E0277]: the trait bound `(..., ..., ..., ...): Trait` is not satisfied +error[E0277]: the trait bound `((_, _, _, _), _, _, _): Trait` is not satisfied --> $DIR/long-e0277.rs:12:21 | LL | require_trait::(); | ^ unsatisfied trait bound | - = help: the trait `Trait` is not implemented for `(..., ..., ..., ...)` + = help: the trait `Trait` is not implemented for `((_, _, _, _), _, _, _)` help: this trait has no implementations, consider adding one --> $DIR/long-e0277.rs:7:1 | diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.stderr b/tests/ui/diagnostic-width/non-copy-type-moved.stderr index 16c01c858b7d0..a9b7685299e8e 100644 --- a/tests/ui/diagnostic-width/non-copy-type-moved.stderr +++ b/tests/ui/diagnostic-width/non-copy-type-moved.stderr @@ -2,7 +2,7 @@ error[E0382]: use of moved value: `x` --> $DIR/non-copy-type-moved.rs:14:14 | LL | fn foo(x: D) { - | - move occurs because `x` has type `(..., ..., ..., ...)`, which does not implement the `Copy` trait + | - move occurs because `x` has type `((_, _, _, _), _, _, _)`, which does not implement the `Copy` trait LL | let _a = x; | - value moved here LL | let _b = x; diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs index 13fe967ba5f8c..c72ab77dfffd4 100644 --- a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs +++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs @@ -7,8 +7,8 @@ type D = (C, C, C, C); fn foo(x: D) { let () = x; //~ ERROR mismatched types - //~^ NOTE this expression has type `((..., - //~| NOTE expected `((..., + //~^ NOTE this expression has type `(((_, + //~| NOTE expected `(((_, //~| NOTE expected tuple //~| NOTE the full name for the type has been written to //~| NOTE consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr index a99657ca113ff..58974cec57564 100644 --- a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr +++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr @@ -2,11 +2,11 @@ error[E0308]: mismatched types --> $DIR/secondary-label-with-long-type.rs:9:9 | LL | let () = x; - | ^^ - this expression has type `((..., ..., ..., ...), ..., ..., ...)` + | ^^ - this expression has type `(((_, _, _, _), _, _, _), _, _, _)` | | - | expected `((..., ..., ..., ...), ..., ..., ...)`, found `()` + | expected `(((_, _, _, _), _, _, _), _, _, _)`, found `()` | - = note: expected tuple `((..., ..., ..., ...), ..., ..., ...)` + = note: expected tuple `(((_, _, _, _), _, _, _), _, _, _)` found unit type `()` = note: the full name for the type has been written to '$TEST_BUILD_DIR/secondary-label-with-long-type.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr b/tests/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr index 330a40d925bb1..e8e3bfd1dd816 100644 --- a/tests/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr +++ b/tests/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr @@ -4,7 +4,7 @@ error[E0320]: overflow while adding drop-check rules for `FingerTree` LL | let ft = | ^^ | - = note: overflowed on `FingerTree>>>>>>>>>` + = note: overflowed on `FingerTree>>>>>>>>>` = note: the full name for the type has been written to '$TEST_BUILD_DIR/dropck_no_diverge_on_nonregular_1.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/error-codes/E0275.stderr b/tests/ui/error-codes/E0275.stderr index 755404c1e1698..36175f636d6fb 100644 --- a/tests/ui/error-codes/E0275.stderr +++ b/tests/ui/error-codes/E0275.stderr @@ -1,11 +1,11 @@ -error[E0275]: overflow evaluating the requirement `Bar>>>>>>: Foo` +error[E0275]: overflow evaluating the requirement `Bar>>>>>>: Foo` --> $DIR/E0275.rs:6:33 | LL | impl Foo for T where Bar: Foo {} | ^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`) -note: required for `Bar>>>>>>>>>>>>` to implement `Foo` +note: required for `Bar>>>>>>>>>>>>` to implement `Foo` --> $DIR/E0275.rs:6:9 | LL | impl Foo for T where Bar: Foo {} diff --git a/tests/ui/higher-ranked/relate-bound-region-ice-144033.rs b/tests/ui/higher-ranked/relate-bound-region-ice-144033.rs new file mode 100644 index 0000000000000..9c3c1a507a458 --- /dev/null +++ b/tests/ui/higher-ranked/relate-bound-region-ice-144033.rs @@ -0,0 +1,23 @@ +// Regression test for . +// This used to ICE with "cannot relate bound region" instead of emitting +// normal errors. + +trait FooMut { + fn bar(self, _: I) + where + for<'b> &'b I: Iterator; +} + +impl FooMut for () { + fn bar(self, _: I) + where + for<'b> &'b I: Iterator, + { + let collection = std::iter::empty::<()>().map(|_| &()); + self.bar(collection) + //~^ ERROR expected `&I` to be an iterator that yields `&()` + //~| ERROR mismatched types + } +} + +fn main() {} diff --git a/tests/ui/higher-ranked/relate-bound-region-ice-144033.stderr b/tests/ui/higher-ranked/relate-bound-region-ice-144033.stderr new file mode 100644 index 0000000000000..e9ec3e9dc0707 --- /dev/null +++ b/tests/ui/higher-ranked/relate-bound-region-ice-144033.stderr @@ -0,0 +1,53 @@ +error[E0271]: expected `&I` to be an iterator that yields `&()`, but it yields `<&I as Iterator>::Item` + --> $DIR/relate-bound-region-ice-144033.rs:17:18 + | +LL | self.bar(collection) + | --- ^^^^^^^^^^ expected `&()`, found associated type + | | + | required by a bound introduced by this call + | + = note: expected reference `&()` + found associated type `<&I as Iterator>::Item` + = help: consider constraining the associated type `<&I as Iterator>::Item` to `&()` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html +note: the method call chain might not have had the expected associated types + --> $DIR/relate-bound-region-ice-144033.rs:16:51 + | +LL | let collection = std::iter::empty::<()>().map(|_| &()); + | ------------------------ ^^^^^^^^^^^^ `Iterator::Item` is `&()` here + | | + | this expression has type `Empty<()>` +note: required by a bound in `FooMut::bar` + --> $DIR/relate-bound-region-ice-144033.rs:8:33 + | +LL | fn bar(self, _: I) + | --- required by a bound in this associated function +LL | where +LL | for<'b> &'b I: Iterator; + | ^^^^^^^^^^^^^ required by this bound in `FooMut::bar` + +error[E0308]: mismatched types + --> $DIR/relate-bound-region-ice-144033.rs:17:18 + | +LL | fn bar(self, _: I) + | - expected this type parameter +... +LL | let collection = std::iter::empty::<()>().map(|_| &()); + | --- the found closure +LL | self.bar(collection) + | --- ^^^^^^^^^^ expected type parameter `I`, found `Map, {closure@...}>` + | | + | arguments to this method are incorrect + | + = note: expected type parameter `I` + found struct `Map, {closure@$DIR/relate-bound-region-ice-144033.rs:16:55: 16:58}>` +note: method defined here + --> $DIR/relate-bound-region-ice-144033.rs:6:8 + | +LL | fn bar(self, _: I) + | ^^^ - + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0271, E0308. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr index 00a5948bdd472..716278f4036e3 100644 --- a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr @@ -11,7 +11,7 @@ LL | | ), LL | | ) { | |_- expected `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn Fn(u32) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a))` because of return type LL | f - | ^ expected `&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&...))))`, found `&dyn Fn(u32)` + | ^ expected `&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&_))))`, found `&dyn Fn(u32)` | = note: expected reference `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn Fn(u32) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a))` found reference `&dyn Fn(u32)` diff --git a/tests/ui/inference/really-long-type-in-let-binding-without-sufficient-type-info.stderr b/tests/ui/inference/really-long-type-in-let-binding-without-sufficient-type-info.stderr index 5c4a1a7582931..d697829c55c95 100644 --- a/tests/ui/inference/really-long-type-in-let-binding-without-sufficient-type-info.stderr +++ b/tests/ui/inference/really-long-type-in-let-binding-without-sufficient-type-info.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `Result<_, (((..., ..., ..., ...), ..., ..., ...), ..., ..., ...)>` +error[E0282]: type annotations needed for `Result<_, ((((i32, i32, i32, i32), _, _, _), _, _, _), _, _, _)>` --> $DIR/really-long-type-in-let-binding-without-sufficient-type-info.rs:8:9 | LL | let y = Err(x); diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs index b8ea353df9385..1abfd88b6bf41 100644 --- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs +++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs @@ -10,7 +10,7 @@ //~| ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` //~| ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` //~| ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` -//~| ERROR reached the recursion limit while instantiating ` as MyTrait>::virtualize` +//~| ERROR reached the recursion limit while instantiating ` as MyTrait>::virtualize` //@ build-fail //@ compile-flags: --diagnostic-width=100 -Zwrite-long-types-to-disk=yes diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr index deccc88e64fa5..0167841cce689 100644 --- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr +++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr @@ -17,7 +17,7 @@ error: reached the recursion limit finding the struct tail for `[u8; 256]` = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -note: the above error was encountered while instantiating `fn virtualize_my_trait::>` +note: the above error was encountered while instantiating `fn virtualize_my_trait::>` --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:38:18 | LL | unsafe { virtualize_my_trait(L, self) } @@ -45,7 +45,7 @@ error: reached the recursion limit finding the struct tail for `SomeData<256>` = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -note: the above error was encountered while instantiating `fn virtualize_my_trait::>` +note: the above error was encountered while instantiating `fn virtualize_my_trait::>` --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:38:18 | LL | unsafe { virtualize_my_trait(L, self) } @@ -73,7 +73,7 @@ error: reached the recursion limit finding the struct tail for `VirtualWrapper>` +note: the above error was encountered while instantiating `fn virtualize_my_trait::>` --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:38:18 | LL | unsafe { virtualize_my_trait(L, self) } @@ -82,7 +82,7 @@ LL | unsafe { virtualize_my_trait(L, self) } = note: the full name for the type has been written to '$TEST_BUILD_DIR/infinite-instantiation-struct-tail-ice-114484.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console -error: reached the recursion limit while instantiating ` as MyTrait>::virtualize` +error: reached the recursion limit while instantiating ` as MyTrait>::virtualize` | note: ` as MyTrait>::virtualize` defined here --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:37:5 diff --git a/tests/ui/infinite/infinite-instantiation.stderr b/tests/ui/infinite/infinite-instantiation.stderr index 3218584441290..c41d0b245b9e7 100644 --- a/tests/ui/infinite/infinite-instantiation.stderr +++ b/tests/ui/infinite/infinite-instantiation.stderr @@ -1,4 +1,4 @@ -error: reached the recursion limit while instantiating `function::>>>>` +error: reached the recursion limit while instantiating `function::>>>>` --> $DIR/infinite-instantiation.rs:22:9 | LL | function(counter - 1, t.to_option()); diff --git a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr index 835f1c6442a78..ddb4d1645af5e 100644 --- a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr +++ b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr @@ -1,4 +1,4 @@ -error: reached the recursion limit while instantiating `<(&(&(&..., ...), ...), ...) as Foo>::recurse` +error: reached the recursion limit while instantiating `<(&(&(&(&(&_, _), _), _), _), _) as Foo>::recurse` --> $DIR/issue-37311.rs:17:9 | LL | (self, self).recurse(); diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr b/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr index dee809ebf7e81..a4d208a8fc24c 100644 --- a/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr +++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr @@ -14,7 +14,7 @@ LL | impl Loop {} | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead -error[E0275]: overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>` +error[E0275]: overflow normalizing the type alias `Poly0<(((((((_,),),),),),),)>` --> $DIR/inherent-impls-overflow.rs:17:1 | LL | type Poly0 = Poly1<(T,)>; @@ -22,7 +22,7 @@ LL | type Poly0 = Poly1<(T,)>; | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead -error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>` +error[E0275]: overflow normalizing the type alias `Poly1<(((((((_,),),),),),),)>` --> $DIR/inherent-impls-overflow.rs:20:1 | LL | type Poly1 = Poly0<(T,)>; @@ -30,7 +30,7 @@ LL | type Poly1 = Poly0<(T,)>; | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead -error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>` +error[E0275]: overflow normalizing the type alias `Poly1<(((((((_,),),),),),),)>` --> $DIR/inherent-impls-overflow.rs:24:1 | LL | impl Poly0<()> {} diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.rs b/tests/ui/lazy-type-alias/inherent-impls-overflow.rs index 66a81321624b0..6ee4f6b943a22 100644 --- a/tests/ui/lazy-type-alias/inherent-impls-overflow.rs +++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.rs @@ -15,14 +15,14 @@ impl Loop {} //[next]~| ERROR overflow evaluating the requirement `Loop == _` type Poly0 = Poly1<(T,)>; -//[current]~^ ERROR overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>` +//[current]~^ ERROR overflow normalizing the type alias `Poly0<(((((((_,),),),),),),)>` //[next]~^^ ERROR overflow evaluating the requirement type Poly1 = Poly0<(T,)>; -//[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>` +//[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((_,),),),),),),)>` //[next]~^^ ERROR overflow evaluating the requirement impl Poly0<()> {} -//[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>` +//[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((_,),),),),),),)>` //[next]~^^ ERROR overflow evaluating the requirement `Poly0<()> == _` //[next]~| ERROR overflow evaluating the requirement diff --git a/tests/ui/limits/type-length-limit-enforcement.stderr b/tests/ui/limits/type-length-limit-enforcement.stderr index 82855bd755285..0313f212d3f7e 100644 --- a/tests/ui/limits/type-length-limit-enforcement.stderr +++ b/tests/ui/limits/type-length-limit-enforcement.stderr @@ -1,4 +1,4 @@ -error: reached the type-length limit while instantiating `drop::>` +error: reached the type-length limit while instantiating `drop::>` --> $DIR/type-length-limit-enforcement.rs:34:5 | LL | drop::>(None); diff --git a/tests/ui/methods/inherent-bound-in-probe.stderr b/tests/ui/methods/inherent-bound-in-probe.stderr index 6502752bcb455..8564fcaf8eac2 100644 --- a/tests/ui/methods/inherent-bound-in-probe.stderr +++ b/tests/ui/methods/inherent-bound-in-probe.stderr @@ -28,7 +28,7 @@ LL | where LL | &'a T: IntoIterator, | ------------- unsatisfied trait bound introduced here = note: 126 redundant requirements hidden - = note: required for `&BitReaderWrapper>>` to implement `IntoIterator` + = note: required for `&BitReaderWrapper>>` to implement `IntoIterator` note: required by a bound in `Helper` --> $DIR/inherent-bound-in-probe.rs:17:12 | diff --git a/tests/ui/methods/probe-error-on-infinite-deref.stderr b/tests/ui/methods/probe-error-on-infinite-deref.stderr index 6148b00116302..4d2f31499173b 100644 --- a/tests/ui/methods/probe-error-on-infinite-deref.stderr +++ b/tests/ui/methods/probe-error-on-infinite-deref.stderr @@ -1,4 +1,4 @@ -error[E0055]: reached the recursion limit while auto-dereferencing `Wrap>>>>>>>>>>` +error[E0055]: reached the recursion limit while auto-dereferencing `Wrap>>>>>>>>>>` --> $DIR/probe-error-on-infinite-deref.rs:14:13 | LL | Wrap(1).lmao(); diff --git a/tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.stderr b/tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.stderr index 225d7503a02a4..899cb3cda8591 100644 --- a/tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.stderr +++ b/tests/ui/mismatched_types/mismatch-sugg-for-shorthand-field.stderr @@ -55,7 +55,7 @@ LL | let a = async { 42 }; | ----- the found `async` block ... LL | let s = Demo { a }; - | ^ expected `Pin>`, found `async` block + | ^ expected `Pin>`, found `async` block | = note: expected struct `Pin + Send + 'static)>>` found `async` block `{async block@$DIR/mismatch-sugg-for-shorthand-field.rs:53:13: 53:18}` diff --git a/tests/ui/parallel-rustc/dyn-trait-ice-153366.stderr b/tests/ui/parallel-rustc/dyn-trait-ice-153366.stderr index ba21ace81c7eb..a9ca104c00d36 100644 --- a/tests/ui/parallel-rustc/dyn-trait-ice-153366.stderr +++ b/tests/ui/parallel-rustc/dyn-trait-ice-153366.stderr @@ -52,7 +52,7 @@ LL | fn iso(a: Fn) -> Option<_> | --------- expected `Option<_>` because of return type ... LL | Box::new(iso_un_option) - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<_>`, found `Box ... {iso_un_option::<_>}>` + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<_>`, found `Box _ {iso_un_option::<_>}>` | = note: expected enum `Option<_>` found struct `Box {type error} {iso_un_option::<_>}>` diff --git a/tests/ui/proc-macro/test-followed-by-attr-macros.rs b/tests/ui/proc-macro/test-followed-by-attr-macros.rs new file mode 100644 index 0000000000000..4f5b9801c552c --- /dev/null +++ b/tests/ui/proc-macro/test-followed-by-attr-macros.rs @@ -0,0 +1,26 @@ +//@ check-pass +//@ compile-flags: --test +//@ proc-macro: test-macros.rs +//@ edition: 2024 + +#![feature(macro_attr)] + +extern crate test_macros; + +fn main() {} + +mod proc_macro_attr { + #[test] + #[test_macros::identity_attr] + fn test() {} +} + +mod macro_rules_attr { + macro_rules! repro { + attr() { $($tt:tt)* } => { $($tt)* } + } + + #[test] + #[repro] + fn test() {} +} diff --git a/tests/ui/recursion/infinite-function-recursion-error-8727.stderr b/tests/ui/recursion/infinite-function-recursion-error-8727.stderr index 13d57ecb3b2f0..28eb26595ead5 100644 --- a/tests/ui/recursion/infinite-function-recursion-error-8727.stderr +++ b/tests/ui/recursion/infinite-function-recursion-error-8727.stderr @@ -9,7 +9,7 @@ LL | generic::>(); = help: a `loop` may express intention better if this is on purpose = note: `#[warn(unconditional_recursion)]` on by default -error: reached the recursion limit while instantiating `generic::>>>>` +error: reached the recursion limit while instantiating `generic::>>>>` --> $DIR/infinite-function-recursion-error-8727.rs:9:5 | LL | generic::>(); diff --git a/tests/ui/recursion/issue-23122-2.stderr b/tests/ui/recursion/issue-23122-2.stderr index 39cd0eb35a630..2fda276d03729 100644 --- a/tests/ui/recursion/issue-23122-2.stderr +++ b/tests/ui/recursion/issue-23122-2.stderr @@ -1,11 +1,11 @@ -error[E0275]: overflow evaluating the requirement `<<<<<<<... as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized` +error[E0275]: overflow evaluating the requirement `<<<<<<<_ as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized` --> $DIR/issue-23122-2.rs:11:17 | LL | type Next = as Next>::Next; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`) -note: required for `GetNext<<<<... as Next>::Next as Next>::Next as Next>::Next>` to implement `Next` +note: required for `GetNext<<<<_ as Next>::Next as Next>::Next as Next>::Next>` to implement `Next` --> $DIR/issue-23122-2.rs:10:15 | LL | impl Next for GetNext { diff --git a/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr b/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr index cf3bc4578a727..8eb49c49ad58e 100644 --- a/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr +++ b/tests/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr @@ -4,7 +4,7 @@ error[E0320]: overflow while adding drop-check rules for `S` LL | fn f(x: S) {} | ^ | - = note: overflowed on `S` + = note: overflowed on `S` = note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-38591-non-regular-dropck-recursion.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/recursion/issue-83150.stderr b/tests/ui/recursion/issue-83150.stderr index a245b001badef..9ec187f055018 100644 --- a/tests/ui/recursion/issue-83150.stderr +++ b/tests/ui/recursion/issue-83150.stderr @@ -15,7 +15,7 @@ error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range, = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`) = note: required for `&mut Map<&mut Range, {closure@issue-83150.rs:12:24}>` to implement `Iterator` = note: 65 redundant requirements hidden - = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut ..., ...>, ...>, ...>, ...>` to implement `Iterator` + = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<_, _>, _>, _>, _>, _>` to implement `Iterator` = note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-83150.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/recursion/recursion.stderr b/tests/ui/recursion/recursion.stderr index 974f18ed103d1..987a69767c14b 100644 --- a/tests/ui/recursion/recursion.stderr +++ b/tests/ui/recursion/recursion.stderr @@ -1,4 +1,4 @@ -error: reached the recursion limit while instantiating `test::>>>>>>` +error: reached the recursion limit while instantiating `test::>>>>>>` --> $DIR/recursion.rs:17:11 | LL | _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})} diff --git a/tests/ui/recursion/recursive-impl-trait-iterator-by-ref-67552.stderr b/tests/ui/recursion/recursive-impl-trait-iterator-by-ref-67552.stderr index 8d6d44dcbe2fb..6a01b5d8f5b79 100644 --- a/tests/ui/recursion/recursive-impl-trait-iterator-by-ref-67552.stderr +++ b/tests/ui/recursion/recursive-impl-trait-iterator-by-ref-67552.stderr @@ -1,4 +1,4 @@ -error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &mut &mut &mut ...>` +error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &mut &mut &mut _>` --> $DIR/recursive-impl-trait-iterator-by-ref-67552.rs:28:9 | LL | rec(identity(&mut it)) diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr index f217370b024b5..1b410322aacbe 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr @@ -15,6 +15,11 @@ LL | const fn get>(self: R) -> u32 { ... LL | } | - value is dropped here + | +help: consider further restricting type parameter `R` with unstable trait `Destruct` + | +LL | const fn get + [const] Destruct>(self: R) -> u32 { + | ++++++++++++++++++ error[E0801]: invalid generic `self` parameter type: `R` --> $DIR/arbitrary-self-from-method-substs-ice.rs:10:49 diff --git a/tests/ui/static/static-drop-scope.stderr b/tests/ui/static/static-drop-scope.stderr index 0fdf081e23432..84e99a3988121 100644 --- a/tests/ui/static/static-drop-scope.stderr +++ b/tests/ui/static/static-drop-scope.stderr @@ -37,6 +37,11 @@ LL | const fn const_drop(_: T) {} | ^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions + | +help: consider restricting type parameter `T` with unstable trait `Destruct` + | +LL | const fn const_drop(_: T) {} + | ++++++++++++++++++ error[E0493]: destructor of `(T, ())` cannot be evaluated at compile-time --> $DIR/static-drop-scope.rs:17:5 diff --git a/tests/ui/suggestions/box-future-wrong-output.stderr b/tests/ui/suggestions/box-future-wrong-output.stderr index bac26ae8fb5dd..39e0f3c45009b 100644 --- a/tests/ui/suggestions/box-future-wrong-output.stderr +++ b/tests/ui/suggestions/box-future-wrong-output.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/box-future-wrong-output.rs:20:39 | LL | let _: BoxFuture<'static, bool> = async {}.boxed(); - | ------------------------ ^^^^^^^^^^^^^^^^ expected `Pin>`, found `Pin + Send>>` + | ------------------------ ^^^^^^^^^^^^^^^^ expected `Pin>`, found `Pin + Send>>` | | | expected due to this | diff --git a/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr index 61a1d30d31d4a..a38aa47932b56 100644 --- a/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr +++ b/tests/ui/suggestions/expected-boxed-future-isnt-pinned.stderr @@ -5,7 +5,7 @@ LL | fn foo + Send + 'static>(x: F) -> BoxFuture<'static, | - found this type parameter ----------------------- expected `Pin + Send + 'static)>>` because of return type LL | // We could instead use an `async` block, but this way we have no std spans. LL | x - | ^ expected `Pin>`, found type parameter `F` + | ^ expected `Pin>`, found type parameter `F` | = note: expected struct `Pin + Send + 'static)>>` found type parameter `F` @@ -20,7 +20,7 @@ error[E0308]: mismatched types LL | fn bar + Send + 'static>(x: F) -> BoxFuture<'static, i32> { | ----------------------- expected `Pin + Send + 'static)>>` because of return type LL | Box::new(x) - | ^^^^^^^^^^^ expected `Pin>`, found `Box` + | ^^^^^^^^^^^ expected `Pin>`, found `Box` | = note: expected struct `Pin + Send + 'static)>>` found struct `Box` @@ -76,7 +76,7 @@ LL | fn zap() -> BoxFuture<'static, i32> { LL | / async { LL | | 42 LL | | } - | |_____^ expected `Pin>`, found `async` block + | |_____^ expected `Pin>`, found `async` block | = note: expected struct `Pin + Send + 'static)>>` found `async` block `{async block@$DIR/expected-boxed-future-isnt-pinned.rs:28:5: 28:10}` diff --git a/tests/ui/suggestions/issue-107860.stderr b/tests/ui/suggestions/issue-107860.stderr index 2bfd219398141..ab35d639c92d3 100644 --- a/tests/ui/suggestions/issue-107860.stderr +++ b/tests/ui/suggestions/issue-107860.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-107860.rs:3:36 | LL | async fn str(T: &str) -> &str { &str } - | ^^^^ expected `&str`, found `&fn(&str) -> ... {str::<_>}` + | ^^^^ expected `&str`, found `&fn(&str) -> _ {str::<_>}` | = note: expected reference `&str` found reference `&for<'a> fn(&'a str) -> impl Future {str::<_>}` diff --git a/tests/ui/trait-bounds/associated-error-bound-issue-145586.stderr b/tests/ui/trait-bounds/associated-error-bound-issue-145586.stderr index 18cfece99ffa6..4c3b1ec6c928d 100644 --- a/tests/ui/trait-bounds/associated-error-bound-issue-145586.stderr +++ b/tests/ui/trait-bounds/associated-error-bound-issue-145586.stderr @@ -8,7 +8,7 @@ LL | fn deserialize_ignored_any(self, visitor: V) -> Result>::Value, E>` because of return type ... LL | Ok(deserializer) => deserializer.deserialize_ignored_any(visitor), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Result<>::Value, E>`, found `Result<>::Value, ...>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Result<>::Value, E>`, found `Result<>::Value, _>` | = note: expected enum `Result<_, E>` found enum `Result<_, >::Error>` diff --git a/tests/ui/traits/const-traits/minicore-drop-fail.stderr b/tests/ui/traits/const-traits/minicore-drop-fail.stderr index 12d1877a18aba..2cb1256e37667 100644 --- a/tests/ui/traits/const-traits/minicore-drop-fail.stderr +++ b/tests/ui/traits/const-traits/minicore-drop-fail.stderr @@ -30,6 +30,11 @@ LL | const fn drop_arbitrary(_: T) { LL | LL | } | - value is dropped here + | +help: consider restricting type parameter `T` with trait `Destruct` + | +LL | const fn drop_arbitrary(_: T) { + | ++++++++++++++++++ error: aborting due to 4 previous errors diff --git a/tests/ui/traits/issue-68295.stderr b/tests/ui/traits/issue-68295.stderr index 8bc315302417b..aeda5e2bea4b0 100644 --- a/tests/ui/traits/issue-68295.stderr +++ b/tests/ui/traits/issue-68295.stderr @@ -5,7 +5,7 @@ LL | fn crash(input: Matrix) -> Matrix | ----------------- expected `Matrix` because of return type ... LL | input.into_owned() - | ^^^^^^^^^^^^^^^^^^ expected `Matrix`, found `Matrix` + | ^^^^^^^^^^^^^^^^^^ expected `Matrix`, found `Matrix` | = note: expected struct `Matrix<_, _, u32>` found struct `Matrix<_, _, <() as Allocator>::Buffer>` diff --git a/tests/ui/traits/issue-91949-hangs-on-recursion.stderr b/tests/ui/traits/issue-91949-hangs-on-recursion.stderr index a179107885ab2..3eff2944b472f 100644 --- a/tests/ui/traits/issue-91949-hangs-on-recursion.stderr +++ b/tests/ui/traits/issue-91949-hangs-on-recursion.stderr @@ -24,7 +24,7 @@ LL | impl> Iterator for IteratorOfWrapped { | | | unsatisfied trait bound introduced here = note: 256 redundant requirements hidden - = note: required for `IteratorOfWrapped<(), Map>, ...>>` to implement `Iterator` + = note: required for `IteratorOfWrapped<(), Map>, _>>` to implement `Iterator` = note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-91949-hangs-on-recursion.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/traits/next-solver/overflow/global-cache.stderr b/tests/ui/traits/next-solver/overflow/global-cache.stderr index 67616619384c6..de743dc00b891 100644 --- a/tests/ui/traits/next-solver/overflow/global-cache.stderr +++ b/tests/ui/traits/next-solver/overflow/global-cache.stderr @@ -1,4 +1,4 @@ -error[E0275]: overflow evaluating the requirement `Inc>>>>>>: Trait` +error[E0275]: overflow evaluating the requirement `Inc>>>>>>: Trait` --> $DIR/global-cache.rs:21:19 | LL | impls_trait::>>>>(); diff --git a/tests/ui/traits/next-solver/rerun-if-any-opaque-or-has-infer-as-hidden-in-codegen.rs b/tests/ui/traits/next-solver/rerun-if-any-opaque-or-has-infer-as-hidden-in-codegen.rs new file mode 100644 index 0000000000000..8f691ad8f4c45 --- /dev/null +++ b/tests/ui/traits/next-solver/rerun-if-any-opaque-or-has-infer-as-hidden-in-codegen.rs @@ -0,0 +1,34 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +fn mk_vec() -> Vec> { + loop {} +} + +fn parse_feature(feature: &str) -> impl Iterator { + std::iter::once(feature) +} + +fn main() { + // In `codegen_select_candidate`, we try to find an impl for `FlatMap::into_iter` + // We try to prove `FlatMap<...>: IntoIterator`. + // The blanket impl requires `FlatMap<...>: Iterator`. + // The `Iterator` impl of `FlatMap` has nested goals: + // `Projection(Fn::Output, iter::Once`. + // We normalize this goal and set rerun condition to `AnyOpaqueHasInferAsHidden` + // with reason `SelfTyInfer` because we instantiated impls with infers when + // assembling candidates for intermediate goals. + // Then we evaluate the normalized goal: + // `Projection(Fn::Output, iter::Once`. + // The alias term is normalized to rigid alias `impl Iterator` as + // we're in `TypingMode::ErasedNotCoherence`. + // But the expected term is revealed `iter::Once` thus relating failed. + // The goal fails with rerun condition `OpaqueInStorage(parse_feature::opaque)`. + // This goal should be rerun in `TypingMode::Codegen` mode, but + // `AnyOpaqueHasInferAsHidden + OpaqueInStorage = OpaqueInStorageOrAnyOpaqueHasInferAsHidden` + // which didn't trigger rerun in `TypingMode::Codegen` mode previously. + mk_vec() + .into_iter() + .flatten() + .flat_map(parse_feature).into_iter(); +} diff --git a/tests/ui/traits/on_unimplemented_long_types.stderr b/tests/ui/traits/on_unimplemented_long_types.stderr index f32d99a42b12b..0bd8591257b26 100644 --- a/tests/ui/traits/on_unimplemented_long_types.stderr +++ b/tests/ui/traits/on_unimplemented_long_types.stderr @@ -1,4 +1,4 @@ -error[E0277]: `Option>>` doesn't implement `std::fmt::Display` +error[E0277]: `Option>>` doesn't implement `std::fmt::Display` --> $DIR/on_unimplemented_long_types.rs:3:17 | LL | pub fn foo() -> impl std::fmt::Display { @@ -11,9 +11,9 @@ LL | | Some(Some(Some(Some(Some(Some(Some... ... | LL | | ))))))))))), LL | | ))))))))))) - | |_______________- return type was inferred to be `Option>>` here + | |_______________- return type was inferred to be `Option>>` here | - = help: the trait `std::fmt::Display` is not implemented for `Option>>` + = help: the trait `std::fmt::Display` is not implemented for `Option>>` = note: the full name for the type has been written to '$TEST_BUILD_DIR/on_unimplemented_long_types.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/traits/trait-impl-overflow-with-where-clause-20413.stderr b/tests/ui/traits/trait-impl-overflow-with-where-clause-20413.stderr index 72aff1b9ee8b7..b5a7e36518364 100644 --- a/tests/ui/traits/trait-impl-overflow-with-where-clause-20413.stderr +++ b/tests/ui/traits/trait-impl-overflow-with-where-clause-20413.stderr @@ -7,7 +7,7 @@ LL | struct NoData; = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead -error[E0275]: overflow evaluating the requirement `NoData>>>>>>: Foo` +error[E0275]: overflow evaluating the requirement `NoData>>>>>>: Foo` --> $DIR/trait-impl-overflow-with-where-clause-20413.rs:9:36 | LL | impl Foo for T where NoData: Foo { @@ -22,7 +22,7 @@ LL | impl Foo for T where NoData: Foo { = note: 126 redundant requirements hidden = note: required for `NoData` to implement `Foo` -error[E0275]: overflow evaluating the requirement `AlmostNoData>>>>>>: Bar` +error[E0275]: overflow evaluating the requirement `AlmostNoData>>>>>>: Bar` --> $DIR/trait-impl-overflow-with-where-clause-20413.rs:28:42 | LL | impl Bar for T where EvenLessData: Baz { @@ -42,7 +42,7 @@ LL | impl Bar for T where EvenLessData: Baz { = note: 125 redundant requirements hidden = note: required for `EvenLessData` to implement `Baz` -error[E0275]: overflow evaluating the requirement `EvenLessData>>>>>>: Baz` +error[E0275]: overflow evaluating the requirement `EvenLessData>>>>>>: Baz` --> $DIR/trait-impl-overflow-with-where-clause-20413.rs:35:42 | LL | impl Baz for T where AlmostNoData: Bar { diff --git a/tests/ui/trimmed-paths/doc-hidden.rs b/tests/ui/trimmed-paths/doc-hidden.rs index c3125385c7e41..9aca8f0cd8f9e 100644 --- a/tests/ui/trimmed-paths/doc-hidden.rs +++ b/tests/ui/trimmed-paths/doc-hidden.rs @@ -44,7 +44,7 @@ fn uses_local() { DocHiddenInHiddenMod, ) = 3u32; //~^ ERROR mismatched types [E0308] - //~| NOTE expected `(ActuallyPub, ..., ..., ..., ..., ...)`, found `u32` + //~| NOTE expected `(ActuallyPub, DocHidden, _, _, _, _)`, found `u32` //~| NOTE expected tuple `(local::ActuallyPub, DocHidden, local::pub_mod::ActuallyPubInPubMod, DocHiddenInPubMod, ActuallyPubInHiddenMod, DocHiddenInHiddenMod)` } @@ -63,6 +63,6 @@ fn uses_helper() { DocHiddenInHiddenMod, ) = 3u32; //~^ ERROR mismatched types [E0308] - //~| NOTE expected `(ActuallyPub, ..., ..., ..., ..., ...)`, found `u32` + //~| NOTE expected `(ActuallyPub, DocHidden, _, _, _, _)`, found `u32` //~| NOTE expected tuple `(doc_hidden_helper::ActuallyPub, doc_hidden_helper::DocHidden, doc_hidden_helper::pub_mod::ActuallyPubInPubMod, doc_hidden_helper::pub_mod::DocHiddenInPubMod, doc_hidden_helper::hidden_mod::ActuallyPubInHiddenMod, doc_hidden_helper::hidden_mod::DocHiddenInHiddenMod)` } diff --git a/tests/ui/trimmed-paths/doc-hidden.stderr b/tests/ui/trimmed-paths/doc-hidden.stderr index 167c92c50a357..3cf8d99422704 100644 --- a/tests/ui/trimmed-paths/doc-hidden.stderr +++ b/tests/ui/trimmed-paths/doc-hidden.stderr @@ -9,7 +9,7 @@ LL | | DocHidden, ... | LL | | DocHiddenInHiddenMod, LL | | ) = 3u32; - | | - ^^^^ expected `(ActuallyPub, ..., ..., ..., ..., ...)`, found `u32` + | | - ^^^^ expected `(ActuallyPub, DocHidden, _, _, _, _)`, found `u32` | |_____| | expected due to this | @@ -27,7 +27,7 @@ LL | | DocHidden, ... | LL | | DocHiddenInHiddenMod, LL | | ) = 3u32; - | | - ^^^^ expected `(ActuallyPub, ..., ..., ..., ..., ...)`, found `u32` + | | - ^^^^ expected `(ActuallyPub, DocHidden, _, _, _, _)`, found `u32` | |_____| | expected due to this | diff --git a/tests/ui/type-alias-impl-trait/send-bound-nested-async-95719.rs b/tests/ui/type-alias-impl-trait/send-bound-nested-async-95719.rs new file mode 100644 index 0000000000000..9f73dea641197 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/send-bound-nested-async-95719.rs @@ -0,0 +1,53 @@ +// Regression test for . +// The `Send` bound of a GAT `impl Future` was lost when the future was +// wrapped in another `async fn`, failing with "the parameter type `G` may +// not live long enough". +//@ check-pass +//@ edition: 2021 + +#![feature(impl_trait_in_assoc_type)] + +use std::future::Future; + +pub trait Get: Send + Sync { + type Ret<'a>: Future + Send + 'a + where + Self: 'a; + fn get<'a>(&'a self) -> Self::Ret<'a> + where + Self: 'a; +} + +impl Get for usize { + type Ret<'a> + = impl Future + Send + 'a + where + Self: 'a; + + fn get<'a>(&'a self) -> Self::Ret<'a> + where + Self: 'a, + { + async move { *self } + } +} + +fn is_send + Send>(_f: &F) -> bool { + true +} + +async fn wrap(g: &G) -> usize { + let fut = g.get(); + assert!(is_send(&fut)); + fut.await +} + +async fn wrap_wrap(g: &G) -> usize { + let fut = wrap(g); + assert!(is_send(&fut)); + fut.await +} + +fn main() { + let _ = wrap_wrap(&0usize); +} diff --git a/tests/ui/typeck/issue-107775.stderr b/tests/ui/typeck/issue-107775.stderr index 1be2689746941..b2878a779de93 100644 --- a/tests/ui/typeck/issue-107775.stderr +++ b/tests/ui/typeck/issue-107775.stderr @@ -6,7 +6,7 @@ LL | map.insert(1, Struct::do_something); | | | ... which causes `map` to have type `HashMap<{integer}, fn(u8) -> Pin + Send>> {::do_something::<'_>}>` LL | Self { map } - | ^^^ expected `HashMap Pin>>`, found `HashMap<{integer}, ...>` + | ^^^ expected `HashMap Pin>>`, found `HashMap<{integer}, _>` | = note: expected struct `HashMap Pin + Send + 'static)>>>` found struct `HashMap<{integer}, fn(_) -> Pin + Send>> {::do_something::<'_>}>`