Auto merge of #106708 - JohnTitor:rollup-xcmg5yv, r=JohnTitor
Rollup of 14 pull requests Successful merges: - #105194 (Add comment to cleanup_kinds) - #106521 (remove E0280) - #106628 (Remove unneeded ItemId::Primitive variant) - #106635 (std sync tests: better type name, clarifying comment) - #106642 (Add test for #106062) - #106645 ([RFC 2397] Initial implementation) - #106653 (Fix help docs for -Zallow-features) - #106657 (Remove myself from rust-lang/rust reviewers) - #106662 (specialize impl of `ToString` on `bool`) - #106669 (create helper function for `rustc_lint_defs::Level` and remove it's duplicated code) - #106671 (Change flags with a fixed default value from Option<bool> to bool) - #106689 (Fix invalid files array re-creation in rustdoc-gui tester) - #106690 (Fix scrolling for item declaration block) - #106698 (Add compiler-errors to some trait system notification groups) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
ca855e6e42
@ -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<mir::BasicBlock, CleanupKind> {
|
||||
fn discover_masters<'tcx>(
|
||||
result: &mut IndexVec<mir::BasicBlock, CleanupKind>,
|
||||
|
@ -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
|
||||
|
@ -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()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(...))]`.
|
||||
|
@ -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:
|
||||
// ==========================================================================
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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!(
|
||||
|
@ -1241,7 +1241,7 @@ options! {
|
||||
|
||||
// tidy-alphabetical-start
|
||||
allow_features: Option<Vec<String>> = (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<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
box_noalias: bool = (true, parse_bool, [TRACKED],
|
||||
"emit noalias metadata for box (default: yes)"),
|
||||
branch_protection: Option<BranchProtection> = (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<usize> = (None, parse_opt_number, [TRACKED],
|
||||
"the size at which the `large_assignments` lint starts to be emitted"),
|
||||
mutable_noalias: Option<bool> = (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)"),
|
||||
|
@ -613,6 +613,7 @@ symbols! {
|
||||
dispatch_from_dyn,
|
||||
div,
|
||||
div_assign,
|
||||
do_not_recommend,
|
||||
doc,
|
||||
doc_alias,
|
||||
doc_auto_cfg,
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -254,12 +254,12 @@ fn adjust_for_rust_scalar<'tcx>(
|
||||
// The aliasing rules for `Box<T>` 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
|
||||
|
@ -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 {
|
||||
|
@ -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());
|
||||
|
@ -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<Option<Foo>> = UnsafeCell::new(None));
|
||||
thread_local!(static FOO: UnsafeCell<Option<NotifyOnDrop>> = UnsafeCell::new(None));
|
||||
run(&FOO);
|
||||
thread_local!(static FOO2: UnsafeCell<Option<Foo>> = const { UnsafeCell::new(None) });
|
||||
thread_local!(static FOO2: UnsafeCell<Option<NotifyOnDrop>> = const { UnsafeCell::new(None) });
|
||||
run(&FOO2);
|
||||
|
||||
fn run(key: &'static LocalKey<UnsafeCell<Option<Foo>>>) {
|
||||
fn run(key: &'static LocalKey<UnsafeCell<Option<NotifyOnDrop>>>) {
|
||||
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<Option<S1>> = UnsafeCell::new(None));
|
||||
thread_local!(static K2: UnsafeCell<Option<Foo>> = UnsafeCell::new(None));
|
||||
thread_local!(static K2: UnsafeCell<Option<NotifyOnDrop>> = 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<Option<S1>> = const { UnsafeCell::new(None) });
|
||||
thread_local!(static K2: UnsafeCell<Option<Foo>> = const { UnsafeCell::new(None) });
|
||||
thread_local!(static K2: UnsafeCell<Option<NotifyOnDrop>> = 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())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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) => {
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<F: std::hash::Hash + Eq>(
|
||||
ty: &mut RenderType,
|
||||
cache: &mut Cache,
|
||||
itemid_to_pathid: &mut FxHashMap<ItemId, usize>,
|
||||
map: &mut FxHashMap<F, usize>,
|
||||
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<ItemId, usize>,
|
||||
primitives: &mut FxHashMap<Symbol, usize>,
|
||||
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,
|
||||
);
|
||||
|
@ -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;
|
||||
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Self::Item>;
|
||||
fn size_hint(&self) -> (usize, Option<usize>);
|
||||
fn count(self) -> usize
|
||||
where
|
||||
Self: Sized;
|
||||
fn last(self) -> Option<Self::Item>
|
||||
where
|
||||
Self: Sized;
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), usize>;
|
||||
fn nth(&mut self, n: usize) -> Option<Self::Item>;
|
||||
fn step_by(self, step: usize) -> StepBy<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter>
|
||||
where
|
||||
Self: Sized,
|
||||
U: IntoIterator<Item = Self::Item>;
|
||||
fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
|
||||
where
|
||||
Self: Sized,
|
||||
U: IntoIterator;
|
||||
fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
Self::Item: Clone;
|
||||
fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
|
||||
where
|
||||
Self: Sized,
|
||||
G: FnMut() -> Self::Item;
|
||||
fn map<B, F>(self, f: F) -> Map<Self, F>
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(Self::Item) -> B;
|
||||
fn for_each<F>(self, f: F)
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(Self::Item);
|
||||
fn filter<P>(self, predicate: P) -> Filter<Self, P>
|
||||
where
|
||||
Self: Sized,
|
||||
P: FnMut(&Self::Item) -> bool;
|
||||
fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(Self::Item) -> Option<B>;
|
||||
fn enumerate(self) -> Enumerate<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
fn peekable(self) -> Peekable<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
|
||||
where
|
||||
Self: Sized,
|
||||
P: FnMut(&Self::Item) -> bool;
|
||||
fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
|
||||
where
|
||||
Self: Sized,
|
||||
P: FnMut(&Self::Item) -> bool;
|
||||
fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
|
||||
where
|
||||
Self: Sized,
|
||||
P: FnMut(Self::Item) -> Option<B>;
|
||||
fn skip(self, n: usize) -> Skip<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
fn take(self, n: usize) -> Take<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(&mut St, Self::Item) -> Option<B>;
|
||||
fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
|
||||
where
|
||||
Self: Sized,
|
||||
U: IntoIterator,
|
||||
F: FnMut(Self::Item) -> U;
|
||||
fn flatten(self) -> Flatten<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
Self::Item: IntoIterator;
|
||||
fn fuse(self) -> Fuse<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
fn inspect<F>(self, f: F) -> Inspect<Self, F>
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(&Self::Item);
|
||||
fn by_ref(&mut self) -> &mut Self
|
||||
where
|
||||
Self: Sized;
|
||||
fn collect<B: FromIterator<Self::Item>>(self) -> B
|
||||
where
|
||||
Self: Sized;
|
||||
fn collect_into<E: Extend<Self::Item>>(self, collection: &mut E) -> &mut E
|
||||
where
|
||||
Self: Sized;
|
||||
fn partition<B, F>(self, f: F) -> (B, B)
|
||||
where
|
||||
Self: Sized,
|
||||
B: Default + Extend<Self::Item>,
|
||||
F: FnMut(&Self::Item) -> bool;
|
||||
fn partition_in_place<'a, T: 'a, P>(mut self, predicate: P) -> usize
|
||||
where
|
||||
Self: Sized + DoubleEndedIterator<Item = &'a mut T>,
|
||||
P: FnMut(&T) -> bool;
|
||||
fn is_partitioned<P>(mut self, mut predicate: P) -> bool
|
||||
where
|
||||
Self: Sized,
|
||||
P: FnMut(Self::Item) -> bool;
|
||||
fn fold<B, F>(mut self, init: B, mut f: F) -> B
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(B, Self::Item) -> B;
|
||||
fn reduce<F>(mut self, f: F) -> Option<Self::Item>
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(Self::Item, Self::Item) -> Self::Item;
|
||||
fn all<F>(&mut self, f: F) -> bool
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(Self::Item) -> bool;
|
||||
fn any<F>(&mut self, f: F) -> bool
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(Self::Item) -> bool;
|
||||
fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
|
||||
where
|
||||
Self: Sized,
|
||||
P: FnMut(&Self::Item) -> bool;
|
||||
fn find_map<B, F>(&mut self, f: F) -> Option<B>
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(Self::Item) -> Option<B>;
|
||||
fn position<P>(&mut self, predicate: P) -> Option<usize>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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})
|
||||
|
@ -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`.
|
||||
|
@ -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() -> () {}
|
||||
|
||||
|
@ -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`.
|
||||
|
26
src/test/ui/mir/issue-106062.rs
Normal file
26
src/test/ui/mir/issue-106062.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// edition:2018
|
||||
|
||||
use std::{future::Future, marker::PhantomData};
|
||||
|
||||
fn spawn<T>(future: T) -> PhantomData<T::Output>
|
||||
where
|
||||
T: Future,
|
||||
{
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct IncomingServer {}
|
||||
impl IncomingServer {
|
||||
async fn connection_handler(handler: impl Sized) -> Result<Ok, std::io::Error> {
|
||||
//~^ 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() {}
|
16
src/test/ui/mir/issue-106062.stderr
Normal file
16
src/test/ui/mir/issue-106062.stderr
Normal file
@ -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<Ok, std::io::Error> {
|
||||
| ^^ not a type
|
||||
|
|
||||
help: try using the variant's enum
|
||||
|
|
||||
LL | async fn connection_handler(handler: impl Sized) -> Result<core::result::Result, std::io::Error> {
|
||||
| ~~~~~~~~~~~~~~~~~~~~
|
||||
LL | async fn connection_handler(handler: impl Sized) -> Result<std::result::Result, std::io::Error> {
|
||||
| ~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0573`.
|
@ -0,0 +1,21 @@
|
||||
#![feature(do_not_recommend)]
|
||||
|
||||
pub trait Foo {
|
||||
}
|
||||
|
||||
impl Foo for i32 {
|
||||
}
|
||||
|
||||
pub trait Bar {
|
||||
}
|
||||
|
||||
#[do_not_recommend]
|
||||
impl<T: Foo> Bar for T {
|
||||
}
|
||||
|
||||
fn stuff<T: Bar>(_: T) {}
|
||||
|
||||
fn main() {
|
||||
stuff(1u8);
|
||||
//~^ the trait bound `u8: Foo` is not satisfied
|
||||
}
|
@ -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<T: Foo> Bar for T {
|
||||
| ^^^ ^
|
||||
note: required by a bound in `stuff`
|
||||
--> $DIR/feature-gate-do_not_recommend.rs:16:13
|
||||
|
|
||||
LL | fn stuff<T: Bar>(_: T) {}
|
||||
| ^^^ required by this bound in `stuff`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -0,0 +1,7 @@
|
||||
#[do_not_recommend]
|
||||
//~^ ERROR the `#[do_not_recommend]` attribute is an experimental feature
|
||||
trait Foo {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
@ -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 <https://github.com/rust-lang/rust/issues/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`.
|
@ -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.
|
||||
|
@ -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",
|
||||
|
Loading…
x
Reference in New Issue
Block a user