diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index c7617d2e464..dd1ac2c74ae 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -261,6 +261,9 @@ impl CleanupKind { } } +/// MSVC requires unwinding code to be split to a tree of *funclets*, where each funclet can only +/// branch to itself or to its parent. Luckily, the code we generates matches this pattern. +/// Recover that structure in an analyze pass. pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec { fn discover_masters<'tcx>( result: &mut IndexVec, diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 686c22bc386..a132a8146e9 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -574,7 +574,7 @@ E0791: include_str!("./error_codes/E0791.md"), // E0274, // on_unimplemented #2 // E0278, // requirement is not satisfied // E0279, - E0280, // requirement is not satisfied +// E0280, // changed to ICE // E0285, // overflow evaluation builtin bounds // E0296, // replaced with a generic attribute input check // E0298, // cannot compare constants diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 794b6efcc2b..dad5e98aac0 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -179,16 +179,7 @@ impl IntoDiagnosticArg for type_ir::FloatTy { impl IntoDiagnosticArg for Level { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - DiagnosticArgValue::Str(Cow::Borrowed(match self { - Level::Allow => "-A", - Level::Warn => "-W", - Level::ForceWarn(_) => "--force-warn", - Level::Deny => "-D", - Level::Forbid => "-F", - Level::Expect(_) => { - unreachable!("lints with the level of `expect` should not run this code"); - } - })) + DiagnosticArgValue::Str(Cow::Borrowed(self.to_cmd_flag())) } } diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index beade4d44da..691c0955cad 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -374,6 +374,8 @@ declare_features! ( (active, deprecated_safe, "1.61.0", Some(94978), None), /// Allows having using `suggestion` in the `#[deprecated]` attribute. (active, deprecated_suggestion, "1.61.0", Some(94785), None), + /// Controls errors in trait implementations. + (active, do_not_recommend, "1.67.0", Some(51992), None), /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`. (active, doc_auto_cfg, "1.58.0", Some(43781), None), /// Allows `#[doc(cfg(...))]`. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index ad85231860d..af56a0b2459 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -487,6 +487,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ experimental!(collapse_debuginfo) ), + // RFC 2397 + gated!(do_not_recommend, Normal, template!(Word), WarnFollowing, experimental!(do_not_recommend)), + // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: // ========================================================================== diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 316e2e29cd8..a3b9891ee64 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -715,7 +715,7 @@ fn test_unstable_options_tracking_hash() { tracked!(asm_comments, true); tracked!(assume_incomplete_release, true); tracked!(binary_dep_depinfo, true); - tracked!(box_noalias, Some(false)); + tracked!(box_noalias, false); tracked!( branch_protection, Some(BranchProtection { @@ -754,7 +754,7 @@ fn test_unstable_options_tracking_hash() { tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]); tracked!(mir_opt_level, Some(4)); tracked!(move_size_limit, Some(4096)); - tracked!(mutable_noalias, Some(true)); + tracked!(mutable_noalias, false); tracked!(no_generate_arange_section, true); tracked!(no_jump_tables, true); tracked!(no_link, true); diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index aa54b3d8ac2..f4b4c5168bf 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -253,6 +253,19 @@ impl Level { } } + pub fn to_cmd_flag(self) -> &'static str { + match self { + Level::Warn => "-W", + Level::Deny => "-D", + Level::Forbid => "-F", + Level::Allow => "-A", + Level::ForceWarn(_) => "--force-warn", + Level::Expect(_) => { + unreachable!("the expect level does not have a commandline flag") + } + } + } + pub fn is_error(self) -> bool { match self { Level::Allow | Level::Expect(_) | Level::Warn | Level::ForceWarn(_) => false, diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index eb48b325e84..c61de97d532 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -234,16 +234,7 @@ pub fn explain_lint_level_source( err.note_once(&format!("`#[{}({})]` on by default", level.as_str(), name)); } LintLevelSource::CommandLine(lint_flag_val, orig_level) => { - let flag = match orig_level { - Level::Warn => "-W", - Level::Deny => "-D", - Level::Forbid => "-F", - Level::Allow => "-A", - Level::ForceWarn(_) => "--force-warn", - Level::Expect(_) => { - unreachable!("the expect level does not have a commandline flag") - } - }; + let flag = orig_level.to_cmd_flag(); let hyphen_case_lint_name = name.replace('_', "-"); if lint_flag_val.as_str() == name { err.note_once(&format!( diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 043a60a1c53..4c236067688 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1241,7 +1241,7 @@ options! { // tidy-alphabetical-start allow_features: Option> = (None, parse_opt_comma_list, [TRACKED], - "only allow the listed language features to be enabled in code (space separated)"), + "only allow the listed language features to be enabled in code (comma separated)"), always_encode_mir: bool = (false, parse_bool, [TRACKED], "encode MIR of all functions into the crate metadata (default: no)"), asm_comments: bool = (false, parse_bool, [TRACKED], @@ -1255,7 +1255,7 @@ options! { binary_dep_depinfo: bool = (false, parse_bool, [TRACKED], "include artifacts (sysroot, crate dependencies) used during compilation in dep-info \ (default: no)"), - box_noalias: Option = (None, parse_opt_bool, [TRACKED], + box_noalias: bool = (true, parse_bool, [TRACKED], "emit noalias metadata for box (default: yes)"), branch_protection: Option = (None, parse_branch_protection, [TRACKED], "set options for branch target identification and pointer authentication on AArch64"), @@ -1437,7 +1437,7 @@ options! { "use line numbers relative to the function in mir pretty printing"), move_size_limit: Option = (None, parse_opt_number, [TRACKED], "the size at which the `large_assignments` lint starts to be emitted"), - mutable_noalias: Option = (None, parse_opt_bool, [TRACKED], + mutable_noalias: bool = (true, parse_bool, [TRACKED], "emit noalias metadata for mutable references (default: yes)"), nll_facts: bool = (false, parse_bool, [UNTRACKED], "dump facts from NLL analysis into side files (default: no)"), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 5d5f8d6d654..fbb12701d96 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -613,6 +613,7 @@ symbols! { dispatch_from_dyn, div, div_assign, + do_not_recommend, doc, doc_alias, doc_auto_cfg, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 9c098e1a2fc..5f06c4d8282 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1102,15 +1102,19 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) - | ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) => { - let predicate = self.resolve_vars_if_possible(obligation.predicate); - struct_span_err!( - self.tcx.sess, + span_bug!( span, - E0280, - "the requirement `{}` is not satisfied", - predicate + "outlives clauses should not error outside borrowck. obligation: `{:?}`", + obligation + ) + } + + ty::PredicateKind::Clause(ty::Clause::Projection(..)) => { + span_bug!( + span, + "projection clauses should be implied from elsewhere. obligation: `{:?}`", + obligation ) } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index f8a5691f29d..d1197774fe9 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -254,12 +254,12 @@ fn adjust_for_rust_scalar<'tcx>( // The aliasing rules for `Box` are still not decided, but currently we emit // `noalias` for it. This can be turned off using an unstable flag. // See https://github.com/rust-lang/unsafe-code-guidelines/issues/326 - let noalias_for_box = cx.tcx.sess.opts.unstable_opts.box_noalias.unwrap_or(true); + let noalias_for_box = cx.tcx.sess.opts.unstable_opts.box_noalias; // LLVM prior to version 12 had known miscompiles in the presence of noalias attributes // (see #54878), so it was conditionally disabled, but we don't support earlier // versions at all anymore. We still support turning it off using -Zmutable-noalias. - let noalias_mut_ref = cx.tcx.sess.opts.unstable_opts.mutable_noalias.unwrap_or(true); + let noalias_mut_ref = cx.tcx.sess.opts.unstable_opts.mutable_noalias; // `&mut` pointer parameters never alias other parameters, // or mutable global data diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 24f1b3a1c87..3118c7189a5 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2548,6 +2548,15 @@ impl ToString for char { } } +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "bool_to_string_specialization", since = "CURRENT_RUSTC_VERSION")] +impl ToString for bool { + #[inline] + fn to_string(&self) -> String { + String::from(if *self { "true" } else { "false" }) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "u8_to_string_specialization", since = "1.54.0")] impl ToString for u8 { diff --git a/library/std/src/sync/mutex/tests.rs b/library/std/src/sync/mutex/tests.rs index 93900566f11..1786a3c09ff 100644 --- a/library/std/src/sync/mutex/tests.rs +++ b/library/std/src/sync/mutex/tests.rs @@ -181,7 +181,7 @@ fn test_mutex_arc_poison() { let arc2 = arc.clone(); let _ = thread::spawn(move || { let lock = arc2.lock().unwrap(); - assert_eq!(*lock, 2); + assert_eq!(*lock, 2); // deliberate assertion failure to poison the mutex }) .join(); assert!(arc.lock().is_err()); diff --git a/library/std/src/thread/local/tests.rs b/library/std/src/thread/local/tests.rs index 80dc4c038d6..964c7fc5b0c 100644 --- a/library/std/src/thread/local/tests.rs +++ b/library/std/src/thread/local/tests.rs @@ -23,11 +23,11 @@ impl Signal { } } -struct Foo(Signal); +struct NotifyOnDrop(Signal); -impl Drop for Foo { +impl Drop for NotifyOnDrop { fn drop(&mut self) { - let Foo(ref f) = *self; + let NotifyOnDrop(ref f) = *self; f.notify(); } } @@ -82,18 +82,18 @@ fn states() { #[test] fn smoke_dtor() { - thread_local!(static FOO: UnsafeCell> = UnsafeCell::new(None)); + thread_local!(static FOO: UnsafeCell> = UnsafeCell::new(None)); run(&FOO); - thread_local!(static FOO2: UnsafeCell> = const { UnsafeCell::new(None) }); + thread_local!(static FOO2: UnsafeCell> = const { UnsafeCell::new(None) }); run(&FOO2); - fn run(key: &'static LocalKey>>) { + fn run(key: &'static LocalKey>>) { let signal = Signal::default(); let signal2 = signal.clone(); let t = thread::spawn(move || unsafe { let mut signal = Some(signal2); key.with(|f| { - *f.get() = Some(Foo(signal.take().unwrap())); + *f.get() = Some(NotifyOnDrop(signal.take().unwrap())); }); }); signal.wait(); @@ -187,13 +187,13 @@ fn self_referential() { fn dtors_in_dtors_in_dtors() { struct S1(Signal); thread_local!(static K1: UnsafeCell> = UnsafeCell::new(None)); - thread_local!(static K2: UnsafeCell> = UnsafeCell::new(None)); + thread_local!(static K2: UnsafeCell> = UnsafeCell::new(None)); impl Drop for S1 { fn drop(&mut self) { let S1(ref signal) = *self; unsafe { - let _ = K2.try_with(|s| *s.get() = Some(Foo(signal.clone()))); + let _ = K2.try_with(|s| *s.get() = Some(NotifyOnDrop(signal.clone()))); } } } @@ -211,13 +211,13 @@ fn dtors_in_dtors_in_dtors() { fn dtors_in_dtors_in_dtors_const_init() { struct S1(Signal); thread_local!(static K1: UnsafeCell> = const { UnsafeCell::new(None) }); - thread_local!(static K2: UnsafeCell> = const { UnsafeCell::new(None) }); + thread_local!(static K2: UnsafeCell> = const { UnsafeCell::new(None) }); impl Drop for S1 { fn drop(&mut self) { let S1(ref signal) = *self; unsafe { - let _ = K2.try_with(|s| *s.get() = Some(Foo(signal.clone()))); + let _ = K2.try_with(|s| *s.get() = Some(NotifyOnDrop(signal.clone()))); } } } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index d1601272af7..aad24b4a074 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -600,7 +600,9 @@ fn build_module_items( items.push(clean::Item { name: None, attrs: Box::new(clean::Attributes::default()), - item_id: ItemId::Primitive(prim_ty, did.krate), + // We can use the item's `DefId` directly since the only information ever used + // from it is `DefId.krate`. + item_id: ItemId::DefId(did), kind: Box::new(clean::ImportItem(clean::Import::new_simple( item.ident.name, clean::ImportSource { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 827afafbba3..5c63efef717 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -62,8 +62,6 @@ pub(crate) enum ItemId { Auto { trait_: DefId, for_: DefId }, /// Identifier that is used for blanket implementations. Blanket { impl_id: DefId, for_: DefId }, - /// Identifier for primitive types. - Primitive(PrimitiveType, CrateNum), } impl ItemId { @@ -73,7 +71,6 @@ impl ItemId { ItemId::Auto { for_: id, .. } | ItemId::Blanket { for_: id, .. } | ItemId::DefId(id) => id.is_local(), - ItemId::Primitive(_, krate) => krate == LOCAL_CRATE, } } @@ -98,7 +95,6 @@ impl ItemId { ItemId::Auto { for_: id, .. } | ItemId::Blanket { for_: id, .. } | ItemId::DefId(id) => id.krate, - ItemId::Primitive(_, krate) => krate, } } } @@ -707,15 +703,13 @@ impl Item { let def_id = match self.item_id { // Anything but DefId *shouldn't* matter, but return a reasonable value anyway. ItemId::Auto { .. } | ItemId::Blanket { .. } => return None, - // Primitives and Keywords are written in the source code as private modules. - // The modules need to be private so that nobody actually uses them, but the - // keywords and primitives that they are documenting are public. - ItemId::Primitive(..) => return Some(Visibility::Public), ItemId::DefId(def_id) => def_id, }; match *self.kind { - // Explication on `ItemId::Primitive` just above. + // Primitives and Keywords are written in the source code as private modules. + // The modules need to be private so that nobody actually uses them, but the + // keywords and primitives that they are documenting are public. ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) => return Some(Visibility::Public), // Variant fields inherit their enum's visibility. StructFieldItem(..) if is_field_vis_inherited(tcx, def_id) => { diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs index b236bd7be4f..e607a16ad54 100644 --- a/src/librustdoc/formats/mod.rs +++ b/src/librustdoc/formats/mod.rs @@ -53,12 +53,6 @@ impl Impl { ItemId::Blanket { impl_id, .. } => impl_id, ItemId::Auto { trait_, .. } => trait_, ItemId::DefId(def_id) => def_id, - ItemId::Primitive(_, _) => { - panic!( - "Unexpected ItemId::Primitive in expect_def_id: {:?}", - self.impl_item.item_id - ) - } } } diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 2d61519d6c9..bc74d9cf969 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -3,7 +3,6 @@ use std::collections::BTreeMap; use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty::TyCtxt; -use rustc_span::def_id::LOCAL_CRATE; use rustc_span::symbol::Symbol; use serde::ser::{Serialize, SerializeStruct, Serializer}; @@ -24,6 +23,7 @@ pub(crate) fn build_index<'tcx>( tcx: TyCtxt<'tcx>, ) -> String { let mut itemid_to_pathid = FxHashMap::default(); + let mut primitives = FxHashMap::default(); let mut crate_paths = vec![]; // Attach all orphan items to the type's definition if the type @@ -78,42 +78,16 @@ pub(crate) fn build_index<'tcx>( // First, on function signatures let mut search_index = std::mem::replace(&mut cache.search_index, Vec::new()); for item in search_index.iter_mut() { - fn convert_render_type( + fn insert_into_map( ty: &mut RenderType, - cache: &mut Cache, - itemid_to_pathid: &mut FxHashMap, + map: &mut FxHashMap, + itemid: F, lastpathid: &mut usize, crate_paths: &mut Vec<(ItemType, Symbol)>, + item_type: ItemType, + path: Symbol, ) { - if let Some(generics) = &mut ty.generics { - for item in generics { - convert_render_type(item, cache, itemid_to_pathid, lastpathid, crate_paths); - } - } - let Cache { ref paths, ref external_paths, .. } = *cache; - let Some(id) = ty.id.clone() else { - assert!(ty.generics.is_some()); - return; - }; - let (itemid, path, item_type) = match id { - RenderTypeId::DefId(defid) => { - if let Some(&(ref fqp, item_type)) = - paths.get(&defid).or_else(|| external_paths.get(&defid)) - { - (ItemId::DefId(defid), *fqp.last().unwrap(), item_type) - } else { - ty.id = None; - return; - } - } - RenderTypeId::Primitive(primitive) => ( - ItemId::Primitive(primitive, LOCAL_CRATE), - primitive.as_sym(), - ItemType::Primitive, - ), - RenderTypeId::Index(_) => return, - }; - match itemid_to_pathid.entry(itemid) { + match map.entry(itemid) { Entry::Occupied(entry) => ty.id = Some(RenderTypeId::Index(*entry.get())), Entry::Vacant(entry) => { let pathid = *lastpathid; @@ -124,12 +98,72 @@ pub(crate) fn build_index<'tcx>( } } } + + fn convert_render_type( + ty: &mut RenderType, + cache: &mut Cache, + itemid_to_pathid: &mut FxHashMap, + primitives: &mut FxHashMap, + lastpathid: &mut usize, + crate_paths: &mut Vec<(ItemType, Symbol)>, + ) { + if let Some(generics) = &mut ty.generics { + for item in generics { + convert_render_type( + item, + cache, + itemid_to_pathid, + primitives, + lastpathid, + crate_paths, + ); + } + } + let Cache { ref paths, ref external_paths, .. } = *cache; + let Some(id) = ty.id.clone() else { + assert!(ty.generics.is_some()); + return; + }; + match id { + RenderTypeId::DefId(defid) => { + if let Some(&(ref fqp, item_type)) = + paths.get(&defid).or_else(|| external_paths.get(&defid)) + { + insert_into_map( + ty, + itemid_to_pathid, + ItemId::DefId(defid), + lastpathid, + crate_paths, + item_type, + *fqp.last().unwrap(), + ); + } else { + ty.id = None; + } + } + RenderTypeId::Primitive(primitive) => { + let sym = primitive.as_sym(); + insert_into_map( + ty, + primitives, + sym, + lastpathid, + crate_paths, + ItemType::Primitive, + sym, + ); + } + RenderTypeId::Index(_) => {} + } + } if let Some(search_type) = &mut item.search_type { for item in &mut search_type.inputs { convert_render_type( item, cache, &mut itemid_to_pathid, + &mut primitives, &mut lastpathid, &mut crate_paths, ); @@ -139,6 +173,7 @@ pub(crate) fn build_index<'tcx>( item, cache, &mut itemid_to_pathid, + &mut primitives, &mut lastpathid, &mut crate_paths, ); diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 8ec4631f7d0..91bc63f83b6 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -338,6 +338,10 @@ pre { .item-decl pre { overflow-x: auto; } +/* This rule allows to have scrolling on the X axis. */ +.item-decl .type-contents-toggle { + contain: initial; +} .source .content pre { padding: 20px; diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 56283b2c0ef..bd95ec18650 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -252,7 +252,6 @@ pub(crate) fn from_item_id_with_name(item_id: ItemId, tcx: TyCtxt<'_>, name: Opt ItemId::Auto { for_, trait_ } => { Id(format!("a:{}-{}", DisplayDefId(trait_, tcx, None), DisplayDefId(for_, tcx, name))) } - ItemId::Primitive(_, _) => unreachable!(), } } diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs index 24aecc70d65..34e67d9d254 100644 --- a/src/test/rustdoc-gui/src/lib2/lib.rs +++ b/src/test/rustdoc-gui/src/lib2/lib.rs @@ -183,3 +183,161 @@ impl ItemInfoAlignmentTest { #[deprecated] pub fn bar() {} } + +pub mod scroll_traits { + use std::iter::*; + + /// Shamelessly (partially) copied from `std::iter::Iterator`. + /// It allows us to check that the scroll is working as expected on "hidden" items. + pub trait Iterator { + type Item; + + fn next(&mut self) -> Option; + fn size_hint(&self) -> (usize, Option); + fn count(self) -> usize + where + Self: Sized; + fn last(self) -> Option + where + Self: Sized; + fn advance_by(&mut self, n: usize) -> Result<(), usize>; + fn nth(&mut self, n: usize) -> Option; + fn step_by(self, step: usize) -> StepBy + where + Self: Sized; + fn chain(self, other: U) -> Chain + where + Self: Sized, + U: IntoIterator; + fn zip(self, other: U) -> Zip + where + Self: Sized, + U: IntoIterator; + fn intersperse(self, separator: Self::Item) -> Intersperse + where + Self: Sized, + Self::Item: Clone; + fn intersperse_with(self, separator: G) -> IntersperseWith + where + Self: Sized, + G: FnMut() -> Self::Item; + fn map(self, f: F) -> Map + where + Self: Sized, + F: FnMut(Self::Item) -> B; + fn for_each(self, f: F) + where + Self: Sized, + F: FnMut(Self::Item); + fn filter

