Auto merge of #91406 - matthiaskrgr:rollup-a2whn8m, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #91294 (Visit type in process_projection_elem.) - #91340 (Bump compiler_builtins to 0.1.55 to bring in fixes for targets lackin…) - #91366 (Only show notable traits if both types are the same) - #91397 (Emit a warning on generic parameters with doc comments) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
d384ff7930
12 changed files with 92 additions and 65 deletions
|
@ -678,9 +678,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compiler_builtins"
|
name = "compiler_builtins"
|
||||||
version = "0.1.53"
|
version = "0.1.55"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2467ff455350a4df7d02f1ed1449d0279605a763de5d586dcf6aa7d732508bcb"
|
checksum = "c9ac60765140c97aaf531dae151a287646b0805ec725805da9e2a3ee31cd501c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
|
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
|
||||||
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
||||||
use rustc_middle::mir::{Body, Location, PlaceElem, Promoted};
|
use rustc_middle::mir::{Body, Location, Promoted};
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::subst::SubstsRef;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||||
|
|
||||||
|
@ -62,22 +62,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
|
||||||
debug!(?ty);
|
debug!(?ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_projection_elem(
|
|
||||||
&mut self,
|
|
||||||
elem: PlaceElem<'tcx>,
|
|
||||||
_: Location,
|
|
||||||
) -> Option<PlaceElem<'tcx>> {
|
|
||||||
if let PlaceElem::Field(field, ty) = elem {
|
|
||||||
let new_ty = self.renumber_regions(ty);
|
|
||||||
|
|
||||||
if new_ty != ty {
|
|
||||||
return Some(PlaceElem::Field(field, new_ty));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
|
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
|
||||||
*substs = self.renumber_regions(*substs);
|
*substs = self.renumber_regions(*substs);
|
||||||
|
|
|
@ -1079,6 +1079,10 @@ impl EarlyLintPass for UnusedDocComment {
|
||||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
|
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
|
||||||
warn_if_doc(cx, expr.span, "expressions", &expr.attrs);
|
warn_if_doc(cx, expr.span, "expressions", &expr.attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_generic_param(&mut self, cx: &EarlyContext<'_>, param: &ast::GenericParam) {
|
||||||
|
warn_if_doc(cx, param.ident.span, "generic parameters", ¶m.attrs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
|
|
|
@ -1004,8 +1004,12 @@ macro_rules! visit_place_fns {
|
||||||
|
|
||||||
if new_local == local { None } else { Some(PlaceElem::Index(new_local)) }
|
if new_local == local { None } else { Some(PlaceElem::Index(new_local)) }
|
||||||
}
|
}
|
||||||
|
PlaceElem::Field(field, ty) => {
|
||||||
|
let mut new_ty = ty;
|
||||||
|
self.visit_ty(&mut new_ty, TyContext::Location(location));
|
||||||
|
if ty != new_ty { Some(PlaceElem::Field(field, new_ty)) } else { None }
|
||||||
|
}
|
||||||
PlaceElem::Deref
|
PlaceElem::Deref
|
||||||
| PlaceElem::Field(..)
|
|
||||||
| PlaceElem::ConstantIndex { .. }
|
| PlaceElem::ConstantIndex { .. }
|
||||||
| PlaceElem::Subslice { .. }
|
| PlaceElem::Subslice { .. }
|
||||||
| PlaceElem::Downcast(..) => None,
|
| PlaceElem::Downcast(..) => None,
|
||||||
|
|
|
@ -316,28 +316,6 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_projection_elem(
|
|
||||||
&mut self,
|
|
||||||
elem: PlaceElem<'tcx>,
|
|
||||||
_: Location,
|
|
||||||
) -> Option<PlaceElem<'tcx>> {
|
|
||||||
match elem {
|
|
||||||
PlaceElem::Index(local) => {
|
|
||||||
if let Some(replacement) = self.replacements.for_src(local) {
|
|
||||||
bug!(
|
|
||||||
"cannot replace {:?} with {:?} in index projection {:?}",
|
|
||||||
local,
|
|
||||||
replacement,
|
|
||||||
elem,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
|
fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
|
||||||
if let Some(replacement) = self.replacements.for_src(place.local) {
|
if let Some(replacement) = self.replacements.for_src(place.local) {
|
||||||
// Rebase `place`s projections onto `replacement`'s.
|
// Rebase `place`s projections onto `replacement`'s.
|
||||||
|
|
|
@ -35,24 +35,4 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
|
||||||
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
|
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
|
||||||
*ty = self.tcx.normalize_erasing_regions(self.param_env, ty);
|
*ty = self.tcx.normalize_erasing_regions(self.param_env, ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn process_projection_elem(
|
|
||||||
&mut self,
|
|
||||||
elem: PlaceElem<'tcx>,
|
|
||||||
_: Location,
|
|
||||||
) -> Option<PlaceElem<'tcx>> {
|
|
||||||
match elem {
|
|
||||||
PlaceElem::Field(field, ty) => {
|
|
||||||
let new_ty = self.tcx.normalize_erasing_regions(self.param_env, ty);
|
|
||||||
if ty != new_ty { Some(PlaceElem::Field(field, new_ty)) } else { None }
|
|
||||||
}
|
|
||||||
// None of those contain a Ty.
|
|
||||||
PlaceElem::Index(..)
|
|
||||||
| PlaceElem::Deref
|
|
||||||
| PlaceElem::ConstantIndex { .. }
|
|
||||||
| PlaceElem::Subslice { .. }
|
|
||||||
| PlaceElem::Downcast(..) => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ panic_unwind = { path = "../panic_unwind", optional = true }
|
||||||
panic_abort = { path = "../panic_abort" }
|
panic_abort = { path = "../panic_abort" }
|
||||||
core = { path = "../core" }
|
core = { path = "../core" }
|
||||||
libc = { version = "0.2.108", default-features = false, features = ['rustc-dep-of-std'] }
|
libc = { version = "0.2.108", default-features = false, features = ['rustc-dep-of-std'] }
|
||||||
compiler_builtins = { version = "0.1.53" }
|
compiler_builtins = { version = "0.1.55" }
|
||||||
profiler_builtins = { path = "../profiler_builtins", optional = true }
|
profiler_builtins = { path = "../profiler_builtins", optional = true }
|
||||||
unwind = { path = "../unwind" }
|
unwind = { path = "../unwind" }
|
||||||
hashbrown = { version = "0.11", default-features = false, features = ['rustc-dep-of-std'] }
|
hashbrown = { version = "0.11", default-features = false, features = ['rustc-dep-of-std'] }
|
||||||
|
|
|
@ -1468,6 +1468,45 @@ crate enum Type {
|
||||||
rustc_data_structures::static_assert_size!(Type, 72);
|
rustc_data_structures::static_assert_size!(Type, 72);
|
||||||
|
|
||||||
impl Type {
|
impl Type {
|
||||||
|
/// When comparing types for equality, it can help to ignore `&` wrapping.
|
||||||
|
crate fn without_borrowed_ref(&self) -> &Type {
|
||||||
|
let mut result = self;
|
||||||
|
while let Type::BorrowedRef { type_, .. } = result {
|
||||||
|
result = &*type_;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if two types are "potentially the same".
|
||||||
|
/// This is different from `Eq`, because it knows that things like
|
||||||
|
/// `Placeholder` are possible matches for everything.
|
||||||
|
crate fn is_same(&self, other: &Self, cache: &Cache) -> bool {
|
||||||
|
match (self, other) {
|
||||||
|
// Recursive cases.
|
||||||
|
(Type::Tuple(a), Type::Tuple(b)) => {
|
||||||
|
a.len() == b.len() && a.iter().zip(b).all(|(a, b)| a.is_same(&b, cache))
|
||||||
|
}
|
||||||
|
(Type::Slice(a), Type::Slice(b)) => a.is_same(&b, cache),
|
||||||
|
(Type::Array(a, al), Type::Array(b, bl)) => al == bl && a.is_same(&b, cache),
|
||||||
|
(Type::RawPointer(mutability, type_), Type::RawPointer(b_mutability, b_type_)) => {
|
||||||
|
mutability == b_mutability && type_.is_same(&b_type_, cache)
|
||||||
|
}
|
||||||
|
(
|
||||||
|
Type::BorrowedRef { mutability, type_, .. },
|
||||||
|
Type::BorrowedRef { mutability: b_mutability, type_: b_type_, .. },
|
||||||
|
) => mutability == b_mutability && type_.is_same(&b_type_, cache),
|
||||||
|
// Placeholders and generics are equal to all other types.
|
||||||
|
(Type::Infer, _) | (_, Type::Infer) => true,
|
||||||
|
(Type::Generic(_), _) | (_, Type::Generic(_)) => true,
|
||||||
|
// Other cases, such as primitives, just use recursion.
|
||||||
|
(a, b) => a
|
||||||
|
.def_id(cache)
|
||||||
|
.and_then(|a| Some((a, b.def_id(cache)?)))
|
||||||
|
.map(|(a, b)| a == b)
|
||||||
|
.unwrap_or(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
crate fn primitive_type(&self) -> Option<PrimitiveType> {
|
crate fn primitive_type(&self) -> Option<PrimitiveType> {
|
||||||
match *self {
|
match *self {
|
||||||
Primitive(p) | BorrowedRef { type_: box Primitive(p), .. } => Some(p),
|
Primitive(p) | BorrowedRef { type_: box Primitive(p), .. } => Some(p),
|
||||||
|
|
|
@ -1235,10 +1235,17 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
|
||||||
fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String {
|
fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String {
|
||||||
let mut out = Buffer::html();
|
let mut out = Buffer::html();
|
||||||
|
|
||||||
if let Some(did) = decl.output.as_return().and_then(|t| t.def_id(cx.cache())) {
|
if let Some((did, ty)) = decl.output.as_return().and_then(|t| Some((t.def_id(cx.cache())?, t)))
|
||||||
|
{
|
||||||
if let Some(impls) = cx.cache().impls.get(&did) {
|
if let Some(impls) = cx.cache().impls.get(&did) {
|
||||||
for i in impls {
|
for i in impls {
|
||||||
let impl_ = i.inner_impl();
|
let impl_ = i.inner_impl();
|
||||||
|
if !impl_.for_.without_borrowed_ref().is_same(ty.without_borrowed_ref(), cx.cache())
|
||||||
|
{
|
||||||
|
// Two different types might have the same did,
|
||||||
|
// without actually being the same.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if let Some(trait_) = &impl_.trait_ {
|
if let Some(trait_) = &impl_.trait_ {
|
||||||
let trait_did = trait_.def_id();
|
let trait_did = trait_.def_id();
|
||||||
|
|
||||||
|
|
20
src/test/rustdoc/doc-notable_trait-slice.rs
Normal file
20
src/test/rustdoc/doc-notable_trait-slice.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#![feature(doc_notable_trait)]
|
||||||
|
|
||||||
|
#[doc(notable_trait)]
|
||||||
|
pub trait SomeTrait {}
|
||||||
|
|
||||||
|
pub struct SomeStruct;
|
||||||
|
pub struct OtherStruct;
|
||||||
|
impl SomeTrait for &[SomeStruct] {}
|
||||||
|
|
||||||
|
// @has doc_notable_trait_slice/fn.bare_fn_matches.html
|
||||||
|
// @has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]'
|
||||||
|
pub fn bare_fn_matches() -> &'static [SomeStruct] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
|
||||||
|
// @has doc_notable_trait_slice/fn.bare_fn_no_matches.html
|
||||||
|
// @!has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]'
|
||||||
|
pub fn bare_fn_no_matches() -> &'static [OtherStruct] {
|
||||||
|
&[]
|
||||||
|
}
|
|
@ -26,4 +26,7 @@ fn doc_comment_on_expr(num: u8) -> bool {
|
||||||
num == 3
|
num == 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn doc_comment_on_generic<#[doc = "x"] T>(val: T) {}
|
||||||
|
//~^ ERROR: unused doc comment
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -41,6 +41,14 @@ LL | num == 3
|
||||||
|
|
|
|
||||||
= help: use `//` for a plain comment
|
= help: use `//` for a plain comment
|
||||||
|
|
||||||
|
error: unused doc comment
|
||||||
|
--> $DIR/unused-doc-comments-edge-cases.rs:29:27
|
||||||
|
|
|
||||||
|
LL | fn doc_comment_on_generic<#[doc = "x"] T>(val: T) {}
|
||||||
|
| ^^^^^^^^^^^^ - rustdoc does not generate documentation for generic parameters
|
||||||
|
|
|
||||||
|
= help: use `//` for a plain comment
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/unused-doc-comments-edge-cases.rs:14:9
|
--> $DIR/unused-doc-comments-edge-cases.rs:14:9
|
||||||
|
|
|
|
||||||
|
@ -55,7 +63,7 @@ help: you might have meant to return this value
|
||||||
LL | return true;
|
LL | return true;
|
||||||
| ++++++ +
|
| ++++++ +
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0308, E0658.
|
Some errors have detailed explanations: E0308, E0658.
|
||||||
For more information about an error, try `rustc --explain E0308`.
|
For more information about an error, try `rustc --explain E0308`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue