From a052f2cce1df8ac5ac9fcd104c948545f8b5f2f4 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 20 Sep 2022 11:55:07 +0000 Subject: [PATCH 01/17] Add the `#[derive_const]` attribute --- .../src/cfg_accessible.rs | 1 + compiler/rustc_builtin_macros/src/derive.rs | 9 ++--- .../src/deriving/bounds.rs | 2 ++ .../src/deriving/clone.rs | 2 ++ .../src/deriving/cmp/eq.rs | 2 ++ .../src/deriving/cmp/ord.rs | 2 ++ .../src/deriving/cmp/partial_eq.rs | 2 ++ .../src/deriving/cmp/partial_ord.rs | 2 ++ .../src/deriving/debug.rs | 2 ++ .../src/deriving/decodable.rs | 2 ++ .../src/deriving/default.rs | 2 ++ .../src/deriving/encodable.rs | 2 ++ .../src/deriving/generic/mod.rs | 6 ++-- .../rustc_builtin_macros/src/deriving/hash.rs | 2 ++ .../rustc_builtin_macros/src/deriving/mod.rs | 35 ++++++++++++------- compiler/rustc_builtin_macros/src/lib.rs | 3 +- compiler/rustc_expand/src/base.rs | 4 ++- compiler/rustc_expand/src/expand.rs | 13 +++---- compiler/rustc_expand/src/proc_macro.rs | 1 + compiler/rustc_resolve/src/macros.rs | 2 +- compiler/rustc_span/src/symbol.rs | 1 + library/core/src/macros/mod.rs | 13 +++++++ library/core/src/prelude/v1.rs | 4 +++ library/std/src/prelude/v1.rs | 4 +++ src/test/ui/issues/issue-32655.stderr | 14 ++++++-- .../const_derives/derive-const-gate.rs | 4 +++ .../const_derives/derive-const-gate.stderr | 11 ++++++ .../derive-const-non-const-type.rs | 13 +++++++ .../derive-const-non-const-type.stderr | 14 ++++++++ .../const_derives/derive-const-use.rs | 19 ++++++++++ 30 files changed, 163 insertions(+), 30 deletions(-) create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs diff --git a/compiler/rustc_builtin_macros/src/cfg_accessible.rs b/compiler/rustc_builtin_macros/src/cfg_accessible.rs index cb5359dd1e27e..86df3c44eb334 100644 --- a/compiler/rustc_builtin_macros/src/cfg_accessible.rs +++ b/compiler/rustc_builtin_macros/src/cfg_accessible.rs @@ -34,6 +34,7 @@ impl MultiItemModifier for Expander { span: Span, meta_item: &ast::MetaItem, item: Annotatable, + _is_derive_const: bool, ) -> ExpandResult, Annotatable> { let template = AttributeTemplate { list: Some("path"), ..Default::default() }; let attr = &ecx.attribute(meta_item.clone()); diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index e0fb7affb3498..01f237e6ab5fa 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -10,7 +10,7 @@ use rustc_session::Session; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; -pub(crate) struct Expander; +pub(crate) struct Expander(pub bool); impl MultiItemModifier for Expander { fn expand( @@ -19,6 +19,7 @@ impl MultiItemModifier for Expander { span: Span, meta_item: &ast::MetaItem, item: Annotatable, + _: bool, ) -> ExpandResult, Annotatable> { let sess = ecx.sess; if report_bad_target(sess, &item, span) { @@ -58,20 +59,20 @@ impl MultiItemModifier for Expander { report_path_args(sess, &meta); meta.path }) - .map(|path| (path, dummy_annotatable(), None)) + .map(|path| (path, dummy_annotatable(), None, self.0)) .collect(); // Do not configure or clone items unless necessary. match &mut resolutions[..] { [] => {} - [(_, first_item, _), others @ ..] => { + [(_, first_item, ..), others @ ..] => { *first_item = cfg_eval( sess, features, item.clone(), ecx.current_expansion.lint_node_id, ); - for (_, item, _) in others { + for (_, item, _, _) in others { *item = first_item.clone(); } } diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 77e0b6c55a80e..3a5b7ecde8a9e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -12,6 +12,7 @@ pub fn expand_deriving_copy( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { let trait_def = TraitDef { span, @@ -21,6 +22,7 @@ pub fn expand_deriving_copy( supports_unions: true, methods: Vec::new(), associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push); diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index c7f2d95e72f0c..6d9be879cd19f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -14,6 +14,7 @@ pub fn expand_deriving_clone( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { // The simple form is `fn clone(&self) -> Self { *self }`, possibly with // some additional `AssertParamIsClone` assertions. @@ -86,6 +87,7 @@ pub fn expand_deriving_clone( combine_substructure: substructure, }], associated_types: Vec::new(), + is_const, }; trait_def.expand_ext(cx, mitem, item, push, is_simple) diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index 5b556c5c9b9d1..9c01314112a59 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -15,6 +15,7 @@ pub fn expand_deriving_eq( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { let span = cx.with_def_site_ctxt(span); let inline = cx.meta_word(span, sym::inline); @@ -41,6 +42,7 @@ pub fn expand_deriving_eq( })), }], associated_types: Vec::new(), + is_const, }; super::inject_impl_of_structural_trait(cx, span, item, path_std!(marker::StructuralEq), push); diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs index 7262586955811..d5c81c387834e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs @@ -13,6 +13,7 @@ pub fn expand_deriving_ord( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { let inline = cx.meta_word(span, sym::inline); let attrs = thin_vec![cx.attribute(inline)]; @@ -33,6 +34,7 @@ pub fn expand_deriving_ord( combine_substructure: combine_substructure(Box::new(|a, b, c| cs_cmp(a, b, c))), }], associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs index 42ee65b570a2a..11b838a076c6d 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs @@ -14,6 +14,7 @@ pub fn expand_deriving_partial_eq( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr { let base = true; @@ -88,6 +89,7 @@ pub fn expand_deriving_partial_eq( supports_unions: false, methods, associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) } diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs index 516892aeda96f..107a01190bb40 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -13,6 +13,7 @@ pub fn expand_deriving_partial_ord( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { let ordering_ty = Path(path_std!(cmp::Ordering)); let ret_ty = @@ -42,6 +43,7 @@ pub fn expand_deriving_partial_ord( supports_unions: false, methods: vec![partial_cmp_def], associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) } diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 4af7fd8165388..cf977c0824d8d 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -13,6 +13,7 @@ pub fn expand_deriving_debug( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { // &mut ::std::fmt::Formatter let fmtr = Ref(Box::new(Path(path_std!(fmt::Formatter))), ast::Mutability::Mut); @@ -36,6 +37,7 @@ pub fn expand_deriving_debug( })), }], associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) } diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs index 7174dbbe7ea8b..a27a068f31a27 100644 --- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs @@ -16,6 +16,7 @@ pub fn expand_deriving_rustc_decodable( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { let krate = sym::rustc_serialize; let typaram = sym::__D; @@ -54,6 +55,7 @@ pub fn expand_deriving_rustc_decodable( })), }], associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index a94c8a996e642..35b23f2f8f31a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -16,6 +16,7 @@ pub fn expand_deriving_default( mitem: &ast::MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { item.visit_with(&mut DetectNonVariantDefaultAttr { cx }); @@ -46,6 +47,7 @@ pub fn expand_deriving_default( })), }], associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) } diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs index b220e54238f46..f06cf0c56bc70 100644 --- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs @@ -100,6 +100,7 @@ pub fn expand_deriving_rustc_encodable( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { let krate = sym::rustc_serialize; let typaram = sym::__S; @@ -138,6 +139,7 @@ pub fn expand_deriving_rustc_encodable( })), }], associated_types: Vec::new(), + is_const, }; trait_def.expand(cx, mitem, item, push) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 3cc160adb5397..78dbe8e5979e2 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -171,7 +171,7 @@ use rustc_ast::{GenericArg, GenericParamKind, VariantData}; use rustc_attr as attr; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; use std::cell::RefCell; use std::iter; use std::vec; @@ -200,6 +200,8 @@ pub struct TraitDef<'a> { pub methods: Vec>, pub associated_types: Vec<(Ident, Ty)>, + + pub is_const: bool, } pub struct MethodDef<'a> { @@ -726,7 +728,7 @@ impl<'a> TraitDef<'a> { unsafety: ast::Unsafe::No, polarity: ast::ImplPolarity::Positive, defaultness: ast::Defaultness::Final, - constness: ast::Const::No, + constness: if self.is_const { ast::Const::Yes(DUMMY_SP) } else { ast::Const::No }, generics: trait_generics, of_trait: opt_trait_ref, self_ty: self_type, diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index f1f02e7ce7787..ef3da94f9e3f5 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -13,6 +13,7 @@ pub fn expand_deriving_hash( mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable), + is_const: bool, ) { let path = Path::new_(pathvec_std!(hash::Hash), vec![], PathKind::Std); @@ -38,6 +39,7 @@ pub fn expand_deriving_hash( })), }], associated_types: Vec::new(), + is_const, }; hash_trait_def.expand(cx, mitem, item, push); diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index a65d0bad6de80..5b89da91d4278 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -38,9 +38,10 @@ pub mod partial_ord; pub mod generic; -pub(crate) struct BuiltinDerive( - pub(crate) fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)), -); +pub(crate) type BuiltinDeriveFn = + fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable), bool); + +pub(crate) struct BuiltinDerive(pub(crate) BuiltinDeriveFn); impl MultiItemModifier for BuiltinDerive { fn expand( @@ -49,6 +50,7 @@ impl MultiItemModifier for BuiltinDerive { span: Span, meta_item: &MetaItem, item: Annotatable, + is_derive_const: bool, ) -> ExpandResult, Annotatable> { // FIXME: Built-in derives often forget to give spans contexts, // so we are doing it here in a centralized way. @@ -57,21 +59,28 @@ impl MultiItemModifier for BuiltinDerive { match item { Annotatable::Stmt(stmt) => { if let ast::StmtKind::Item(item) = stmt.into_inner().kind { - (self.0)(ecx, span, meta_item, &Annotatable::Item(item), &mut |a| { - // Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx' - // to the function - items.push(Annotatable::Stmt(P(ast::Stmt { - id: ast::DUMMY_NODE_ID, - kind: ast::StmtKind::Item(a.expect_item()), - span, - }))); - }); + (self.0)( + ecx, + span, + meta_item, + &Annotatable::Item(item), + &mut |a| { + // Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx' + // to the function + items.push(Annotatable::Stmt(P(ast::Stmt { + id: ast::DUMMY_NODE_ID, + kind: ast::StmtKind::Item(a.expect_item()), + span, + }))); + }, + is_derive_const, + ); } else { unreachable!("should have already errored on non-item statement") } } _ => { - (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a)); + (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a), is_derive_const); } } ExpandResult::Ready(items) diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 8aeb3b82a9cd0..ab1fcde16865f 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -97,7 +97,8 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { bench: test::expand_bench, cfg_accessible: cfg_accessible::Expander, cfg_eval: cfg_eval::expand, - derive: derive::Expander, + derive: derive::Expander(false), + derive_const: derive::Expander(true), global_allocator: global_allocator::expand, test: test::expand_test, test_case: test::expand_test_case, diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index e1da3ecdec7f4..b3d187848be9c 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -248,6 +248,7 @@ pub trait MultiItemModifier { span: Span, meta_item: &ast::MetaItem, item: Annotatable, + is_derive_const: bool, ) -> ExpandResult, Annotatable>; } @@ -261,6 +262,7 @@ where span: Span, meta_item: &ast::MetaItem, item: Annotatable, + _is_derive_const: bool, ) -> ExpandResult, Annotatable> { ExpandResult::Ready(self(ecx, span, meta_item, item)) } @@ -871,7 +873,7 @@ impl SyntaxExtension { /// Error type that denotes indeterminacy. pub struct Indeterminate; -pub type DeriveResolutions = Vec<(ast::Path, Annotatable, Option>)>; +pub type DeriveResolutions = Vec<(ast::Path, Annotatable, Option>, bool)>; pub trait ResolverExpand { fn next_node_id(&mut self) -> NodeId; diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index c2add852a0679..a63b59d31cfd9 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -319,6 +319,7 @@ pub enum InvocationKind { }, Derive { path: ast::Path, + is_const: bool, item: Annotatable, }, } @@ -460,13 +461,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> { derive_invocations.reserve(derives.len()); derives .into_iter() - .map(|(path, item, _exts)| { + .map(|(path, item, _exts, is_const)| { // FIXME: Consider using the derive resolutions (`_exts`) // instead of enqueuing the derives to be resolved again later. let expn_id = LocalExpnId::fresh_empty(); derive_invocations.push(( Invocation { - kind: InvocationKind::Derive { path, item }, + kind: InvocationKind::Derive { path, item, is_const }, fragment_kind, expansion_data: ExpansionData { id: expn_id, @@ -699,7 +700,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { SyntaxExtensionKind::LegacyAttr(expander) => { match validate_attr::parse_meta(&self.cx.sess.parse_sess, &attr) { Ok(meta) => { - let items = match expander.expand(self.cx, span, &meta, item) { + let items = match expander.expand(self.cx, span, &meta, item, false) { ExpandResult::Ready(items) => items, ExpandResult::Retry(item) => { // Reassemble the original invocation for retrying. @@ -731,19 +732,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } _ => unreachable!(), }, - InvocationKind::Derive { path, item } => match ext { + InvocationKind::Derive { path, item, is_const } => match ext { SyntaxExtensionKind::Derive(expander) | SyntaxExtensionKind::LegacyDerive(expander) => { if let SyntaxExtensionKind::Derive(..) = ext { self.gate_proc_macro_input(&item); } let meta = ast::MetaItem { kind: MetaItemKind::Word, span, path }; - let items = match expander.expand(self.cx, span, &meta, item) { + let items = match expander.expand(self.cx, span, &meta, item, is_const) { ExpandResult::Ready(items) => items, ExpandResult::Retry(item) => { // Reassemble the original invocation for retrying. return ExpandResult::Retry(Invocation { - kind: InvocationKind::Derive { path: meta.path, item }, + kind: InvocationKind::Derive { path: meta.path, item, is_const }, ..invoc }); } diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index 1a2ab9d190ebd..e9a6919206894 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -112,6 +112,7 @@ impl MultiItemModifier for DeriveProcMacro { span: Span, _meta_item: &ast::MetaItem, item: Annotatable, + _is_derive_const: bool, ) -> ExpandResult, Annotatable> { // We need special handling for statement items // (e.g. `fn foo() { #[derive(Debug)] struct Bar; }`) diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index dafa10e9e0026..8ef99e5ef968a 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -356,7 +356,7 @@ impl<'a> ResolverExpand for Resolver<'a> { has_derive_copy: false, }); let parent_scope = self.invocation_parent_scopes[&expn_id]; - for (i, (path, _, opt_ext)) in entry.resolutions.iter_mut().enumerate() { + for (i, (path, _, opt_ext, _)) in entry.resolutions.iter_mut().enumerate() { if opt_ext.is_none() { *opt_ext = Some( match self.resolve_macro_path( diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 562360130e92f..0a9570979d5af 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -614,6 +614,7 @@ symbols! { deref_mut, deref_target, derive, + derive_const, derive_default_enum, destruct, destructuring_assignment, diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index fd96e1ff77d53..e504db8143447 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1464,6 +1464,19 @@ pub(crate) mod builtin { /* compiler built-in */ } + /// Attribute macro used to apply derive macros for implementing traits + /// in a const context. + /// + /// See [the reference] for more info. + /// + /// [the reference]: ../../../reference/attributes/derive.html + #[unstable(feature = "derive_const", issue = "none")] + #[rustc_builtin_macro] + #[cfg(not(bootstrap))] + pub macro derive_const($item:item) { + /* compiler built-in */ + } + /// Attribute macro applied to a function to turn it into a unit test. /// /// See [the reference] for more info. diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index b566e211cd89d..f52c06d7eadc2 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -78,6 +78,10 @@ pub use crate::macros::builtin::{RustcDecodable, RustcEncodable}; #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] pub use crate::macros::builtin::{bench, derive, global_allocator, test, test_case}; +#[unstable(feature = "derive_const", issue = "none")] +#[cfg(not(bootstrap))] +pub use crate::macros::builtin::derive_const; + #[unstable( feature = "cfg_accessible", issue = "64797", diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index 0226c4d7a2581..93f4a17bbfca3 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -62,6 +62,10 @@ pub use core::prelude::v1::{RustcDecodable, RustcEncodable}; #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] pub use core::prelude::v1::{bench, derive, global_allocator, test, test_case}; +#[unstable(feature = "derive_const", issue = "none")] +#[cfg(not(bootstrap))] +pub use core::prelude::v1::derive_const; + // Do not `doc(no_inline)` either. #[unstable( feature = "cfg_accessible", diff --git a/src/test/ui/issues/issue-32655.stderr b/src/test/ui/issues/issue-32655.stderr index 2d9ce430a462d..5a758c7002b92 100644 --- a/src/test/ui/issues/issue-32655.stderr +++ b/src/test/ui/issues/issue-32655.stderr @@ -2,18 +2,28 @@ error: cannot find attribute `derive_Clone` in this scope --> $DIR/issue-32655.rs:3:11 | LL | #[derive_Clone] - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `derive_const` ... LL | foo!(); | ------ in this macro invocation | + ::: $SRC_DIR/core/src/macros/mod.rs:LL:COL + | +LL | pub macro derive_const($item:item) { + | ---------------------- similarly named attribute macro `derive_const` defined here + | = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find attribute `derive_Clone` in this scope --> $DIR/issue-32655.rs:15:7 | LL | #[derive_Clone] - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `derive_const` + | + ::: $SRC_DIR/core/src/macros/mod.rs:LL:COL + | +LL | pub macro derive_const($item:item) { + | ---------------------- similarly named attribute macro `derive_const` defined here error: aborting due to 2 previous errors diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs new file mode 100644 index 0000000000000..348ca0ab1906b --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs @@ -0,0 +1,4 @@ +#[derive_const(Default)] //~ ERROR use of unstable library feature +pub struct S; + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr new file mode 100644 index 0000000000000..cc9bdd2715f70 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr @@ -0,0 +1,11 @@ +error[E0658]: use of unstable library feature 'derive_const' + --> $DIR/derive-const-gate.rs:1:3 + | +LL | #[derive_const(Default)] + | ^^^^^^^^^^^^ + | + = help: add `#![feature(derive_const)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs new file mode 100644 index 0000000000000..92843a8a2da48 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs @@ -0,0 +1,13 @@ +#![feature(derive_const)] + +pub struct A; + +impl Default for A { + fn default() -> A { A } +} + +#[derive_const(Default)] +pub struct S(A); +//~^ cannot call non-const fn + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr new file mode 100644 index 0000000000000..d463c774e289e --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr @@ -0,0 +1,14 @@ +error[E0015]: cannot call non-const fn `::default` in constant functions + --> $DIR/derive-const-non-const-type.rs:10:14 + | +LL | #[derive_const(Default)] + | ------- in this derive macro expansion +LL | pub struct S(A); + | ^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0015`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs new file mode 100644 index 0000000000000..d1fbeac8598e4 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs @@ -0,0 +1,19 @@ +// check-pass +#![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)] + +pub struct A; + +impl const Default for A { + fn default() -> A { A } +} + +impl const PartialEq for A { + fn eq(&self, _: &A) -> bool { true } +} + +#[derive_const(Default, PartialEq)] +pub struct S((), A); + +const _: () = assert!(S((), A) == S::default()); + +fn main() {} From 2f7b4d91e21863cd7e9ffc24d18299db432639c5 Mon Sep 17 00:00:00 2001 From: Alex Brachet Date: Mon, 10 Oct 2022 20:13:10 +0000 Subject: [PATCH 02/17] Don't internalize __llvm_profile_counter_bias Currently, LLVM profiling runtime counter relocation cannot be used by rust during LTO because symbols are being internalized before all symbol information is known. This mode makes LLVM emit a __llvm_profile_counter_bias symbol which is referenced by the profiling initialization, which itself is pulled in by the rust driver here [1]. It is enabled with -Cllvm-args=-runtime-counter-relocation for platforms which are opt-in to this mode like Linux. On these platforms there will be no link error, rather just surprising behavior for a user which request runtime counter relocation. The profiling runtime will not see that symbol go on as if it were never there. On Fuchsia, the profiling runtime must have this symbol which will cause a hard link error. As an aside, I don't have enough context as to why rust's LTO model is how it is. AFAICT, the internalize pass is only safe to run at link time when all symbol information is actually known, this being an example as to why. I think special casing this symbol as a known one that LLVM can emit which should not have it's visbility de-escalated should be fine given how seldom this pattern of defining an undefined symbol to get initilization code pulled in is. From a quick grep, __llvm_profile_runtime is the only symbol that rustc does this for. [1] https://github.com/rust-lang/rust/blob/0265a3e93bf1b89d97cae113ed214954d5c35e22/compiler/rustc_codegen_ssa/src/back/linker.rs#L598 --- .../rustc_codegen_ssa/src/back/symbol_export.rs | 15 +++++++++++---- src/test/codegen/pgo-counter-bias.rs | 9 +++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 src/test/codegen/pgo-counter-bias.rs diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 8d7e2c5cf3939..341b28424e40b 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -212,10 +212,17 @@ fn exported_symbols_provider_local<'tcx>( // These are weak symbols that point to the profile version and the // profile name, which need to be treated as exported so LTO doesn't nix // them. - const PROFILER_WEAK_SYMBOLS: [&str; 2] = - ["__llvm_profile_raw_version", "__llvm_profile_filename"]; - - symbols.extend(PROFILER_WEAK_SYMBOLS.iter().map(|sym| { + // __llvm_profile_counter_bias is not weak, but is only referenced by the + // profiling initialization runtime, which is itself pulled in by an + // undefined reference to __llvm_profile_runtime. This happens at link time + // and thus this symbol cannot be internalized until then. + const PROFILER_DEFAULT_VIS_SYMBOLS: [&str; 3] = [ + "__llvm_profile_raw_version", + "__llvm_profile_filename", + "__llvm_profile_counter_bias", + ]; + + symbols.extend(PROFILER_DEFAULT_VIS_SYMBOLS.iter().map(|sym| { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym)); ( exported_symbol, diff --git a/src/test/codegen/pgo-counter-bias.rs b/src/test/codegen/pgo-counter-bias.rs new file mode 100644 index 0000000000000..b9019e9de7b22 --- /dev/null +++ b/src/test/codegen/pgo-counter-bias.rs @@ -0,0 +1,9 @@ +// Test that __llvm_profile_counter_bias does not get internalized by lto. + +// compile-flags: -Cprofile-generate -Cllvm-args=-runtime-counter-relocation -Clto=fat +// needs-profiler-support +// no-prefer-dynamic + +// CHECK: @__llvm_profile_counter_bias = {{.*}}global + +pub fn main() {} From 9bcc083c873be61e62446d0240a72f99d71350e0 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 7 Nov 2022 14:43:28 +0000 Subject: [PATCH 03/17] run-make-fulldeps: fix split debuginfo test Add lots of comments to this test and enable parts of the test that were added but never ran. Signed-off-by: David Wood --- .../split-debuginfo/Makefile | 160 ++++++++++++++++-- 1 file changed, 145 insertions(+), 15 deletions(-) diff --git a/src/test/run-make-fulldeps/split-debuginfo/Makefile b/src/test/run-make-fulldeps/split-debuginfo/Makefile index 1032f3408f062..a511aff4f3af2 100644 --- a/src/test/run-make-fulldeps/split-debuginfo/Makefile +++ b/src/test/run-make-fulldeps/split-debuginfo/Makefile @@ -3,7 +3,7 @@ include ../tools.mk all: off packed unpacked ifeq ($(UNAME),Darwin) -# If disabled, don't run dsymutil +# If disabled, don't run `dsymutil`. off: rm -rf $(TMPDIR)/*.dSYM $(RUSTC) foo.rs -g -C split-debuginfo=off @@ -29,98 +29,228 @@ unpacked: [ ! -d $(TMPDIR)/foo.dSYM ] else ifdef IS_WINDOWS -# Windows only supports =packed +# Windows only supports packed debuginfo - nothing to test. off: packed: unpacked: else +# Some non-Windows, non-Darwin platforms are not stable, and some are. ifeq ($(UNAME),Linux) UNSTABLEOPTS := else UNSTABLEOPTS := -Zunstable-options endif +# - Debuginfo in `.o` files +# - `.o` deleted +# - `.dwo` never created +# - `.dwp` never created off: $(RUSTC) foo.rs -g -C $(UNSTABLEOPTS) split-debuginfo=off [ ! -f $(TMPDIR)/*.dwp ] [ ! -f $(TMPDIR)/*.dwo ] - $(RUSTC) foo.rs -g [ ! -f $(TMPDIR)/*.dwp ] [ ! -f $(TMPDIR)/*.dwo ] -packed: packed-split packed-single +packed: packed-split packed-single packed-remapped packed-crosscrate +# - Debuginfo in `.dwo` files +# - `.o` deleted +# - `.dwo` deleted +# - `.dwp` present packed-split: $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=split - ls $(TMPDIR)/*.dwp - rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + rm $(TMPDIR)/foo.dwp + rm $(TMPDIR)/$(call BIN,foo) +# - Debuginfo in `.o` files +# - `.o` deleted +# - `.dwo` never created +# - `.dwp` present packed-single: $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=single - ls $(TMPDIR)/*.dwp + ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - rm -rf $(TMPDIR)/*.dwp + rm $(TMPDIR)/foo.dwp + rm $(TMPDIR)/$(call BIN,foo) packed-remapped: packed-remapped-split packed-remapped-single +# - Debuginfo in `.dwo` files +# - `.o` and binary refer to remapped `.dwo` paths which do not exist +# - `.o` deleted +# - `.dwo` deleted +# - `.dwp` present packed-remapped-split: $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \ -Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + rm $(TMPDIR)/foo.dwp + rm $(TMPDIR)/$(call BIN,foo) +# - Debuginfo in `.o` files +# - `.o` and binary refer to remapped `.o` paths which do not exist +# - `.o` deleted +# - `.dwo` never created +# - `.dwp` present packed-remapped-single: $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \ -Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + rm $(TMPDIR)/foo.dwp + rm $(TMPDIR)/$(call BIN,foo) packed-crosscrate: packed-crosscrate-split packed-crosscrate-single +# - Debuginfo in `.dwo` files +# - (bar) `.rlib` file created, contains `.dwo` +# - (bar) `.o` deleted +# - (bar) `.dwo` deleted +# - (bar) `.dwp` never created +# - (main) `.o` deleted +# - (main) `.dwo` deleted +# - (main) `.dwp` present packed-crosscrate-split: $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed \ -Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs ls $(TMPDIR)/*.rlib + ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options $(UNSTABLEOPTS) \ + $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \ -C split-debuginfo=packed -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs - rm $(TMPDIR)/*.dwo + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 rm $(TMPDIR)/main.dwp rm $(TMPDIR)/$(call BIN,main) +# - Debuginfo in `.o` files +# - (bar) `.rlib` file created, contains `.o` +# - (bar) `.o` deleted +# - (bar) `.dwo` never created +# - (bar) `.dwp` never created +# - (main) `.o` deleted +# - (main) `.dwo` never created +# - (main) `.dwp` present packed-crosscrate-single: $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed \ -Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs ls $(TMPDIR)/*.rlib + ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options $(UNSTABLEOPTS) \ + $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \ -C split-debuginfo=packed -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs + ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 rm $(TMPDIR)/main.dwp rm $(TMPDIR)/$(call BIN,main) -unpacked: unpacked-split unpacked-single unpacked-remapped-split unpacked-remapped-single +unpacked: unpacked-split unpacked-single unpacked-remapped unpacked-crosscrate +# - Debuginfo in `.dwo` files +# - `.o` deleted +# - `.dwo` present +# - `.dwp` never created unpacked-split: $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=split + ls $(TMPDIR)/*.o && exit 1 || exit 0 + rm $(TMPDIR)/*.dwo ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo - rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo + rm $(TMPDIR)/$(call BIN,foo) +# - Debuginfo in `.o` files +# - `.o` present +# - `.dwo` never created +# - `.dwp` never created unpacked-single: $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=single - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + ls $(TMPDIR)/*.o ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/$(call BIN,foo) + +unpacked-remapped: unpacked-remapped-split unpacked-remapped-single +# - Debuginfo in `.dwo` files +# - `.o` and binary refer to remapped `.dwo` paths which do not exist +# - `.o` deleted +# - `.dwo` present +# - `.dwp` never created unpacked-remapped-split: $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \ -Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 + ls $(TMPDIR)/*.o && exit 1 || exit 0 + rm $(TMPDIR)/*.dwo + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/$(call BIN,foo) +# - Debuginfo in `.o` files +# - `.o` and binary refer to remapped `.o` paths which do not exist +# - `.o` present +# - `.dwo` never created +# - `.dwp` never created unpacked-remapped-single: $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \ -Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 + ls $(TMPDIR)/*.o + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/$(call BIN,foo) + +unpacked-crosscrate: packed-crosscrate-split packed-crosscrate-single + +# - Debuginfo in `.dwo` files +# - (bar) `.rlib` file created, contains `.dwo` +# - (bar) `.o` deleted +# - (bar) `.dwo` present +# - (bar) `.dwp` never created +# - (main) `.o` deleted +# - (main) `.dwo` present +# - (main) `.dwp` never created +unpacked-crosscrate-split: + $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=unpacked \ + -Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs + ls $(TMPDIR)/*.rlib + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \ + -C split-debuginfo=unpacked -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs + ls $(TMPDIR)/*.o && exit 1 || exit 0 + rm $(TMPDIR)/*.dwo + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/$(call BIN,main) + +# - Debuginfo in `.o` files +# - (bar) `.rlib` file created, contains `.o` +# - (bar) `.o` present +# - (bar) `.dwo` never created +# - (bar) `.dwp` never created +# - (main) `.o` present +# - (main) `.dwo` never created +# - (main) `.dwp` never created +unpacked-crosscrate-single: + $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=unpacked \ + -Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs + ls $(TMPDIR)/*.rlib + ls $(TMPDIR)/*.o + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \ + -C split-debuginfo=unpacked -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs + ls $(TMPDIR)/*.o + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/$(call BIN,main) endif endif From 29dc08307dde3051ab6bf17c53f2db99e32681ee Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 7 Nov 2022 15:15:24 +0000 Subject: [PATCH 04/17] llvm: dwo only emitted when object code emitted `CompiledModule` should not think a DWARF object was emitted when a bitcode-only compilation has happened, this can confuse archive file creation (which expects to create an archive containing non-existent dwo files). Signed-off-by: David Wood --- compiler/rustc_codegen_llvm/src/back/write.rs | 16 +++++- .../split-debuginfo/Makefile | 56 ++++++++++++++++++- .../run-make-fulldeps/split-debuginfo/baz.rs | 1 + 3 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 src/test/run-make-fulldeps/split-debuginfo/baz.rs diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 11053a8f6c452..97d0de47b3a6e 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -765,11 +765,21 @@ pub(crate) unsafe fn codegen( drop(handlers); } + // `.dwo` files are only emitted if: + // + // - Object files are being emitted (i.e. bitcode only or metadata only compilations will not + // produce dwarf objects, even if otherwise enabled) + // - Target supports Split DWARF + // - Split debuginfo is enabled + // - Split DWARF kind is `split` (i.e. debuginfo is split into `.dwo` files, not different + // sections in the `.o` files). + let dwarf_object_emitted = matches!(config.emit_obj, EmitObj::ObjectCode(_)) + && cgcx.target_can_use_split_dwarf + && cgcx.split_debuginfo != SplitDebuginfo::Off + && cgcx.split_dwarf_kind == SplitDwarfKind::Split; Ok(module.into_compiled_module( config.emit_obj != EmitObj::None, - cgcx.target_can_use_split_dwarf - && cgcx.split_debuginfo != SplitDebuginfo::Off - && cgcx.split_dwarf_kind == SplitDwarfKind::Split, + dwarf_object_emitted, config.emit_bc, &cgcx.output_filenames, )) diff --git a/src/test/run-make-fulldeps/split-debuginfo/Makefile b/src/test/run-make-fulldeps/split-debuginfo/Makefile index a511aff4f3af2..1831ab38fab49 100644 --- a/src/test/run-make-fulldeps/split-debuginfo/Makefile +++ b/src/test/run-make-fulldeps/split-debuginfo/Makefile @@ -53,7 +53,7 @@ off: [ ! -f $(TMPDIR)/*.dwp ] [ ! -f $(TMPDIR)/*.dwo ] -packed: packed-split packed-single packed-remapped packed-crosscrate +packed: packed-split packed-single packed-lto packed-remapped packed-crosscrate # - Debuginfo in `.dwo` files # - `.o` deleted @@ -77,6 +77,32 @@ packed-single: rm $(TMPDIR)/foo.dwp rm $(TMPDIR)/$(call BIN,foo) +packed-lto: packed-lto-split packed-lto-single + +# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated +# - `.o` never created +# - `.dwo` never created +# - `.dwp` never created +packed-lto-split: + $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split \ + --crate-type=rlib -Clinker-plugin-lto + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/libbaz.rlib + +# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated +# - `.o` never created +# - `.dwo` never created +# - `.dwp` never created +packed-lto-single: + $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=packed -Zsplit-dwarf-kind=single \ + --crate-type=rlib -Clinker-plugin-lto + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/libbaz.rlib + packed-remapped: packed-remapped-split packed-remapped-single # - Debuginfo in `.dwo` files @@ -153,7 +179,7 @@ packed-crosscrate-single: rm $(TMPDIR)/main.dwp rm $(TMPDIR)/$(call BIN,main) -unpacked: unpacked-split unpacked-single unpacked-remapped unpacked-crosscrate +unpacked: unpacked-split unpacked-single unpacked-lto unpacked-remapped unpacked-crosscrate # - Debuginfo in `.dwo` files # - `.o` deleted @@ -177,6 +203,32 @@ unpacked-single: ls $(TMPDIR)/*.dwp && exit 1 || exit 0 rm $(TMPDIR)/$(call BIN,foo) +unpacked-lto: packed-lto-split packed-lto-single + +# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated +# - `.o` never created +# - `.dwo` never created +# - `.dwp` never created +unpacked-lto-split: + $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=split \ + --crate-type=rlib -Clinker-plugin-lto + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/libbaz.rlib + +# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated +# - `.o` never created +# - `.dwo` never created +# - `.dwp` never created +unpacked-lto-single: + $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=single \ + --crate-type=rlib -Clinker-plugin-lto + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/libbaz.rlib + unpacked-remapped: unpacked-remapped-split unpacked-remapped-single # - Debuginfo in `.dwo` files diff --git a/src/test/run-make-fulldeps/split-debuginfo/baz.rs b/src/test/run-make-fulldeps/split-debuginfo/baz.rs new file mode 100644 index 0000000000000..8b1a393741c96 --- /dev/null +++ b/src/test/run-make-fulldeps/split-debuginfo/baz.rs @@ -0,0 +1 @@ +// empty From 0e0bcd95cda4293915ecd68921320a0928cdd0bb Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Fri, 4 Nov 2022 16:27:28 +0000 Subject: [PATCH 05/17] prevent uninitialized access in black_box for zero-sized-types --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 15 +++++++-- src/test/ui/sanitize/memory-passing.rs | 32 ++++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/sanitize/memory-passing.rs diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 825011941a241..cf590a43826e5 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -340,17 +340,26 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { sym::black_box => { args[0].val.store(self, result); - + let result_val_span = [result.llval]; // We need to "use" the argument in some way LLVM can't introspect, and on // targets that support it we can typically leverage inline assembly to do // this. LLVM's interpretation of inline assembly is that it's, well, a black // box. This isn't the greatest implementation since it probably deoptimizes // more than we want, but it's so far good enough. + // + // For zero-sized types, the location pointed to by the result may be + // uninitialized. Do not "use" the result in this case; instead just clobber + // the memory. + let (constraint, inputs): (&str, &[_]) = if result.layout.is_zst() { + ("~{memory}", &[]) + } else { + ("r,~{memory}", &result_val_span) + }; crate::asm::inline_asm_call( self, "", - "r,~{memory}", - &[result.llval], + constraint, + inputs, self.type_void(), true, false, diff --git a/src/test/ui/sanitize/memory-passing.rs b/src/test/ui/sanitize/memory-passing.rs new file mode 100644 index 0000000000000..6d9b70ad6b1c2 --- /dev/null +++ b/src/test/ui/sanitize/memory-passing.rs @@ -0,0 +1,32 @@ +// needs-sanitizer-support +// needs-sanitizer-memory +// +// revisions: unoptimized optimized +// +// [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O +// [unoptimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins +// +// run-pass +// +// This test case intentionally limits the usage of the std, +// since it will be linked with an uninstrumented version of it. + +#![feature(core_intrinsics)] +#![feature(start)] +#![allow(invalid_value)] + +use std::hint::black_box; + +fn calling_black_box_on_zst_ok() { + // It's OK to call black_box on a value of a zero-sized type, even if its + // underlying the memory location is uninitialized. For non-zero-sized types, + // this would be an MSAN error. + let zst = (); + black_box(zst); +} + +#[start] +fn main(_: isize, _: *const *const u8) -> isize { + calling_black_box_on_zst_ok(); + 0 +} From 3074678cd1c9a2934ef11122b3744523083f1736 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Tue, 8 Nov 2022 02:14:02 +0800 Subject: [PATCH 06/17] Mark `trait_upcasting` feature no longer incomplete. --- compiler/rustc_feature/src/active.rs | 6 +-- src/test/ui/codegen/issue-99551.rs | 1 - src/test/ui/traits/trait-upcasting/basic.rs | 1 - .../correct-supertrait-substitution.rs | 1 - src/test/ui/traits/trait-upcasting/diamond.rs | 1 - .../traits/trait-upcasting/invalid-upcast.rs | 1 - .../trait-upcasting/invalid-upcast.stderr | 30 +++++++------- .../issue-11515-upcast-fn_mut-fn.rs | 1 - .../ui/traits/trait-upcasting/lifetime.rs | 1 - .../multiple-occurrence-ambiguousity.rs | 3 +- .../multiple-occurrence-ambiguousity.stderr | 2 +- .../ui/traits/trait-upcasting/replace-vptr.rs | 1 - src/test/ui/traits/trait-upcasting/struct.rs | 1 - .../traits/trait-upcasting/subtrait-method.rs | 1 - .../trait-upcasting/subtrait-method.stderr | 20 +++++----- .../trait-upcasting/type-checking-test-1.rs | 1 - .../type-checking-test-1.stderr | 4 +- .../trait-upcasting/type-checking-test-2.rs | 1 - .../type-checking-test-2.stderr | 8 ++-- .../type-checking-test-3.polonius.stderr | 8 +--- .../trait-upcasting/type-checking-test-3.rs | 5 +-- .../type-checking-test-3.stderr | 4 +- .../type-checking-test-4.polonius.stderr | 39 ++++++++++++++----- .../trait-upcasting/type-checking-test-4.rs | 13 +++---- .../type-checking-test-4.stderr | 12 +++--- 25 files changed, 83 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 09a747662e266..b6fe48f1bb8a1 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -510,9 +510,9 @@ declare_features! ( (active, thread_local, "1.0.0", Some(29594), None), /// Allows defining `trait X = A + B;` alias items. (active, trait_alias, "1.24.0", Some(41517), None), - /// Allows upcasting trait objects via supertraits. - /// Trait upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`. - (incomplete, trait_upcasting, "1.56.0", Some(65991), None), + /// Allows dyn upcasting trait objects via supertraits. + /// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`. + (active, trait_upcasting, "1.56.0", Some(65991), None), /// Allows #[repr(transparent)] on unions (RFC 2645). (active, transparent_unions, "1.37.0", Some(60405), None), /// Allows inconsistent bounds in where clauses. diff --git a/src/test/ui/codegen/issue-99551.rs b/src/test/ui/codegen/issue-99551.rs index f24874c992eaf..b223aff4e9492 100644 --- a/src/test/ui/codegen/issue-99551.rs +++ b/src/test/ui/codegen/issue-99551.rs @@ -1,6 +1,5 @@ // build-pass #![feature(trait_upcasting)] -#![allow(incomplete_features)] pub trait A {} pub trait B {} diff --git a/src/test/ui/traits/trait-upcasting/basic.rs b/src/test/ui/traits/trait-upcasting/basic.rs index 484a222bc012d..570ec5160bfe9 100644 --- a/src/test/ui/traits/trait-upcasting/basic.rs +++ b/src/test/ui/traits/trait-upcasting/basic.rs @@ -1,7 +1,6 @@ // run-pass #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait Foo: PartialEq + std::fmt::Debug + Send + Sync { fn a(&self) -> i32 { diff --git a/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs b/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs index 8d0a9ef0ace69..eae5cf8d58d01 100644 --- a/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs +++ b/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs @@ -1,6 +1,5 @@ // run-pass #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait Foo: Bar + Bar {} trait Bar { diff --git a/src/test/ui/traits/trait-upcasting/diamond.rs b/src/test/ui/traits/trait-upcasting/diamond.rs index e4e23c1a26e78..a4f81c464b402 100644 --- a/src/test/ui/traits/trait-upcasting/diamond.rs +++ b/src/test/ui/traits/trait-upcasting/diamond.rs @@ -1,7 +1,6 @@ // run-pass #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait Foo: PartialEq + std::fmt::Debug + Send + Sync { fn a(&self) -> i32 { diff --git a/src/test/ui/traits/trait-upcasting/invalid-upcast.rs b/src/test/ui/traits/trait-upcasting/invalid-upcast.rs index 24022450406a7..e634bbd5ac6f5 100644 --- a/src/test/ui/traits/trait-upcasting/invalid-upcast.rs +++ b/src/test/ui/traits/trait-upcasting/invalid-upcast.rs @@ -1,5 +1,4 @@ #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait Foo { fn a(&self) -> i32 { diff --git a/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr b/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr index b4530ed0c3a94..3aa21ee3dddfb 100644 --- a/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr +++ b/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:54:35 + --> $DIR/invalid-upcast.rs:53:35 | LL | let _: &dyn std::fmt::Debug = baz; | -------------------- ^^^ expected trait `Debug`, found trait `Baz` @@ -10,7 +10,7 @@ LL | let _: &dyn std::fmt::Debug = baz; found reference `&dyn Baz` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:56:24 + --> $DIR/invalid-upcast.rs:55:24 | LL | let _: &dyn Send = baz; | --------- ^^^ expected trait `Send`, found trait `Baz` @@ -21,7 +21,7 @@ LL | let _: &dyn Send = baz; found reference `&dyn Baz` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:58:24 + --> $DIR/invalid-upcast.rs:57:24 | LL | let _: &dyn Sync = baz; | --------- ^^^ expected trait `Sync`, found trait `Baz` @@ -32,7 +32,7 @@ LL | let _: &dyn Sync = baz; found reference `&dyn Baz` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:61:25 + --> $DIR/invalid-upcast.rs:60:25 | LL | let bar: &dyn Bar = baz; | -------- ^^^ expected trait `Bar`, found trait `Baz` @@ -43,7 +43,7 @@ LL | let bar: &dyn Bar = baz; found reference `&dyn Baz` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:63:35 + --> $DIR/invalid-upcast.rs:62:35 | LL | let _: &dyn std::fmt::Debug = bar; | -------------------- ^^^ expected trait `Debug`, found trait `Bar` @@ -54,7 +54,7 @@ LL | let _: &dyn std::fmt::Debug = bar; found reference `&dyn Bar` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:65:24 + --> $DIR/invalid-upcast.rs:64:24 | LL | let _: &dyn Send = bar; | --------- ^^^ expected trait `Send`, found trait `Bar` @@ -65,7 +65,7 @@ LL | let _: &dyn Send = bar; found reference `&dyn Bar` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:67:24 + --> $DIR/invalid-upcast.rs:66:24 | LL | let _: &dyn Sync = bar; | --------- ^^^ expected trait `Sync`, found trait `Bar` @@ -76,7 +76,7 @@ LL | let _: &dyn Sync = bar; found reference `&dyn Bar` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:70:25 + --> $DIR/invalid-upcast.rs:69:25 | LL | let foo: &dyn Foo = baz; | -------- ^^^ expected trait `Foo`, found trait `Baz` @@ -87,7 +87,7 @@ LL | let foo: &dyn Foo = baz; found reference `&dyn Baz` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:72:35 + --> $DIR/invalid-upcast.rs:71:35 | LL | let _: &dyn std::fmt::Debug = foo; | -------------------- ^^^ expected trait `Debug`, found trait `Foo` @@ -98,7 +98,7 @@ LL | let _: &dyn std::fmt::Debug = foo; found reference `&dyn Foo` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:74:24 + --> $DIR/invalid-upcast.rs:73:24 | LL | let _: &dyn Send = foo; | --------- ^^^ expected trait `Send`, found trait `Foo` @@ -109,7 +109,7 @@ LL | let _: &dyn Send = foo; found reference `&dyn Foo` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:76:24 + --> $DIR/invalid-upcast.rs:75:24 | LL | let _: &dyn Sync = foo; | --------- ^^^ expected trait `Sync`, found trait `Foo` @@ -120,7 +120,7 @@ LL | let _: &dyn Sync = foo; found reference `&dyn Foo` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:79:25 + --> $DIR/invalid-upcast.rs:78:25 | LL | let foo: &dyn Foo = bar; | -------- ^^^ expected trait `Foo`, found trait `Bar` @@ -131,7 +131,7 @@ LL | let foo: &dyn Foo = bar; found reference `&dyn Bar` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:81:35 + --> $DIR/invalid-upcast.rs:80:35 | LL | let _: &dyn std::fmt::Debug = foo; | -------------------- ^^^ expected trait `Debug`, found trait `Foo` @@ -142,7 +142,7 @@ LL | let _: &dyn std::fmt::Debug = foo; found reference `&dyn Foo` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:83:24 + --> $DIR/invalid-upcast.rs:82:24 | LL | let _: &dyn Send = foo; | --------- ^^^ expected trait `Send`, found trait `Foo` @@ -153,7 +153,7 @@ LL | let _: &dyn Send = foo; found reference `&dyn Foo` error[E0308]: mismatched types - --> $DIR/invalid-upcast.rs:85:24 + --> $DIR/invalid-upcast.rs:84:24 | LL | let _: &dyn Sync = foo; | --------- ^^^ expected trait `Sync`, found trait `Foo` diff --git a/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs b/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs index 6d88002540c1a..b672963ae9887 100644 --- a/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs +++ b/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs @@ -1,6 +1,5 @@ // run-pass #![feature(trait_upcasting)] -#![allow(incomplete_features)] struct Test { func: Box, diff --git a/src/test/ui/traits/trait-upcasting/lifetime.rs b/src/test/ui/traits/trait-upcasting/lifetime.rs index f029a6f081f58..9825158c2dd38 100644 --- a/src/test/ui/traits/trait-upcasting/lifetime.rs +++ b/src/test/ui/traits/trait-upcasting/lifetime.rs @@ -1,7 +1,6 @@ // run-pass #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait Foo: PartialEq + std::fmt::Debug + Send + Sync { fn a(&self) -> i32 { diff --git a/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs b/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs index 6986ad6217240..2e53a00a90e9c 100644 --- a/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs +++ b/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs @@ -1,12 +1,11 @@ // check-fail #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait Bar { fn bar(&self, _: T) {} } -trait Foo : Bar + Bar { +trait Foo: Bar + Bar { fn foo(&self, _: ()) {} } diff --git a/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr b/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr index 9564813512c4a..0ad18be03cdf9 100644 --- a/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr +++ b/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/multiple-occurrence-ambiguousity.rs:21:26 + --> $DIR/multiple-occurrence-ambiguousity.rs:20:26 | LL | let t: &dyn Bar<_> = s; | ----------- ^ expected trait `Bar`, found trait `Foo` diff --git a/src/test/ui/traits/trait-upcasting/replace-vptr.rs b/src/test/ui/traits/trait-upcasting/replace-vptr.rs index 1164e43611a1d..9ccfc9306ac0c 100644 --- a/src/test/ui/traits/trait-upcasting/replace-vptr.rs +++ b/src/test/ui/traits/trait-upcasting/replace-vptr.rs @@ -1,7 +1,6 @@ // run-pass #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait A { fn foo_a(&self); diff --git a/src/test/ui/traits/trait-upcasting/struct.rs b/src/test/ui/traits/trait-upcasting/struct.rs index 0f3cb285bf4c3..a3e41696956cb 100644 --- a/src/test/ui/traits/trait-upcasting/struct.rs +++ b/src/test/ui/traits/trait-upcasting/struct.rs @@ -1,7 +1,6 @@ // run-pass #![feature(trait_upcasting)] -#![allow(incomplete_features)] use std::rc::Rc; use std::sync::Arc; diff --git a/src/test/ui/traits/trait-upcasting/subtrait-method.rs b/src/test/ui/traits/trait-upcasting/subtrait-method.rs index 3508e15284bf2..136d15af0e8b2 100644 --- a/src/test/ui/traits/trait-upcasting/subtrait-method.rs +++ b/src/test/ui/traits/trait-upcasting/subtrait-method.rs @@ -1,5 +1,4 @@ #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait Foo: PartialEq + std::fmt::Debug + Send + Sync { fn a(&self) -> i32 { diff --git a/src/test/ui/traits/trait-upcasting/subtrait-method.stderr b/src/test/ui/traits/trait-upcasting/subtrait-method.stderr index af7a410f6d92c..918159e845b9e 100644 --- a/src/test/ui/traits/trait-upcasting/subtrait-method.stderr +++ b/src/test/ui/traits/trait-upcasting/subtrait-method.stderr @@ -1,64 +1,64 @@ error[E0599]: no method named `c` found for reference `&dyn Bar` in the current scope - --> $DIR/subtrait-method.rs:56:9 + --> $DIR/subtrait-method.rs:55:9 | LL | bar.c(); | ^ help: there is a method with a similar name: `a` | = help: items from traits can only be used if the trait is implemented and in scope note: `Baz` defines an item `c`, perhaps you need to implement it - --> $DIR/subtrait-method.rs:28:1 + --> $DIR/subtrait-method.rs:27:1 | LL | trait Baz: Bar { | ^^^^^^^^^^^^^^ error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope - --> $DIR/subtrait-method.rs:60:9 + --> $DIR/subtrait-method.rs:59:9 | LL | foo.b(); | ^ help: there is a method with a similar name: `a` | = help: items from traits can only be used if the trait is implemented and in scope note: `Bar` defines an item `b`, perhaps you need to implement it - --> $DIR/subtrait-method.rs:18:1 + --> $DIR/subtrait-method.rs:17:1 | LL | trait Bar: Foo { | ^^^^^^^^^^^^^^ error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope - --> $DIR/subtrait-method.rs:62:9 + --> $DIR/subtrait-method.rs:61:9 | LL | foo.c(); | ^ help: there is a method with a similar name: `a` | = help: items from traits can only be used if the trait is implemented and in scope note: `Baz` defines an item `c`, perhaps you need to implement it - --> $DIR/subtrait-method.rs:28:1 + --> $DIR/subtrait-method.rs:27:1 | LL | trait Baz: Bar { | ^^^^^^^^^^^^^^ error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope - --> $DIR/subtrait-method.rs:66:9 + --> $DIR/subtrait-method.rs:65:9 | LL | foo.b(); | ^ help: there is a method with a similar name: `a` | = help: items from traits can only be used if the trait is implemented and in scope note: `Bar` defines an item `b`, perhaps you need to implement it - --> $DIR/subtrait-method.rs:18:1 + --> $DIR/subtrait-method.rs:17:1 | LL | trait Bar: Foo { | ^^^^^^^^^^^^^^ error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope - --> $DIR/subtrait-method.rs:68:9 + --> $DIR/subtrait-method.rs:67:9 | LL | foo.c(); | ^ help: there is a method with a similar name: `a` | = help: items from traits can only be used if the trait is implemented and in scope note: `Baz` defines an item `c`, perhaps you need to implement it - --> $DIR/subtrait-method.rs:28:1 + --> $DIR/subtrait-method.rs:27:1 | LL | trait Baz: Bar { | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs index 79ddedd418756..6bc9f4a75d333 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs @@ -1,5 +1,4 @@ #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait Foo: Bar + Bar {} trait Bar { diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr index 3985372119e88..fe269d8e99bf5 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr @@ -1,5 +1,5 @@ error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>` - --> $DIR/type-checking-test-1.rs:17:13 + --> $DIR/type-checking-test-1.rs:16:13 | LL | let _ = x as &dyn Bar<_>; // Ambiguous | ^^^^^^^^^^^^^^^^ invalid cast @@ -10,7 +10,7 @@ LL | let _ = &x as &dyn Bar<_>; // Ambiguous | + error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied - --> $DIR/type-checking-test-1.rs:17:13 + --> $DIR/type-checking-test-1.rs:16:13 | LL | let _ = x as &dyn Bar<_>; // Ambiguous | ^ the trait `Bar<_>` is not implemented for `&dyn Foo` diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs index 32754c5380378..36b11dffdb158 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs @@ -1,5 +1,4 @@ #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait Foo: Bar + Bar {} trait Bar { diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr index 93c71f54eb53a..ef007d5cb909f 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr @@ -1,5 +1,5 @@ error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar` - --> $DIR/type-checking-test-2.rs:20:13 + --> $DIR/type-checking-test-2.rs:19:13 | LL | let _ = x as &dyn Bar; // Error | ^^^^^^^^^^^^^^^^^^ invalid cast @@ -10,7 +10,7 @@ LL | let _ = &x as &dyn Bar; // Error | + error[E0277]: the trait bound `&dyn Foo: Bar` is not satisfied - --> $DIR/type-checking-test-2.rs:20:13 + --> $DIR/type-checking-test-2.rs:19:13 | LL | let _ = x as &dyn Bar; // Error | ^ the trait `Bar` is not implemented for `&dyn Foo` @@ -18,7 +18,7 @@ LL | let _ = x as &dyn Bar; // Error = note: required for the cast from `&dyn Foo` to the object type `dyn Bar` error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>` - --> $DIR/type-checking-test-2.rs:26:13 + --> $DIR/type-checking-test-2.rs:25:13 | LL | let a = x as &dyn Bar<_>; // Ambiguous | ^^^^^^^^^^^^^^^^ invalid cast @@ -29,7 +29,7 @@ LL | let a = &x as &dyn Bar<_>; // Ambiguous | + error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied - --> $DIR/type-checking-test-2.rs:26:13 + --> $DIR/type-checking-test-2.rs:25:13 | LL | let a = x as &dyn Bar<_>; // Ambiguous | ^ the trait `Bar<_>` is not implemented for `&dyn Foo` diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr index e48ba709af1fd..e6cb6a753998f 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr @@ -1,22 +1,18 @@ error: lifetime may not live long enough - --> $DIR/type-checking-test-3.rs:13:13 + --> $DIR/type-checking-test-3.rs:11:13 | LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here LL | let _ = x as &dyn Bar<'a>; // Error | ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` - | - = help: consider replacing `'a` with `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-3.rs:18:13 + --> $DIR/type-checking-test-3.rs:16:13 | LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) { | -- lifetime `'a` defined here LL | let _ = x as &dyn Bar<'static>; // Error | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` - | - = help: consider replacing `'a` with `'static` error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs index b3aa2279a30a0..b2db3a127974c 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs @@ -1,5 +1,4 @@ #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait Foo<'a>: Bar<'a> {} trait Bar<'a> {} @@ -10,12 +9,12 @@ fn test_correct(x: &dyn Foo<'static>) { fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { let _ = x as &dyn Bar<'a>; // Error - //~^ ERROR lifetime may not live long enough + //~^ ERROR lifetime may not live long enough } fn test_wrong2<'a>(x: &dyn Foo<'a>) { let _ = x as &dyn Bar<'static>; // Error - //~^ ERROR lifetime may not live long enough + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr index 5ad151b50924d..e6cb6a753998f 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/type-checking-test-3.rs:12:13 + --> $DIR/type-checking-test-3.rs:11:13 | LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here @@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'a>; // Error | ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-3.rs:17:13 + --> $DIR/type-checking-test-3.rs:16:13 | LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) { | -- lifetime `'a` defined here diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr index a3411f40ad0fb..8d506e5807ece 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr @@ -1,33 +1,52 @@ error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:17:13 + --> $DIR/type-checking-test-4.rs:15:13 | LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here LL | let _ = x as &dyn Bar<'static, 'a>; // Error | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` - | - = help: consider replacing `'a` with `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:22:13 + --> $DIR/type-checking-test-4.rs:20:13 | LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here LL | let _ = x as &dyn Bar<'a, 'static>; // Error | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` - | - = help: consider replacing `'a` with `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:29:5 + --> $DIR/type-checking-test-4.rs:26:5 | LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here -... +LL | let y = x as &dyn Bar<'_, '_>; LL | y.get_b() // ERROR | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/type-checking-test-4.rs:31:5 + | +LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | -- lifetime `'a` defined here +LL | <_ as Bar>::get_b(x) // ERROR + | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/type-checking-test-4.rs:36:5 + | +LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | -- lifetime `'a` defined here +LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/type-checking-test-4.rs:44:5 | - = help: consider replacing `'a` with `'static` +LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | -- lifetime `'a` defined here +... +LL | z.get_b() // ERROR + | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static` -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs index 70ccc87fc3e14..f40c48f0d125f 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs @@ -1,5 +1,4 @@ #![feature(trait_upcasting)] -#![allow(incomplete_features)] trait Foo<'a>: Bar<'a, 'a> {} trait Bar<'a, 'b> { @@ -14,28 +13,28 @@ fn test_correct(x: &dyn Foo<'static>) { fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { let _ = x as &dyn Bar<'static, 'a>; // Error - //~^ ERROR lifetime may not live long enough + //~^ ERROR lifetime may not live long enough } fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { let _ = x as &dyn Bar<'a, 'static>; // Error - //~^ ERROR lifetime may not live long enough + //~^ ERROR lifetime may not live long enough } fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { let y = x as &dyn Bar<'_, '_>; y.get_b() // ERROR - //~^ ERROR lifetime may not live long enough + //~^ ERROR lifetime may not live long enough } fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { <_ as Bar>::get_b(x) // ERROR - //~^ ERROR lifetime may not live long enough + //~^ ERROR lifetime may not live long enough } fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { <_ as Bar<'_, '_>>::get_b(x) // ERROR - //~^ ERROR lifetime may not live long enough + //~^ ERROR lifetime may not live long enough } fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { @@ -43,7 +42,7 @@ fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { y.get_b(); // ERROR let z = y; z.get_b() // ERROR - //~^ ERROR lifetime may not live long enough + //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr index 436129d0bee52..8d506e5807ece 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:16:13 + --> $DIR/type-checking-test-4.rs:15:13 | LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here @@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'static, 'a>; // Error | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:21:13 + --> $DIR/type-checking-test-4.rs:20:13 | LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here @@ -15,7 +15,7 @@ LL | let _ = x as &dyn Bar<'a, 'static>; // Error | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:27:5 + --> $DIR/type-checking-test-4.rs:26:5 | LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here @@ -24,7 +24,7 @@ LL | y.get_b() // ERROR | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:32:5 + --> $DIR/type-checking-test-4.rs:31:5 | LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here @@ -32,7 +32,7 @@ LL | <_ as Bar>::get_b(x) // ERROR | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:37:5 + --> $DIR/type-checking-test-4.rs:36:5 | LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here @@ -40,7 +40,7 @@ LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:45:5 + --> $DIR/type-checking-test-4.rs:44:5 | LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | -- lifetime `'a` defined here From c467006fd0d0fd046590c7867fcfef2062d144a3 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Tue, 8 Nov 2022 19:45:41 +0900 Subject: [PATCH 07/17] suggest removing unnecessary . to use a floating point literal --- compiler/rustc_hir_typeck/src/demand.rs | 3 +- .../src/fn_ctxt/suggestions.rs | 21 ++++++++ ...ecessary_dot_for_floating_point_literal.rs | 6 +++ ...sary_dot_for_floating_point_literal.stderr | 52 +++++++++++++++++++ 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs create mode 100644 src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 7f78f5fb8a7b2..be618eb664c3f 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -43,7 +43,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected) || self.suggest_copied_or_cloned(err, expr, expr_ty, expected) || self.suggest_into(err, expr, expr_ty, expected) - || self.suggest_option_to_bool(err, expr, expr_ty, expected); + || self.suggest_option_to_bool(err, expr, expr_ty, expected) + || self.suggest_floating_point_literal(err, expr, expected); self.note_type_is_not_clone(err, expected, expr_ty, expr); self.note_need_for_fn_pointer(err, expected, expr_ty); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index a14759e254c49..fb8669e949cdf 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1204,6 +1204,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + #[instrument(skip(self, err))] + pub(crate) fn suggest_floating_point_literal( + &self, + err: &mut Diagnostic, + expr: &hir::Expr<'_>, + expected_ty: Ty<'tcx>, + ) -> bool { + if let ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), [start, _], _) = expr.kind + && expected_ty.is_floating_point() + { + err.span_suggestion_verbose( + self.tcx.sess.source_map().next_point(start.span), + "remove the unnecessary `.` operator to to use a floating point literal", + "", + Applicability::MachineApplicable, + ); + return true; + } + false + } + fn is_loop(&self, id: hir::HirId) -> bool { let node = self.tcx.hir().get(id); matches!(node, Node::Expr(Expr { kind: ExprKind::Loop(..), .. })) diff --git a/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs new file mode 100644 index 0000000000000..b1eda63d56e27 --- /dev/null +++ b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs @@ -0,0 +1,6 @@ +fn main() { + let _: f64 = 0..10; //~ ERROR mismatched types + let _: f64 = 0..; //~ ERROR mismatched types + let _: f64 = ..10; //~ ERROR mismatched types + let _: f64 = std::ops::Range { start: 0, end: 1 }; //~ ERROR mismatched types +} diff --git a/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr new file mode 100644 index 0000000000000..2f1d7dc230f4d --- /dev/null +++ b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr @@ -0,0 +1,52 @@ +error[E0308]: mismatched types + --> $DIR/unnecessary_dot_for_floating_point_literal.rs:2:18 + | +LL | let _: f64 = 0..10; + | --- ^^^^^ expected `f64`, found struct `std::ops::Range` + | | + | expected due to this + | + = note: expected type `f64` + found struct `std::ops::Range<{integer}>` +help: remove the unnecessary `.` operator to to use a floating point literal + | +LL - let _: f64 = 0..10; +LL + let _: f64 = 0.10; + | + +error[E0308]: mismatched types + --> $DIR/unnecessary_dot_for_floating_point_literal.rs:3:18 + | +LL | let _: f64 = 0..; + | --- ^^^ expected `f64`, found struct `RangeFrom` + | | + | expected due to this + | + = note: expected type `f64` + found struct `RangeFrom<{integer}>` + +error[E0308]: mismatched types + --> $DIR/unnecessary_dot_for_floating_point_literal.rs:4:18 + | +LL | let _: f64 = ..10; + | --- ^^^^ expected `f64`, found struct `RangeTo` + | | + | expected due to this + | + = note: expected type `f64` + found struct `RangeTo<{integer}>` + +error[E0308]: mismatched types + --> $DIR/unnecessary_dot_for_floating_point_literal.rs:5:18 + | +LL | let _: f64 = std::ops::Range { start: 0, end: 1 }; + | --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `f64`, found struct `std::ops::Range` + | | + | expected due to this + | + = note: expected type `f64` + found struct `std::ops::Range<{integer}>` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. From 004986b79b933a5c9ec160b977f791b154c8d275 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Tue, 8 Nov 2022 19:45:48 +0900 Subject: [PATCH 08/17] avoid unnecessary `format!` --- compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index fb8669e949cdf..5a0af00b6e1fc 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -374,7 +374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let annotation_span = ty.span; err.span_suggestion( annotation_span.with_hi(annotation_span.lo()), - format!("alternatively, consider changing the type annotation"), + "alternatively, consider changing the type annotation", suggest_annotation, Applicability::MaybeIncorrect, ); From 6018f115aa7365db39a9df1f883123076403a97b Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 10 Nov 2022 07:24:22 +0900 Subject: [PATCH 09/17] emit errors when using `RangeFrom` and `RangeTo` --- .../src/fn_ctxt/suggestions.rs | 43 ++++++++++++++----- ...ecessary_dot_for_floating_point_literal.rs | 2 +- ...sary_dot_for_floating_point_literal.stderr | 17 +++++--- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 5a0af00b6e1fc..06e6e4350fcbc 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1211,18 +1211,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, expected_ty: Ty<'tcx>, ) -> bool { - if let ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), [start, _], _) = expr.kind - && expected_ty.is_floating_point() - { - err.span_suggestion_verbose( - self.tcx.sess.source_map().next_point(start.span), - "remove the unnecessary `.` operator to to use a floating point literal", - "", - Applicability::MachineApplicable, - ); - return true; + if !expected_ty.is_floating_point() { + return false; + } + match expr.kind { + ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), [start, end], _) => { + err.span_suggestion_verbose( + start.span.shrink_to_hi().with_hi(end.span.lo()), + "remove the unnecessary `.` operator for a floating point literal", + '.', + Applicability::MaybeIncorrect, + ); + true + } + ExprKind::Struct(QPath::LangItem(LangItem::RangeFrom, ..), [start], _) => { + err.span_suggestion_verbose( + expr.span.with_lo(start.span.hi()), + "remove the unnecessary `.` operator for a floating point literal", + '.', + Applicability::MaybeIncorrect, + ); + true + } + ExprKind::Struct(QPath::LangItem(LangItem::RangeTo, ..), [end], _) => { + err.span_suggestion_verbose( + expr.span.until(end.span), + "remove the unnecessary `.` operator and add an integer part for a floating point literal", + "0.", + Applicability::MaybeIncorrect, + ); + true + } + _ => false, } - false } fn is_loop(&self, id: hir::HirId) -> bool { diff --git a/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs index b1eda63d56e27..c1a944562683a 100644 --- a/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs +++ b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs @@ -1,6 +1,6 @@ fn main() { let _: f64 = 0..10; //~ ERROR mismatched types - let _: f64 = 0..; //~ ERROR mismatched types + let _: f64 = 1..; //~ ERROR mismatched types let _: f64 = ..10; //~ ERROR mismatched types let _: f64 = std::ops::Range { start: 0, end: 1 }; //~ ERROR mismatched types } diff --git a/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr index 2f1d7dc230f4d..773f1392ae765 100644 --- a/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr +++ b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr @@ -8,22 +8,25 @@ LL | let _: f64 = 0..10; | = note: expected type `f64` found struct `std::ops::Range<{integer}>` -help: remove the unnecessary `.` operator to to use a floating point literal - | -LL - let _: f64 = 0..10; -LL + let _: f64 = 0.10; +help: remove the unnecessary `.` operator for a floating point literal | +LL | let _: f64 = 0.10; + | ~ error[E0308]: mismatched types --> $DIR/unnecessary_dot_for_floating_point_literal.rs:3:18 | -LL | let _: f64 = 0..; +LL | let _: f64 = 1..; | --- ^^^ expected `f64`, found struct `RangeFrom` | | | expected due to this | = note: expected type `f64` found struct `RangeFrom<{integer}>` +help: remove the unnecessary `.` operator for a floating point literal + | +LL | let _: f64 = 1.; + | ~ error[E0308]: mismatched types --> $DIR/unnecessary_dot_for_floating_point_literal.rs:4:18 @@ -35,6 +38,10 @@ LL | let _: f64 = ..10; | = note: expected type `f64` found struct `RangeTo<{integer}>` +help: remove the unnecessary `.` operator and add an integer part for a floating point literal + | +LL | let _: f64 = 0.10; + | ~~ error[E0308]: mismatched types --> $DIR/unnecessary_dot_for_floating_point_literal.rs:5:18 From 84e1fbcadfa6299e63e517e722485b47fc99daad Mon Sep 17 00:00:00 2001 From: Florian Bartels Date: Mon, 5 Sep 2022 10:56:06 +0200 Subject: [PATCH 10/17] Add no_std AArch64 support for the QNX Neutrino (nto) 7.1 RTOS This change allows to compile no_std applications for the QNX Neutrino realtime operating system for ARM 64 bit CPUs. Tested with QNX Neutrino 7.1. --- .../src/spec/aarch64_unknown_nto_qnx_710.rs | 28 +++++ compiler/rustc_target/src/spec/mod.rs | 4 + .../rustc_target/src/spec/nto_qnx_base.rs | 19 +++ .../src/spec/x86_64_pc_nto_qnx710.rs | 21 ++++ src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 2 + src/doc/rustc/src/platform-support/nto-qnx.md | 117 ++++++++++++++++++ 7 files changed, 192 insertions(+) create mode 100644 compiler/rustc_target/src/spec/aarch64_unknown_nto_qnx_710.rs create mode 100644 compiler/rustc_target/src/spec/nto_qnx_base.rs create mode 100644 compiler/rustc_target/src/spec/x86_64_pc_nto_qnx710.rs create mode 100644 src/doc/rustc/src/platform-support/nto-qnx.md diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_nto_qnx_710.rs b/compiler/rustc_target/src/spec/aarch64_unknown_nto_qnx_710.rs new file mode 100644 index 0000000000000..916b6137b650a --- /dev/null +++ b/compiler/rustc_target/src/spec/aarch64_unknown_nto_qnx_710.rs @@ -0,0 +1,28 @@ +use super::nto_qnx_base; +use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions}; + +pub fn target() -> Target { + Target { + llvm_target: "aarch64-unknown-unknown".into(), + pointer_width: 64, + // from: https://llvm.org/docs/LangRef.html#data-layout + // e = little endian + // m:e = ELF mangling: Private symbols get a .L prefix + // i8:8:32 = 8-bit-integer, minimum_alignment=8, preferred_alignment=32 + // i16:16:32 = 16-bit-integer, minimum_alignment=16, preferred_alignment=32 + // i64:64 = 64-bit-integer, minimum_alignment=64, preferred_alignment=64 + // i128:128 = 128-bit-integer, minimum_alignment=128, preferred_alignment=128 + // n32:64 = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently. + // S128 = 128 bits are the natural alignment of the stack in bits. + data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), + arch: "aarch64".into(), + options: TargetOptions { + max_atomic_width: Some(128), + pre_link_args: TargetOptions::link_args( + LinkerFlavor::Gnu(Cc::Yes, Lld::No), + &["-Vgcc_ntoaarch64le_cxx"], + ), + ..nto_qnx_base::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 77d9a0920036a..e809f646860b0 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -74,6 +74,7 @@ mod linux_musl_base; mod linux_uclibc_base; mod msvc_base; mod netbsd_base; +mod nto_qnx_base; mod openbsd_base; mod redox_base; mod solaris_base; @@ -1242,6 +1243,9 @@ supported_targets! { ("x86_64-unknown-none", x86_64_unknown_none), ("mips64-openwrt-linux-musl", mips64_openwrt_linux_musl), + + ("aarch64-unknown-nto-qnx7.1.0", aarch64_unknown_nto_qnx_710), + ("x86_64-pc-nto-qnx7.1.0", x86_64_pc_nto_qnx710), } /// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]> diff --git a/compiler/rustc_target/src/spec/nto_qnx_base.rs b/compiler/rustc_target/src/spec/nto_qnx_base.rs new file mode 100644 index 0000000000000..6fb581ef5ce34 --- /dev/null +++ b/compiler/rustc_target/src/spec/nto_qnx_base.rs @@ -0,0 +1,19 @@ +use crate::spec::{cvs, RelroLevel, TargetOptions}; + +pub fn opts() -> TargetOptions { + TargetOptions { + crt_static_respected: true, + dynamic_linking: true, + env: "nto71".into(), + executables: true, + families: cvs!["unix"], + has_rpath: true, + has_thread_local: false, + linker: Some("qcc".into()), + os: "nto".into(), + position_independent_executables: true, + static_position_independent_executables: true, + relro_level: RelroLevel::Full, + ..Default::default() + } +} diff --git a/compiler/rustc_target/src/spec/x86_64_pc_nto_qnx710.rs b/compiler/rustc_target/src/spec/x86_64_pc_nto_qnx710.rs new file mode 100644 index 0000000000000..e9b3acee2e7f1 --- /dev/null +++ b/compiler/rustc_target/src/spec/x86_64_pc_nto_qnx710.rs @@ -0,0 +1,21 @@ +use super::nto_qnx_base; +use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions}; + +pub fn target() -> Target { + Target { + llvm_target: "x86_64-pc-unknown".into(), + pointer_width: 64, + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .into(), + arch: "x86_64".into(), + options: TargetOptions { + cpu: "x86-64".into(), + max_atomic_width: Some(64), + pre_link_args: TargetOptions::link_args( + LinkerFlavor::Gnu(Cc::Yes, Lld::No), + &["-Vgcc_ntox86_64_cxx"], + ), + ..nto_qnx_base::opts() + }, + } +} diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 86bb2c0d3816a..2d3b830946145 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -33,6 +33,7 @@ - [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md) - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md) - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md) + - [\*-nto-qnx-\*](platform-support/nto-qnx.md) - [*-unknown-openbsd](platform-support/openbsd.md) - [\*-unknown-uefi](platform-support/unknown-uefi.md) - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 0315f1e3725ff..28929acb9b48d 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -214,6 +214,7 @@ target | std | host | notes [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | +[`aarch64-unknown-nto-qnx7.1.0`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.1 RTOS | `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD `aarch64-unknown-hermit` | ✓ | | ARM64 HermitCore `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) @@ -303,6 +304,7 @@ target | std | host | notes `x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst on x86_64 `x86_64-apple-tvos` | * | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator +[`x86_64-pc-nto-qnx7.1.0`](platform-support/nto-qnx.md) | ? | | x86 64-bit QNX Neutrino 7.1 RTOS | [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | `x86_64-pc-windows-msvc` | * | | 64-bit Windows XP support `x86_64-sun-solaris` | ? | | Deprecated target for 64-bit Solaris 10/11, illumos diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md new file mode 100644 index 0000000000000..2d4265334eaca --- /dev/null +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -0,0 +1,117 @@ +# nto-qnx + +**Tier: 3** + +[BlackBerry® QNX®][BlackBerry] Neutrino (nto) Real-time operating system. +The support has been implemented jointly by [Elektrobit Automotive GmbH][Elektrobit] +and [BlackBerry][BlackBerry]. + +[BlackBerry]: https://blackberry.qnx.com +[Elektrobit]: https://www.elektrobit.com + +## Target maintainers + +- Florian Bartels, `Florian.Bartels@elektrobit.com`, https://github.com/flba-eb + +## Requirements + +Currently, only cross-compilation for QNX Neutrino on AArch64 and x86_64 are supported (little endian). +Adding other architectures that are supported by QNX Neutrino is possible. + +The standard library does not yet support QNX Neutrino. Therefore, only `no_std` code can +be compiled. + +`core` and `alloc` (with default allocator) are supported. + +Applications must link against `libc.so` (see example). This is required because applications +always link against the `crt` library and `crt` depends on `libc.so`. + +The correct version of `qcc` must be available by setting the `$PATH` variable (e.g. by sourcing `qnxsdp-env.sh` of the +QNX Neutrino toolchain). + +### Small example application + +```rust +#![no_std] +#![no_main] +#![feature(lang_items)] + +// We must always link against libc, even if no external functions are used +// "extern C" - Block can be empty but must be present +#[link(name = "c")] +extern "C" { + pub fn printf(format: *const core::ffi::c_char, ...) -> core::ffi::c_int; +} + +#[no_mangle] +pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize { + const HELLO: &'static str = "Hello World, the answer is %d\n\0"; + unsafe { + printf(HELLO.as_ptr() as *const _, 42); + } + 0 +} + +use core::panic::PanicInfo; + +#[panic_handler] +fn panic(_panic: &PanicInfo<'_>) -> ! { + loop {} +} + +#[lang = "eh_personality"] +#[no_mangle] +pub extern "C" fn rust_eh_personality() {} +``` + +The QNX Neutrino support of Rust has been tested with QNX Neutrino 7.1. + +There are no further known requirements. + +## Conditional compilation + +For conditional compilation, following QNX Neutrino specific attributes are defined: + +- `target_os` = `"nto"` +- `target_env` = `"nto71"` (for QNX Neutrino 7.1) + +## Building the target + +1. Create a `config.toml` + +Example content: + +```toml +profile = "compiler" +changelog-seen = 2 +``` + +2. Compile the Rust toolchain for an `x86_64-unknown-linux-gnu` host (for both `aarch64` and `x86_64` targets) + +Run the following: + +```bash +env \ + CC_aarch64-unknown-nto-qnx7.1.0="qcc" \ + CFLAGS_aarch64-unknown-nto-qnx7.1.0="-Vgcc_ntoaarch64le_cxx" \ + CXX_aarch64-unknown-nto-qnx7.1.0="qcc" \ + AR_aarch64_unknown_nto_qnx7.1.0="ntoaarch64-ar" \ + CC_x86_64-pc-nto-qnx7.1.0="qcc" \ + CFLAGS_x86_64-pc-nto-qnx7.1.0="-Vgcc_ntox86_64_cxx" \ + CXX_x86_64-pc-nto-qnx7.1.0="qcc" \ + AR_x86_64_pc_nto_qnx7.1.0="ntox86_64-ar" \ + ./x.py build --target aarch64-unknown-nto-qnx7.1.0 --target x86_64-pc-nto-qnx7.1.0 --target x86_64-unknown-linux-gnu rustc library/core library/alloc/ +``` + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for this target, you must either build Rust with the target enabled (see "Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +## Testing + +Compiled executables can directly be run on QNX Neutrino. + +## Cross-compilation toolchains and C code + +Compiling C code requires the same environment variables to be set as compiling the Rust toolchain (see above), to ensure `qcc` is used with proper arguments. To ensure compatibility, do not specify any further arguments that for example change calling conventions or memory layout. From ae71df987baba72251db819f32e77308e88e9c13 Mon Sep 17 00:00:00 2001 From: Florian Bartels Date: Wed, 5 Oct 2022 12:32:22 +0200 Subject: [PATCH 11/17] Add `nto` as known `target_os` --- src/test/ui/check-cfg/well-known-values.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/check-cfg/well-known-values.stderr b/src/test/ui/check-cfg/well-known-values.stderr index 4ec74494fe09b..6c0dc05ba2330 100644 --- a/src/test/ui/check-cfg/well-known-values.stderr +++ b/src/test/ui/check-cfg/well-known-values.stderr @@ -6,7 +6,7 @@ LL | #[cfg(target_os = "linuz")] | | | help: did you mean: `"linux"` | - = note: expected values for `target_os` are: android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, watchos, windows, xous + = note: expected values for `target_os` are: android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, nto, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, watchos, windows, xous = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value From 014f7f4092da54315c4f4a781f2e8879a2372120 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 3 Nov 2022 17:06:41 +0000 Subject: [PATCH 12/17] Remove some redundant arguments --- .../src/annotate_snippet_emitter_writer.rs | 1 - compiler/rustc_errors/src/emitter.rs | 13 +++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index f14b8ee3254f3..c450c276366e1 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -52,7 +52,6 @@ impl Emitter for AnnotateSnippetEmitterWriter { let (mut primary_span, suggestions) = self.primary_span_formatted(&diag, &fluent_args); self.fix_multispans_in_extern_macros_and_render_macro_backtrace( - &self.source_map, &mut primary_span, &mut children, &diag.level, diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index b7b8fe3f25a04..94df0c03b954e 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -314,7 +314,6 @@ pub trait Emitter: Translate { fn fix_multispans_in_extern_macros_and_render_macro_backtrace( &self, - source_map: &Option>, span: &mut MultiSpan, children: &mut Vec, level: &Level, @@ -340,7 +339,7 @@ pub trait Emitter: Translate { .collect(); if !backtrace { - self.fix_multispans_in_extern_macros(source_map, span, children); + self.fix_multispans_in_extern_macros(span, children); } self.render_multispans_macro_backtrace(span, children, backtrace); @@ -480,15 +479,13 @@ pub trait Emitter: Translate { // this will change the span to point at the use site. fn fix_multispans_in_extern_macros( &self, - source_map: &Option>, span: &mut MultiSpan, children: &mut Vec, ) { - let Some(source_map) = source_map else { return }; debug!("fix_multispans_in_extern_macros: before: span={:?} children={:?}", span, children); - self.fix_multispan_in_extern_macros(source_map, span); + self.fix_multispan_in_extern_macros(span); for child in children.iter_mut() { - self.fix_multispan_in_extern_macros(source_map, &mut child.span); + self.fix_multispan_in_extern_macros(&mut child.span); } debug!("fix_multispans_in_extern_macros: after: span={:?} children={:?}", span, children); } @@ -496,7 +493,8 @@ pub trait Emitter: Translate { // This "fixes" MultiSpans that contain `Span`s pointing to locations inside of external macros. // Since these locations are often difficult to read, // we move these spans from the external macros to their corresponding use site. - fn fix_multispan_in_extern_macros(&self, source_map: &Lrc, span: &mut MultiSpan) { + fn fix_multispan_in_extern_macros(&self, span: &mut MultiSpan) { + let Some(source_map) = self.source_map() else { return }; // First, find all the spans in external macros and point instead at their use site. let replacements: Vec<(Span, Span)> = span .primary_spans() @@ -544,7 +542,6 @@ impl Emitter for EmitterWriter { debug!("emit_diagnostic: suggestions={:?}", suggestions); self.fix_multispans_in_extern_macros_and_render_macro_backtrace( - &self.sm, &mut primary_span, &mut children, &diag.level, From 21ce58732bc70a1696e31219ca5f2c0c25860798 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 11 Nov 2022 14:45:18 +0000 Subject: [PATCH 13/17] Don't add message that will never be shown to users It will still be used in json, as seen by the ui test changes --- .../src/traits/error_reporting/suggestions.rs | 4 ++-- src/test/ui/iterators/collect-into-array.rs | 1 - src/test/ui/iterators/collect-into-array.stderr | 2 +- src/test/ui/iterators/collect-into-slice.rs | 2 -- src/test/ui/iterators/collect-into-slice.stderr | 6 +++--- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index aece4ab792285..02e880a8e6e95 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2445,12 +2445,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { (Ok(l), Ok(r)) => l.line == r.line, _ => true, }; - if !ident.span.overlaps(span) && !same_line { + if !ident.span.is_dummy() && !ident.span.overlaps(span) && !same_line { multispan.push_span_label(ident.span, "required by a bound in this"); } } let descr = format!("required by a bound in `{}`", item_name); - if span != DUMMY_SP { + if !span.is_dummy() { let msg = format!("required by this bound in `{}`", item_name); multispan.push_span_label(span, msg); err.span_note(multispan, &descr); diff --git a/src/test/ui/iterators/collect-into-array.rs b/src/test/ui/iterators/collect-into-array.rs index 7d35da825328e..4c424999b754d 100644 --- a/src/test/ui/iterators/collect-into-array.rs +++ b/src/test/ui/iterators/collect-into-array.rs @@ -1,5 +1,4 @@ fn main() { - //~^ NOTE required by a bound in this let whatever: [u32; 10] = (0..10).collect(); //~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator //~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()` diff --git a/src/test/ui/iterators/collect-into-array.stderr b/src/test/ui/iterators/collect-into-array.stderr index 7fe9707e6d232..a23a36a88abb3 100644 --- a/src/test/ui/iterators/collect-into-array.stderr +++ b/src/test/ui/iterators/collect-into-array.stderr @@ -1,5 +1,5 @@ error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator - --> $DIR/collect-into-array.rs:3:31 + --> $DIR/collect-into-array.rs:2:31 | LL | let whatever: [u32; 10] = (0..10).collect(); | ^^^^^^^ ------- required by a bound introduced by this call diff --git a/src/test/ui/iterators/collect-into-slice.rs b/src/test/ui/iterators/collect-into-slice.rs index 5eade075613fe..09832c260d04e 100644 --- a/src/test/ui/iterators/collect-into-slice.rs +++ b/src/test/ui/iterators/collect-into-slice.rs @@ -1,6 +1,4 @@ fn process_slice(data: &[i32]) { - //~^ NOTE required by a bound in this - //~| NOTE required by a bound in this todo!() } diff --git a/src/test/ui/iterators/collect-into-slice.stderr b/src/test/ui/iterators/collect-into-slice.stderr index bce40118bdfa0..bc152467ce3a5 100644 --- a/src/test/ui/iterators/collect-into-slice.stderr +++ b/src/test/ui/iterators/collect-into-slice.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[i32]` cannot be known at compilation time - --> $DIR/collect-into-slice.rs:8:9 + --> $DIR/collect-into-slice.rs:6:9 | LL | let some_generated_vec = (0..10).collect(); | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -9,7 +9,7 @@ LL | let some_generated_vec = (0..10).collect(); = help: unsized locals are gated as an unstable feature error[E0277]: the size for values of type `[i32]` cannot be known at compilation time - --> $DIR/collect-into-slice.rs:8:38 + --> $DIR/collect-into-slice.rs:6:38 | LL | let some_generated_vec = (0..10).collect(); | ^^^^^^^ doesn't have a size known at compile-time @@ -22,7 +22,7 @@ LL | fn collect>(self) -> B | ^ required by this bound in `collect` error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size - --> $DIR/collect-into-slice.rs:8:30 + --> $DIR/collect-into-slice.rs:6:30 | LL | let some_generated_vec = (0..10).collect(); | ^^^^^^^ ------- required by a bound introduced by this call From df2adc4760a1c03096ab4b39512ba90b983c2332 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 4 Nov 2022 16:04:47 +0000 Subject: [PATCH 14/17] Print all labels, even if they have no span. Fall back to main item's span. --- .../locales/en-US/passes.ftl | 5 +- compiler/rustc_errors/src/emitter.rs | 47 ++++++++++++---- compiler/rustc_passes/src/check_attr.rs | 55 ++++++++++++++----- compiler/rustc_passes/src/errors.rs | 3 + compiler/rustc_resolve/src/diagnostics.rs | 10 ++-- .../rustc_resolve/src/late/diagnostics.rs | 18 +++--- src/test/ui/asm/naked-invalid-attr.stderr | 2 +- ...43106-gating-of-builtin-attrs-error.stderr | 6 +- .../issue-43106-gating-of-builtin-attrs.rs | 2 +- ...issue-43106-gating-of-builtin-attrs.stderr | 8 +-- .../issue-69396-const-no-type-in-macro.stderr | 5 +- 11 files changed, 110 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl index 5239ff9dc0571..001e53d1d0e4c 100644 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl @@ -47,7 +47,10 @@ passes_no_coverage_not_coverable = passes_should_be_applied_to_fn = attribute should be applied to a function definition - .label = not a function definition + .label = {$on_crate -> + [true] cannot be applied to crates + *[false] not a function definition + } passes_naked_tracked_caller = cannot use `#[track_caller]` with `#[naked]` diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 94df0c03b954e..55c7997a51363 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2210,22 +2210,45 @@ impl FileWithAnnotatedLines { if let Some(ref sm) = emitter.source_map() { for span_label in msp.span_labels() { + let fixup_lo_hi = |span: Span| { + let lo = sm.lookup_char_pos(span.lo()); + let mut hi = sm.lookup_char_pos(span.hi()); + + // Watch out for "empty spans". If we get a span like 6..6, we + // want to just display a `^` at 6, so convert that to + // 6..7. This is degenerate input, but it's best to degrade + // gracefully -- and the parser likes to supply a span like + // that for EOF, in particular. + + if lo.col_display == hi.col_display && lo.line == hi.line { + hi.col_display += 1; + } + (lo, hi) + }; + if span_label.span.is_dummy() { + if let Some(span) = msp.primary_span() { + // if we don't know where to render the annotation, emit it as a note + // on the primary span. + + let (lo, hi) = fixup_lo_hi(span); + + let ann = Annotation { + start_col: lo.col_display, + end_col: hi.col_display, + is_primary: span_label.is_primary, + label: span_label + .label + .as_ref() + .map(|m| emitter.translate_message(m, args).to_string()), + annotation_type: AnnotationType::Singleline, + }; + add_annotation_to_file(&mut output, lo.file, lo.line, ann); + } continue; } - let lo = sm.lookup_char_pos(span_label.span.lo()); - let mut hi = sm.lookup_char_pos(span_label.span.hi()); - - // Watch out for "empty spans". If we get a span like 6..6, we - // want to just display a `^` at 6, so convert that to - // 6..7. This is degenerate input, but it's best to degrade - // gracefully -- and the parser likes to supply a span like - // that for EOF, in particular. - - if lo.col_display == hi.col_display && lo.line == hi.line { - hi.col_display += 1; - } + let (lo, hi) = fixup_lo_hi(span_label.span); if lo.line != hi.line { let ml = MultilineAnnotation { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 27a57adf964a3..0c34b0e1bf3f9 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -119,13 +119,13 @@ impl CheckAttrVisitor<'_> { } sym::naked => self.check_naked(hir_id, attr, span, target), sym::rustc_legacy_const_generics => { - self.check_rustc_legacy_const_generics(&attr, span, target, item) + self.check_rustc_legacy_const_generics(hir_id, &attr, span, target, item) } sym::rustc_lint_query_instability => { - self.check_rustc_lint_query_instability(&attr, span, target) + self.check_rustc_lint_query_instability(hir_id, &attr, span, target) } sym::rustc_lint_diagnostics => { - self.check_rustc_lint_diagnostics(&attr, span, target) + self.check_rustc_lint_diagnostics(hir_id, &attr, span, target) } sym::rustc_lint_opt_ty => self.check_rustc_lint_opt_ty(&attr, span, target), sym::rustc_lint_opt_deny_field_access => { @@ -135,7 +135,9 @@ impl CheckAttrVisitor<'_> { | sym::rustc_dirty | sym::rustc_if_this_changed | sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr), - sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target), + sym::cmse_nonsecure_entry => { + self.check_cmse_nonsecure_entry(hir_id, attr, span, target) + } sym::collapse_debuginfo => self.check_collapse_debuginfo(attr, span, target), sym::const_trait => self.check_const_trait(attr, span, target), sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target), @@ -386,6 +388,7 @@ impl CheckAttrVisitor<'_> { self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn { attr_span: attr.span, defn_span: span, + on_crate: hir_id == CRATE_HIR_ID, }); false } @@ -393,7 +396,13 @@ impl CheckAttrVisitor<'_> { } /// Checks if `#[cmse_nonsecure_entry]` is applied to a function definition. - fn check_cmse_nonsecure_entry(&self, attr: &Attribute, span: Span, target: Target) -> bool { + fn check_cmse_nonsecure_entry( + &self, + hir_id: HirId, + attr: &Attribute, + span: Span, + target: Target, + ) -> bool { match target { Target::Fn | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, @@ -401,6 +410,7 @@ impl CheckAttrVisitor<'_> { self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn { attr_span: attr.span, defn_span: span, + on_crate: hir_id == CRATE_HIR_ID, }); false } @@ -465,9 +475,11 @@ impl CheckAttrVisitor<'_> { true } _ => { - self.tcx - .sess - .emit_err(errors::TrackedCallerWrongLocation { attr_span, defn_span: span }); + self.tcx.sess.emit_err(errors::TrackedCallerWrongLocation { + attr_span, + defn_span: span, + on_crate: hir_id == CRATE_HIR_ID, + }); false } } @@ -576,6 +588,7 @@ impl CheckAttrVisitor<'_> { self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn { attr_span: attr.span, defn_span: span, + on_crate: hir_id == CRATE_HIR_ID, }); false } @@ -1240,7 +1253,7 @@ impl CheckAttrVisitor<'_> { UNUSED_ATTRIBUTES, hir_id, attr.span, - errors::Cold { span }, + errors::Cold { span, on_crate: hir_id == CRATE_HIR_ID }, ); } } @@ -1376,6 +1389,7 @@ impl CheckAttrVisitor<'_> { /// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument. fn check_rustc_legacy_const_generics( &self, + hir_id: HirId, attr: &Attribute, span: Span, target: Target, @@ -1386,6 +1400,7 @@ impl CheckAttrVisitor<'_> { self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn { attr_span: attr.span, defn_span: span, + on_crate: hir_id == CRATE_HIR_ID, }); return false; } @@ -1450,12 +1465,19 @@ impl CheckAttrVisitor<'_> { /// Helper function for checking that the provided attribute is only applied to a function or /// method. - fn check_applied_to_fn_or_method(&self, attr: &Attribute, span: Span, target: Target) -> bool { + fn check_applied_to_fn_or_method( + &self, + hir_id: HirId, + attr: &Attribute, + span: Span, + target: Target, + ) -> bool { let is_function = matches!(target, Target::Fn | Target::Method(..)); if !is_function { self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn { attr_span: attr.span, defn_span: span, + on_crate: hir_id == CRATE_HIR_ID, }); false } else { @@ -1467,17 +1489,24 @@ impl CheckAttrVisitor<'_> { /// or method. fn check_rustc_lint_query_instability( &self, + hir_id: HirId, attr: &Attribute, span: Span, target: Target, ) -> bool { - self.check_applied_to_fn_or_method(attr, span, target) + self.check_applied_to_fn_or_method(hir_id, attr, span, target) } /// Checks that the `#[rustc_lint_diagnostics]` attribute is only applied to a function or /// method. - fn check_rustc_lint_diagnostics(&self, attr: &Attribute, span: Span, target: Target) -> bool { - self.check_applied_to_fn_or_method(attr, span, target) + fn check_rustc_lint_diagnostics( + &self, + hir_id: HirId, + attr: &Attribute, + span: Span, + target: Target, + ) -> bool { + self.check_applied_to_fn_or_method(hir_id, attr, span, target) } /// Checks that the `#[rustc_lint_opt_ty]` attribute is only applied to a struct. diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 1dbf0d642e2af..c6cd69add28a0 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -81,6 +81,7 @@ pub struct AttrShouldBeAppliedToFn { pub attr_span: Span, #[label] pub defn_span: Span, + pub on_crate: bool, } #[derive(Diagnostic)] @@ -97,6 +98,7 @@ pub struct TrackedCallerWrongLocation { pub attr_span: Span, #[label] pub defn_span: Span, + pub on_crate: bool, } #[derive(Diagnostic)] @@ -367,6 +369,7 @@ pub struct MustNotSuspend { pub struct Cold { #[label] pub span: Span, + pub on_crate: bool, } #[derive(LintDiagnostic)] diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 7961e3f1194e1..a12918b297990 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -241,10 +241,12 @@ impl<'a> Resolver<'a> { )); err.span_label(span, format!("`{}` re{} here", name, new_participle)); - err.span_label( - self.session.source_map().guess_head_span(old_binding.span), - format!("previous {} of the {} `{}` here", old_noun, old_kind, name), - ); + if !old_binding.span.is_dummy() && old_binding.span != span { + err.span_label( + self.session.source_map().guess_head_span(old_binding.span), + format!("previous {} of the {} `{}` here", old_noun, old_kind, name), + ); + } // See https://github.com/rust-lang/rust/issues/32354 use NameBindingKind::Import; diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a1338dcd4771b..346024bb5984b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -806,14 +806,16 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.code(rustc_errors::error_code!(E0411)); err.span_label(span, "`Self` is only available in impls, traits, and type definitions"); if let Some(item_kind) = self.diagnostic_metadata.current_item { - err.span_label( - item_kind.ident.span, - format!( - "`Self` not allowed in {} {}", - item_kind.kind.article(), - item_kind.kind.descr() - ), - ); + if !item_kind.ident.span.is_dummy() { + err.span_label( + item_kind.ident.span, + format!( + "`Self` not allowed in {} {}", + item_kind.kind.article(), + item_kind.kind.descr() + ), + ); + } } true } diff --git a/src/test/ui/asm/naked-invalid-attr.stderr b/src/test/ui/asm/naked-invalid-attr.stderr index 58344be93346d..e8ddccc854abe 100644 --- a/src/test/ui/asm/naked-invalid-attr.stderr +++ b/src/test/ui/asm/naked-invalid-attr.stderr @@ -36,7 +36,7 @@ error: attribute should be applied to a function definition --> $DIR/naked-invalid-attr.rs:5:1 | LL | #![naked] - | ^^^^^^^^^ + | ^^^^^^^^^ cannot be applied to crates error: aborting due to 5 previous errors diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr index 5a645cf4ef987..7876704042188 100644 --- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr +++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr @@ -110,19 +110,19 @@ error: attribute should be applied to an `extern crate` item --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1 | LL | #![no_link] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ not an `extern crate` item error: attribute should be applied to a free function, impl method or static --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:27:1 | LL | #![export_name = "2200"] - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ not a free function, impl method or static error[E0518]: attribute should be applied to function or closure --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:29:1 | LL | #![inline] - | ^^^^^^^^^^ + | ^^^^^^^^^^ not a function or closure error: `macro_export` attribute cannot be used at crate level --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1 diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index 8db12e55d25c2..1fa315f3d2159 100644 --- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -1,6 +1,6 @@ //~ NOTE not a function //~| NOTE not a foreign function or static -//~| NOTE not a function or static +//~| NOTE cannot be applied to crates //~| NOTE not an `extern` block // This test enumerates as many compiler-builtin ungated attributes as // possible (that is, all the mutually compatible ones), and checks diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index 310d1f720eb7c..30039267979fb 100644 --- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -403,7 +403,7 @@ warning: attribute should be applied to a function definition --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1 | LL | #![cold] - | ^^^^^^^^ + | ^^^^^^^^ cannot be applied to crates | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! @@ -411,7 +411,7 @@ warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1 | LL | #![link()] - | ^^^^^^^^^^ + | ^^^^^^^^^^ not an `extern` block | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! @@ -419,7 +419,7 @@ warning: attribute should be applied to a foreign function or static --> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1 | LL | #![link_name = "1900"] - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ not a foreign function or static | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! @@ -427,7 +427,7 @@ warning: attribute should be applied to a function or static --> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1 | LL | #![link_section = "1800"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ not a function or static | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! diff --git a/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr b/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr index f581429a28154..89aeafebac497 100644 --- a/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr +++ b/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr @@ -2,10 +2,7 @@ error[E0428]: the name `A` is defined multiple times --> $DIR/issue-69396-const-no-type-in-macro.rs:4:13 | LL | const A = "A".$fn(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | `A` redefined here - | previous definition of the value `A` here + | ^^^^^^^^^^^^^^^^^^^^ `A` redefined here ... LL | / suite! { LL | | len; From f149837f0db964ffc3b67bfa003da621113ef522 Mon Sep 17 00:00:00 2001 From: Florian Bartels <108917393+flba-eb@users.noreply.github.com> Date: Fri, 11 Nov 2022 16:29:33 +0100 Subject: [PATCH 15/17] Add Tristan as maintainer --- src/doc/rustc/src/platform-support/nto-qnx.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 2d4265334eaca..62d426bf3161b 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -12,6 +12,7 @@ and [BlackBerry][BlackBerry]. ## Target maintainers - Florian Bartels, `Florian.Bartels@elektrobit.com`, https://github.com/flba-eb +- Tristan Roach, `TRoach@blackberry.com`, https://github.com/gh-tr ## Requirements From f6d7f0807275f709adab2a3ead9c51d0f2291e9d Mon Sep 17 00:00:00 2001 From: StackDoubleFlow Date: Mon, 7 Nov 2022 22:42:07 -0600 Subject: [PATCH 16/17] Issue error when `-C link-self-contained` option is used on unsupported platforms Document supported targets for `-C link-self-contained` Move `LinkSelfContainedDefault::True` from wasm_base to wasm32_wasi --- compiler/rustc_codegen_ssa/src/back/link.rs | 3 +++ compiler/rustc_codegen_ssa/src/errors.rs | 4 ++++ compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl | 2 ++ compiler/rustc_target/src/spec/wasm32_wasi.rs | 6 +++++- compiler/rustc_target/src/spec/wasm_base.rs | 4 ---- src/doc/rustc/src/codegen-options/index.md | 4 ++-- 6 files changed, 16 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 5a1ad792924fc..cc9367f53265a 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1582,6 +1582,9 @@ fn detect_self_contained_mingw(sess: &Session) -> bool { /// We only provide such support for a very limited number of targets. fn self_contained(sess: &Session, crate_type: CrateType) -> bool { if let Some(self_contained) = sess.opts.cg.link_self_contained { + if sess.target.link_self_contained == LinkSelfContainedDefault::False { + sess.emit_err(errors::UnsupportedLinkSelfContained); + } return self_contained; } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 36c94462b0b3e..d24579364c476 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -521,3 +521,7 @@ pub enum AppleSdkRootError<'a> { #[diag(codegen_ssa_apple_sdk_error_sdk_path)] SdkPath { sdk_name: &'a str, error: Error }, } + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unsupported_link_self_contained)] +pub struct UnsupportedLinkSelfContained; diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index ad0d758210175..717c7816fabc2 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -182,3 +182,5 @@ codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$ codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}` codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {error} + +codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs index 93a956403e50f..6f0bbf0672d44 100644 --- a/compiler/rustc_target/src/spec/wasm32_wasi.rs +++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs @@ -72,7 +72,8 @@ //! best we can with this target. Don't start relying on too much here unless //! you know what you're getting in to! -use super::{crt_objects, wasm_base, Cc, LinkerFlavor, Target}; +use super::crt_objects::{self, LinkSelfContainedDefault}; +use super::{wasm_base, Cc, LinkerFlavor, Target}; pub fn target() -> Target { let mut options = wasm_base::options(); @@ -83,6 +84,9 @@ pub fn target() -> Target { options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained(); options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained(); + // FIXME: Figure out cases in which WASM needs to link with a native toolchain. + options.link_self_contained = LinkSelfContainedDefault::True; + // Right now this is a bit of a workaround but we're currently saying that // the target by default has a static crt which we're taking as a signal // for "use the bundled crt". If that's turned off then the system's crt diff --git a/compiler/rustc_target/src/spec/wasm_base.rs b/compiler/rustc_target/src/spec/wasm_base.rs index 528a84a8b37cb..625d3b37c4f26 100644 --- a/compiler/rustc_target/src/spec/wasm_base.rs +++ b/compiler/rustc_target/src/spec/wasm_base.rs @@ -1,4 +1,3 @@ -use super::crt_objects::LinkSelfContainedDefault; use super::{cvs, Cc, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel}; pub fn options() -> TargetOptions { @@ -95,9 +94,6 @@ pub fn options() -> TargetOptions { pre_link_args, - // FIXME: Figure out cases in which WASM needs to link with a native toolchain. - link_self_contained: LinkSelfContainedDefault::True, - // This has no effect in LLVM 8 or prior, but in LLVM 9 and later when // PIC code is implemented this has quite a drastic effect if it stays // at the default, `pic`. In an effort to keep wasm binaries as minimal diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index f5a49410ea555..7e355b7fccfc4 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -210,8 +210,8 @@ metrics. ## link-self-contained -On targets that support it this flag controls whether the linker will use libraries and objects -shipped with Rust instead or those in the system. +On `windows-gnu`, `linux-musl`, and `wasi` targets, this flag controls whether the +linker will use libraries and objects shipped with Rust instead or those in the system. It takes one of the following values: * no value: rustc will use heuristic to disable self-contained mode if system has necessary tools. From 934c4141cc56bda1f46d508df71d1ed8524fb915 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 11 Nov 2022 22:07:29 +0000 Subject: [PATCH 17/17] Update cargo 9 commits in 9286a1beba5b28b115bad67de2ae91fb1c61eb0b..a3dfea71ca0c888a88111086898aa833c291d497 2022-11-04 06:41:49 +0000 to 2022-11-11 03:50:47 +0000 - fix: return non UTF-8 error message (rust-lang/cargo#11321) - Extract `two_kinds_of_msg_format_err` message to de-duplicate it (rust-lang/cargo#11358) - Propagate change of artifact bin dep to its parent fingerprint (rust-lang/cargo#11353) - Fix not a hyperlink warnings (rust-lang/cargo#11357) - Fix wait-for-publish with sparse registry (rust-lang/cargo#11356) - Add `rm` alias to configuration docs (rust-lang/cargo#11351) - Add `registries.crates-io.protocol` docs (rust-lang/cargo#11350) - test(features2): test to prevent regressing of optional host deps of dep (rust-lang/cargo#11342) - Bump to 0.68.0, update changelog (rust-lang/cargo#11340) --- Cargo.lock | 2 +- src/tools/cargo | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ddacf9cf02463..c105d04c1f440 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -273,7 +273,7 @@ dependencies = [ [[package]] name = "cargo" -version = "0.67.0" +version = "0.68.0" dependencies = [ "anyhow", "atty", diff --git a/src/tools/cargo b/src/tools/cargo index 9286a1beba5b2..a3dfea71ca0c8 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 9286a1beba5b28b115bad67de2ae91fb1c61eb0b +Subproject commit a3dfea71ca0c888a88111086898aa833c291d497