mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 15:01:51 +00:00
Auto merge of #98987 - GuillaumeGomez:rollup-bcy32bp, r=GuillaumeGomez
Rollup of 7 pull requests Successful merges: - #96935 (Allow arithmetic and certain bitwise ops on AtomicPtr) - #98519 (Replace some `guess_head_span` with `def_span`) - #98911 (rustdoc: filter '_ lifetimes from ty::Generics) - #98939 (rustdoc: Add more semantic information to impl IDs) - #98971 (Fix typo in file descriptor docs) - #98983 (docs: Add overview of `rustc_middle::mir::TerminatorKind`) - #98984 (Remove erroneous doc comment) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7665c35430
@ -812,12 +812,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
return FnSelfUse {
|
||||
var_span: stmt.source_info.span,
|
||||
fn_call_span: *fn_span,
|
||||
fn_span: self
|
||||
.infcx
|
||||
.tcx
|
||||
.sess
|
||||
.source_map()
|
||||
.guess_head_span(self.infcx.tcx.def_span(method_did)),
|
||||
fn_span: self.infcx.tcx.def_span(method_did),
|
||||
kind,
|
||||
};
|
||||
}
|
||||
|
@ -513,9 +513,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
};
|
||||
|
||||
let ty = substs.type_at(0);
|
||||
if int_type_width_signed(ty, bx.tcx()).is_some()
|
||||
|| (ty.is_unsafe_ptr() && op == "xchg")
|
||||
{
|
||||
if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
|
||||
let mut ptr = args[0].immediate();
|
||||
let mut val = args[1].immediate();
|
||||
if ty.is_unsafe_ptr() {
|
||||
|
@ -155,8 +155,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
});
|
||||
|
||||
if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
|
||||
let span =
|
||||
tcx.sess.source_map().guess_head_span(tcx.def_span(data.impl_def_id));
|
||||
let span = tcx.def_span(data.impl_def_id);
|
||||
err.span_note(span, "impl defined here, but it is not `const`");
|
||||
}
|
||||
}
|
||||
@ -205,7 +204,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
|
||||
match self_ty.kind() {
|
||||
FnDef(def_id, ..) => {
|
||||
let span = tcx.sess.source_map().guess_head_span(tcx.def_span(*def_id));
|
||||
let span = tcx.def_span(*def_id);
|
||||
if ccx.tcx.is_const_fn_raw(*def_id) {
|
||||
span_bug!(span, "calling const FnDef errored when it shouldn't");
|
||||
}
|
||||
|
@ -148,12 +148,10 @@ fn msg_span_from_early_bound_and_free_regions<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
region: ty::Region<'tcx>,
|
||||
) -> (String, Span) {
|
||||
let sm = tcx.sess.source_map();
|
||||
|
||||
let scope = region.free_region_binding_scope(tcx).expect_local();
|
||||
match *region {
|
||||
ty::ReEarlyBound(ref br) => {
|
||||
let mut sp = sm.guess_head_span(tcx.def_span(scope));
|
||||
let mut sp = tcx.def_span(scope);
|
||||
if let Some(param) =
|
||||
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
|
||||
{
|
||||
@ -174,7 +172,7 @@ fn msg_span_from_early_bound_and_free_regions<'tcx>(
|
||||
} else {
|
||||
match fr.bound_region {
|
||||
ty::BoundRegionKind::BrNamed(_, name) => {
|
||||
let mut sp = sm.guess_head_span(tcx.def_span(scope));
|
||||
let mut sp = tcx.def_span(scope);
|
||||
if let Some(param) =
|
||||
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name))
|
||||
{
|
||||
@ -193,7 +191,7 @@ fn msg_span_from_early_bound_and_free_regions<'tcx>(
|
||||
),
|
||||
_ => (
|
||||
format!("the lifetime `{}` as defined here", region),
|
||||
sm.guess_head_span(tcx.def_span(scope)),
|
||||
tcx.def_span(scope),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -23,10 +23,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
|
||||
let mut err = struct_span_err!(self.tcx.sess, sp, E0276, "{}", msg);
|
||||
|
||||
if let Some(trait_item_span) = self.tcx.hir().span_if_local(trait_item_def_id) {
|
||||
let span = self.tcx.sess.source_map().guess_head_span(trait_item_span);
|
||||
if trait_item_def_id.is_local() {
|
||||
let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
|
||||
err.span_label(span, format!("definition of `{}` from trait", item_name));
|
||||
err.span_label(
|
||||
self.tcx.def_span(trait_item_def_id),
|
||||
format!("definition of `{}` from trait", item_name),
|
||||
);
|
||||
}
|
||||
|
||||
err.span_label(sp, format!("impl has extra requirement {}", requirement));
|
||||
|
@ -552,7 +552,6 @@ impl MissingDoc {
|
||||
&self,
|
||||
cx: &LateContext<'_>,
|
||||
def_id: LocalDefId,
|
||||
sp: Span,
|
||||
article: &'static str,
|
||||
desc: &'static str,
|
||||
) {
|
||||
@ -579,16 +578,12 @@ impl MissingDoc {
|
||||
let attrs = cx.tcx.hir().attrs(cx.tcx.hir().local_def_id_to_hir_id(def_id));
|
||||
let has_doc = attrs.iter().any(has_doc);
|
||||
if !has_doc {
|
||||
cx.struct_span_lint(
|
||||
MISSING_DOCS,
|
||||
cx.tcx.sess.source_map().guess_head_span(sp),
|
||||
|lint| {
|
||||
lint.build(fluent::lint::builtin_missing_doc)
|
||||
.set_arg("article", article)
|
||||
.set_arg("desc", desc)
|
||||
.emit();
|
||||
},
|
||||
);
|
||||
cx.struct_span_lint(MISSING_DOCS, cx.tcx.def_span(def_id), |lint| {
|
||||
lint.build(fluent::lint::builtin_missing_doc)
|
||||
.set_arg("article", article)
|
||||
.set_arg("desc", desc)
|
||||
.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -611,13 +606,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
||||
}
|
||||
|
||||
fn check_crate(&mut self, cx: &LateContext<'_>) {
|
||||
self.check_missing_docs_attrs(
|
||||
cx,
|
||||
CRATE_DEF_ID,
|
||||
cx.tcx.def_span(CRATE_DEF_ID),
|
||||
"the",
|
||||
"crate",
|
||||
);
|
||||
self.check_missing_docs_attrs(cx, CRATE_DEF_ID, "the", "crate");
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
|
||||
@ -647,13 +636,13 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
||||
|
||||
let (article, desc) = cx.tcx.article_and_description(it.def_id.to_def_id());
|
||||
|
||||
self.check_missing_docs_attrs(cx, it.def_id, it.span, article, desc);
|
||||
self.check_missing_docs_attrs(cx, it.def_id, article, desc);
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'_>, trait_item: &hir::TraitItem<'_>) {
|
||||
let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id());
|
||||
|
||||
self.check_missing_docs_attrs(cx, trait_item.def_id, trait_item.span, article, desc);
|
||||
self.check_missing_docs_attrs(cx, trait_item.def_id, article, desc);
|
||||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
|
||||
@ -681,23 +670,23 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
||||
}
|
||||
|
||||
let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id());
|
||||
self.check_missing_docs_attrs(cx, impl_item.def_id, impl_item.span, article, desc);
|
||||
self.check_missing_docs_attrs(cx, impl_item.def_id, article, desc);
|
||||
}
|
||||
|
||||
fn check_foreign_item(&mut self, cx: &LateContext<'_>, foreign_item: &hir::ForeignItem<'_>) {
|
||||
let (article, desc) = cx.tcx.article_and_description(foreign_item.def_id.to_def_id());
|
||||
self.check_missing_docs_attrs(cx, foreign_item.def_id, foreign_item.span, article, desc);
|
||||
self.check_missing_docs_attrs(cx, foreign_item.def_id, article, desc);
|
||||
}
|
||||
|
||||
fn check_field_def(&mut self, cx: &LateContext<'_>, sf: &hir::FieldDef<'_>) {
|
||||
if !sf.is_positional() {
|
||||
let def_id = cx.tcx.hir().local_def_id(sf.hir_id);
|
||||
self.check_missing_docs_attrs(cx, def_id, sf.span, "a", "struct field")
|
||||
self.check_missing_docs_attrs(cx, def_id, "a", "struct field")
|
||||
}
|
||||
}
|
||||
|
||||
fn check_variant(&mut self, cx: &LateContext<'_>, v: &hir::Variant<'_>) {
|
||||
self.check_missing_docs_attrs(cx, cx.tcx.hir().local_def_id(v.id), v.span, "a", "variant");
|
||||
self.check_missing_docs_attrs(cx, cx.tcx.hir().local_def_id(v.id), "a", "variant");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1013,12 +1013,13 @@ impl<'hir> Map<'hir> {
|
||||
ItemKind::Use(path, _) => path.span,
|
||||
_ => named_span(item.span, item.ident, item.kind.generics()),
|
||||
},
|
||||
Node::Variant(variant) => named_span(variant.span, variant.ident, None),
|
||||
Node::ImplItem(item) => named_span(item.span, item.ident, Some(item.generics)),
|
||||
Node::ForeignItem(item) => match item.kind {
|
||||
ForeignItemKind::Fn(decl, _, _) => until_within(item.span, decl.output.span()),
|
||||
_ => named_span(item.span, item.ident, None),
|
||||
},
|
||||
Node::Ctor(..) => return self.opt_span(self.get_parent_node(hir_id)),
|
||||
Node::Ctor(_) => return self.opt_span(self.get_parent_node(hir_id)),
|
||||
_ => self.span_with_body(hir_id),
|
||||
};
|
||||
Some(span)
|
||||
|
@ -396,6 +396,8 @@ pub struct CopyNonOverlapping<'tcx> {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Terminators
|
||||
|
||||
/// The various kinds of terminators, representing ways of exiting from a basic block.
|
||||
///
|
||||
/// A note on unwinding: Panics may occur during the execution of some terminators. Depending on the
|
||||
/// `-C panic` flag, this may either cause the program to abort or the call stack to unwind. Such
|
||||
/// terminators have a `cleanup: Option<BasicBlock>` field on them. If stack unwinding occurs, then
|
||||
@ -911,7 +913,7 @@ pub enum Operand<'tcx> {
|
||||
static_assert_size!(Operand<'_>, 24);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// Rvalues
|
||||
// Rvalues
|
||||
|
||||
/// The various kinds of rvalues that can appear in MIR.
|
||||
///
|
||||
|
@ -795,7 +795,7 @@ fn foo(&self) -> Self::T { String::new() }
|
||||
if item_def_id == proj_ty_item_def_id =>
|
||||
{
|
||||
Some((
|
||||
self.sess.source_map().guess_head_span(self.def_span(item.def_id)),
|
||||
self.def_span(item.def_id),
|
||||
format!("consider calling `{}`", self.def_path_str(item.def_id)),
|
||||
))
|
||||
}
|
||||
|
@ -1112,18 +1112,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
})
|
||||
.collect::<Option<Vec<ArgKind>>>()?,
|
||||
),
|
||||
Node::Item(&hir::Item { span, kind: hir::ItemKind::Fn(ref sig, ..), .. })
|
||||
| Node::ImplItem(&hir::ImplItem {
|
||||
span,
|
||||
kind: hir::ImplItemKind::Fn(ref sig, _),
|
||||
..
|
||||
})
|
||||
Node::Item(&hir::Item { kind: hir::ItemKind::Fn(ref sig, ..), .. })
|
||||
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(ref sig, _), .. })
|
||||
| Node::TraitItem(&hir::TraitItem {
|
||||
span,
|
||||
kind: hir::TraitItemKind::Fn(ref sig, _),
|
||||
..
|
||||
kind: hir::TraitItemKind::Fn(ref sig, _), ..
|
||||
}) => (
|
||||
sm.guess_head_span(span),
|
||||
sig.span,
|
||||
sig.decl
|
||||
.inputs
|
||||
.iter()
|
||||
@ -1138,7 +1132,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
),
|
||||
Node::Ctor(ref variant_data) => {
|
||||
let span = variant_data.ctor_hir_id().map_or(DUMMY_SP, |id| hir.span(id));
|
||||
let span = sm.guess_head_span(span);
|
||||
(span, vec![ArgKind::empty(); variant_data.fields().len()])
|
||||
}
|
||||
_ => panic!("non-FnLike node found: {:?}", node),
|
||||
@ -2185,7 +2178,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
||||
let mut post = vec![];
|
||||
for def_id in impls {
|
||||
match self.tcx.span_of_impl(*def_id) {
|
||||
Ok(span) => spans.push(self.tcx.sess.source_map().guess_head_span(span)),
|
||||
Ok(span) => spans.push(span),
|
||||
Err(name) => {
|
||||
crates.push(name);
|
||||
if let Some(header) = to_pretty_impl_header(self.tcx, *def_id) {
|
||||
@ -2532,8 +2525,7 @@ pub fn recursive_type_with_infinite_size_error<'tcx>(
|
||||
spans: Vec<(Span, Option<hir::HirId>)>,
|
||||
) {
|
||||
assert!(type_def_id.is_local());
|
||||
let span = tcx.hir().span_if_local(type_def_id).unwrap();
|
||||
let span = tcx.sess.source_map().guess_head_span(span);
|
||||
let span = tcx.def_span(type_def_id);
|
||||
let path = tcx.def_path_str(type_def_id);
|
||||
let mut err =
|
||||
struct_span_err!(tcx.sess, span, E0072, "recursive type `{}` has infinite size", path);
|
||||
|
@ -340,10 +340,7 @@ fn report_negative_positive_conflict(
|
||||
positive_impl_def_id: DefId,
|
||||
sg: &mut specialization_graph::Graph,
|
||||
) {
|
||||
let impl_span = tcx
|
||||
.sess
|
||||
.source_map()
|
||||
.guess_head_span(tcx.span_of_impl(local_impl_def_id.to_def_id()).unwrap());
|
||||
let impl_span = tcx.def_span(local_impl_def_id);
|
||||
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
@ -356,10 +353,7 @@ fn report_negative_positive_conflict(
|
||||
|
||||
match tcx.span_of_impl(negative_impl_def_id) {
|
||||
Ok(span) => {
|
||||
err.span_label(
|
||||
tcx.sess.source_map().guess_head_span(span),
|
||||
"negative implementation here".to_string(),
|
||||
);
|
||||
err.span_label(span, "negative implementation here");
|
||||
}
|
||||
Err(cname) => {
|
||||
err.note(&format!("negative implementation in crate `{}`", cname));
|
||||
@ -368,10 +362,7 @@ fn report_negative_positive_conflict(
|
||||
|
||||
match tcx.span_of_impl(positive_impl_def_id) {
|
||||
Ok(span) => {
|
||||
err.span_label(
|
||||
tcx.sess.source_map().guess_head_span(span),
|
||||
"positive implementation here".to_string(),
|
||||
);
|
||||
err.span_label(span, "positive implementation here");
|
||||
}
|
||||
Err(cname) => {
|
||||
err.note(&format!("positive implementation in crate `{}`", cname));
|
||||
@ -388,8 +379,7 @@ fn report_conflicting_impls(
|
||||
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
|
||||
sg: &mut specialization_graph::Graph,
|
||||
) {
|
||||
let impl_span =
|
||||
tcx.sess.source_map().guess_head_span(tcx.span_of_impl(impl_def_id.to_def_id()).unwrap());
|
||||
let impl_span = tcx.def_span(impl_def_id);
|
||||
|
||||
// Work to be done after we've built the DiagnosticBuilder. We have to define it
|
||||
// now because the struct_lint methods don't return back the DiagnosticBuilder
|
||||
@ -416,10 +406,7 @@ fn report_conflicting_impls(
|
||||
let mut err = err.build(&msg);
|
||||
match tcx.span_of_impl(overlap.with_impl) {
|
||||
Ok(span) => {
|
||||
err.span_label(
|
||||
tcx.sess.source_map().guess_head_span(span),
|
||||
"first implementation here".to_string(),
|
||||
);
|
||||
err.span_label(span, "first implementation here".to_string());
|
||||
|
||||
err.span_label(
|
||||
impl_span,
|
||||
|
@ -1958,9 +1958,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(sp) = tcx.hir().span_if_local(adt_def.did()) {
|
||||
let sp = tcx.sess.source_map().guess_head_span(sp);
|
||||
err.span_label(sp, format!("variant `{}` not found here", assoc_ident));
|
||||
if adt_def.did().is_local() {
|
||||
err.span_label(
|
||||
tcx.def_span(adt_def.did()),
|
||||
format!("variant `{assoc_ident}` not found for this enum"),
|
||||
);
|
||||
}
|
||||
|
||||
err.emit()
|
||||
@ -2450,7 +2452,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
|
||||
let msg = format!("`Self` is of type `{ty}`");
|
||||
if let (Ok(i_sp), Some(t_sp)) = (span_of_impl, span_of_ty) {
|
||||
let i_sp = tcx.sess.source_map().guess_head_span(i_sp);
|
||||
let mut span: MultiSpan = vec![t_sp].into();
|
||||
span.push_span_label(
|
||||
i_sp,
|
||||
|
@ -288,11 +288,9 @@ fn check_panic_info_fn(
|
||||
tcx.sess.span_err(decl.output.span(), "return type should be `!`");
|
||||
}
|
||||
|
||||
let span = tcx.def_span(fn_id);
|
||||
let inputs = fn_sig.inputs();
|
||||
if inputs.len() != 1 {
|
||||
let span = tcx.sess.source_map().guess_head_span(span);
|
||||
tcx.sess.span_err(span, "function should have one argument");
|
||||
tcx.sess.span_err(tcx.def_span(fn_id), "function should have one argument");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -345,9 +343,7 @@ fn check_alloc_error_fn(
|
||||
|
||||
let inputs = fn_sig.inputs();
|
||||
if inputs.len() != 1 {
|
||||
let span = tcx.def_span(fn_id);
|
||||
let span = tcx.sess.source_map().guess_head_span(span);
|
||||
tcx.sess.span_err(span, "function should have one argument");
|
||||
tcx.sess.span_err(tcx.def_span(fn_id), "function should have one argument");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1034,7 +1030,6 @@ fn check_impl_items_against_trait<'tcx>(
|
||||
compare_impl_method(
|
||||
tcx,
|
||||
&ty_impl_item,
|
||||
impl_item.span,
|
||||
&ty_trait_item,
|
||||
impl_trait_ref,
|
||||
opt_trait_span,
|
||||
@ -1094,17 +1089,20 @@ fn check_impl_items_against_trait<'tcx>(
|
||||
}
|
||||
|
||||
if !missing_items.is_empty() {
|
||||
let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
|
||||
missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
|
||||
missing_items_err(tcx, tcx.def_span(impl_id), &missing_items, full_impl_span);
|
||||
}
|
||||
|
||||
if let Some(missing_items) = must_implement_one_of {
|
||||
let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
|
||||
let attr_span = tcx
|
||||
.get_attr(impl_trait_ref.def_id, sym::rustc_must_implement_one_of)
|
||||
.map(|attr| attr.span);
|
||||
|
||||
missing_items_must_implement_one_of_err(tcx, impl_span, missing_items, attr_span);
|
||||
missing_items_must_implement_one_of_err(
|
||||
tcx,
|
||||
tcx.def_span(impl_id),
|
||||
missing_items,
|
||||
attr_span,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,14 +33,13 @@ use super::{potentially_plural_count, FnCtxt, Inherited};
|
||||
pub(crate) fn compare_impl_method<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: &ty::AssocItem,
|
||||
impl_m_span: Span,
|
||||
trait_m: &ty::AssocItem,
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
trait_item_span: Option<Span>,
|
||||
) {
|
||||
debug!("compare_impl_method(impl_trait_ref={:?})", impl_trait_ref);
|
||||
|
||||
let impl_m_span = tcx.sess.source_map().guess_head_span(impl_m_span);
|
||||
let impl_m_span = tcx.def_span(impl_m.def_id);
|
||||
|
||||
if let Err(_) = compare_self_type(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref) {
|
||||
return;
|
||||
@ -444,13 +443,9 @@ fn check_region_bounds_on_impl_item<'tcx>(
|
||||
.as_local()
|
||||
.and_then(|did| tcx.hir().get_generics(did))
|
||||
.map_or(def_span, |g| g.span);
|
||||
let generics_span = tcx.hir().span_if_local(trait_m.def_id).map(|sp| {
|
||||
let def_sp = tcx.sess.source_map().guess_head_span(sp);
|
||||
trait_m
|
||||
.def_id
|
||||
.as_local()
|
||||
.and_then(|did| tcx.hir().get_generics(did))
|
||||
.map_or(def_sp, |g| g.span)
|
||||
let generics_span = trait_m.def_id.as_local().map(|did| {
|
||||
let def_sp = tcx.def_span(did);
|
||||
tcx.hir().get_generics(did).map_or(def_sp, |g| g.span)
|
||||
});
|
||||
|
||||
let reported = tcx.sess.emit_err(LifetimesOrBoundsMismatchOnTrait {
|
||||
@ -1044,8 +1039,7 @@ fn compare_generic_param_kinds<'tcx>(
|
||||
err.span_label(trait_header_span, "");
|
||||
err.span_label(param_trait_span, make_param_message("expected", param_trait));
|
||||
|
||||
let impl_header_span =
|
||||
tcx.sess.source_map().guess_head_span(tcx.def_span(tcx.parent(impl_item.def_id)));
|
||||
let impl_header_span = tcx.def_span(tcx.parent(impl_item.def_id));
|
||||
err.span_label(impl_header_span, "");
|
||||
err.span_label(param_impl_span, make_param_message("found", param_impl));
|
||||
|
||||
|
@ -184,9 +184,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
} else if let (ty::FnDef(def_id, ..), true) =
|
||||
(&found.kind(), self.suggest_fn_call(err, expr, expected, found))
|
||||
{
|
||||
if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
|
||||
let sp = self.sess().source_map().guess_head_span(sp);
|
||||
err.span_label(sp, &format!("{} defined here", found));
|
||||
if def_id.is_local() {
|
||||
err.span_label(self.tcx.def_span(def_id), &format!("{} defined here", found));
|
||||
}
|
||||
} else if !self.check_for_cast(err, expr, found, expected, expected_ty_expr) {
|
||||
let is_struct_pat_shorthand_field =
|
||||
|
@ -121,11 +121,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}) else {
|
||||
continue;
|
||||
};
|
||||
let note_span = self
|
||||
.tcx
|
||||
.hir()
|
||||
.span_if_local(item.def_id)
|
||||
.or_else(|| self.tcx.hir().span_if_local(impl_did));
|
||||
|
||||
let note_span = if item.def_id.is_local() {
|
||||
Some(self.tcx.def_span(item.def_id))
|
||||
} else if impl_did.is_local() {
|
||||
Some(self.tcx.def_span(impl_did))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let impl_ty = self.tcx.at(span).type_of(impl_did);
|
||||
|
||||
@ -158,10 +161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
if let Some(note_span) = note_span {
|
||||
// We have a span pointing to the method. Show note with snippet.
|
||||
err.span_note(
|
||||
self.tcx.sess.source_map().guess_head_span(note_span),
|
||||
¬e_str,
|
||||
);
|
||||
err.span_note(note_span, ¬e_str);
|
||||
} else {
|
||||
err.note(¬e_str);
|
||||
}
|
||||
@ -197,11 +197,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
CandidateSource::Trait(trait_did) => {
|
||||
let Some(item) = self.associated_value(trait_did, item_name) else { continue };
|
||||
let item_span = self
|
||||
.tcx
|
||||
.sess
|
||||
.source_map()
|
||||
.guess_head_span(self.tcx.def_span(item.def_id));
|
||||
let item_span = self.tcx.def_span(item.def_id);
|
||||
let idx = if sources.len() > 1 {
|
||||
let msg = &format!(
|
||||
"candidate #{} is defined in the trait `{}`",
|
||||
@ -471,9 +467,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
err.note(&format!("`count` is defined on `{iterator_trait}`, which `{actual}` does not implement"));
|
||||
}
|
||||
} else if !unsatisfied_predicates.is_empty() {
|
||||
let def_span = |def_id| {
|
||||
self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id))
|
||||
};
|
||||
let mut type_params = FxHashMap::default();
|
||||
|
||||
// Pick out the list of unimplemented traits on the receiver.
|
||||
@ -564,22 +557,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
);
|
||||
match &self_ty.kind() {
|
||||
// Point at the type that couldn't satisfy the bound.
|
||||
ty::Adt(def, _) => bound_spans.push((def_span(def.did()), msg)),
|
||||
ty::Adt(def, _) => {
|
||||
bound_spans.push((self.tcx.def_span(def.did()), msg))
|
||||
}
|
||||
// Point at the trait object that couldn't satisfy the bound.
|
||||
ty::Dynamic(preds, _) => {
|
||||
for pred in preds.iter() {
|
||||
match pred.skip_binder() {
|
||||
ty::ExistentialPredicate::Trait(tr) => {
|
||||
bound_spans.push((def_span(tr.def_id), msg.clone()))
|
||||
}
|
||||
ty::ExistentialPredicate::Trait(tr) => bound_spans
|
||||
.push((self.tcx.def_span(tr.def_id), msg.clone())),
|
||||
ty::ExistentialPredicate::Projection(_)
|
||||
| ty::ExistentialPredicate::AutoTrait(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Point at the closure that couldn't satisfy the bound.
|
||||
ty::Closure(def_id, _) => bound_spans
|
||||
.push((def_span(*def_id), format!("doesn't satisfy `{}`", quiet))),
|
||||
ty::Closure(def_id, _) => bound_spans.push((
|
||||
tcx.def_span(*def_id),
|
||||
format!("doesn't satisfy `{}`", quiet),
|
||||
)),
|
||||
_ => {}
|
||||
}
|
||||
};
|
||||
@ -1469,21 +1465,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
_ => None,
|
||||
})
|
||||
.collect::<FxHashSet<_>>();
|
||||
let sm = self.tcx.sess.source_map();
|
||||
let mut spans: MultiSpan = def_ids
|
||||
.iter()
|
||||
.filter_map(|def_id| {
|
||||
let span = self.tcx.def_span(*def_id);
|
||||
if span.is_dummy() { None } else { Some(sm.guess_head_span(span)) }
|
||||
if span.is_dummy() { None } else { Some(span) }
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into();
|
||||
|
||||
for pred in &preds {
|
||||
match pred.self_ty().kind() {
|
||||
ty::Adt(def, _) => {
|
||||
ty::Adt(def, _) if def.did().is_local() => {
|
||||
spans.push_span_label(
|
||||
sm.guess_head_span(self.tcx.def_span(def.did())),
|
||||
self.tcx.def_span(def.did()),
|
||||
format!("must implement `{}`", pred.trait_ref.print_only_trait_path()),
|
||||
);
|
||||
}
|
||||
@ -2090,9 +2085,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
match &potential_candidates[..] {
|
||||
[] => {}
|
||||
[trait_info] if trait_info.def_id.is_local() => {
|
||||
let span = self.tcx.hir().span_if_local(trait_info.def_id).unwrap();
|
||||
err.span_note(
|
||||
self.tcx.sess.source_map().guess_head_span(span),
|
||||
self.tcx.def_span(trait_info.def_id),
|
||||
&format!(
|
||||
"`{}` defines an item `{}`, perhaps you need to {} it",
|
||||
self.tcx.def_path_str(trait_info.def_id),
|
||||
|
@ -9,7 +9,6 @@ use rustc_errors::struct_span_err;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits;
|
||||
|
||||
mod builtin;
|
||||
@ -18,11 +17,6 @@ mod inherent_impls_overlap;
|
||||
mod orphan;
|
||||
mod unsafety;
|
||||
|
||||
/// Obtains the span of just the impl header of `impl_def_id`.
|
||||
fn impl_header_span(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) -> Span {
|
||||
tcx.sess.source_map().guess_head_span(tcx.span_of_impl(impl_def_id.to_def_id()).unwrap())
|
||||
}
|
||||
|
||||
fn check_impl(tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_ref: ty::TraitRef<'_>) {
|
||||
debug!(
|
||||
"(checking implementation) adding impl for trait '{:?}', item '{}'",
|
||||
@ -47,56 +41,53 @@ fn enforce_trait_manually_implementable(
|
||||
) {
|
||||
let did = Some(trait_def_id);
|
||||
let li = tcx.lang_items();
|
||||
let impl_header_span = tcx.def_span(impl_def_id);
|
||||
|
||||
// Disallow *all* explicit impls of `Pointee`, `DiscriminantKind`, `Sized` and `Unsize` for now.
|
||||
if did == li.pointee_trait() {
|
||||
let span = impl_header_span(tcx, impl_def_id);
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
impl_header_span,
|
||||
E0322,
|
||||
"explicit impls for the `Pointee` trait are not permitted"
|
||||
)
|
||||
.span_label(span, "impl of `Pointee` not allowed")
|
||||
.span_label(impl_header_span, "impl of `Pointee` not allowed")
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
if did == li.discriminant_kind_trait() {
|
||||
let span = impl_header_span(tcx, impl_def_id);
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
impl_header_span,
|
||||
E0322,
|
||||
"explicit impls for the `DiscriminantKind` trait are not permitted"
|
||||
)
|
||||
.span_label(span, "impl of `DiscriminantKind` not allowed")
|
||||
.span_label(impl_header_span, "impl of `DiscriminantKind` not allowed")
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
if did == li.sized_trait() {
|
||||
let span = impl_header_span(tcx, impl_def_id);
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
impl_header_span,
|
||||
E0322,
|
||||
"explicit impls for the `Sized` trait are not permitted"
|
||||
)
|
||||
.span_label(span, "impl of `Sized` not allowed")
|
||||
.span_label(impl_header_span, "impl of `Sized` not allowed")
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
|
||||
if did == li.unsize_trait() {
|
||||
let span = impl_header_span(tcx, impl_def_id);
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
impl_header_span,
|
||||
E0328,
|
||||
"explicit impls for the `Unsize` trait are not permitted"
|
||||
)
|
||||
.span_label(span, "impl of `Unsize` not allowed")
|
||||
.span_label(impl_header_span, "impl of `Unsize` not allowed")
|
||||
.emit();
|
||||
return;
|
||||
}
|
||||
@ -110,10 +101,9 @@ fn enforce_trait_manually_implementable(
|
||||
tcx.trait_def(trait_def_id).specialization_kind
|
||||
{
|
||||
if !tcx.features().specialization && !tcx.features().min_specialization {
|
||||
let span = impl_header_span(tcx, impl_def_id);
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
span,
|
||||
impl_header_span,
|
||||
"implementing `rustc_specialization_trait` traits is unstable",
|
||||
)
|
||||
.help("add `#![feature(min_specialization)]` to the crate attributes to enable")
|
||||
@ -138,8 +128,13 @@ fn enforce_empty_impls_for_marker_traits(
|
||||
return;
|
||||
}
|
||||
|
||||
let span = impl_header_span(tcx, impl_def_id);
|
||||
struct_span_err!(tcx.sess, span, E0715, "impls for marker traits cannot contain items").emit();
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
tcx.def_span(impl_def_id),
|
||||
E0715,
|
||||
"impls for marker traits cannot contain items"
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
@ -217,7 +212,7 @@ fn check_object_overlap<'tcx>(
|
||||
} else {
|
||||
let mut supertrait_def_ids = traits::supertrait_def_ids(tcx, component_def_id);
|
||||
if supertrait_def_ids.any(|d| d == trait_def_id) {
|
||||
let span = impl_header_span(tcx, impl_def_id);
|
||||
let span = tcx.def_span(impl_def_id);
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
|
@ -47,7 +47,7 @@ fn do_orphan_check_impl<'tcx>(
|
||||
let hir::ItemKind::Impl(ref impl_) = item.kind else {
|
||||
bug!("{:?} is not an impl: {:?}", def_id, item);
|
||||
};
|
||||
let sp = tcx.sess.source_map().guess_head_span(item.span);
|
||||
let sp = tcx.def_span(def_id);
|
||||
let tr = impl_.of_trait.as_ref().unwrap();
|
||||
|
||||
// Ensure no opaque types are present in this impl header. See issues #76202 and #86411 for examples,
|
||||
|
@ -223,15 +223,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
||||
if !def_id.is_local() {
|
||||
return None;
|
||||
}
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
||||
match tcx.hir().find(hir_id) {
|
||||
Some(Node::Item(hir::Item { span: item_span, .. })) => {
|
||||
Some(tcx.sess.source_map().guess_head_span(*item_span))
|
||||
}
|
||||
_ => {
|
||||
span_bug!(tcx.def_span(def_id), "main has a non-function type");
|
||||
}
|
||||
}
|
||||
Some(tcx.def_span(def_id))
|
||||
}
|
||||
|
||||
fn main_fn_return_type_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
|
||||
@ -416,7 +408,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
||||
error = true;
|
||||
}
|
||||
if let hir::IsAsync::Async = sig.header.asyncness {
|
||||
let span = tcx.sess.source_map().guess_head_span(it.span);
|
||||
let span = tcx.def_span(it.def_id);
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
|
@ -93,7 +93,7 @@ impl const From<char> for u128 {
|
||||
/// Map `char` with code point in U+0000..=U+00FF to byte in 0x00..=0xFF with same value, failing
|
||||
/// if the code point is greater than U+00FF.
|
||||
///
|
||||
/// See [`impl From<u8> for char`](char#impl-From<u8>) for details on the encoding.
|
||||
/// See [`impl From<u8> for char`](char#impl-From<u8>-for-char) for details on the encoding.
|
||||
#[stable(feature = "u8_from_char", since = "1.59.0")]
|
||||
impl TryFrom<char> for u8 {
|
||||
type Error = TryFromCharError;
|
||||
@ -229,7 +229,7 @@ impl TryFrom<u32> for char {
|
||||
|
||||
/// The error type returned when a conversion from [`prim@u32`] to [`prim@char`] fails.
|
||||
///
|
||||
/// This `struct` is created by the [`char::try_from<u32>`](char#impl-TryFrom<u32>) method.
|
||||
/// This `struct` is created by the [`char::try_from<u32>`](char#impl-TryFrom<u32>-for-char) method.
|
||||
/// See its documentation for more.
|
||||
#[stable(feature = "try_from", since = "1.34.0")]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -180,7 +180,7 @@ mod sip;
|
||||
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
|
||||
/// [`HashSet`]: ../../std/collections/struct.HashSet.html
|
||||
/// [`hash`]: Hash::hash
|
||||
/// [impl]: ../../std/primitive.str.html#impl-Hash
|
||||
/// [impl]: ../../std/primitive.str.html#impl-Hash-for-str
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_diagnostic_item = "Hash"]
|
||||
pub trait Hash {
|
||||
|
@ -389,7 +389,7 @@
|
||||
//! [`Option`] of a collection of each contained value of the original
|
||||
//! [`Option`] values, or [`None`] if any of the elements was [`None`].
|
||||
//!
|
||||
//! [impl-FromIterator]: Option#impl-FromIterator%3COption%3CA%3E%3E
|
||||
//! [impl-FromIterator]: Option#impl-FromIterator%3COption%3CA%3E%3E-for-Option%3CV%3E
|
||||
//!
|
||||
//! ```
|
||||
//! let v = [Some(2), Some(4), None, Some(8)];
|
||||
@ -405,8 +405,8 @@
|
||||
//! to provide the [`product`][Iterator::product] and
|
||||
//! [`sum`][Iterator::sum] methods.
|
||||
//!
|
||||
//! [impl-Product]: Option#impl-Product%3COption%3CU%3E%3E
|
||||
//! [impl-Sum]: Option#impl-Sum%3COption%3CU%3E%3E
|
||||
//! [impl-Product]: Option#impl-Product%3COption%3CU%3E%3E-for-Option%3CT%3E
|
||||
//! [impl-Sum]: Option#impl-Sum%3COption%3CU%3E%3E-for-Option%3CT%3E
|
||||
//!
|
||||
//! ```
|
||||
//! let v = [None, Some(1), Some(2), Some(3)];
|
||||
|
@ -459,7 +459,7 @@
|
||||
//! [`Result`] of a collection of each contained value of the original
|
||||
//! [`Result`] values, or [`Err`] if any of the elements was [`Err`].
|
||||
//!
|
||||
//! [impl-FromIterator]: Result#impl-FromIterator%3CResult%3CA%2C%20E%3E%3E
|
||||
//! [impl-FromIterator]: Result#impl-FromIterator%3CResult%3CA%2C%20E%3E%3E-for-Result%3CV%2C%20E%3E
|
||||
//!
|
||||
//! ```
|
||||
//! let v = [Ok(2), Ok(4), Err("err!"), Ok(8)];
|
||||
@ -475,8 +475,8 @@
|
||||
//! to provide the [`product`][Iterator::product] and
|
||||
//! [`sum`][Iterator::sum] methods.
|
||||
//!
|
||||
//! [impl-Product]: Result#impl-Product%3CResult%3CU%2C%20E%3E%3E
|
||||
//! [impl-Sum]: Result#impl-Sum%3CResult%3CU%2C%20E%3E%3E
|
||||
//! [impl-Product]: Result#impl-Product%3CResult%3CU%2C%20E%3E%3E-for-Result%3CT%2C%20E%3E
|
||||
//! [impl-Sum]: Result#impl-Sum%3CResult%3CU%2C%20E%3E%3E-for-Result%3CT%2C%20E%3E
|
||||
//!
|
||||
//! ```
|
||||
//! let v = [Err("error!"), Ok(1), Ok(2), Ok(3), Err("foo")];
|
||||
|
@ -1451,6 +1451,347 @@ impl<T> AtomicPtr<T> {
|
||||
}
|
||||
Err(prev)
|
||||
}
|
||||
|
||||
/// Offsets the pointer's address by adding `val` (in units of `T`),
|
||||
/// returning the previous pointer.
|
||||
///
|
||||
/// This is equivalent to using [`wrapping_add`] to atomically perform the
|
||||
/// equivalent of `ptr = ptr.wrapping_add(val);`.
|
||||
///
|
||||
/// This method operates in units of `T`, which means that it cannot be used
|
||||
/// to offset the pointer by an amount which is not a multiple of
|
||||
/// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to
|
||||
/// work with a deliberately misaligned pointer. In such cases, you may use
|
||||
/// the [`fetch_byte_add`](Self::fetch_byte_add) method instead.
|
||||
///
|
||||
/// `fetch_ptr_add` takes an [`Ordering`] argument which describes the
|
||||
/// memory ordering of this operation. All ordering modes are possible. Note
|
||||
/// that using [`Acquire`] makes the store part of this operation
|
||||
/// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
|
||||
///
|
||||
/// **Note**: This method is only available on platforms that support atomic
|
||||
/// operations on [`AtomicPtr`].
|
||||
///
|
||||
/// [`wrapping_add`]: pointer::wrapping_add
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
|
||||
/// use core::sync::atomic::{AtomicPtr, Ordering};
|
||||
///
|
||||
/// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
|
||||
/// assert_eq!(atom.fetch_ptr_add(1, Ordering::Relaxed).addr(), 0);
|
||||
/// // Note: units of `size_of::<i64>()`.
|
||||
/// assert_eq!(atom.load(Ordering::Relaxed).addr(), 8);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "95228")]
|
||||
pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T {
|
||||
self.fetch_byte_add(val.wrapping_mul(core::mem::size_of::<T>()), order)
|
||||
}
|
||||
|
||||
/// Offsets the pointer's address by subtracting `val` (in units of `T`),
|
||||
/// returning the previous pointer.
|
||||
///
|
||||
/// This is equivalent to using [`wrapping_sub`] to atomically perform the
|
||||
/// equivalent of `ptr = ptr.wrapping_sub(val);`.
|
||||
///
|
||||
/// This method operates in units of `T`, which means that it cannot be used
|
||||
/// to offset the pointer by an amount which is not a multiple of
|
||||
/// `size_of::<T>()`. This can sometimes be inconvenient, as you may want to
|
||||
/// work with a deliberately misaligned pointer. In such cases, you may use
|
||||
/// the [`fetch_byte_sub`](Self::fetch_byte_sub) method instead.
|
||||
///
|
||||
/// `fetch_ptr_sub` takes an [`Ordering`] argument which describes the memory
|
||||
/// ordering of this operation. All ordering modes are possible. Note that
|
||||
/// using [`Acquire`] makes the store part of this operation [`Relaxed`],
|
||||
/// and using [`Release`] makes the load part [`Relaxed`].
|
||||
///
|
||||
/// **Note**: This method is only available on platforms that support atomic
|
||||
/// operations on [`AtomicPtr`].
|
||||
///
|
||||
/// [`wrapping_sub`]: pointer::wrapping_sub
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(strict_provenance_atomic_ptr)]
|
||||
/// use core::sync::atomic::{AtomicPtr, Ordering};
|
||||
///
|
||||
/// let array = [1i32, 2i32];
|
||||
/// let atom = AtomicPtr::new(array.as_ptr().wrapping_add(1) as *mut _);
|
||||
///
|
||||
/// assert!(core::ptr::eq(
|
||||
/// atom.fetch_ptr_sub(1, Ordering::Relaxed),
|
||||
/// &array[1],
|
||||
/// ));
|
||||
/// assert!(core::ptr::eq(atom.load(Ordering::Relaxed), &array[0]));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "95228")]
|
||||
pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T {
|
||||
self.fetch_byte_sub(val.wrapping_mul(core::mem::size_of::<T>()), order)
|
||||
}
|
||||
|
||||
/// Offsets the pointer's address by adding `val` *bytes*, returning the
|
||||
/// previous pointer.
|
||||
///
|
||||
/// This is equivalent to using [`wrapping_add`] and [`cast`] to atomically
|
||||
/// perform `ptr = ptr.cast::<u8>().wrapping_add(val).cast::<T>()`.
|
||||
///
|
||||
/// `fetch_byte_add` takes an [`Ordering`] argument which describes the
|
||||
/// memory ordering of this operation. All ordering modes are possible. Note
|
||||
/// that using [`Acquire`] makes the store part of this operation
|
||||
/// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
|
||||
///
|
||||
/// **Note**: This method is only available on platforms that support atomic
|
||||
/// operations on [`AtomicPtr`].
|
||||
///
|
||||
/// [`wrapping_add`]: pointer::wrapping_add
|
||||
/// [`cast`]: pointer::cast
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
|
||||
/// use core::sync::atomic::{AtomicPtr, Ordering};
|
||||
///
|
||||
/// let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
|
||||
/// assert_eq!(atom.fetch_byte_add(1, Ordering::Relaxed).addr(), 0);
|
||||
/// // Note: in units of bytes, not `size_of::<i64>()`.
|
||||
/// assert_eq!(atom.load(Ordering::Relaxed).addr(), 1);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "95228")]
|
||||
pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T {
|
||||
#[cfg(not(bootstrap))]
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
atomic_add(self.p.get(), core::ptr::invalid_mut(val), order).cast()
|
||||
}
|
||||
#[cfg(bootstrap)]
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
atomic_add(self.p.get().cast::<usize>(), val, order) as *mut T
|
||||
}
|
||||
}
|
||||
|
||||
/// Offsets the pointer's address by subtracting `val` *bytes*, returning the
|
||||
/// previous pointer.
|
||||
///
|
||||
/// This is equivalent to using [`wrapping_sub`] and [`cast`] to atomically
|
||||
/// perform `ptr = ptr.cast::<u8>().wrapping_sub(val).cast::<T>()`.
|
||||
///
|
||||
/// `fetch_byte_sub` takes an [`Ordering`] argument which describes the
|
||||
/// memory ordering of this operation. All ordering modes are possible. Note
|
||||
/// that using [`Acquire`] makes the store part of this operation
|
||||
/// [`Relaxed`], and using [`Release`] makes the load part [`Relaxed`].
|
||||
///
|
||||
/// **Note**: This method is only available on platforms that support atomic
|
||||
/// operations on [`AtomicPtr`].
|
||||
///
|
||||
/// [`wrapping_sub`]: pointer::wrapping_sub
|
||||
/// [`cast`]: pointer::cast
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
|
||||
/// use core::sync::atomic::{AtomicPtr, Ordering};
|
||||
///
|
||||
/// let atom = AtomicPtr::<i64>::new(core::ptr::invalid_mut(1));
|
||||
/// assert_eq!(atom.fetch_byte_sub(1, Ordering::Relaxed).addr(), 1);
|
||||
/// assert_eq!(atom.load(Ordering::Relaxed).addr(), 0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "95228")]
|
||||
pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T {
|
||||
#[cfg(not(bootstrap))]
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
atomic_sub(self.p.get(), core::ptr::invalid_mut(val), order).cast()
|
||||
}
|
||||
#[cfg(bootstrap)]
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
atomic_sub(self.p.get().cast::<usize>(), val, order) as *mut T
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs a bitwise "or" operation on the address of the current pointer,
|
||||
/// and the argument `val`, and stores a pointer with provenance of the
|
||||
/// current pointer and the resulting address.
|
||||
///
|
||||
/// This is equivalent equivalent to using [`map_addr`] to atomically
|
||||
/// perform `ptr = ptr.map_addr(|a| a | val)`. This can be used in tagged
|
||||
/// pointer schemes to atomically set tag bits.
|
||||
///
|
||||
/// **Caveat**: This operation returns the previous value. To compute the
|
||||
/// stored value without losing provenance, you may use [`map_addr`]. For
|
||||
/// example: `a.fetch_or(val).map_addr(|a| a | val)`.
|
||||
///
|
||||
/// `fetch_or` takes an [`Ordering`] argument which describes the memory
|
||||
/// ordering of this operation. All ordering modes are possible. Note that
|
||||
/// using [`Acquire`] makes the store part of this operation [`Relaxed`],
|
||||
/// and using [`Release`] makes the load part [`Relaxed`].
|
||||
///
|
||||
/// **Note**: This method is only available on platforms that support atomic
|
||||
/// operations on [`AtomicPtr`].
|
||||
///
|
||||
/// This API and its claimed semantics are part of the Strict Provenance
|
||||
/// experiment, see the [module documentation for `ptr`][crate::ptr] for
|
||||
/// details.
|
||||
///
|
||||
/// [`map_addr`]: pointer::map_addr
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
|
||||
/// use core::sync::atomic::{AtomicPtr, Ordering};
|
||||
///
|
||||
/// let pointer = &mut 3i64 as *mut i64;
|
||||
///
|
||||
/// let atom = AtomicPtr::<i64>::new(pointer);
|
||||
/// // Tag the bottom bit of the pointer.
|
||||
/// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 0);
|
||||
/// // Extract and untag.
|
||||
/// let tagged = atom.load(Ordering::Relaxed);
|
||||
/// assert_eq!(tagged.addr() & 1, 1);
|
||||
/// assert_eq!(tagged.map_addr(|p| p & !1), pointer);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "95228")]
|
||||
pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T {
|
||||
#[cfg(not(bootstrap))]
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
atomic_or(self.p.get(), core::ptr::invalid_mut(val), order).cast()
|
||||
}
|
||||
#[cfg(bootstrap)]
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
atomic_or(self.p.get().cast::<usize>(), val, order) as *mut T
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs a bitwise "and" operation on the address of the current
|
||||
/// pointer, and the argument `val`, and stores a pointer with provenance of
|
||||
/// the current pointer and the resulting address.
|
||||
///
|
||||
/// This is equivalent equivalent to using [`map_addr`] to atomically
|
||||
/// perform `ptr = ptr.map_addr(|a| a & val)`. This can be used in tagged
|
||||
/// pointer schemes to atomically unset tag bits.
|
||||
///
|
||||
/// **Caveat**: This operation returns the previous value. To compute the
|
||||
/// stored value without losing provenance, you may use [`map_addr`]. For
|
||||
/// example: `a.fetch_and(val).map_addr(|a| a & val)`.
|
||||
///
|
||||
/// `fetch_and` takes an [`Ordering`] argument which describes the memory
|
||||
/// ordering of this operation. All ordering modes are possible. Note that
|
||||
/// using [`Acquire`] makes the store part of this operation [`Relaxed`],
|
||||
/// and using [`Release`] makes the load part [`Relaxed`].
|
||||
///
|
||||
/// **Note**: This method is only available on platforms that support atomic
|
||||
/// operations on [`AtomicPtr`].
|
||||
///
|
||||
/// This API and its claimed semantics are part of the Strict Provenance
|
||||
/// experiment, see the [module documentation for `ptr`][crate::ptr] for
|
||||
/// details.
|
||||
///
|
||||
/// [`map_addr`]: pointer::map_addr
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
|
||||
/// use core::sync::atomic::{AtomicPtr, Ordering};
|
||||
///
|
||||
/// let pointer = &mut 3i64 as *mut i64;
|
||||
/// // A tagged pointer
|
||||
/// let atom = AtomicPtr::<i64>::new(pointer.map_addr(|a| a | 1));
|
||||
/// assert_eq!(atom.fetch_or(1, Ordering::Relaxed).addr() & 1, 1);
|
||||
/// // Untag, and extract the previously tagged pointer.
|
||||
/// let untagged = atom.fetch_and(!1, Ordering::Relaxed)
|
||||
/// .map_addr(|a| a & !1);
|
||||
/// assert_eq!(untagged, pointer);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "95228")]
|
||||
pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T {
|
||||
#[cfg(not(bootstrap))]
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
atomic_and(self.p.get(), core::ptr::invalid_mut(val), order).cast()
|
||||
}
|
||||
#[cfg(bootstrap)]
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
atomic_and(self.p.get().cast::<usize>(), val, order) as *mut T
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs a bitwise "xor" operation on the address of the current
|
||||
/// pointer, and the argument `val`, and stores a pointer with provenance of
|
||||
/// the current pointer and the resulting address.
|
||||
///
|
||||
/// This is equivalent equivalent to using [`map_addr`] to atomically
|
||||
/// perform `ptr = ptr.map_addr(|a| a ^ val)`. This can be used in tagged
|
||||
/// pointer schemes to atomically toggle tag bits.
|
||||
///
|
||||
/// **Caveat**: This operation returns the previous value. To compute the
|
||||
/// stored value without losing provenance, you may use [`map_addr`]. For
|
||||
/// example: `a.fetch_xor(val).map_addr(|a| a ^ val)`.
|
||||
///
|
||||
/// `fetch_xor` takes an [`Ordering`] argument which describes the memory
|
||||
/// ordering of this operation. All ordering modes are possible. Note that
|
||||
/// using [`Acquire`] makes the store part of this operation [`Relaxed`],
|
||||
/// and using [`Release`] makes the load part [`Relaxed`].
|
||||
///
|
||||
/// **Note**: This method is only available on platforms that support atomic
|
||||
/// operations on [`AtomicPtr`].
|
||||
///
|
||||
/// This API and its claimed semantics are part of the Strict Provenance
|
||||
/// experiment, see the [module documentation for `ptr`][crate::ptr] for
|
||||
/// details.
|
||||
///
|
||||
/// [`map_addr`]: pointer::map_addr
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(strict_provenance_atomic_ptr, strict_provenance)]
|
||||
/// use core::sync::atomic::{AtomicPtr, Ordering};
|
||||
///
|
||||
/// let pointer = &mut 3i64 as *mut i64;
|
||||
/// let atom = AtomicPtr::<i64>::new(pointer);
|
||||
///
|
||||
/// // Toggle a tag bit on the pointer.
|
||||
/// atom.fetch_xor(1, Ordering::Relaxed);
|
||||
/// assert_eq!(atom.load(Ordering::Relaxed).addr() & 1, 1);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[unstable(feature = "strict_provenance_atomic_ptr", issue = "95228")]
|
||||
pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T {
|
||||
#[cfg(not(bootstrap))]
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
atomic_xor(self.p.get(), core::ptr::invalid_mut(val), order).cast()
|
||||
}
|
||||
#[cfg(bootstrap)]
|
||||
// SAFETY: data races are prevented by atomic intrinsics.
|
||||
unsafe {
|
||||
atomic_xor(self.p.get().cast::<usize>(), val, order) as *mut T
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_has_atomic_load_store = "8")]
|
||||
|
@ -127,6 +127,91 @@ fn int_max() {
|
||||
assert_eq!(x.load(SeqCst), 0xf731);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(not(target_arch = "arm"), target_os = "linux"))] // Missing intrinsic in compiler-builtins
|
||||
fn ptr_add_null() {
|
||||
let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
|
||||
assert_eq!(atom.fetch_ptr_add(1, SeqCst).addr(), 0);
|
||||
assert_eq!(atom.load(SeqCst).addr(), 8);
|
||||
|
||||
assert_eq!(atom.fetch_byte_add(1, SeqCst).addr(), 8);
|
||||
assert_eq!(atom.load(SeqCst).addr(), 9);
|
||||
|
||||
assert_eq!(atom.fetch_ptr_sub(1, SeqCst).addr(), 9);
|
||||
assert_eq!(atom.load(SeqCst).addr(), 1);
|
||||
|
||||
assert_eq!(atom.fetch_byte_sub(1, SeqCst).addr(), 1);
|
||||
assert_eq!(atom.load(SeqCst).addr(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(not(target_arch = "arm"), target_os = "linux"))] // Missing intrinsic in compiler-builtins
|
||||
fn ptr_add_data() {
|
||||
let num = 0i64;
|
||||
let n = &num as *const i64 as *mut _;
|
||||
let atom = AtomicPtr::<i64>::new(n);
|
||||
assert_eq!(atom.fetch_ptr_add(1, SeqCst), n);
|
||||
assert_eq!(atom.load(SeqCst), n.wrapping_add(1));
|
||||
|
||||
assert_eq!(atom.fetch_ptr_sub(1, SeqCst), n.wrapping_add(1));
|
||||
assert_eq!(atom.load(SeqCst), n);
|
||||
let bytes_from_n = |b| n.cast::<u8>().wrapping_add(b).cast::<i64>();
|
||||
|
||||
assert_eq!(atom.fetch_byte_add(1, SeqCst), n);
|
||||
assert_eq!(atom.load(SeqCst), bytes_from_n(1));
|
||||
|
||||
assert_eq!(atom.fetch_byte_add(5, SeqCst), bytes_from_n(1));
|
||||
assert_eq!(atom.load(SeqCst), bytes_from_n(6));
|
||||
|
||||
assert_eq!(atom.fetch_byte_sub(1, SeqCst), bytes_from_n(6));
|
||||
assert_eq!(atom.load(SeqCst), bytes_from_n(5));
|
||||
|
||||
assert_eq!(atom.fetch_byte_sub(5, SeqCst), bytes_from_n(5));
|
||||
assert_eq!(atom.load(SeqCst), n);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(not(target_arch = "arm"), target_os = "linux"))] // Missing intrinsic in compiler-builtins
|
||||
fn ptr_bitops() {
|
||||
let atom = AtomicPtr::<i64>::new(core::ptr::null_mut());
|
||||
assert_eq!(atom.fetch_or(0b0111, SeqCst).addr(), 0);
|
||||
assert_eq!(atom.load(SeqCst).addr(), 0b0111);
|
||||
|
||||
assert_eq!(atom.fetch_and(0b1101, SeqCst).addr(), 0b0111);
|
||||
assert_eq!(atom.load(SeqCst).addr(), 0b0101);
|
||||
|
||||
assert_eq!(atom.fetch_xor(0b1111, SeqCst).addr(), 0b0101);
|
||||
assert_eq!(atom.load(SeqCst).addr(), 0b1010);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(not(target_arch = "arm"), target_os = "linux"))] // Missing intrinsic in compiler-builtins
|
||||
fn ptr_bitops_tagging() {
|
||||
#[repr(align(16))]
|
||||
struct Tagme(u128);
|
||||
|
||||
let tagme = Tagme(1000);
|
||||
let ptr = &tagme as *const Tagme as *mut Tagme;
|
||||
let atom: AtomicPtr<Tagme> = AtomicPtr::new(ptr);
|
||||
|
||||
const MASK_TAG: usize = 0b1111;
|
||||
const MASK_PTR: usize = !MASK_TAG;
|
||||
|
||||
assert_eq!(ptr.addr() & MASK_TAG, 0);
|
||||
|
||||
assert_eq!(atom.fetch_or(0b0111, SeqCst), ptr);
|
||||
assert_eq!(atom.load(SeqCst), ptr.map_addr(|a| a | 0b111));
|
||||
|
||||
assert_eq!(atom.fetch_and(MASK_PTR | 0b0010, SeqCst), ptr.map_addr(|a| a | 0b111));
|
||||
assert_eq!(atom.load(SeqCst), ptr.map_addr(|a| a | 0b0010));
|
||||
|
||||
assert_eq!(atom.fetch_xor(0b1011, SeqCst), ptr.map_addr(|a| a | 0b0010));
|
||||
assert_eq!(atom.load(SeqCst), ptr.map_addr(|a| a | 0b1001));
|
||||
|
||||
assert_eq!(atom.fetch_and(MASK_PTR, SeqCst), ptr.map_addr(|a| a | 0b1001));
|
||||
assert_eq!(atom.load(SeqCst), ptr);
|
||||
}
|
||||
|
||||
static S_FALSE: AtomicBool = AtomicBool::new(false);
|
||||
static S_TRUE: AtomicBool = AtomicBool::new(true);
|
||||
static S_INT: AtomicIsize = AtomicIsize::new(0);
|
||||
|
@ -90,6 +90,7 @@
|
||||
#![feature(slice_group_by)]
|
||||
#![feature(split_array)]
|
||||
#![feature(strict_provenance)]
|
||||
#![feature(strict_provenance_atomic_ptr)]
|
||||
#![feature(trusted_random_access)]
|
||||
#![feature(unsize)]
|
||||
#![feature(unzip_option)]
|
||||
|
@ -73,7 +73,7 @@ pub trait FromRawFd {
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The `fd` passed in must be a valid an open file descriptor.
|
||||
/// The `fd` passed in must be a valid and open file descriptor.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -629,6 +629,7 @@ fn clean_ty_generics<'tcx>(
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
ty::GenericParamDefKind::Lifetime if param.name == kw::UnderscoreLifetime => None,
|
||||
ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
|
||||
ty::GenericParamDefKind::Type { synthetic, .. } => {
|
||||
if param.name == kw::SelfUpper {
|
||||
|
@ -634,7 +634,6 @@ fn render_impls(
|
||||
&[],
|
||||
ImplRenderingParameters {
|
||||
show_def_docs: true,
|
||||
is_on_foreign_type: false,
|
||||
show_default_items: true,
|
||||
show_non_assoc_items: true,
|
||||
toggle_open_by_default,
|
||||
@ -1071,7 +1070,6 @@ fn render_assoc_items_inner(
|
||||
&[],
|
||||
ImplRenderingParameters {
|
||||
show_def_docs: true,
|
||||
is_on_foreign_type: false,
|
||||
show_default_items: true,
|
||||
show_non_assoc_items: true,
|
||||
toggle_open_by_default: true,
|
||||
@ -1287,7 +1285,6 @@ fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String {
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct ImplRenderingParameters {
|
||||
show_def_docs: bool,
|
||||
is_on_foreign_type: bool,
|
||||
show_default_items: bool,
|
||||
/// Whether or not to show methods.
|
||||
show_non_assoc_items: bool,
|
||||
@ -1603,7 +1600,6 @@ fn render_impl(
|
||||
parent,
|
||||
rendering_params.show_def_docs,
|
||||
use_absolute,
|
||||
rendering_params.is_on_foreign_type,
|
||||
aliases,
|
||||
);
|
||||
if toggled {
|
||||
@ -1688,21 +1684,12 @@ pub(crate) fn render_impl_summary(
|
||||
containing_item: &clean::Item,
|
||||
show_def_docs: bool,
|
||||
use_absolute: Option<bool>,
|
||||
is_on_foreign_type: bool,
|
||||
// This argument is used to reference same type with different paths to avoid duplication
|
||||
// in documentation pages for trait with automatic implementations like "Send" and "Sync".
|
||||
aliases: &[String],
|
||||
) {
|
||||
let id = cx.derive_id(match i.inner_impl().trait_ {
|
||||
Some(ref t) => {
|
||||
if is_on_foreign_type {
|
||||
get_id_for_impl_on_foreign_type(&i.inner_impl().for_, t, cx)
|
||||
} else {
|
||||
format!("impl-{}", small_url_encode(format!("{:#}", t.print(cx))))
|
||||
}
|
||||
}
|
||||
None => "impl".to_string(),
|
||||
});
|
||||
let id =
|
||||
cx.derive_id(get_id_for_impl(&i.inner_impl().for_, i.inner_impl().trait_.as_ref(), cx));
|
||||
let aliases = if aliases.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
@ -1986,21 +1973,18 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
|
||||
let mut ret = impls
|
||||
.iter()
|
||||
.filter_map(|it| {
|
||||
if let Some(ref i) = it.inner_impl().trait_ {
|
||||
let i_display = format!("{:#}", i.print(cx));
|
||||
let out = Escape(&i_display);
|
||||
let encoded =
|
||||
id_map.derive(small_url_encode(format!("impl-{:#}", i.print(cx))));
|
||||
let prefix = match it.inner_impl().polarity {
|
||||
ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
|
||||
ty::ImplPolarity::Negative => "!",
|
||||
};
|
||||
let generated =
|
||||
format!("<a href=\"#{}\">{}{}</a>", encoded, prefix, out);
|
||||
if links.insert(generated.clone()) { Some(generated) } else { None }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
let trait_ = it.inner_impl().trait_.as_ref()?;
|
||||
let encoded =
|
||||
id_map.derive(get_id_for_impl(&it.inner_impl().for_, Some(trait_), cx));
|
||||
|
||||
let i_display = format!("{:#}", trait_.print(cx));
|
||||
let out = Escape(&i_display);
|
||||
let prefix = match it.inner_impl().polarity {
|
||||
ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
|
||||
ty::ImplPolarity::Negative => "!",
|
||||
};
|
||||
let generated = format!("<a href=\"#{}\">{}{}</a>", encoded, prefix, out);
|
||||
if links.insert(generated.clone()) { Some(generated) } else { None }
|
||||
})
|
||||
.collect::<Vec<String>>();
|
||||
ret.sort();
|
||||
@ -2147,12 +2131,11 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea
|
||||
}
|
||||
}
|
||||
|
||||
fn get_id_for_impl_on_foreign_type(
|
||||
for_: &clean::Type,
|
||||
trait_: &clean::Path,
|
||||
cx: &Context<'_>,
|
||||
) -> String {
|
||||
small_url_encode(format!("impl-{:#}-for-{:#}", trait_.print(cx), for_.print(cx)))
|
||||
fn get_id_for_impl(for_: &clean::Type, trait_: Option<&clean::Path>, cx: &Context<'_>) -> String {
|
||||
match trait_ {
|
||||
Some(t) => small_url_encode(format!("impl-{:#}-for-{:#}", t.print(cx), for_.print(cx))),
|
||||
None => small_url_encode(format!("impl-{:#}", for_.print(cx))),
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String, String)> {
|
||||
@ -2161,10 +2144,7 @@ fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String
|
||||
i.trait_.as_ref().map(|trait_| {
|
||||
// Alternative format produces no URLs,
|
||||
// so this parameter does nothing.
|
||||
(
|
||||
format!("{:#}", i.for_.print(cx)),
|
||||
get_id_for_impl_on_foreign_type(&i.for_, trait_, cx),
|
||||
)
|
||||
(format!("{:#}", i.for_.print(cx)), get_id_for_impl(&i.for_, Some(trait_), cx))
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
|
@ -864,7 +864,6 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
|
||||
&[],
|
||||
ImplRenderingParameters {
|
||||
show_def_docs: false,
|
||||
is_on_foreign_type: true,
|
||||
show_default_items: false,
|
||||
show_non_assoc_items: true,
|
||||
toggle_open_by_default: false,
|
||||
@ -1642,7 +1641,6 @@ fn render_implementor(
|
||||
aliases,
|
||||
ImplRenderingParameters {
|
||||
show_def_docs: false,
|
||||
is_on_foreign_type: false,
|
||||
show_default_items: false,
|
||||
show_non_assoc_items: false,
|
||||
toggle_open_by_default: false,
|
||||
|
@ -1,12 +1,12 @@
|
||||
// MIR for `Test::X` 0 mir_map
|
||||
|
||||
fn Test::X(_1: usize) -> Test {
|
||||
let mut _0: Test; // return place in scope 0 at $DIR/unusual-item-types.rs:16:5: 16:13
|
||||
let mut _0: Test; // return place in scope 0 at $DIR/unusual-item-types.rs:16:5: 16:6
|
||||
|
||||
bb0: {
|
||||
Deinit(_0); // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:13
|
||||
((_0 as X).0: usize) = move _1; // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:13
|
||||
discriminant(_0) = 0; // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:13
|
||||
return; // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:13
|
||||
Deinit(_0); // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:6
|
||||
((_0 as X).0: usize) = move _1; // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:6
|
||||
discriminant(_0) = 0; // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:6
|
||||
return; // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:6
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
// MIR for `Test::X` 0 mir_map
|
||||
|
||||
fn Test::X(_1: usize) -> Test {
|
||||
let mut _0: Test; // return place in scope 0 at $DIR/unusual-item-types.rs:16:5: 16:13
|
||||
let mut _0: Test; // return place in scope 0 at $DIR/unusual-item-types.rs:16:5: 16:6
|
||||
|
||||
bb0: {
|
||||
Deinit(_0); // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:13
|
||||
((_0 as X).0: usize) = move _1; // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:13
|
||||
discriminant(_0) = 0; // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:13
|
||||
return; // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:13
|
||||
Deinit(_0); // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:6
|
||||
((_0 as X).0: usize) = move _1; // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:6
|
||||
discriminant(_0) = 0; // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:6
|
||||
return; // scope 0 at $DIR/unusual-item-types.rs:16:5: 16:6
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ move-cursor-to: "h2#implementations"
|
||||
assert-css: ("h2#implementations a.anchor", {"color": "rgb(0, 0, 0)"})
|
||||
|
||||
// Same thing with the impl block title.
|
||||
move-cursor-to: "#impl"
|
||||
assert-css: ("#impl a.anchor", {"color": "rgb(0, 0, 0)"})
|
||||
move-cursor-to: "#impl-HeavilyDocumentedStruct"
|
||||
assert-css: ("#impl-HeavilyDocumentedStruct a.anchor", {"color": "rgb(0, 0, 0)"})
|
||||
|
||||
assert-css: ("#title-for-struct-impl-item-doc", {"margin-left": "0px"})
|
||||
|
@ -23,9 +23,9 @@ assert-css: (
|
||||
ALL,
|
||||
)
|
||||
|
||||
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl
|
||||
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl-Foo
|
||||
assert-css: (
|
||||
"#impl",
|
||||
"#impl-Foo",
|
||||
{"color": "rgb(197, 197, 197)", "background-color": "rgba(255, 236, 164, 0.06)"},
|
||||
)
|
||||
|
||||
@ -62,9 +62,9 @@ assert-css: (
|
||||
ALL,
|
||||
)
|
||||
|
||||
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl
|
||||
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl-Foo
|
||||
assert-css: (
|
||||
"#impl",
|
||||
"#impl-Foo",
|
||||
{"color": "rgb(221, 221, 221)", "background-color": "rgb(73, 74, 61)"},
|
||||
)
|
||||
|
||||
@ -99,8 +99,8 @@ assert-css: (
|
||||
ALL,
|
||||
)
|
||||
|
||||
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl
|
||||
assert-css: ("#impl", {"color": "rgb(0, 0, 0)", "background-color": "rgb(253, 255, 211)"})
|
||||
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#impl-Foo
|
||||
assert-css: ("#impl-Foo", {"color": "rgb(0, 0, 0)", "background-color": "rgb(253, 255, 211)"})
|
||||
|
||||
goto: file://|DOC_PATH|/test_docs/struct.Foo.html#method.must_use
|
||||
assert-css: (
|
||||
|
@ -32,8 +32,8 @@ assert-css: ("h4#sub-heading-for-field", {"border-bottom-width": "0px"})
|
||||
assert-css: ("h2#implementations", {"font-size": "22px"})
|
||||
assert-css: ("h2#implementations", {"border-bottom-width": "1px"})
|
||||
|
||||
assert-css: ("#impl > h3.code-header", {"font-size": "18px"})
|
||||
assert-css: ("#impl > h3.code-header", {"border-bottom-width": "0px"})
|
||||
assert-css: ("#impl-HeavilyDocumentedStruct > h3.code-header", {"font-size": "18px"})
|
||||
assert-css: ("#impl-HeavilyDocumentedStruct > h3.code-header", {"border-bottom-width": "0px"})
|
||||
assert-css: ("#method\.do_nothing > h4.code-header", {"font-size": "16px"})
|
||||
assert-css: ("#method\.do_nothing > h4.code-header", {"border-bottom-width": "0px"})
|
||||
|
||||
@ -87,8 +87,8 @@ assert-css: ("h6#structy-prose-sub-heading", {"border-bottom-width": "0px"})
|
||||
assert-css: ("h2#implementations", {"font-size": "22px"})
|
||||
assert-css: ("h2#implementations", {"border-bottom-width": "1px"})
|
||||
|
||||
assert-css: ("#impl > h3.code-header", {"font-size": "18px"})
|
||||
assert-css: ("#impl > h3.code-header", {"border-bottom-width": "0px"})
|
||||
assert-css: ("#impl-HeavilyDocumentedEnum > h3.code-header", {"font-size": "18px"})
|
||||
assert-css: ("#impl-HeavilyDocumentedEnum > h3.code-header", {"border-bottom-width": "0px"})
|
||||
assert-css: ("#method\.do_nothing > h4.code-header", {"font-size": "16px"})
|
||||
assert-css: ("#method\.do_nothing > h4.code-header", {"border-bottom-width": "0px"})
|
||||
|
||||
@ -129,8 +129,8 @@ assert-css: ("h4#sub-heading-for-union-variant", {"border-bottom-width": "0px"})
|
||||
assert-css: ("h2#implementations", {"font-size": "22px"})
|
||||
assert-css: ("h2#implementations", {"border-bottom-width": "1px"})
|
||||
|
||||
assert-css: ("#impl > h3.code-header", {"font-size": "18px"})
|
||||
assert-css: ("#impl > h3.code-header", {"border-bottom-width": "0px"})
|
||||
assert-css: ("#impl-HeavilyDocumentedUnion > h3.code-header", {"font-size": "18px"})
|
||||
assert-css: ("#impl-HeavilyDocumentedUnion > h3.code-header", {"border-bottom-width": "0px"})
|
||||
assert-css: ("h4#title-for-union-impl-doc", {"font-size": "16px"})
|
||||
assert-css: ("h4#title-for-union-impl-doc", {"border-bottom-width": "0px"})
|
||||
assert-css: ("h5#sub-heading-for-union-impl-doc", {"font-size": "16px"})
|
||||
|
@ -6,8 +6,8 @@ assert: "#implementors-list"
|
||||
assert-count: ("#implementors-list .impl", 2)
|
||||
// Now we check that both implementors have an anchor, an ID and a similar DOM.
|
||||
assert: ("#implementors-list .impl:nth-child(1) > a.anchor")
|
||||
assert-attribute: ("#implementors-list .impl:nth-child(1)", {"id": "impl-Whatever"})
|
||||
assert-attribute: ("#implementors-list .impl:nth-child(1) > a.anchor", {"href": "#impl-Whatever"})
|
||||
assert-attribute: ("#implementors-list .impl:nth-child(1)", {"id": "impl-Whatever-for-Struct"})
|
||||
assert-attribute: ("#implementors-list .impl:nth-child(1) > a.anchor", {"href": "#impl-Whatever-for-Struct"})
|
||||
assert: "#implementors-list .impl:nth-child(1) > .code-header.in-band"
|
||||
|
||||
assert: ("#implementors-list .impl:nth-child(2) > a.anchor")
|
||||
@ -16,8 +16,16 @@ assert-attribute: ("#implementors-list .impl:nth-child(2) > a.anchor", {"href":
|
||||
assert: "#implementors-list .impl:nth-child(2) > .code-header.in-band"
|
||||
|
||||
goto: file://|DOC_PATH|/test_docs/struct.HasEmptyTraits.html
|
||||
compare-elements-position-near-false: ("#impl-EmptyTrait1", "#impl-EmptyTrait2", {"y": 30})
|
||||
compare-elements-position-near: ("#impl-EmptyTrait3 h3", "#impl-EmptyTrait3 .item-info", {"y": 30})
|
||||
compare-elements-position-near-false: (
|
||||
"#impl-EmptyTrait1-for-HasEmptyTraits",
|
||||
"#impl-EmptyTrait2-for-HasEmptyTraits",
|
||||
{"y": 30},
|
||||
)
|
||||
compare-elements-position-near: (
|
||||
"#impl-EmptyTrait3-for-HasEmptyTraits h3",
|
||||
"#impl-EmptyTrait3-for-HasEmptyTraits .item-info",
|
||||
{"y": 30},
|
||||
)
|
||||
|
||||
// Now check that re-exports work correctly.
|
||||
// There should be exactly one impl shown on both of these pages.
|
||||
|
@ -15,14 +15,17 @@ assert-text: (
|
||||
// Checking the "item-info" on an impl block as well:
|
||||
goto: file://|DOC_PATH|/lib2/struct.LongItemInfo2.html
|
||||
compare-elements-property: (
|
||||
"#impl-SimpleTrait .item-info",
|
||||
"#impl-SimpleTrait + .docblock",
|
||||
"#impl-SimpleTrait-for-LongItemInfo2 .item-info",
|
||||
"#impl-SimpleTrait-for-LongItemInfo2 + .docblock",
|
||||
["scrollWidth"],
|
||||
)
|
||||
assert-property: ("#impl-SimpleTrait .item-info", {"scrollWidth": "866"})
|
||||
assert-property: (
|
||||
"#impl-SimpleTrait-for-LongItemInfo2 .item-info",
|
||||
{"scrollWidth": "866"},
|
||||
)
|
||||
// Just to be sure we're comparing the correct "item-info":
|
||||
assert-text: (
|
||||
"#impl-SimpleTrait .item-info",
|
||||
"#impl-SimpleTrait-for-LongItemInfo2 .item-info",
|
||||
"Available on Android or Linux or Emscripten or DragonFly BSD",
|
||||
STARTS_WITH,
|
||||
)
|
||||
|
@ -8,5 +8,5 @@ click: ".impl-items .rustdoc-toggle summary::before" // This is the position of
|
||||
assert-attribute-false: (".impl-items .rustdoc-toggle", {"open": ""})
|
||||
|
||||
// Click the "Trait" part of "impl Trait" and verify it navigates.
|
||||
click: "#impl-Trait h3 a:first-of-type"
|
||||
click: "#impl-Trait-for-Foo h3 a:first-of-type"
|
||||
assert-text: (".fqn .in-band", "Trait lib2::Trait")
|
||||
|
@ -16,7 +16,7 @@ error: missing documentation for a struct
|
||||
--> $DIR/deny-missing-docs-crate.rs:3:1
|
||||
|
|
||||
LL | pub struct Foo;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// @has 'foo/struct.Foo.html'
|
||||
// @has - '//*[@id="impl-Send"]' 'impl !Send for Foo'
|
||||
// @has - '//*[@id="impl-Sync"]' 'impl !Sync for Foo'
|
||||
// @has - '//*[@id="impl-Send-for-Foo"]' 'impl !Send for Foo'
|
||||
// @has - '//*[@id="impl-Sync-for-Foo"]' 'impl !Sync for Foo'
|
||||
pub struct Foo(*const i8);
|
||||
pub trait Whatever: Send {}
|
||||
impl<T: Send + ?Sized> Whatever for T {}
|
||||
|
@ -7,3 +7,11 @@ where
|
||||
{
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub struct Extra;
|
||||
|
||||
pub trait MyTrait<T> {
|
||||
fn run() {}
|
||||
}
|
||||
|
||||
impl MyTrait<&Extra> for Extra {}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// @has foo/struct.S.html '//*[@id="impl-Into%3CU%3E"]//h3[@class="code-header in-band"]' 'impl<T, U> Into<U> for T'
|
||||
// @has foo/struct.S.html '//*[@id="impl-Into%3CU%3E-for-S"]//h3[@class="code-header in-band"]' 'impl<T, U> Into<U> for T'
|
||||
pub struct S2 {}
|
||||
mod m {
|
||||
pub struct S {}
|
||||
|
@ -36,7 +36,7 @@ pub struct Foo<const N: usize> where u8: Trait<N>;
|
||||
// @has foo/struct.Bar.html '//pre[@class="rust struct"]' 'pub struct Bar<T, const N: usize>(_)'
|
||||
pub struct Bar<T, const N: usize>([T; N]);
|
||||
|
||||
// @has foo/struct.Foo.html '//*[@id="impl"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Foo<M> where u8: Trait<M>'
|
||||
// @has foo/struct.Foo.html '//*[@id="impl-Foo%3CM%3E"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Foo<M> where u8: Trait<M>'
|
||||
impl<const M: usize> Foo<M> where u8: Trait<M> {
|
||||
// @has - '//*[@id="associatedconstant.FOO_ASSOC"]' 'pub const FOO_ASSOC: usize'
|
||||
pub const FOO_ASSOC: usize = M + 13;
|
||||
@ -47,7 +47,7 @@ impl<const M: usize> Foo<M> where u8: Trait<M> {
|
||||
}
|
||||
}
|
||||
|
||||
// @has foo/struct.Bar.html '//*[@id="impl"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Bar<u8, M>'
|
||||
// @has foo/struct.Bar.html '//*[@id="impl-Bar%3Cu8%2C%20M%3E"]/h3[@class="code-header in-band"]' 'impl<const M: usize> Bar<u8, M>'
|
||||
impl<const M: usize> Bar<u8, M> {
|
||||
// @has - '//*[@id="method.hey"]' \
|
||||
// 'pub fn hey<const N: usize>(&self) -> Foo<N> where u8: Trait<N>'
|
||||
|
@ -9,20 +9,20 @@ pub enum Order {
|
||||
}
|
||||
|
||||
// @has foo/struct.VSet.html '//pre[@class="rust struct"]' 'pub struct VSet<T, const ORDER: Order>'
|
||||
// @has foo/struct.VSet.html '//*[@id="impl-Send"]/h3[@class="code-header in-band"]' 'impl<T, const ORDER: Order> Send for VSet<T, ORDER>'
|
||||
// @has foo/struct.VSet.html '//*[@id="impl-Sync"]/h3[@class="code-header in-band"]' 'impl<T, const ORDER: Order> Sync for VSet<T, ORDER>'
|
||||
// @has foo/struct.VSet.html '//*[@id="impl-Send-for-VSet%3CT%2C%20ORDER%3E"]/h3[@class="code-header in-band"]' 'impl<T, const ORDER: Order> Send for VSet<T, ORDER>'
|
||||
// @has foo/struct.VSet.html '//*[@id="impl-Sync-for-VSet%3CT%2C%20ORDER%3E"]/h3[@class="code-header in-band"]' 'impl<T, const ORDER: Order> Sync for VSet<T, ORDER>'
|
||||
pub struct VSet<T, const ORDER: Order> {
|
||||
inner: Vec<T>,
|
||||
}
|
||||
|
||||
// @has foo/struct.VSet.html '//*[@id="impl"]/h3[@class="code-header in-band"]' 'impl<T> VSet<T, { Order::Sorted }>'
|
||||
// @has foo/struct.VSet.html '//*[@id="impl-VSet%3CT%2C%20{%20Order%3A%3ASorted%20}%3E"]/h3[@class="code-header in-band"]' 'impl<T> VSet<T, { Order::Sorted }>'
|
||||
impl<T> VSet<T, { Order::Sorted }> {
|
||||
pub fn new() -> Self {
|
||||
Self { inner: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
// @has foo/struct.VSet.html '//*[@id="impl-1"]/h3[@class="code-header in-band"]' 'impl<T> VSet<T, { Order::Unsorted }>'
|
||||
// @has foo/struct.VSet.html '//*[@id="impl-VSet%3CT%2C%20{%20Order%3A%3AUnsorted%20}%3E"]/h3[@class="code-header in-band"]' 'impl<T> VSet<T, { Order::Unsorted }>'
|
||||
impl<T> VSet<T, { Order::Unsorted }> {
|
||||
pub fn new() -> Self {
|
||||
Self { inner: Vec::new() }
|
||||
@ -31,7 +31,7 @@ impl<T> VSet<T, { Order::Unsorted }> {
|
||||
|
||||
pub struct Escape<const S: &'static str>;
|
||||
|
||||
// @has foo/struct.Escape.html '//*[@id="impl"]/h3[@class="code-header in-band"]' 'impl Escape<r#"<script>alert("Escape");</script>"#>'
|
||||
// @has foo/struct.Escape.html '//*[@id="impl-Escape%3Cr#%22%3Cscript%3Ealert(%22Escape%22)%3B%3C/script%3E%22#%3E"]/h3[@class="code-header in-band"]' 'impl Escape<r#"<script>alert("Escape");</script>"#>'
|
||||
impl Escape<r#"<script>alert("Escape");</script>"#> {
|
||||
pub fn f() {}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
#![crate_name = "foo"]
|
||||
|
||||
|
||||
pub trait Foo<T> {
|
||||
fn foo() {}
|
||||
}
|
||||
@ -8,5 +7,5 @@ pub trait Foo<T> {
|
||||
pub struct Bar;
|
||||
|
||||
// @has foo/struct.Bar.html
|
||||
// @has - '//*[@class="sidebar-elems"]//section//a[@href="#impl-Foo%3Cunsafe%20extern%20%22C%22%20fn()%3E"]' 'Foo<unsafe extern "C" fn()>'
|
||||
// @has - '//*[@class="sidebar-elems"]//section//a[@href="#impl-Foo%3Cunsafe%20extern%20%22C%22%20fn()%3E-for-Bar"]' 'Foo<unsafe extern "C" fn()>'
|
||||
impl Foo<unsafe extern "C" fn()> for Bar {}
|
||||
|
@ -1,19 +1,19 @@
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// @has foo/struct.Foo.html
|
||||
// @has - '//div[@id="synthetic-implementations-list"]/*[@id="impl-Send"]' 'impl Send for Foo'
|
||||
// @has - '//div[@id="synthetic-implementations-list"]/*[@id="impl-Send-for-Foo"]' 'impl Send for Foo'
|
||||
pub struct Foo;
|
||||
|
||||
pub trait EmptyTrait {}
|
||||
|
||||
// @has - '//div[@id="trait-implementations-list"]/*[@id="impl-EmptyTrait"]' 'impl EmptyTrait for Foo'
|
||||
// @has - '//div[@id="trait-implementations-list"]/*[@id="impl-EmptyTrait-for-Foo"]' 'impl EmptyTrait for Foo'
|
||||
impl EmptyTrait for Foo {}
|
||||
|
||||
pub trait NotEmpty {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
// @has - '//div[@id="trait-implementations-list"]/details/summary/*[@id="impl-NotEmpty"]' 'impl NotEmpty for Foo'
|
||||
// @has - '//div[@id="trait-implementations-list"]/details/summary/*[@id="impl-NotEmpty-for-Foo"]' 'impl NotEmpty for Foo'
|
||||
impl NotEmpty for Foo {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
use std::fmt;
|
||||
|
||||
// @!has foo/struct.Bar.html '//*[@id="impl-ToString"]//h3[@class="code-header in-band"]' 'impl<T> ToString for T'
|
||||
// @!has foo/struct.Bar.html '//*[@id="impl-ToString-for-Bar"]' ''
|
||||
pub struct Bar;
|
||||
|
||||
// @has foo/struct.Foo.html '//*[@id="impl-ToString"]//h3[@class="code-header in-band"]' 'impl<T> ToString for T'
|
||||
// @has foo/struct.Foo.html '//*[@id="impl-ToString-for-Foo"]//h3[@class="code-header in-band"]' 'impl<T> ToString for T'
|
||||
pub struct Foo;
|
||||
// @has foo/struct.Foo.html '//*[@class="sidebar-elems"]//section//a[@href="#impl-ToString"]' 'ToString'
|
||||
// @has foo/struct.Foo.html '//*[@class="sidebar-elems"]//section//a[@href="#impl-ToString-for-Foo"]' 'ToString'
|
||||
|
||||
impl fmt::Display for Foo {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
@ -11,11 +11,11 @@ pub struct Bar;
|
||||
|
||||
struct Hidden;
|
||||
|
||||
// @!has foo/struct.Bar.html '//*[@id="impl-Foo"]' 'impl Foo for Bar'
|
||||
// @!has foo/struct.Bar.html '//*[@id="impl-Foo-for-Bar"]' 'impl Foo for Bar'
|
||||
impl Foo for Bar {}
|
||||
// @!has foo/struct.Bar.html '//*[@id="impl-Dark"]' 'impl Dark for Bar'
|
||||
// @!has foo/struct.Bar.html '//*[@id="impl-Dark-for-Bar"]' 'impl Dark for Bar'
|
||||
impl Dark for Bar {}
|
||||
// @has foo/struct.Bar.html '//*[@id="impl-Bam"]' 'impl Bam for Bar'
|
||||
// @has foo/struct.Bar.html '//*[@id="impl-Bam-for-Bar"]' 'impl Bam for Bar'
|
||||
// @has foo/trait.Bam.html '//*[@id="implementors-list"]' 'impl Bam for Bar'
|
||||
impl Bam for Bar {}
|
||||
// @!has foo/trait.Bam.html '//*[@id="implementors-list"]' 'impl Bam for Hidden'
|
||||
|
@ -5,7 +5,7 @@
|
||||
pub struct MyType;
|
||||
|
||||
// @has 'impl_box/struct.MyType.html'
|
||||
// @has '-' '//*[@id="impl-Iterator"]' 'impl Iterator for Box<MyType>'
|
||||
// @has '-' '//*[@id="impl-Iterator-for-Box%3CMyType%3E"]' 'impl Iterator for Box<MyType>'
|
||||
|
||||
impl Iterator for Box<MyType> {
|
||||
type Item = ();
|
||||
|
@ -5,7 +5,7 @@ pub trait MyTrait {
|
||||
fn my_string(&self) -> String;
|
||||
}
|
||||
|
||||
// @has - "//div[@id='implementors-list']//*[@id='impl-MyTrait']//h3[@class='code-header in-band']" "impl<T> MyTrait for T where T: Debug"
|
||||
// @has - "//div[@id='implementors-list']//*[@id='impl-MyTrait-for-T']//h3[@class='code-header in-band']" "impl<T> MyTrait for T where T: Debug"
|
||||
impl<T> MyTrait for T
|
||||
where
|
||||
T: fmt::Debug,
|
||||
|
@ -13,5 +13,5 @@ extern crate real_gimli;
|
||||
// @!has foo/trait.Deref.html '//*[@id="impl-Deref-for-EndianSlice"]//h3[@class="code-header in-band"]' 'impl Deref for EndianSlice'
|
||||
pub use realcore::Deref;
|
||||
|
||||
// @has foo/trait.Join.html '//*[@id="impl-Join"]//h3[@class="code-header in-band"]' 'impl Join for Foo'
|
||||
// @has foo/trait.Join.html '//*[@id="impl-Join-for-Foo"]//h3[@class="code-header in-band"]' 'impl Join for Foo'
|
||||
pub use realcore::Join;
|
||||
|
@ -5,8 +5,8 @@
|
||||
// the ID is correctly derived.
|
||||
|
||||
// @has 'foo/struct.AnotherStruct.html'
|
||||
// @count - '//*[@class="sidebar"]//a[@href="#impl-AnAmazingTrait"]' 1
|
||||
// @count - '//*[@class="sidebar"]//a[@href="#impl-AnAmazingTrait-1"]' 1
|
||||
// @count - '//*[@class="sidebar"]//a[@href="#impl-AnAmazingTrait-for-AnotherStruct%3C()%3E"]' 1
|
||||
// @count - '//*[@class="sidebar"]//a[@href="#impl-AnAmazingTrait-for-AnotherStruct%3CT%3E"]' 1
|
||||
|
||||
pub trait Something {}
|
||||
|
||||
|
@ -11,3 +11,7 @@ extern crate issue_98697_reexport_with_anonymous_lifetime;
|
||||
// @has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'fn repro<F>() where F: Fn(&str)'
|
||||
// @!has issue_98697/fn.repro.html '//pre[@class="rust fn"]/code' 'for<'
|
||||
pub use issue_98697_reexport_with_anonymous_lifetime::repro;
|
||||
|
||||
// @has issue_98697/struct.Extra.html '//div[@id="trait-implementations-list"]//h3[@class="code-header in-band"]' 'impl MyTrait<&Extra> for Extra'
|
||||
// @!has issue_98697/struct.Extra.html '//div[@id="trait-implementations-list"]//h3[@class="code-header in-band"]' 'impl<'
|
||||
pub use issue_98697_reexport_with_anonymous_lifetime::Extra;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![feature(rustdoc_internals)]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// @has foo/primitive.i32.html '//*[@id="impl-ToString"]//h3[@class="code-header in-band"]' 'impl<T> ToString for T'
|
||||
// @has foo/primitive.i32.html '//*[@id="impl-ToString-for-i32"]//h3[@class="code-header in-band"]' 'impl<T> ToString for T'
|
||||
|
||||
#[doc(primitive = "i32")]
|
||||
/// Some useless docs, wouhou!
|
||||
|
@ -29,10 +29,11 @@ pub trait Tr<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]' '~const'
|
||||
// @has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/a[@class="trait"]' 'Clone'
|
||||
// @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where"]' '~const'
|
||||
// @has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where fmt-newline"]' ': Clone'
|
||||
// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]' ''
|
||||
// @!has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header in-band"]' '~const'
|
||||
// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header in-band"]/a[@class="trait"]' 'Clone'
|
||||
// @!has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header in-band"]/span[@class="where"]' '~const'
|
||||
// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header in-band"]/span[@class="where fmt-newline"]' ': Clone'
|
||||
impl<T: ~const Clone + ~const Destruct> const Tr<T> for T
|
||||
where
|
||||
Option<T>: ~const Clone + ~const Destruct,
|
||||
|
@ -11,7 +11,7 @@ pub struct Bar {
|
||||
pub struct Foo<T: ?Sized>(T);
|
||||
|
||||
// @has foo/struct.Unsized.html
|
||||
// @has - '//*[@id="impl-Sized"]//h3[@class="code-header in-band"]' 'impl !Sized for Unsized'
|
||||
// @has - '//*[@id="impl-Sized-for-Unsized"]//h3[@class="code-header in-band"]' 'impl !Sized for Unsized'
|
||||
pub struct Unsized {
|
||||
data: [u8],
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// @has foo/struct.Unsized.html
|
||||
// @has - '//*[@id="impl-Sized"]/h3[@class="code-header in-band"]' 'impl !Sized for Unsized'
|
||||
// @!has - '//*[@id="impl-Sized"]//a[@class="srclink"]' 'source'
|
||||
// @has - '//*[@id="impl-Sync"]/h3[@class="code-header in-band"]' 'impl Sync for Unsized'
|
||||
// @!has - '//*[@id="impl-Sync"]//a[@class="srclink"]' 'source'
|
||||
// @has - '//*[@id="impl-Any"]/h3[@class="code-header in-band"]' 'impl<T> Any for T'
|
||||
// @has - '//*[@id="impl-Any"]//a[@class="srclink"]' 'source'
|
||||
// @has - '//*[@id="impl-Sized-for-Unsized"]/h3[@class="code-header in-band"]' 'impl !Sized for Unsized'
|
||||
// @!has - '//*[@id="impl-Sized-for-Unsized"]//a[@class="srclink"]' 'source'
|
||||
// @has - '//*[@id="impl-Sync-for-Unsized"]/h3[@class="code-header in-band"]' 'impl Sync for Unsized'
|
||||
// @!has - '//*[@id="impl-Sync-for-Unsized"]//a[@class="srclink"]' 'source'
|
||||
// @has - '//*[@id="impl-Any-for-Unsized"]/h3[@class="code-header in-band"]' 'impl<T> Any for T'
|
||||
// @has - '//*[@id="impl-Any-for-Unsized"]//a[@class="srclink"]' 'source'
|
||||
pub struct Unsized {
|
||||
data: [u8],
|
||||
}
|
||||
|
@ -43,5 +43,5 @@ impl Trait for Struct {
|
||||
// @!has - '//*[@id="method.d"]/../../div[@class="docblock"]/p/em'
|
||||
fn d() {}
|
||||
|
||||
// @has - '//*[@id="impl-Trait"]/h3//a/@href' 'trait.Trait.html'
|
||||
// @has - '//*[@id="impl-Trait-for-Struct"]/h3//a/@href' 'trait.Trait.html'
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ LL | XEmpty3 {},
|
||||
| ------- `XE::XEmpty3` defined here
|
||||
LL | XEmpty4,
|
||||
LL | XEmpty5(),
|
||||
| --------- similarly named tuple variant `XEmpty5` defined here
|
||||
| ------- similarly named tuple variant `XEmpty5` defined here
|
||||
|
|
||||
help: use struct pattern syntax instead
|
||||
|
|
||||
@ -51,7 +51,7 @@ LL | XEmpty3 {},
|
||||
| ------- `XE::XEmpty3` defined here
|
||||
LL | XEmpty4,
|
||||
LL | XEmpty5(),
|
||||
| --------- similarly named tuple variant `XEmpty5` defined here
|
||||
| ------- similarly named tuple variant `XEmpty5` defined here
|
||||
|
|
||||
help: use struct pattern syntax instead
|
||||
|
|
||||
|
@ -36,7 +36,7 @@ LL | XE::XEmpty5 => (),
|
||||
LL | XEmpty4,
|
||||
| ------- similarly named unit variant `XEmpty4` defined here
|
||||
LL | XEmpty5(),
|
||||
| --------- `XE::XEmpty5` defined here
|
||||
| ------- `XE::XEmpty5` defined here
|
||||
|
|
||||
help: use the tuple variant pattern syntax instead
|
||||
|
|
||||
|
@ -108,7 +108,7 @@ LL | XE::XEmpty4() => (),
|
||||
LL | XEmpty4,
|
||||
| ------- `XE::XEmpty4` defined here
|
||||
LL | XEmpty5(),
|
||||
| --------- similarly named tuple variant `XEmpty5` defined here
|
||||
| ------- similarly named tuple variant `XEmpty5` defined here
|
||||
|
|
||||
help: use this syntax instead
|
||||
|
|
||||
@ -139,7 +139,7 @@ LL | XE::XEmpty4(..) => (),
|
||||
LL | XEmpty4,
|
||||
| ------- `XE::XEmpty4` defined here
|
||||
LL | XEmpty5(),
|
||||
| --------- similarly named tuple variant `XEmpty5` defined here
|
||||
| ------- similarly named tuple variant `XEmpty5` defined here
|
||||
|
|
||||
help: use this syntax instead
|
||||
|
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no variant named `B` found for enum `S`
|
||||
--> $DIR/issue-34209.rs:7:12
|
||||
|
|
||||
LL | enum S {
|
||||
| ------ variant `B` not found here
|
||||
| ------ variant `B` not found for this enum
|
||||
...
|
||||
LL | S::B {} => {},
|
||||
| ^ help: there is a variant with a similar name: `A`
|
||||
|
@ -1,13 +1,8 @@
|
||||
error[E0308]: method not compatible with trait
|
||||
--> $DIR/issue-37884.rs:6:5
|
||||
|
|
||||
LL | / fn next(&'a mut self) -> Option<Self::Item>
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | {
|
||||
LL | | Some(&mut self.0)
|
||||
LL | | }
|
||||
| |_____^ lifetime mismatch
|
||||
LL | fn next(&'a mut self) -> Option<Self::Item>
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected fn pointer `fn(&mut RepeatMut<'a, T>) -> Option<_>`
|
||||
found fn pointer `fn(&'a mut RepeatMut<'a, T>) -> Option<_>`
|
||||
|
@ -24,7 +24,7 @@ LL | const VAL: T;
|
||||
| ------------ `VAL` from trait
|
||||
...
|
||||
LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation
|
||||
|
||||
error: constant expression depends on a generic parameter
|
||||
--> $DIR/issue-77919.rs:2:9
|
||||
|
@ -2,7 +2,7 @@ error: missing documentation for a type alias
|
||||
--> $DIR/lint-missing-doc.rs:11:1
|
||||
|
|
||||
LL | pub type PubTypedef = String;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-missing-doc.rs:3:9
|
||||
@ -56,13 +56,13 @@ error: missing documentation for an associated type
|
||||
--> $DIR/lint-missing-doc.rs:64:5
|
||||
|
|
||||
LL | type AssociatedType;
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for an associated type
|
||||
--> $DIR/lint-missing-doc.rs:65:5
|
||||
|
|
||||
LL | type AssociatedTypeDef = Self;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for an associated function
|
||||
--> $DIR/lint-missing-doc.rs:81:5
|
||||
@ -92,13 +92,13 @@ error: missing documentation for a constant
|
||||
--> $DIR/lint-missing-doc.rs:151:1
|
||||
|
|
||||
LL | pub const FOO4: u32 = 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a static
|
||||
--> $DIR/lint-missing-doc.rs:161:1
|
||||
|
|
||||
LL | pub static BAR4: u32 = 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a function
|
||||
--> $DIR/lint-missing-doc.rs:167:5
|
||||
@ -122,19 +122,19 @@ error: missing documentation for a function
|
||||
--> $DIR/lint-missing-doc.rs:189:5
|
||||
|
|
||||
LL | pub fn extern_fn_undocumented(f: f32) -> f32;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a static
|
||||
--> $DIR/lint-missing-doc.rs:194:5
|
||||
|
|
||||
LL | pub static EXTERN_STATIC_UNDOCUMENTED: u8;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a foreign type
|
||||
--> $DIR/lint-missing-doc.rs:199:5
|
||||
|
|
||||
LL | pub type ExternTyUndocumented;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 22 previous errors
|
||||
|
||||
|
@ -19,7 +19,7 @@ error[E0593]: function is expected to take 0 arguments, but it takes 1 argument
|
||||
--> $DIR/issue-47706.rs:27:9
|
||||
|
|
||||
LL | Bar(i32),
|
||||
| -------- takes 1 argument
|
||||
| --- takes 1 argument
|
||||
...
|
||||
LL | foo(Qux::Bar);
|
||||
| --- ^^^^^^^^ expected function that takes 0 arguments
|
||||
|
@ -94,7 +94,7 @@ LL | check(xm7::V);
|
||||
LL | V {},
|
||||
| - `xm7::V` defined here
|
||||
LL | TV(),
|
||||
| ---- similarly named tuple variant `TV` defined here
|
||||
| -- similarly named tuple variant `TV` defined here
|
||||
|
|
||||
help: use struct literal syntax instead
|
||||
|
|
||||
|
@ -60,7 +60,7 @@ LL | E1::Z0() => {}
|
||||
::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:15
|
||||
|
|
||||
LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
|
||||
| -- ---- similarly named tuple variant `Z1` defined here
|
||||
| -- -- similarly named tuple variant `Z1` defined here
|
||||
| |
|
||||
| `E1::Z0` defined here
|
||||
|
|
||||
@ -82,7 +82,7 @@ LL | E1::Z0(x) => {}
|
||||
::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:15
|
||||
|
|
||||
LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
|
||||
| -- ---- similarly named tuple variant `Z1` defined here
|
||||
| -- -- similarly named tuple variant `Z1` defined here
|
||||
| |
|
||||
| `E1::Z0` defined here
|
||||
|
|
||||
@ -104,7 +104,7 @@ LL | E1::Z1 => {}
|
||||
::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:19
|
||||
|
|
||||
LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
|
||||
| -- ---- `E1::Z1` defined here
|
||||
| -- -- `E1::Z1` defined here
|
||||
| |
|
||||
| similarly named unit variant `Z0` defined here
|
||||
|
|
||||
@ -295,7 +295,7 @@ LL | E1::Z1(x) => {}
|
||||
::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:19
|
||||
|
|
||||
LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
|
||||
| ---- tuple variant has 0 fields
|
||||
| -- tuple variant has 0 fields
|
||||
|
||||
error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 3 fields
|
||||
--> $DIR/pat-tuple-field-count-cross.rs:39:9
|
||||
|
@ -289,7 +289,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has
|
||||
--> $DIR/pat-tuple-overfield.rs:71:16
|
||||
|
|
||||
LL | Z1(),
|
||||
| ---- tuple variant has 0 fields
|
||||
| -- tuple variant has 0 fields
|
||||
...
|
||||
LL | E1::Z1(_) => {}
|
||||
| ^ expected 0 fields, found 1
|
||||
@ -298,7 +298,7 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has
|
||||
--> $DIR/pat-tuple-overfield.rs:72:16
|
||||
|
|
||||
LL | Z1(),
|
||||
| ---- tuple variant has 0 fields
|
||||
| -- tuple variant has 0 fields
|
||||
...
|
||||
LL | E1::Z1(_, _) => {}
|
||||
| ^ ^ expected 0 fields, found 2
|
||||
|
@ -148,7 +148,7 @@ LL | one!("hello", "world");
|
||||
::: $SRC_DIR/core/src/result.rs:LL:COL
|
||||
|
|
||||
LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
|
||||
| --------------------------------------------------- similarly named tuple variant `Ok` defined here
|
||||
| -- similarly named tuple variant `Ok` defined here
|
||||
|
|
||||
= note: this error originates in the macro `parent_source_spans` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
@ -164,7 +164,7 @@ LL | two!("yay", "rust");
|
||||
::: $SRC_DIR/core/src/result.rs:LL:COL
|
||||
|
|
||||
LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
|
||||
| --------------------------------------------------- similarly named tuple variant `Ok` defined here
|
||||
| -- similarly named tuple variant `Ok` defined here
|
||||
|
|
||||
= note: this error originates in the macro `parent_source_spans` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
@ -180,7 +180,7 @@ LL | three!("hip", "hop");
|
||||
::: $SRC_DIR/core/src/result.rs:LL:COL
|
||||
|
|
||||
LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
|
||||
| --------------------------------------------------- similarly named tuple variant `Ok` defined here
|
||||
| -- similarly named tuple variant `Ok` defined here
|
||||
|
|
||||
= note: this error originates in the macro `parent_source_spans` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
|
@ -58,7 +58,7 @@ error[E0731]: transparent enum needs exactly one variant, but has 2
|
||||
LL | enum MultipleVariants {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ needs exactly one variant, but has 2
|
||||
LL | Foo(String),
|
||||
| -----------
|
||||
| ---
|
||||
LL | Bar,
|
||||
| --- too many variants in `MultipleVariants`
|
||||
|
||||
|
@ -318,7 +318,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/privacy-enum-ctor.rs:27:20
|
||||
|
|
||||
LL | Fn(u8),
|
||||
| ------ fn(u8) -> Z {Z::Fn} defined here
|
||||
| -- fn(u8) -> Z {Z::Fn} defined here
|
||||
...
|
||||
LL | let _: Z = Z::Fn;
|
||||
| - ^^^^^ expected enum `Z`, found fn item
|
||||
@ -353,7 +353,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/privacy-enum-ctor.rs:43:16
|
||||
|
|
||||
LL | Fn(u8),
|
||||
| ------ fn(u8) -> E {E::Fn} defined here
|
||||
| -- fn(u8) -> E {E::Fn} defined here
|
||||
...
|
||||
LL | let _: E = m::E::Fn;
|
||||
| - ^^^^^^^^ expected enum `E`, found fn item
|
||||
@ -388,7 +388,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/privacy-enum-ctor.rs:51:16
|
||||
|
|
||||
LL | Fn(u8),
|
||||
| ------ fn(u8) -> E {E::Fn} defined here
|
||||
| -- fn(u8) -> E {E::Fn} defined here
|
||||
...
|
||||
LL | let _: E = E::Fn;
|
||||
| - ^^^^^ expected enum `E`, found fn item
|
||||
|
@ -8,7 +8,7 @@ note: the tuple variant `Tuple` is defined here
|
||||
--> $DIR/auxiliary/variants.rs:5:23
|
||||
|
|
||||
LL | #[non_exhaustive] Tuple(u32),
|
||||
| ^^^^^^^^^^
|
||||
| ^^^^^
|
||||
|
||||
error[E0603]: unit variant `Unit` is private
|
||||
--> $DIR/variant.rs:14:47
|
||||
@ -44,7 +44,7 @@ note: the tuple variant `Tuple` is defined here
|
||||
--> $DIR/auxiliary/variants.rs:5:23
|
||||
|
|
||||
LL | #[non_exhaustive] Tuple(u32),
|
||||
| ^^^^^^^^^^
|
||||
| ^^^^^
|
||||
|
||||
error[E0603]: tuple variant `Tuple` is private
|
||||
--> $DIR/variant.rs:26:35
|
||||
@ -56,7 +56,7 @@ note: the tuple variant `Tuple` is defined here
|
||||
--> $DIR/auxiliary/variants.rs:5:23
|
||||
|
|
||||
LL | #[non_exhaustive] Tuple(u32),
|
||||
| ^^^^^^^^^^
|
||||
| ^^^^^
|
||||
|
||||
error[E0639]: cannot create non-exhaustive variant using struct expression
|
||||
--> $DIR/variant.rs:8:26
|
||||
|
@ -130,7 +130,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:35:16
|
||||
|
|
||||
LL | A(usize),
|
||||
| -------- fn(usize) -> E {E::A} defined here
|
||||
| - fn(usize) -> E {E::A} defined here
|
||||
...
|
||||
LL | let _: E = E::A;
|
||||
| - ^^^^ expected enum `E`, found fn item
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no variant named `Squareee` found for enum `Shape`
|
||||
--> $DIR/suggest-variants.rs:12:41
|
||||
|
|
||||
LL | enum Shape {
|
||||
| ---------- variant `Squareee` not found here
|
||||
| ---------- variant `Squareee` not found for this enum
|
||||
...
|
||||
LL | println!("My shape is {:?}", Shape::Squareee { size: 5});
|
||||
| ^^^^^^^^ help: there is a variant with a similar name: `Square`
|
||||
@ -11,7 +11,7 @@ error[E0599]: no variant named `Circl` found for enum `Shape`
|
||||
--> $DIR/suggest-variants.rs:13:41
|
||||
|
|
||||
LL | enum Shape {
|
||||
| ---------- variant `Circl` not found here
|
||||
| ---------- variant `Circl` not found for this enum
|
||||
...
|
||||
LL | println!("My shape is {:?}", Shape::Circl { size: 5});
|
||||
| ^^^^^ help: there is a variant with a similar name: `Circle`
|
||||
@ -20,7 +20,7 @@ error[E0599]: no variant named `Rombus` found for enum `Shape`
|
||||
--> $DIR/suggest-variants.rs:14:41
|
||||
|
|
||||
LL | enum Shape {
|
||||
| ---------- variant `Rombus` not found here
|
||||
| ---------- variant `Rombus` not found for this enum
|
||||
...
|
||||
LL | println!("My shape is {:?}", Shape::Rombus{ size: 5});
|
||||
| ^^^^^^ variant not found in `Shape`
|
||||
|
@ -28,7 +28,7 @@ LL | const VAL: T;
|
||||
| ------------ `VAL` from trait
|
||||
...
|
||||
LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation
|
||||
|
||||
error: constant expression depends on a generic parameter
|
||||
--> $DIR/ice-6252.rs:13:9
|
||||
|
Loading…
Reference in New Issue
Block a user