(self, predicate: P) -> Filter + where + Self: Sized, + P: FnMut(&Self::Item) -> bool; + fn filter_map(self, f: F) -> FilterMap + where + Self: Sized, + F: FnMut(Self::Item) -> Option; + fn enumerate(self) -> Enumerate + where + Self: Sized; + fn peekable(self) -> Peekable + where + Self: Sized; + fn skip_while

(self, predicate: P) -> SkipWhile + where + Self: Sized, + P: FnMut(&Self::Item) -> bool; + fn take_while

(self, predicate: P) -> TakeWhile + where + Self: Sized, + P: FnMut(&Self::Item) -> bool; + fn map_while(self, predicate: P) -> MapWhile + where + Self: Sized, + P: FnMut(Self::Item) -> Option; + fn skip(self, n: usize) -> Skip + where + Self: Sized; + fn take(self, n: usize) -> Take + where + Self: Sized; + fn scan(self, initial_state: St, f: F) -> Scan + where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option; + fn flat_map(self, f: F) -> FlatMap + where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U; + fn flatten(self) -> Flatten + where + Self: Sized, + Self::Item: IntoIterator; + fn fuse(self) -> Fuse + where + Self: Sized; + fn inspect(self, f: F) -> Inspect + where + Self: Sized, + F: FnMut(&Self::Item); + fn by_ref(&mut self) -> &mut Self + where + Self: Sized; + fn collect>(self) -> B + where + Self: Sized; + fn collect_into>(self, collection: &mut E) -> &mut E + where + Self: Sized; + fn partition(self, f: F) -> (B, B) + where + Self: Sized, + B: Default + Extend, + F: FnMut(&Self::Item) -> bool; + fn partition_in_place<'a, T: 'a, P>(mut self, predicate: P) -> usize + where + Self: Sized + DoubleEndedIterator, + P: FnMut(&T) -> bool; + fn is_partitioned

(mut self, mut predicate: P) -> bool + where + Self: Sized, + P: FnMut(Self::Item) -> bool; + fn fold(mut self, init: B, mut f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B; + fn reduce(mut self, f: F) -> Option + where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item; + fn all(&mut self, f: F) -> bool + where + Self: Sized, + F: FnMut(Self::Item) -> bool; + fn any(&mut self, f: F) -> bool + where + Self: Sized, + F: FnMut(Self::Item) -> bool; + fn find

(&mut self, predicate: P) -> Option + where + Self: Sized, + P: FnMut(&Self::Item) -> bool; + fn find_map(&mut self, f: F) -> Option + where + Self: Sized, + F: FnMut(Self::Item) -> Option; + fn position

(&mut self, predicate: P) -> Option + where + Self: Sized, + P: FnMut(Self::Item) -> bool; + /// We will scroll to "string" to ensure it scrolls as expected. + fn this_is_a_method_with_a_long_name_returning_something() -> String; + } + + /// This one doesn't have hidden items (because there are too many) so we can also confirm that it + /// scrolls as expected. + pub trait TraitWithLongItemsName { + fn this_is_a_method_with_a_long_name_returning_something() -> String; + } +} diff --git a/src/test/rustdoc-gui/type-declation-overflow.goml b/src/test/rustdoc-gui/type-declation-overflow.goml index 9b60bc04738..644429c014c 100644 --- a/src/test/rustdoc-gui/type-declation-overflow.goml +++ b/src/test/rustdoc-gui/type-declation-overflow.goml @@ -59,3 +59,18 @@ goto: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLon compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y")) goto: "file://" + |DOC_PATH| + "/lib2/index.html" compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y")) + +// Now we will check that the scrolling is working. +// First on an item with "hidden methods". +goto: "file://" + |DOC_PATH| + "/lib2/scroll_traits/trait.Iterator.html" + +click: ".item-decl .type-contents-toggle" +assert-property: (".item-decl > pre", {"scrollLeft": 0}) +scroll-to: "//*[@class='item-decl']//details/a[text()='String']" +assert-property-false: (".item-decl > pre", {"scrollLeft": 0}) + +// Then on an item without "hidden methods". +goto: "file://" + |DOC_PATH| + "/lib2/scroll_traits/trait.TraitWithLongItemsName.html" +assert-property: (".item-decl > pre", {"scrollLeft": 0}) +scroll-to: "//*[@class='item-decl']//code/a[text()='String']" +assert-property-false: (".item-decl > pre", {"scrollLeft": 0}) diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout index 537dc92be19..43f30f3d6e8 100644 --- a/src/test/rustdoc-ui/z-help.stdout +++ b/src/test/rustdoc-ui/z-help.stdout @@ -1,4 +1,4 @@ - -Z allow-features=val -- only allow the listed language features to be enabled in code (space separated) + -Z allow-features=val -- only allow the listed language features to be enabled in code (comma separated) -Z always-encode-mir=val -- encode MIR of all functions into the crate metadata (default: no) -Z asm-comments=val -- generate comments into the assembly (may change behavior) (default: no) -Z assert-incr-state=val -- assert that the incremental cache is in given state: either `loaded` or `not-loaded`. diff --git a/src/test/ui/chalkify/bugs/async.rs b/src/test/ui/chalkify/bugs/async.rs index ed0f5dc9bd3..86ce42631b4 100644 --- a/src/test/ui/chalkify/bugs/async.rs +++ b/src/test/ui/chalkify/bugs/async.rs @@ -1,6 +1,13 @@ // check-fail -// known-bug: unknown -// compile-flags: -Z trait-solver=chalk --edition=2021 +// known-bug +// unset-rustc-env:RUST_BACKTRACE +// compile-flags:-Z trait-solver=chalk --edition=2021 +// error-pattern:stack backtrace: +// failure-status:101 +// normalize-stderr-test "note: .*" -> "" +// normalize-stderr-test "thread 'rustc' .*" -> "" +// normalize-stderr-test " .*\n" -> "" +// normalize-stderr-test "DefId([^)]*)" -> "..." fn main() -> () {} diff --git a/src/test/ui/chalkify/bugs/async.stderr b/src/test/ui/chalkify/bugs/async.stderr index eda867f4159..7e2466dece4 100644 --- a/src/test/ui/chalkify/bugs/async.stderr +++ b/src/test/ui/chalkify/bugs/async.stderr @@ -1,48 +1,40 @@ -error[E0277]: `[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future - --> $DIR/async.rs:7:29 - | -LL | async fn foo(x: u32) -> u32 { - | _____________________________- -LL | | x -LL | | } - | | ^ - | | | - | |_`[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future - | required by a bound introduced by this call - | - = help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:7:29: 9:2]` - = note: [async fn body@$DIR/async.rs:7:29: 9:2] must be a future or must implement `IntoFuture` to be awaited -note: required by a bound in `identity_future` - --> $SRC_DIR/core/src/future/mod.rs:LL:COL +error[E0277]: `[async fn body@$DIR/async.rs:14:29: 16:2]` is not a future +LL |LL | |LL | | } -error[E0277]: the size for values of type `<[async fn body@$DIR/async.rs:7:29: 9:2] as Future>::Output` cannot be known at compilation time - --> $DIR/async.rs:7:29 - | -LL | async fn foo(x: u32) -> u32 { - | _____________________________^ -LL | | x -LL | | } - | |_^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `<[async fn body@$DIR/async.rs:7:29: 9:2] as Future>::Output` -note: required by a bound in `identity_future` - --> $SRC_DIR/core/src/future/mod.rs:LL:COL -error[E0277]: `[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future - --> $DIR/async.rs:7:25 - | +error[E0277]: the size for values of type `<[async fn body@$DIR/async.rs:14:29: 16:2] as Future>::Output` cannot be known at compilation time +LL |LL | |LL | | } + + +error[E0277]: `[async fn body@$DIR/async.rs:14:29: 16:2]` is not a future LL | async fn foo(x: u32) -> u32 { - | ^^^ `[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future - | - = help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:7:29: 9:2]` - = note: [async fn body@$DIR/async.rs:7:29: 9:2] must be a future or must implement `IntoFuture` to be awaited -error[E0280]: the requirement `<[async fn body@$DIR/async.rs:7:29: 9:2] as Future>::Output == u32` is not satisfied - --> $DIR/async.rs:7:25 - | +error: internal compiler error: compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs:1114:25: projection clauses should be implied from elsewhere. obligation: `Obligation(predicate=Binder(ProjectionPredicate(AliasTy { substs: [[async fn body@$DIR/async.rs:14:29: 16:2]], def_id: ...), _use_mk_alias_ty_instead: () }, Term::Ty(u32)), []), depth=0)` LL | async fn foo(x: u32) -> u32 { - | ^^^ + +stack backtrace: + + + + + + + + + +query stack during panic: +#0 [typeck] type-checking `foo` +#1 [thir_body] building THIR for `foo` +#2 [mir_built] building MIR for `foo` +#3 [unsafety_check_result] unsafety-checking `foo` +#4 [mir_const] preparing `foo` for borrow checking +#5 [mir_promoted] processing MIR for `foo` +#6 [mir_borrowck] borrow-checking `foo` +#7 [type_of] computing type of `foo::{opaque#0}` +#8 [check_mod_item_types] checking item types in top-level module +#9 [analysis] running analysis passes on this crate +end of query stack error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/mir/issue-106062.rs b/src/test/ui/mir/issue-106062.rs new file mode 100644 index 00000000000..621ba566ee3 --- /dev/null +++ b/src/test/ui/mir/issue-106062.rs @@ -0,0 +1,26 @@ +// edition:2018 + +use std::{future::Future, marker::PhantomData}; + +fn spawn(future: T) -> PhantomData +where + T: Future, +{ + loop {} +} + +#[derive(Debug)] +struct IncomingServer {} +impl IncomingServer { + async fn connection_handler(handler: impl Sized) -> Result { + //~^ ERROR expected type, found variant `Ok` [E0573] + loop {} + } + async fn spawn(&self, request_handler: impl Sized) { + async move { + spawn(Self::connection_handler(&request_handler)); + }; + } +} + +fn main() {} diff --git a/src/test/ui/mir/issue-106062.stderr b/src/test/ui/mir/issue-106062.stderr new file mode 100644 index 00000000000..2f6524d03e0 --- /dev/null +++ b/src/test/ui/mir/issue-106062.stderr @@ -0,0 +1,16 @@ +error[E0573]: expected type, found variant `Ok` + --> $DIR/issue-106062.rs:15:64 + | +LL | async fn connection_handler(handler: impl Sized) -> Result { + | ^^ not a type + | +help: try using the variant's enum + | +LL | async fn connection_handler(handler: impl Sized) -> Result { + | ~~~~~~~~~~~~~~~~~~~~ +LL | async fn connection_handler(handler: impl Sized) -> Result { + | ~~~~~~~~~~~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0573`. diff --git a/src/test/ui/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.rs b/src/test/ui/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.rs new file mode 100644 index 00000000000..5053c115b45 --- /dev/null +++ b/src/test/ui/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.rs @@ -0,0 +1,21 @@ +#![feature(do_not_recommend)] + +pub trait Foo { +} + +impl Foo for i32 { +} + +pub trait Bar { +} + +#[do_not_recommend] +impl Bar for T { +} + +fn stuff(_: T) {} + +fn main() { + stuff(1u8); + //~^ the trait bound `u8: Foo` is not satisfied +} diff --git a/src/test/ui/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr b/src/test/ui/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr new file mode 100644 index 00000000000..2749add82ac --- /dev/null +++ b/src/test/ui/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr @@ -0,0 +1,23 @@ +error[E0277]: the trait bound `u8: Foo` is not satisfied + --> $DIR/feature-gate-do_not_recommend.rs:19:11 + | +LL | stuff(1u8); + | ----- ^^^ the trait `Foo` is not implemented for `u8` + | | + | required by a bound introduced by this call + | + = help: the trait `Foo` is implemented for `i32` +note: required for `u8` to implement `Bar` + --> $DIR/feature-gate-do_not_recommend.rs:13:14 + | +LL | impl Bar for T { + | ^^^ ^ +note: required by a bound in `stuff` + --> $DIR/feature-gate-do_not_recommend.rs:16:13 + | +LL | fn stuff(_: T) {} + | ^^^ required by this bound in `stuff` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/rfc-2397-do-not-recommend/unstable-feature.rs b/src/test/ui/rfc-2397-do-not-recommend/unstable-feature.rs new file mode 100644 index 00000000000..b816c4a19da --- /dev/null +++ b/src/test/ui/rfc-2397-do-not-recommend/unstable-feature.rs @@ -0,0 +1,7 @@ +#[do_not_recommend] +//~^ ERROR the `#[do_not_recommend]` attribute is an experimental feature +trait Foo { +} + +fn main() { +} diff --git a/src/test/ui/rfc-2397-do-not-recommend/unstable-feature.stderr b/src/test/ui/rfc-2397-do-not-recommend/unstable-feature.stderr new file mode 100644 index 00000000000..425d7e4bca0 --- /dev/null +++ b/src/test/ui/rfc-2397-do-not-recommend/unstable-feature.stderr @@ -0,0 +1,12 @@ +error[E0658]: the `#[do_not_recommend]` attribute is an experimental feature + --> $DIR/unstable-feature.rs:1:1 + | +LL | #[do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #51992 for more information + = help: add `#![feature(do_not_recommend)]` 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/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js index 900ca389436..554b2f81fa3 100644 --- a/src/tools/rustdoc-gui/tester.js +++ b/src/tools/rustdoc-gui/tester.js @@ -278,7 +278,8 @@ async function main(argv) { await runTests(opts, framework_options, files, new_results, status_bar, it + 1 >= NB_RETRY); Array.prototype.push.apply(results.successful, new_results.successful); // We generate the new list of files with the previously failing tests. - files = Array.prototype.concat(new_results.failed, new_results.errored); + files = Array.prototype.concat(new_results.failed, new_results.errored).map( + f => f['file_name']); if (files.length > originalFilesLen / 2) { // If we have too many failing tests, it's very likely not flaky failures anymore so // no need to retry. diff --git a/triagebot.toml b/triagebot.toml index 58108dac496..bee0371d36e 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -344,14 +344,14 @@ cc = ["@BoxyUwU"] [mentions."compiler/rustc_trait_selection/src/solve/"] message = "Some changes occurred to the core trait solver" -cc = ["@lcnr"] +cc = ["@lcnr", "@compiler-errors"] [mentions."compiler/rustc_trait_selection/src/traits/engine.rs"] message = """ Some changes occurred in engine.rs, potentially modifying the public API \ of `ObligationCtxt`. """ -cc = ["@lcnr"] +cc = ["@lcnr", "@compiler-errors"] [mentions."compiler/rustc_error_codes/src/error_codes.rs"] message = "Some changes occurred in diagnostic error codes" @@ -487,12 +487,10 @@ libs = [ ] bootstrap = [ "@Mark-Simulacrum", - "@jyn514", ] infra-ci = [ "@Mark-Simulacrum", "@pietroalbini", - "@jyn514", ] rustdoc = [ "@jsha",