diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 61d953cd6f1cc..753e2f07c042e 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -273,40 +273,58 @@ pub trait Emitter { DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr), }; - let bundle = match self.fluent_bundle() { - Some(bundle) if bundle.has_message(&identifier) => bundle, - _ => self.fallback_fluent_bundle(), - }; + let translate_with_bundle = |bundle: &'a FluentBundle| -> Option<(Cow<'_, str>, Vec<_>)> { + let message = bundle.get_message(&identifier)?; + let value = match attr { + Some(attr) => message.get_attribute(attr)?.value(), + None => message.value()?, + }; + debug!(?message, ?value); - let message = bundle.get_message(&identifier).expect("missing diagnostic in fluent bundle"); - let value = match attr { - Some(attr) => { - if let Some(attr) = message.get_attribute(attr) { - attr.value() - } else { - panic!("missing attribute `{attr}` in fluent message `{identifier}`") - } - } - None => { - if let Some(value) = message.value() { - value - } else { - panic!("missing value in fluent message `{identifier}`") - } - } + let mut errs = vec![]; + let translated = bundle.format_pattern(value, Some(&args), &mut errs); + debug!(?translated, ?errs); + Some((translated, errs)) }; - let mut err = vec![]; - let translated = bundle.format_pattern(value, Some(&args), &mut err); - trace!(?translated, ?err); - debug_assert!( - err.is_empty(), - "identifier: {:?}, args: {:?}, errors: {:?}", - identifier, - args, - err - ); - translated + self.fluent_bundle() + .and_then(|bundle| translate_with_bundle(bundle)) + // If `translate_with_bundle` returns `None` with the primary bundle, this is likely + // just that the primary bundle doesn't contain the message being translated, so + // proceed to the fallback bundle. + // + // However, when errors are produced from translation, then that means the translation + // is broken (e.g. `{$foo}` exists in a translation but `foo` isn't provided). + // + // In debug builds, assert so that compiler devs can spot the broken translation and + // fix it.. + .inspect(|(_, errs)| { + debug_assert!( + errs.is_empty(), + "identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}", + identifier, + attr, + args, + errs + ); + }) + // ..otherwise, for end users, an error about this wouldn't be useful or actionable, so + // just hide it and try with the fallback bundle. + .filter(|(_, errs)| errs.is_empty()) + .or_else(|| translate_with_bundle(self.fallback_fluent_bundle())) + .map(|(translated, errs)| { + // Always bail out for errors with the fallback bundle. + assert!( + errs.is_empty(), + "identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}", + identifier, + attr, + args, + errs + ); + translated + }) + .expect("failed to find message in primary or fallback fluent bundles") } /// Formats the substitutions of the primary_span diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 15c1858023de7..f83e972efd56e 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -6,9 +6,10 @@ #![feature(drain_filter)] #![feature(if_let_guard)] #![cfg_attr(bootstrap, feature(let_chains))] +#![feature(adt_const_params)] #![feature(let_else)] #![feature(never_type)] -#![feature(adt_const_params)] +#![feature(result_option_inspect)] #![feature(rustc_attrs)] #![allow(incomplete_features)] #![allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 72c23776d3399..197c038489835 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -68,7 +68,12 @@ impl<'a> Parser<'a> { if !self.maybe_consume_incorrect_semicolon(&items) { let msg = &format!("expected item, found {token_str}"); let mut err = self.struct_span_err(self.token.span, msg); - err.span_label(self.token.span, "expected item"); + let label = if self.is_kw_followed_by_ident(kw::Let) { + "consider using `const` or `static` instead of `let` for global variables" + } else { + "expected item" + }; + err.span_label(self.token.span, label); return Err(err); } } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 6a8298605a23b..b7acde6ed794f 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2423,13 +2423,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let pretty = parse_pretty(&unstable_opts, error_format); - if !unstable_opts.unstable_options - && !target_triple.triple().contains("apple") - && cg.split_debuginfo.is_some() - { - early_error(error_format, "`-Csplit-debuginfo` is unstable on this platform"); - } - // Try to find a directory containing the Rust `src`, for more details see // the doc comment on the `real_rust_source_base_dir` field. let tmp_buf; diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 9669287b3f370..538110d6e3587 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -661,8 +661,9 @@ impl Session { ) } + /// Returns `true` if the target can use the current split debuginfo configuration. pub fn target_can_use_split_dwarf(&self) -> bool { - !self.target.is_like_windows && !self.target.is_like_osx + self.target.options.supported_split_debuginfo.contains(&self.split_debuginfo()) } pub fn generate_proc_macro_decls_symbol(&self, stable_crate_id: StableCrateId) -> String { @@ -1543,6 +1544,13 @@ fn validate_commandline_args_with_session_available(sess: &Session) { sess.err(&format!("requested DWARF version {} is greater than 5", dwarf_version)); } } + + if !sess.target_can_use_split_dwarf() && !sess.opts.unstable_opts.unstable_options { + sess.err(&format!( + "`-Csplit-debuginfo={}` is unstable on this platform", + sess.split_debuginfo() + )); + } } /// Holds data on the current incremental compilation session, if there is one. diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index db38ff50c7878..d2f9984760170 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -79,6 +79,11 @@ pub fn opts(os: &'static str, arch: &'static str, abi: &'static str) -> TargetOp // The historical default for macOS targets is to run `dsymutil` which // generates a packed version of debuginfo split from the main file. split_debuginfo: SplitDebuginfo::Packed, + supported_split_debuginfo: Cow::Borrowed(&[ + SplitDebuginfo::Packed, + SplitDebuginfo::Unpacked, + SplitDebuginfo::Off, + ]), // This environment variable is pretty magical but is intended for // producing deterministic builds. This was first discovered to be used diff --git a/compiler/rustc_target/src/spec/linux_base.rs b/compiler/rustc_target/src/spec/linux_base.rs index f4fce3b4050aa..df8e848124a9b 100644 --- a/compiler/rustc_target/src/spec/linux_base.rs +++ b/compiler/rustc_target/src/spec/linux_base.rs @@ -1,4 +1,5 @@ -use crate::spec::{cvs, RelroLevel, TargetOptions}; +use crate::spec::{cvs, RelroLevel, SplitDebuginfo, TargetOptions}; +use std::borrow::Cow; pub fn opts() -> TargetOptions { TargetOptions { @@ -10,6 +11,11 @@ pub fn opts() -> TargetOptions { relro_level: RelroLevel::Full, has_thread_local: true, crt_static_respected: true, + supported_split_debuginfo: Cow::Borrowed(&[ + SplitDebuginfo::Packed, + SplitDebuginfo::Unpacked, + SplitDebuginfo::Off, + ]), ..Default::default() } } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index f7abeafd38f10..2c832a732663f 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1441,6 +1441,8 @@ pub struct TargetOptions { /// How to handle split debug information, if at all. Specifying `None` has /// target-specific meaning. pub split_debuginfo: SplitDebuginfo, + /// Which kinds of split debuginfo are supported by the target? + pub supported_split_debuginfo: StaticCow<[SplitDebuginfo]>, /// The sanitizers supported by this target /// @@ -1599,6 +1601,8 @@ impl Default for TargetOptions { eh_frame_header: true, has_thumb_interworking: false, split_debuginfo: SplitDebuginfo::Off, + // `Off` is supported by default, but targets can remove this manually, e.g. Windows. + supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]), supported_sanitizers: SanitizerSet::empty(), default_adjusted_cabi: None, c_enum_min_bits: 32, @@ -1907,6 +1911,25 @@ impl Target { } } } ); + ($key_name:ident, falliable_list) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|j| { + if let Some(v) = j.as_array() { + match v.iter().map(|a| FromStr::from_str(a.as_str().unwrap())).collect() { + Ok(l) => { base.$key_name = l }, + // FIXME: `falliable_list` can't re-use the `key!` macro for list + // elements and the error messages from that macro, so it has a bad + // generic message instead + Err(_) => return Some(Err( + format!("`{:?}` is not a valid value for `{}`", j, name) + )), + } + } else { + incorrect_type.push(name) + } + Some(Ok(())) + }).unwrap_or(Ok(())) + } ); ($key_name:ident, optional) => ( { let name = (stringify!($key_name)).replace("_", "-"); if let Some(o) = obj.remove(&name) { @@ -2194,6 +2217,7 @@ impl Target { key!(eh_frame_header, bool); key!(has_thumb_interworking, bool); key!(split_debuginfo, SplitDebuginfo)?; + key!(supported_split_debuginfo, falliable_list)?; key!(supported_sanitizers, SanitizerSet)?; key!(default_adjusted_cabi, Option)?; key!(c_enum_min_bits, u64); @@ -2438,6 +2462,7 @@ impl ToJson for Target { target_option_val!(eh_frame_header); target_option_val!(has_thumb_interworking); target_option_val!(split_debuginfo); + target_option_val!(supported_split_debuginfo); target_option_val!(supported_sanitizers); target_option_val!(c_enum_min_bits); target_option_val!(generate_arange_section); diff --git a/compiler/rustc_target/src/spec/msvc_base.rs b/compiler/rustc_target/src/spec/msvc_base.rs index edb30b72bf68d..ec9609a2b26a1 100644 --- a/compiler/rustc_target/src/spec/msvc_base.rs +++ b/compiler/rustc_target/src/spec/msvc_base.rs @@ -1,4 +1,5 @@ use crate::spec::{LinkerFlavor, LldFlavor, SplitDebuginfo, TargetOptions}; +use std::borrow::Cow; pub fn opts() -> TargetOptions { // Suppress the verbose logo and authorship debugging output, which would needlessly @@ -18,6 +19,7 @@ pub fn opts() -> TargetOptions { // Currently this is the only supported method of debuginfo on MSVC // where `*.pdb` files show up next to the final artifact. split_debuginfo: SplitDebuginfo::Packed, + supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Packed]), ..Default::default() } diff --git a/compiler/rustc_target/src/spec/windows_gnu_base.rs b/compiler/rustc_target/src/spec/windows_gnu_base.rs index 90e0af3e38afe..296345f651826 100644 --- a/compiler/rustc_target/src/spec/windows_gnu_base.rs +++ b/compiler/rustc_target/src/spec/windows_gnu_base.rs @@ -1,5 +1,6 @@ use crate::spec::crt_objects::{self, CrtObjectsFallback}; -use crate::spec::{cvs, LinkerFlavor, TargetOptions}; +use crate::spec::{cvs, LinkerFlavor, SplitDebuginfo, TargetOptions}; +use std::borrow::Cow; pub fn opts() -> TargetOptions { let mut pre_link_args = TargetOptions::link_args( @@ -86,6 +87,8 @@ pub fn opts() -> TargetOptions { emit_debug_gdb_scripts: false, requires_uwtable: true, eh_frame_header: false, + // FIXME(davidtwco): Support Split DWARF on Windows GNU. + supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]), ..Default::default() } } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 758f1ef97664f..1e6cb53f3eeae 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -44,7 +44,7 @@ use rustc_trait_selection::traits::error_reporting::{ }; use rustc_trait_selection::traits::wf::object_region_bounds; -use smallvec::SmallVec; +use smallvec::{smallvec, SmallVec}; use std::collections::BTreeSet; use std::slice; @@ -368,36 +368,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { return (tcx.intern_substs(&[]), arg_count); } - let is_object = self_ty.map_or(false, |ty| ty == self.tcx().types.trait_object_dummy_self); - struct SubstsForAstPathCtxt<'a, 'tcx> { astconv: &'a (dyn AstConv<'tcx> + 'a), def_id: DefId, generic_args: &'a GenericArgs<'a>, span: Span, - missing_type_params: Vec, inferred_params: Vec, infer_args: bool, - is_object: bool, - } - - impl<'tcx, 'a> SubstsForAstPathCtxt<'tcx, 'a> { - fn default_needs_object_self(&mut self, param: &ty::GenericParamDef) -> bool { - let tcx = self.astconv.tcx(); - if let GenericParamDefKind::Type { has_default, .. } = param.kind { - if self.is_object && has_default { - let default_ty = tcx.at(self.span).type_of(param.def_id); - let self_param = tcx.types.self_param; - if default_ty.walk().any(|arg| arg == self_param.into()) { - // There is no suitable inference default for a type parameter - // that references self, in an object type. - return true; - } - } - } - - false - } } impl<'a, 'tcx> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for SubstsForAstPathCtxt<'a, 'tcx> { @@ -500,41 +477,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { GenericParamDefKind::Type { has_default, .. } => { if !infer_args && has_default { // No type parameter provided, but a default exists. - - // If we are converting an object type, then the - // `Self` parameter is unknown. However, some of the - // other type parameters may reference `Self` in their - // defaults. This will lead to an ICE if we are not - // careful! - if self.default_needs_object_self(param) { - self.missing_type_params.push(param.name); - tcx.ty_error().into() - } else { - // This is a default type parameter. - let substs = substs.unwrap(); - if substs.iter().any(|arg| match arg.unpack() { - GenericArgKind::Type(ty) => ty.references_error(), - _ => false, - }) { - // Avoid ICE #86756 when type error recovery goes awry. - return tcx.ty_error().into(); - } - self.astconv - .normalize_ty( - self.span, - EarlyBinder(tcx.at(self.span).type_of(param.def_id)) - .subst(tcx, substs), - ) - .into() + let substs = substs.unwrap(); + if substs.iter().any(|arg| match arg.unpack() { + GenericArgKind::Type(ty) => ty.references_error(), + _ => false, + }) { + // Avoid ICE #86756 when type error recovery goes awry. + return tcx.ty_error().into(); } + self.astconv + .normalize_ty( + self.span, + EarlyBinder(tcx.at(self.span).type_of(param.def_id)) + .subst(tcx, substs), + ) + .into() } else if infer_args { - // No type parameters were provided, we can infer all. - let param = if !self.default_needs_object_self(param) { - Some(param) - } else { - None - }; - self.astconv.ty_infer(param, self.span).into() + self.astconv.ty_infer(Some(param), self.span).into() } else { // We've already errored above about the mismatch. tcx.ty_error().into() @@ -564,10 +523,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { def_id, span, generic_args, - missing_type_params: vec![], inferred_params: vec![], infer_args, - is_object, }; let substs = Self::create_substs_for_generic_args( tcx, @@ -579,13 +536,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &mut substs_ctx, ); - self.complain_about_missing_type_params( - substs_ctx.missing_type_params, - def_id, - span, - generic_args.args.is_empty(), - ); - debug!( "create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}", generics, self_ty, substs @@ -1490,23 +1440,71 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Erase the `dummy_self` (`trait_object_dummy_self`) used above. let existential_trait_refs = regular_traits.iter().map(|i| { i.trait_ref().map_bound(|trait_ref: ty::TraitRef<'tcx>| { - if trait_ref.self_ty() != dummy_self { - // FIXME: There appears to be a missing filter on top of `expand_trait_aliases`, - // which picks up non-supertraits where clauses - but also, the object safety - // completely ignores trait aliases, which could be object safety hazards. We - // `delay_span_bug` here to avoid an ICE in stable even when the feature is - // disabled. (#66420) - tcx.sess.delay_span_bug( - DUMMY_SP, - &format!( - "trait_ref_to_existential called on {:?} with non-dummy Self", - trait_ref, - ), + assert_eq!(trait_ref.self_ty(), dummy_self); + + // Verify that `dummy_self` did not leak inside default type parameters. This + // could not be done at path creation, since we need to see through trait aliases. + let mut missing_type_params = vec![]; + let mut references_self = false; + let generics = tcx.generics_of(trait_ref.def_id); + let substs: Vec<_> = trait_ref + .substs + .iter() + .enumerate() + .skip(1) // Remove `Self` for `ExistentialPredicate`. + .map(|(index, arg)| { + if let ty::GenericArgKind::Type(ty) = arg.unpack() { + debug!(?ty); + if ty == dummy_self { + let param = &generics.params[index]; + missing_type_params.push(param.name); + tcx.ty_error().into() + } else if ty.walk().any(|arg| arg == dummy_self.into()) { + references_self = true; + tcx.ty_error().into() + } else { + arg + } + } else { + arg + } + }) + .collect(); + let substs = tcx.intern_substs(&substs[..]); + + let span = i.bottom().1; + let empty_generic_args = trait_bounds.iter().any(|hir_bound| { + hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id) + && hir_bound.span.contains(span) + }); + self.complain_about_missing_type_params( + missing_type_params, + trait_ref.def_id, + span, + empty_generic_args, + ); + + if references_self { + let def_id = i.bottom().0.def_id(); + let mut err = struct_span_err!( + tcx.sess, + i.bottom().1, + E0038, + "the {} `{}` cannot be made into an object", + tcx.def_kind(def_id).descr(def_id), + tcx.item_name(def_id), + ); + err.note( + rustc_middle::traits::ObjectSafetyViolation::SupertraitSelf(smallvec![]) + .error_msg(), ); + err.emit(); } - ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) + + ty::ExistentialTraitRef { def_id: trait_ref.def_id, substs } }) }); + let existential_projections = bounds.projection_bounds.iter().map(|(bound, _)| { bound.map_bound(|b| { if b.projection_ty.self_ty() != dummy_self { diff --git a/library/core/src/alloc/global.rs b/library/core/src/alloc/global.rs index 887246c600144..6756eecd0e0f8 100644 --- a/library/core/src/alloc/global.rs +++ b/library/core/src/alloc/global.rs @@ -74,7 +74,7 @@ use crate::ptr; /// { /// return null_mut(); /// }; -/// (self.arena.get() as *mut u8).add(allocated) +/// self.arena.get().cast::().add(allocated) /// } /// unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} /// } diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index c0f609a01b5c8..c25b159c533a1 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1267,20 +1267,21 @@ impl *const T { /// Accessing adjacent `u8` as `u16` /// /// ``` - /// # fn foo(n: usize) { - /// # use std::mem::align_of; + /// use std::mem::align_of; + /// /// # unsafe { - /// let x = [5u8, 6u8, 7u8, 8u8, 9u8]; - /// let ptr = x.as_ptr().add(n) as *const u8; + /// let x = [5_u8, 6, 7, 8, 9]; + /// let ptr = x.as_ptr(); /// let offset = ptr.align_offset(align_of::()); - /// if offset < x.len() - n - 1 { - /// let u16_ptr = ptr.add(offset) as *const u16; - /// assert_ne!(*u16_ptr, 500); + /// + /// if offset < x.len() - 1 { + /// let u16_ptr = ptr.add(offset).cast::(); + /// assert!(*u16_ptr == u16::from_ne_bytes([5, 6]) || *u16_ptr == u16::from_ne_bytes([6, 7])); /// } else { /// // while the pointer can be aligned via `offset`, it would point /// // outside the allocation /// } - /// # } } + /// # } /// ``` #[stable(feature = "align_offset", since = "1.36.0")] #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 7059d0008c4c4..fff06b458c7c1 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1545,20 +1545,23 @@ impl *mut T { /// Accessing adjacent `u8` as `u16` /// /// ``` - /// # fn foo(n: usize) { - /// # use std::mem::align_of; + /// use std::mem::align_of; + /// /// # unsafe { - /// let x = [5u8, 6u8, 7u8, 8u8, 9u8]; - /// let ptr = x.as_ptr().add(n) as *const u8; + /// let mut x = [5_u8, 6, 7, 8, 9]; + /// let ptr = x.as_mut_ptr(); /// let offset = ptr.align_offset(align_of::()); - /// if offset < x.len() - n - 1 { - /// let u16_ptr = ptr.add(offset) as *const u16; - /// assert_ne!(*u16_ptr, 500); + /// + /// if offset < x.len() - 1 { + /// let u16_ptr = ptr.add(offset).cast::(); + /// *u16_ptr = 0; + /// + /// assert!(x == [0, 0, 7, 8, 9] || x == [5, 0, 0, 8, 9]); /// } else { /// // while the pointer can be aligned via `offset`, it would point /// // outside the allocation /// } - /// # } } + /// # } /// ``` #[stable(feature = "align_offset", since = "1.36.0")] #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index f1e659309674c..f43b780ec9a90 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -92,7 +92,7 @@ impl<'a, T> Iter<'a, T> { assume(!ptr.is_null()); let end = if mem::size_of::() == 0 { - (ptr as *const u8).wrapping_add(slice.len()) as *const T + ptr.wrapping_byte_add(slice.len()) } else { ptr.add(slice.len()) }; @@ -228,7 +228,7 @@ impl<'a, T> IterMut<'a, T> { assume(!ptr.is_null()); let end = if mem::size_of::() == 0 { - (ptr as *mut u8).wrapping_add(slice.len()) as *mut T + ptr.wrapping_byte_add(slice.len()) } else { ptr.add(slice.len()) }; diff --git a/library/core/tests/const_ptr.rs b/library/core/tests/const_ptr.rs index 152fed803ecdb..d874f08317f61 100644 --- a/library/core/tests/const_ptr.rs +++ b/library/core/tests/const_ptr.rs @@ -3,7 +3,7 @@ const DATA: [u16; 2] = [u16::from_ne_bytes([0x01, 0x23]), u16::from_ne_bytes([0x const fn unaligned_ptr() -> *const u16 { // Since DATA.as_ptr() is aligned to two bytes, adding 1 byte to that produces an unaligned *const u16 - unsafe { (DATA.as_ptr() as *const u8).add(1) as *const u16 } + unsafe { DATA.as_ptr().byte_add(1) } } #[test] @@ -67,7 +67,7 @@ fn write() { const fn write_unaligned() -> [u16; 2] { let mut two_aligned = [0u16; 2]; unsafe { - let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16; + let unaligned_ptr = two_aligned.as_mut_ptr().byte_add(1); ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45])); } two_aligned @@ -91,7 +91,7 @@ fn mut_ptr_write() { const fn write_unaligned() -> [u16; 2] { let mut two_aligned = [0u16; 2]; unsafe { - let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16; + let unaligned_ptr = two_aligned.as_mut_ptr().byte_add(1); unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45])); } two_aligned diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index db94368f6e0cc..df9b1073a0994 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -14,6 +14,7 @@ #![feature(const_maybe_uninit_assume_init_read)] #![feature(const_nonnull_new)] #![feature(const_num_from_num)] +#![feature(const_pointer_byte_offsets)] #![feature(const_ptr_as_ref)] #![feature(const_ptr_read)] #![feature(const_ptr_write)] @@ -74,6 +75,7 @@ #![feature(never_type)] #![feature(unwrap_infallible)] #![feature(result_into_ok_or_err)] +#![feature(pointer_byte_offsets)] #![feature(portable_simd)] #![feature(ptr_metadata)] #![feature(once_cell)] diff --git a/library/std/src/sys/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/sgx/abi/usercalls/alloc.rs index ea24fedd0eb3d..66fa1efbf103f 100644 --- a/library/std/src/sys/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/sgx/abi/usercalls/alloc.rs @@ -115,7 +115,7 @@ pub unsafe trait UserSafe { /// * the pointer is null. /// * the pointed-to range is not in user memory. unsafe fn check_ptr(ptr: *const Self) { - let is_aligned = |p| -> bool { 0 == (p as usize) & (Self::align_of() - 1) }; + let is_aligned = |p: *const u8| -> bool { 0 == p.addr() & (Self::align_of() - 1) }; assert!(is_aligned(ptr as *const u8)); assert!(is_user_range(ptr as _, mem::size_of_val(unsafe { &*ptr }))); diff --git a/library/std/src/sys/unsupported/alloc.rs b/library/std/src/sys/unsupported/alloc.rs index 8d5d0a2f5ccd1..d715ae45401e6 100644 --- a/library/std/src/sys/unsupported/alloc.rs +++ b/library/std/src/sys/unsupported/alloc.rs @@ -1,15 +1,16 @@ use crate::alloc::{GlobalAlloc, Layout, System}; +use crate::ptr::null_mut; #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { - 0 as *mut u8 + null_mut() } #[inline] unsafe fn alloc_zeroed(&self, _layout: Layout) -> *mut u8 { - 0 as *mut u8 + null_mut() } #[inline] @@ -17,6 +18,6 @@ unsafe impl GlobalAlloc for System { #[inline] unsafe fn realloc(&self, _ptr: *mut u8, _layout: Layout, _new_size: usize) -> *mut u8 { - 0 as *mut u8 + null_mut() } } diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 0ab4824ac0a73..c041da34b844a 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1759,23 +1759,21 @@ impl<'a> Builder<'a> { }, ); - if !target.contains("windows") { - let needs_unstable_opts = target.contains("linux") - || target.contains("solaris") - || target.contains("windows") - || target.contains("bsd") - || target.contains("dragonfly") - || target.contains("illumos"); - - if needs_unstable_opts { - rustflags.arg("-Zunstable-options"); - } - match self.config.rust_split_debuginfo { - SplitDebuginfo::Packed => rustflags.arg("-Csplit-debuginfo=packed"), - SplitDebuginfo::Unpacked => rustflags.arg("-Csplit-debuginfo=unpacked"), - SplitDebuginfo::Off => rustflags.arg("-Csplit-debuginfo=off"), - }; + let split_debuginfo_is_stable = target.contains("linux") + || target.contains("apple") + || (target.contains("msvc") + && self.config.rust_split_debuginfo == SplitDebuginfo::Packed) + || (target.contains("windows") + && self.config.rust_split_debuginfo == SplitDebuginfo::Off); + + if !split_debuginfo_is_stable { + rustflags.arg("-Zunstable-options"); } + match self.config.rust_split_debuginfo { + SplitDebuginfo::Packed => rustflags.arg("-Csplit-debuginfo=packed"), + SplitDebuginfo::Unpacked => rustflags.arg("-Csplit-debuginfo=unpacked"), + SplitDebuginfo::Off => rustflags.arg("-Csplit-debuginfo=off"), + }; if self.config.cmd.bless() { // Bless `expect!` tests. diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 91d5758077c94..1a4786c9b0664 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -415,29 +415,28 @@ impl Item { .unwrap_or(false) } - pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Span { + pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Option { let kind = match &*self.kind { ItemKind::StrippedItem(k) => k, _ => &*self.kind, }; match kind { - ItemKind::ModuleItem(Module { span, .. }) => *span, - ItemKind::ImplItem(box Impl { kind: ImplKind::Auto, .. }) => Span::dummy(), + ItemKind::ModuleItem(Module { span, .. }) => Some(*span), + ItemKind::ImplItem(box Impl { kind: ImplKind::Auto, .. }) => None, ItemKind::ImplItem(box Impl { kind: ImplKind::Blanket(_), .. }) => { if let ItemId::Blanket { impl_id, .. } = self.item_id { - rustc_span(impl_id, tcx) + Some(rustc_span(impl_id, tcx)) } else { panic!("blanket impl item has non-blanket ID") } } - _ => { - self.item_id.as_def_id().map(|did| rustc_span(did, tcx)).unwrap_or_else(Span::dummy) - } + _ => self.item_id.as_def_id().map(|did| rustc_span(did, tcx)), } } pub(crate) fn attr_span(&self, tcx: TyCtxt<'_>) -> rustc_span::Span { - crate::passes::span_of_attrs(&self.attrs).unwrap_or_else(|| self.span(tcx).inner()) + crate::passes::span_of_attrs(&self.attrs) + .unwrap_or_else(|| self.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner())) } /// Finds the `doc` attribute as a NameValue and returns the corresponding @@ -2109,14 +2108,6 @@ impl Span { self.0 } - pub(crate) fn dummy() -> Self { - Self(rustc_span::DUMMY_SP) - } - - pub(crate) fn is_dummy(&self) -> bool { - self.0.is_dummy() - } - pub(crate) fn filename(&self, sess: &Session) -> FileName { sess.source_map().span_to_filename(self.0) } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 2ed7a6f1bb144..3863980339aca 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -301,13 +301,12 @@ impl<'tcx> Context<'tcx> { /// may happen, for example, with externally inlined items where the source /// of their crate documentation isn't known. pub(super) fn src_href(&self, item: &clean::Item) -> Option { - self.href_from_span(item.span(self.tcx()), true) + self.href_from_span(item.span(self.tcx())?, true) } pub(crate) fn href_from_span(&self, span: clean::Span, with_lines: bool) -> Option { - if span.is_dummy() { - return None; - } + assert!(!span.inner().is_dummy()); + let mut root = self.root_path(); let mut path = String::new(); let cnum = span.cnum(self.sess()); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 09c54969ef122..5ed5299e09bc0 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2677,7 +2677,7 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite let contents = match fs::read_to_string(&path) { Ok(contents) => contents, Err(err) => { - let span = item.span(tcx).inner(); + let span = item.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner()); tcx.sess .span_err(span, &format!("failed to read file {}: {}", path.display(), err)); return false; diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index f508808a8b6f5..f37c54e42983f 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -53,6 +53,7 @@ impl LocalSourcesCollector<'_, '_> { fn add_local_source(&mut self, item: &clean::Item) { let sess = self.tcx.sess; let span = item.span(self.tcx); + let Some(span) = span else { return }; // skip all synthetic "files" if !is_real_and_local(span, sess) { return; @@ -109,6 +110,7 @@ impl DocVisitor for SourceCollector<'_, '_> { let tcx = self.cx.tcx(); let span = item.span(tcx); + let Some(span) = span else { return }; let sess = tcx.sess; // If we're not rendering sources, there's nothing to do. diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 4c21fd553289b..14d99f3410d43 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -59,7 +59,7 @@ impl JsonRenderer<'_> { id: from_item_id_with_name(item_id, self.tcx, name), crate_id: item_id.krate().as_u32(), name: name.map(|sym| sym.to_string()), - span: self.convert_span(span), + span: span.and_then(|span| self.convert_span(span)), visibility: self.convert_visibility(visibility), docs, attrs, diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 4c6e3eb040d27..48835abf9525b 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -215,7 +215,6 @@ impl<'a, 'b> DocVisitor for CoverageCalculator<'a, 'b> { None, ); - let filename = i.span(self.ctx.tcx).filename(self.ctx.sess()); let has_doc_example = tests.found_tests != 0; // The `expect_def_id()` should be okay because `local_def_id_to_hir_id` // would presumably panic if a fake `DefIndex` were passed. @@ -261,13 +260,16 @@ impl<'a, 'b> DocVisitor for CoverageCalculator<'a, 'b> { let should_have_docs = !should_be_ignored && (level != lint::Level::Allow || matches!(source, LintLevelSource::Default)); - debug!("counting {:?} {:?} in {:?}", i.type_(), i.name, filename); - self.items.entry(filename).or_default().count_item( - has_docs, - has_doc_example, - should_have_doc_example(self.ctx, i), - should_have_docs, - ); + if let Some(span) = i.span(self.ctx.tcx) { + let filename = span.filename(self.ctx.sess()); + debug!("counting {:?} {:?} in {:?}", i.type_(), i.name, filename); + self.items.entry(filename).or_default().count_item( + has_docs, + has_doc_example, + should_have_doc_example(self.ctx, i), + should_have_docs, + ); + } } } diff --git a/src/test/incremental/split_debuginfo_cached.rs b/src/test/incremental/split_debuginfo_cached.rs index 25c802d5a1d2e..ba8385f89a726 100644 --- a/src/test/incremental/split_debuginfo_cached.rs +++ b/src/test/incremental/split_debuginfo_cached.rs @@ -6,8 +6,8 @@ // only-x86_64-unknown-linux-gnu // revisions:rpass1 rpass2 -// [rpass1]compile-flags: -g -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split -// [rpass2]compile-flags: -g -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split +// [rpass1]compile-flags: -g -Zquery-dep-graph -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split +// [rpass2]compile-flags: -g -Zquery-dep-graph -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split #![feature(rustc_attrs)] // For `rpass2`, nothing has changed so everything should re-used. diff --git a/src/test/incremental/split_debuginfo_mode.rs b/src/test/incremental/split_debuginfo_mode.rs index f2533e4146a84..edc1a80d30e0e 100644 --- a/src/test/incremental/split_debuginfo_mode.rs +++ b/src/test/incremental/split_debuginfo_mode.rs @@ -6,10 +6,10 @@ // only-x86_64-unknown-linux-gnu // revisions:rpass1 rpass2 rpass3 rpass4 -// [rpass1]compile-flags: -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=single -Zsplit-dwarf-inlining=on -// [rpass2]compile-flags: -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=packed -Zsplit-dwarf-kind=single -Zsplit-dwarf-inlining=on -// [rpass3]compile-flags: -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split -Zsplit-dwarf-inlining=on -// [rpass4]compile-flags: -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split -Zsplit-dwarf-inlining=off +// [rpass1]compile-flags: -Zquery-dep-graph -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=single -Zsplit-dwarf-inlining=on +// [rpass2]compile-flags: -Zquery-dep-graph -Csplit-debuginfo=packed -Zsplit-dwarf-kind=single -Zsplit-dwarf-inlining=on +// [rpass3]compile-flags: -Zquery-dep-graph -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split -Zsplit-dwarf-inlining=on +// [rpass4]compile-flags: -Zquery-dep-graph -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split -Zsplit-dwarf-inlining=off #![feature(rustc_attrs)] // For rpass2 we change -Csplit-debuginfo and thus expect every CGU to be recompiled diff --git a/src/test/run-make-fulldeps/split-debuginfo/Makefile b/src/test/run-make-fulldeps/split-debuginfo/Makefile index e2dc64d8ce2dd..61c79cb3103cc 100644 --- a/src/test/run-make-fulldeps/split-debuginfo/Makefile +++ b/src/test/run-make-fulldeps/split-debuginfo/Makefile @@ -36,7 +36,7 @@ unpacked: else # If disabled, don't run dsymutil off: - $(RUSTC) foo.rs -g -C split-debuginfo=off -Z unstable-options + $(RUSTC) foo.rs -g -C split-debuginfo=off [ ! -f $(TMPDIR)/*.dwp ] [ ! -f $(TMPDIR)/*.dwo ] @@ -47,12 +47,12 @@ off: packed: packed-split packed-single packed-split: - $(RUSTC) foo.rs -g -C split-debuginfo=packed -Z unstable-options -Zsplit-dwarf-kind=split + $(RUSTC) foo.rs -g -C split-debuginfo=packed -Zsplit-dwarf-kind=split ls $(TMPDIR)/*.dwp rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo packed-single: - $(RUSTC) foo.rs -g -C split-debuginfo=packed -Z unstable-options -Zsplit-dwarf-kind=single + $(RUSTC) foo.rs -g -C split-debuginfo=packed -Zsplit-dwarf-kind=single ls $(TMPDIR)/*.dwp ls $(TMPDIR)/*.dwo && exit 1 || exit 0 rm -rf $(TMPDIR)/*.dwp @@ -60,19 +60,19 @@ packed-single: packed-remapped: packed-remapped-split packed-remapped-single packed-remapped-split: - $(RUSTC) -Z unstable-options -C split-debuginfo=packed -C debuginfo=2 \ + $(RUSTC) -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 packed-remapped-single: - $(RUSTC) -Z unstable-options -C split-debuginfo=packed -C debuginfo=2 \ + $(RUSTC) -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 packed-crosscrate: packed-crosscrate-split packed-crosscrate-single packed-crosscrate-split: - $(RUSTC) --crate-type lib -Z unstable-options -C split-debuginfo=packed \ + $(RUSTC) --crate-type lib -C split-debuginfo=packed \ -Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs ls $(TMPDIR)/*.rlib ls $(TMPDIR)/*.dwo && exit 1 || exit 0 @@ -84,7 +84,7 @@ packed-crosscrate-split: rm $(TMPDIR)/$(call BIN,main) packed-crosscrate-single: - $(RUSTC) --crate-type lib -Z unstable-options -C split-debuginfo=packed \ + $(RUSTC) --crate-type lib -C split-debuginfo=packed \ -Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs ls $(TMPDIR)/*.rlib ls $(TMPDIR)/*.dwo && exit 1 || exit 0 @@ -98,23 +98,23 @@ packed-crosscrate-single: unpacked: unpacked-split unpacked-single unpacked-remapped-split unpacked-remapped-single unpacked-split: - $(RUSTC) foo.rs -g -C split-debuginfo=unpacked -Z unstable-options -Zsplit-dwarf-kind=split + $(RUSTC) foo.rs -g -C split-debuginfo=unpacked -Zsplit-dwarf-kind=split ls $(TMPDIR)/*.dwp && exit 1 || exit 0 ls $(TMPDIR)/*.dwo rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo unpacked-single: - $(RUSTC) foo.rs -g -C split-debuginfo=unpacked -Z unstable-options -Zsplit-dwarf-kind=single + $(RUSTC) foo.rs -g -C split-debuginfo=unpacked -Zsplit-dwarf-kind=single ls $(TMPDIR)/*.dwp && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 unpacked-remapped-split: - $(RUSTC) -Z unstable-options -C split-debuginfo=unpacked -C debuginfo=2 \ + $(RUSTC) -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 unpacked-remapped-single: - $(RUSTC) -Z unstable-options -C split-debuginfo=unpacked -C debuginfo=2 \ + $(RUSTC) -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 endif diff --git a/src/test/run-make/translation/Makefile b/src/test/run-make/translation/Makefile index bfff75e7acb08..20e86c7f9a072 100644 --- a/src/test/run-make/translation/Makefile +++ b/src/test/run-make/translation/Makefile @@ -9,16 +9,29 @@ FAKEROOT=$(TMPDIR)/fakeroot all: normal custom sysroot -normal: basic-translation.rs +# Check that the test works normally, using the built-in fallback bundle. +normal: test.rs $(RUSTC) $< 2>&1 | grep "struct literal body without path" -custom: basic-translation.rs basic-translation.ftl - $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/basic-translation.ftl 2>&1 | grep "this is a test message" +# Check that a primary bundle can be loaded and will be preferentially used +# where possible. +custom: test.rs working.ftl + $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/working.ftl 2>&1 | grep "this is a test message" + +# Check that a primary bundle with a broken message (e.g. a interpolated +# variable is missing) will use the fallback bundle. +missing: test.rs missing.ftl + $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/missing.ftl 2>&1 | grep "struct literal body without path" + +# Check that a primary bundle without the desired message will use the fallback +# bundle. +broken: test.rs broken.ftl + $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/broken.ftl 2>&1 | grep "struct literal body without path" # Check that a locale can be loaded from the sysroot given a language # identifier by making a local copy of the sysroot and adding the custom locale # to it. -sysroot: basic-translation.rs basic-translation.ftl +sysroot: test.rs working.ftl mkdir $(FAKEROOT) ln -s $(SYSROOT)/* $(FAKEROOT) rm -f $(FAKEROOT)/lib @@ -31,7 +44,7 @@ sysroot: basic-translation.rs basic-translation.ftl mkdir $(FAKEROOT)/lib/rustlib/src ln -s $(SYSROOT)/lib/rustlib/src/* $(FAKEROOT)/lib/rustlib/src mkdir -p $(FAKEROOT)/share/locale/zh-CN/ - ln -s $(CURDIR)/basic-translation.ftl $(FAKEROOT)/share/locale/zh-CN/basic-translation.ftl + ln -s $(CURDIR)/working.ftl $(FAKEROOT)/share/locale/zh-CN/basic-translation.ftl $(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 | grep "this is a test message" # Check that the compiler errors out when the sysroot requested cannot be @@ -43,7 +56,7 @@ sysroot-missing: # Check that the compiler errors out when the sysroot requested cannot be # found. This test might start failing if there actually exists a Klingon # translation of rustc's error messages. -sysroot-invalid: basic-translation.rs basic-translation.ftl +sysroot-invalid: test.rs working.ftl mkdir $(FAKEROOT) ln -s $(SYSROOT)/* $(FAKEROOT) rm -f $(FAKEROOT)/lib diff --git a/src/test/run-make/translation/broken.ftl b/src/test/run-make/translation/broken.ftl new file mode 100644 index 0000000000000..1482dd2824aed --- /dev/null +++ b/src/test/run-make/translation/broken.ftl @@ -0,0 +1,3 @@ +# `foo` isn't provided by this diagnostic so it is expected that the fallback message is used. +parser-struct-literal-body-without-path = this is a {$foo} message + .suggestion = this is a test suggestion diff --git a/src/test/run-make/translation/missing.ftl b/src/test/run-make/translation/missing.ftl new file mode 100644 index 0000000000000..43076b1d6ae79 --- /dev/null +++ b/src/test/run-make/translation/missing.ftl @@ -0,0 +1,3 @@ +# `parser-struct-literal-body-without-path` isn't provided by this resource at all, so the +# fallback should be used. +foo = bar diff --git a/src/test/run-make/translation/basic-translation.rs b/src/test/run-make/translation/test.rs similarity index 100% rename from src/test/run-make/translation/basic-translation.rs rename to src/test/run-make/translation/test.rs diff --git a/src/test/run-make/translation/basic-translation.ftl b/src/test/run-make/translation/working.ftl similarity index 100% rename from src/test/run-make/translation/basic-translation.ftl rename to src/test/run-make/translation/working.ftl diff --git a/src/test/rustdoc-json/impls/auto.rs b/src/test/rustdoc-json/impls/auto.rs new file mode 100644 index 0000000000000..50a0117727189 --- /dev/null +++ b/src/test/rustdoc-json/impls/auto.rs @@ -0,0 +1,10 @@ +#![feature(no_core, auto_traits, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +pub auto trait Bar {} + +// @has auto.json "$.index[*][?(@.kind=='impl')].span" null +pub struct Foo; diff --git a/src/test/ui/associated-types/issue-22560.stderr b/src/test/ui/associated-types/issue-22560.stderr index 700923c1b3f58..2b88cf0b4411e 100644 --- a/src/test/ui/associated-types/issue-22560.stderr +++ b/src/test/ui/associated-types/issue-22560.stderr @@ -1,25 +1,3 @@ -error[E0393]: the type parameter `Rhs` must be explicitly specified - --> $DIR/issue-22560.rs:9:23 - | -LL | trait Sub { - | ------------------- type parameter `Rhs` must be specified for this -... -LL | type Test = dyn Add + Sub; - | ^^^ help: set the type parameter to the desired type: `Sub` - | - = note: because of the default `Self` reference, type parameters must be specified on object types - -error[E0393]: the type parameter `Rhs` must be explicitly specified - --> $DIR/issue-22560.rs:9:17 - | -LL | trait Add { - | ------------------- type parameter `Rhs` must be specified for this -... -LL | type Test = dyn Add + Sub; - | ^^^ help: set the type parameter to the desired type: `Add` - | - = note: because of the default `Self` reference, type parameters must be specified on object types - error[E0225]: only auto traits can be used as additional traits in a trait object --> $DIR/issue-22560.rs:9:23 | @@ -28,7 +6,7 @@ LL | type Test = dyn Add + Sub; | | | first non-auto trait | - = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<[type error]> + Sub<[type error]> {}` + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add + Sub {}` = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit error[E0191]: the value of the associated types `Output` (from trait `Add`), `Output` (from trait `Sub`) must be specified @@ -50,6 +28,28 @@ help: specify the associated types LL | type Test = dyn Add + Sub; | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ +error[E0393]: the type parameter `Rhs` must be explicitly specified + --> $DIR/issue-22560.rs:9:17 + | +LL | trait Add { + | ------------------- type parameter `Rhs` must be specified for this +... +LL | type Test = dyn Add + Sub; + | ^^^ help: set the type parameter to the desired type: `Add` + | + = note: because of the default `Self` reference, type parameters must be specified on object types + +error[E0393]: the type parameter `Rhs` must be explicitly specified + --> $DIR/issue-22560.rs:9:23 + | +LL | trait Sub { + | ------------------- type parameter `Rhs` must be specified for this +... +LL | type Test = dyn Add + Sub; + | ^^^ help: set the type parameter to the desired type: `Sub` + | + = note: because of the default `Self` reference, type parameters must be specified on object types + error: aborting due to 4 previous errors Some errors have detailed explanations: E0191, E0225, E0393. diff --git a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs index b2edc1a1f66ca..6175b7df1107a 100644 --- a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs +++ b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.rs @@ -3,7 +3,6 @@ trait Foo> { //~^ ERROR cycle detected - //~| ERROR cycle detected } fn main() { } diff --git a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr index d4976a0f9c9cd..9d715f4947146 100644 --- a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr +++ b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr @@ -10,30 +10,11 @@ note: cycle used when collecting item types in top-level module | LL | / trait Foo> { LL | | -LL | | -LL | | } -LL | | -LL | | fn main() { } - | |_____________^ - -error[E0391]: cycle detected when computing type of `Foo::X` - --> $DIR/cycle-trait-default-type-trait.rs:4:23 - | -LL | trait Foo> { - | ^^^ - | - = note: ...which immediately requires computing type of `Foo::X` again -note: cycle used when collecting item types in top-level module - --> $DIR/cycle-trait-default-type-trait.rs:4:1 - | -LL | / trait Foo> { -LL | | -LL | | LL | | } LL | | LL | | fn main() { } | |_____________^ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs b/src/test/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs index 043011b3316a7..2d4a8fe202f08 100644 --- a/src/test/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs +++ b/src/test/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs @@ -1,6 +1,6 @@ // build-pass // -// compile-flags: -g --emit=llvm-ir -Zunstable-options -Csplit-debuginfo=unpacked +// compile-flags: -g --emit=llvm-ir -Csplit-debuginfo=unpacked // // Make sure that we don't explode with an error if we don't actually end up emitting any `dwo`s, // as would be the case if we don't actually codegen anything. diff --git a/src/test/ui/issues/issue-21950.stderr b/src/test/ui/issues/issue-21950.stderr index 4909398bb848f..731615a6bd8d4 100644 --- a/src/test/ui/issues/issue-21950.stderr +++ b/src/test/ui/issues/issue-21950.stderr @@ -1,3 +1,12 @@ +error[E0191]: the value of the associated type `Output` (from trait `Add`) must be specified + --> $DIR/issue-21950.rs:10:25 + | +LL | type Output; + | ----------- `Output` defined here +... +LL | let x = &10 as &dyn Add; + | ^^^ help: specify the associated type: `Add` + error[E0393]: the type parameter `Rhs` must be explicitly specified --> $DIR/issue-21950.rs:10:25 | @@ -9,15 +18,6 @@ LL | let x = &10 as &dyn Add; | = note: because of the default `Self` reference, type parameters must be specified on object types -error[E0191]: the value of the associated type `Output` (from trait `Add`) must be specified - --> $DIR/issue-21950.rs:10:25 - | -LL | type Output; - | ----------- `Output` defined here -... -LL | let x = &10 as &dyn Add; - | ^^^ help: specify the associated type: `Add` - error: aborting due to 2 previous errors Some errors have detailed explanations: E0191, E0393. diff --git a/src/test/ui/parser/suggest-const-for-global-var.rs b/src/test/ui/parser/suggest-const-for-global-var.rs new file mode 100644 index 0000000000000..d6216cb7ac275 --- /dev/null +++ b/src/test/ui/parser/suggest-const-for-global-var.rs @@ -0,0 +1,6 @@ +let X: i32 = 12; +//~^ ERROR expected item, found keyword `let` + +fn main() { + println!("{}", X); +} diff --git a/src/test/ui/parser/suggest-const-for-global-var.stderr b/src/test/ui/parser/suggest-const-for-global-var.stderr new file mode 100644 index 0000000000000..94e44ec7f6ce1 --- /dev/null +++ b/src/test/ui/parser/suggest-const-for-global-var.stderr @@ -0,0 +1,8 @@ +error: expected item, found keyword `let` + --> $DIR/suggest-const-for-global-var.rs:1:1 + | +LL | let X: i32 = 12; + | ^^^ consider using `const` or `static` instead of `let` for global variables + +error: aborting due to previous error + diff --git a/src/test/ui/traits/alias/generic-default-in-dyn.rs b/src/test/ui/traits/alias/generic-default-in-dyn.rs new file mode 100644 index 0000000000000..d44e1c2a97530 --- /dev/null +++ b/src/test/ui/traits/alias/generic-default-in-dyn.rs @@ -0,0 +1,10 @@ +trait SendEqAlias = PartialEq; +//~^ ERROR trait aliases are experimental + +struct Foo(dyn SendEqAlias); +//~^ ERROR the type parameter `Rhs` must be explicitly specified [E0393] + +struct Bar(dyn SendEqAlias, T); +//~^ ERROR the type parameter `Rhs` must be explicitly specified [E0393] + +fn main() {} diff --git a/src/test/ui/traits/alias/generic-default-in-dyn.stderr b/src/test/ui/traits/alias/generic-default-in-dyn.stderr new file mode 100644 index 0000000000000..76a068e864a3c --- /dev/null +++ b/src/test/ui/traits/alias/generic-default-in-dyn.stderr @@ -0,0 +1,39 @@ +error[E0658]: trait aliases are experimental + --> $DIR/generic-default-in-dyn.rs:1:1 + | +LL | trait SendEqAlias = PartialEq; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #41517 for more information + = help: add `#![feature(trait_alias)]` to the crate attributes to enable + +error[E0393]: the type parameter `Rhs` must be explicitly specified + --> $DIR/generic-default-in-dyn.rs:4:19 + | +LL | struct Foo(dyn SendEqAlias); + | ^^^^^^^^^^^^^^ missing reference to `Rhs` + | + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | +LL | pub trait PartialEq { + | --------------------------------------- type parameter `Rhs` must be specified for this + | + = note: because of the default `Self` reference, type parameters must be specified on object types + +error[E0393]: the type parameter `Rhs` must be explicitly specified + --> $DIR/generic-default-in-dyn.rs:7:19 + | +LL | struct Bar(dyn SendEqAlias, T); + | ^^^^^^^^^^^^^^ missing reference to `Rhs` + | + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | +LL | pub trait PartialEq { + | --------------------------------------- type parameter `Rhs` must be specified for this + | + = note: because of the default `Self` reference, type parameters must be specified on object types + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0393, E0658. +For more information about an error, try `rustc --explain E0393`. diff --git a/src/test/ui/traits/alias/self-in-generics.rs b/src/test/ui/traits/alias/self-in-generics.rs new file mode 100644 index 0000000000000..6b99431f5bbcf --- /dev/null +++ b/src/test/ui/traits/alias/self-in-generics.rs @@ -0,0 +1,8 @@ +#![feature(trait_alias)] + +pub trait SelfInput = Fn(&mut Self); + +pub fn f(_f: &dyn SelfInput) {} +//~^ ERROR the trait alias `SelfInput` cannot be made into an object [E0038] + +fn main() {} diff --git a/src/test/ui/traits/alias/self-in-generics.stderr b/src/test/ui/traits/alias/self-in-generics.stderr new file mode 100644 index 0000000000000..a1056872ea641 --- /dev/null +++ b/src/test/ui/traits/alias/self-in-generics.stderr @@ -0,0 +1,11 @@ +error[E0038]: the trait alias `SelfInput` cannot be made into an object + --> $DIR/self-in-generics.rs:5:19 + | +LL | pub fn f(_f: &dyn SelfInput) {} + | ^^^^^^^^^ + | + = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/unspecified-self-in-trait-ref.rs b/src/test/ui/traits/unspecified-self-in-trait-ref.rs similarity index 100% rename from src/test/ui/unspecified-self-in-trait-ref.rs rename to src/test/ui/traits/unspecified-self-in-trait-ref.rs diff --git a/src/test/ui/unspecified-self-in-trait-ref.stderr b/src/test/ui/traits/unspecified-self-in-trait-ref.stderr similarity index 100% rename from src/test/ui/unspecified-self-in-trait-ref.stderr rename to src/test/ui/traits/unspecified-self-in-trait-ref.stderr diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 47f2a2d34821c..782c0c254315d 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2015,11 +2015,14 @@ impl<'test> TestCx<'test> { Some(CompareMode::Chalk) => { rustc.args(&["-Zchalk"]); } - Some(CompareMode::SplitDwarf) => { + Some(CompareMode::SplitDwarf) if self.config.target.contains("windows") => { rustc.args(&["-Csplit-debuginfo=unpacked", "-Zunstable-options"]); } + Some(CompareMode::SplitDwarf) => { + rustc.args(&["-Csplit-debuginfo=unpacked"]); + } Some(CompareMode::SplitDwarfSingle) => { - rustc.args(&["-Csplit-debuginfo=packed", "-Zunstable-options"]); + rustc.args(&["-Csplit-debuginfo=packed"]); } None => {} }