Auto merge of #111650 - matthiaskrgr:rollup-n7w17v4, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #107680 (Hide repr attribute from doc of types without guaranteed repr) - #111488 (Use error term in projection if missing associated item in new solver) - #111533 (Handle error body in generator layout) - #111573 (Erase `ReError` properly) - #111592 (Change Vec examples to not assert exact capacity except where it is guaranteed) - #111610 (fix(diagnostic): wrap parens for ref impl trait param) - #111642 ([rustdoc] Only keep impl blocks from bodies) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e77366b57b
25 changed files with 286 additions and 62 deletions
|
@ -1514,8 +1514,8 @@ fn opaque_type_cycle_error(
|
||||||
}
|
}
|
||||||
if tcx.sess.opts.unstable_opts.drop_tracking_mir
|
if tcx.sess.opts.unstable_opts.drop_tracking_mir
|
||||||
&& let DefKind::Generator = tcx.def_kind(closure_def_id)
|
&& let DefKind::Generator = tcx.def_kind(closure_def_id)
|
||||||
|
&& let Some(generator_layout) = tcx.mir_generator_witnesses(closure_def_id)
|
||||||
{
|
{
|
||||||
let generator_layout = tcx.mir_generator_witnesses(closure_def_id);
|
|
||||||
for interior_ty in &generator_layout.field_tys {
|
for interior_ty in &generator_layout.field_tys {
|
||||||
label_match(interior_ty.ty, interior_ty.source_info.span);
|
label_match(interior_ty.ty, interior_ty.source_info.span);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2633,47 +2633,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
Nothing,
|
Nothing,
|
||||||
}
|
}
|
||||||
let ast_generics = hir.get_generics(id.owner.def_id).unwrap();
|
let ast_generics = hir.get_generics(id.owner.def_id).unwrap();
|
||||||
let (sp, mut introducer) = if let Some(span) =
|
|
||||||
ast_generics.bounds_span_for_suggestions(def_id)
|
|
||||||
{
|
|
||||||
(span, Introducer::Plus)
|
|
||||||
} else if let Some(colon_span) = param.colon_span {
|
|
||||||
(colon_span.shrink_to_hi(), Introducer::Nothing)
|
|
||||||
} else {
|
|
||||||
(param.span.shrink_to_hi(), Introducer::Colon)
|
|
||||||
};
|
|
||||||
if matches!(
|
|
||||||
param.kind,
|
|
||||||
hir::GenericParamKind::Type { synthetic: true, .. },
|
|
||||||
) {
|
|
||||||
introducer = Introducer::Plus
|
|
||||||
}
|
|
||||||
let trait_def_ids: FxHashSet<DefId> = ast_generics
|
let trait_def_ids: FxHashSet<DefId> = ast_generics
|
||||||
.bounds_for_param(def_id)
|
.bounds_for_param(def_id)
|
||||||
.flat_map(|bp| bp.bounds.iter())
|
.flat_map(|bp| bp.bounds.iter())
|
||||||
.filter_map(|bound| bound.trait_ref()?.trait_def_id())
|
.filter_map(|bound| bound.trait_ref()?.trait_def_id())
|
||||||
.collect();
|
.collect();
|
||||||
if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
|
if candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) {
|
||||||
err.span_suggestions(
|
return;
|
||||||
sp,
|
}
|
||||||
message(format!(
|
let msg = message(format!(
|
||||||
"restrict type parameter `{}` with",
|
"restrict type parameter `{}` with",
|
||||||
param.name.ident(),
|
param.name.ident(),
|
||||||
)),
|
));
|
||||||
|
let bounds_span = ast_generics.bounds_span_for_suggestions(def_id);
|
||||||
|
if rcvr_ty.is_ref() && param.is_impl_trait() && bounds_span.is_some() {
|
||||||
|
err.multipart_suggestions(
|
||||||
|
msg,
|
||||||
candidates.iter().map(|t| {
|
candidates.iter().map(|t| {
|
||||||
format!(
|
vec![
|
||||||
"{} {}",
|
(param.span.shrink_to_lo(), "(".to_string()),
|
||||||
match introducer {
|
(
|
||||||
Introducer::Plus => " +",
|
bounds_span.unwrap(),
|
||||||
Introducer::Colon => ":",
|
format!(" + {})", self.tcx.def_path_str(t.def_id)),
|
||||||
Introducer::Nothing => "",
|
),
|
||||||
},
|
]
|
||||||
self.tcx.def_path_str(t.def_id),
|
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (sp, introducer) = if let Some(span) = bounds_span {
|
||||||
|
(span, Introducer::Plus)
|
||||||
|
} else if let Some(colon_span) = param.colon_span {
|
||||||
|
(colon_span.shrink_to_hi(), Introducer::Nothing)
|
||||||
|
} else if param.is_impl_trait() {
|
||||||
|
(param.span.shrink_to_hi(), Introducer::Plus)
|
||||||
|
} else {
|
||||||
|
(param.span.shrink_to_hi(), Introducer::Colon)
|
||||||
|
};
|
||||||
|
|
||||||
|
err.span_suggestions(
|
||||||
|
sp,
|
||||||
|
msg,
|
||||||
|
candidates.iter().map(|t| {
|
||||||
|
format!(
|
||||||
|
"{} {}",
|
||||||
|
match introducer {
|
||||||
|
Introducer::Plus => " +",
|
||||||
|
Introducer::Colon => ":",
|
||||||
|
Introducer::Nothing => "",
|
||||||
|
},
|
||||||
|
self.tcx.def_path_str(t.def_id)
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Node::Item(hir::Item {
|
Node::Item(hir::Item {
|
||||||
|
|
|
@ -1516,8 +1516,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
if encode_opt {
|
if encode_opt {
|
||||||
record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id));
|
record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id));
|
||||||
|
|
||||||
if tcx.sess.opts.unstable_opts.drop_tracking_mir && let DefKind::Generator = self.tcx.def_kind(def_id) {
|
if tcx.sess.opts.unstable_opts.drop_tracking_mir
|
||||||
record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- tcx.mir_generator_witnesses(def_id));
|
&& let DefKind::Generator = self.tcx.def_kind(def_id)
|
||||||
|
&& let Some(witnesses) = tcx.mir_generator_witnesses(def_id)
|
||||||
|
{
|
||||||
|
record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- witnesses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if encode_const {
|
if encode_const {
|
||||||
|
|
|
@ -527,7 +527,7 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
query mir_generator_witnesses(key: DefId) -> &'tcx mir::GeneratorLayout<'tcx> {
|
query mir_generator_witnesses(key: DefId) -> &'tcx Option<mir::GeneratorLayout<'tcx>> {
|
||||||
arena_cache
|
arena_cache
|
||||||
desc { |tcx| "generator witness types for `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "generator witness types for `{}`", tcx.def_path_str(key) }
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
|
|
|
@ -1708,7 +1708,9 @@ impl<'tcx> Region<'tcx> {
|
||||||
ty::ReErased => {
|
ty::ReErased => {
|
||||||
flags = flags | TypeFlags::HAS_RE_ERASED;
|
flags = flags | TypeFlags::HAS_RE_ERASED;
|
||||||
}
|
}
|
||||||
ty::ReError(_) => {}
|
ty::ReError(_) => {
|
||||||
|
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("type_flags({:?}) = {:?}", self, flags);
|
debug!("type_flags({:?}) = {:?}", self, flags);
|
||||||
|
|
|
@ -668,10 +668,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
self,
|
self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> impl Iterator<Item = ty::EarlyBinder<Ty<'tcx>>> {
|
) -> impl Iterator<Item = ty::EarlyBinder<Ty<'tcx>>> {
|
||||||
let generator_layout = &self.mir_generator_witnesses(def_id);
|
let generator_layout = self.mir_generator_witnesses(def_id);
|
||||||
generator_layout
|
generator_layout
|
||||||
.field_tys
|
.as_ref()
|
||||||
.iter()
|
.map_or_else(|| [].iter(), |l| l.field_tys.iter())
|
||||||
.filter(|decl| !decl.ignore_for_traits)
|
.filter(|decl| !decl.ignore_for_traits)
|
||||||
.map(|decl| ty::EarlyBinder(decl.ty))
|
.map(|decl| ty::EarlyBinder(decl.ty))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1397,7 +1397,7 @@ fn create_cases<'tcx>(
|
||||||
pub(crate) fn mir_generator_witnesses<'tcx>(
|
pub(crate) fn mir_generator_witnesses<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
) -> GeneratorLayout<'tcx> {
|
) -> Option<GeneratorLayout<'tcx>> {
|
||||||
assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir);
|
assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir);
|
||||||
|
|
||||||
let (body, _) = tcx.mir_promoted(def_id);
|
let (body, _) = tcx.mir_promoted(def_id);
|
||||||
|
@ -1410,6 +1410,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
|
||||||
// Get the interior types and substs which typeck computed
|
// Get the interior types and substs which typeck computed
|
||||||
let movable = match *gen_ty.kind() {
|
let movable = match *gen_ty.kind() {
|
||||||
ty::Generator(_, _, movability) => movability == hir::Movability::Movable,
|
ty::Generator(_, _, movability) => movability == hir::Movability::Movable,
|
||||||
|
ty::Error(_) => return None,
|
||||||
_ => span_bug!(body.span, "unexpected generator type {}", gen_ty),
|
_ => span_bug!(body.span, "unexpected generator type {}", gen_ty),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1425,7 +1426,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
|
||||||
|
|
||||||
check_suspend_tys(tcx, &generator_layout, &body);
|
check_suspend_tys(tcx, &generator_layout, &body);
|
||||||
|
|
||||||
generator_layout
|
Some(generator_layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> MirPass<'tcx> for StateTransform {
|
impl<'tcx> MirPass<'tcx> for StateTransform {
|
||||||
|
|
|
@ -124,10 +124,24 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if !assoc_def.item.defaultness(tcx).has_value() {
|
if !assoc_def.item.defaultness(tcx).has_value() {
|
||||||
tcx.sess.delay_span_bug(
|
let guar = tcx.sess.delay_span_bug(
|
||||||
tcx.def_span(assoc_def.item.def_id),
|
tcx.def_span(assoc_def.item.def_id),
|
||||||
"missing value for assoc item in impl",
|
"missing value for assoc item in impl",
|
||||||
);
|
);
|
||||||
|
let error_term = match assoc_def.item.kind {
|
||||||
|
ty::AssocKind::Const => tcx
|
||||||
|
.const_error(
|
||||||
|
tcx.type_of(goal.predicate.def_id())
|
||||||
|
.subst(tcx, goal.predicate.projection_ty.substs),
|
||||||
|
guar,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
ty::AssocKind::Type => tcx.ty_error(guar).into(),
|
||||||
|
ty::AssocKind::Fn => unreachable!(),
|
||||||
|
};
|
||||||
|
ecx.eq(goal.param_env, goal.predicate.term, error_term)
|
||||||
|
.expect("expected goal term to be fully unconstrained");
|
||||||
|
return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getting the right substitutions here is complex, e.g. given:
|
// Getting the right substitutions here is complex, e.g. given:
|
||||||
|
|
|
@ -2447,10 +2447,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
&& generator_did.is_local()
|
&& generator_did.is_local()
|
||||||
// Try to avoid cycles.
|
// Try to avoid cycles.
|
||||||
&& !generator_within_in_progress_typeck
|
&& !generator_within_in_progress_typeck
|
||||||
|
&& let Some(generator_info) = self.tcx.mir_generator_witnesses(generator_did)
|
||||||
{
|
{
|
||||||
let generator_info = &self.tcx.mir_generator_witnesses(generator_did);
|
|
||||||
debug!(?generator_info);
|
debug!(?generator_info);
|
||||||
|
|
||||||
'find_source: for (variant, source_info) in
|
'find_source: for (variant, source_info) in
|
||||||
generator_info.variant_fields.iter().zip(&generator_info.variant_source_info)
|
generator_info.variant_fields.iter().zip(&generator_info.variant_source_info)
|
||||||
{
|
{
|
||||||
|
|
|
@ -646,14 +646,14 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||||
///
|
///
|
||||||
/// // The vector contains no items, even though it has capacity for more
|
/// // The vector contains no items, even though it has capacity for more
|
||||||
/// assert_eq!(vec.len(), 0);
|
/// assert_eq!(vec.len(), 0);
|
||||||
/// assert_eq!(vec.capacity(), 10);
|
/// assert!(vec.capacity() >= 10);
|
||||||
///
|
///
|
||||||
/// // These are all done without reallocating...
|
/// // These are all done without reallocating...
|
||||||
/// for i in 0..10 {
|
/// for i in 0..10 {
|
||||||
/// vec.push(i);
|
/// vec.push(i);
|
||||||
/// }
|
/// }
|
||||||
/// assert_eq!(vec.len(), 10);
|
/// assert_eq!(vec.len(), 10);
|
||||||
/// assert_eq!(vec.capacity(), 10);
|
/// assert!(vec.capacity() >= 10);
|
||||||
///
|
///
|
||||||
/// // ...but this may make the vector reallocate
|
/// // ...but this may make the vector reallocate
|
||||||
/// vec.push(11);
|
/// vec.push(11);
|
||||||
|
@ -877,7 +877,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||||
/// ```
|
/// ```
|
||||||
/// let mut vec: Vec<i32> = Vec::with_capacity(10);
|
/// let mut vec: Vec<i32> = Vec::with_capacity(10);
|
||||||
/// vec.push(42);
|
/// vec.push(42);
|
||||||
/// assert_eq!(vec.capacity(), 10);
|
/// assert!(vec.capacity() >= 10);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -1028,7 +1028,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||||
/// ```
|
/// ```
|
||||||
/// let mut vec = Vec::with_capacity(10);
|
/// let mut vec = Vec::with_capacity(10);
|
||||||
/// vec.extend([1, 2, 3]);
|
/// vec.extend([1, 2, 3]);
|
||||||
/// assert_eq!(vec.capacity(), 10);
|
/// assert!(vec.capacity() >= 10);
|
||||||
/// vec.shrink_to_fit();
|
/// vec.shrink_to_fit();
|
||||||
/// assert!(vec.capacity() >= 3);
|
/// assert!(vec.capacity() >= 3);
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -1055,7 +1055,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||||
/// ```
|
/// ```
|
||||||
/// let mut vec = Vec::with_capacity(10);
|
/// let mut vec = Vec::with_capacity(10);
|
||||||
/// vec.extend([1, 2, 3]);
|
/// vec.extend([1, 2, 3]);
|
||||||
/// assert_eq!(vec.capacity(), 10);
|
/// assert!(vec.capacity() >= 10);
|
||||||
/// vec.shrink_to(4);
|
/// vec.shrink_to(4);
|
||||||
/// assert!(vec.capacity() >= 4);
|
/// assert!(vec.capacity() >= 4);
|
||||||
/// vec.shrink_to(0);
|
/// vec.shrink_to(0);
|
||||||
|
@ -1090,7 +1090,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||||
/// let mut vec = Vec::with_capacity(10);
|
/// let mut vec = Vec::with_capacity(10);
|
||||||
/// vec.extend([1, 2, 3]);
|
/// vec.extend([1, 2, 3]);
|
||||||
///
|
///
|
||||||
/// assert_eq!(vec.capacity(), 10);
|
/// assert!(vec.capacity() >= 10);
|
||||||
/// let slice = vec.into_boxed_slice();
|
/// let slice = vec.into_boxed_slice();
|
||||||
/// assert_eq!(slice.into_vec().capacity(), 3);
|
/// assert_eq!(slice.into_vec().capacity(), 3);
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -866,7 +866,7 @@ where
|
||||||
///
|
///
|
||||||
/// A data provider provides values by calling this type's provide methods.
|
/// A data provider provides values by calling this type's provide methods.
|
||||||
#[unstable(feature = "provide_any", issue = "96024")]
|
#[unstable(feature = "provide_any", issue = "96024")]
|
||||||
#[repr(transparent)]
|
#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435
|
||||||
pub struct Demand<'a>(dyn Erased<'a> + 'a);
|
pub struct Demand<'a>(dyn Erased<'a> + 'a);
|
||||||
|
|
||||||
impl<'a> Demand<'a> {
|
impl<'a> Demand<'a> {
|
||||||
|
|
|
@ -203,7 +203,7 @@ mod c_long_definition {
|
||||||
// be UB.
|
// be UB.
|
||||||
#[doc = include_str!("c_void.md")]
|
#[doc = include_str!("c_void.md")]
|
||||||
#[cfg_attr(not(bootstrap), lang = "c_void")]
|
#[cfg_attr(not(bootstrap), lang = "c_void")]
|
||||||
#[repr(u8)]
|
#[cfg_attr(not(doc), repr(u8))] // work around https://github.com/rust-lang/rust/issues/90435
|
||||||
#[stable(feature = "core_c_void", since = "1.30.0")]
|
#[stable(feature = "core_c_void", since = "1.30.0")]
|
||||||
pub enum c_void {
|
pub enum c_void {
|
||||||
#[unstable(
|
#[unstable(
|
||||||
|
@ -244,7 +244,7 @@ impl fmt::Debug for c_void {
|
||||||
target_os = "uefi",
|
target_os = "uefi",
|
||||||
windows,
|
windows,
|
||||||
))]
|
))]
|
||||||
#[repr(transparent)]
|
#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435
|
||||||
#[unstable(
|
#[unstable(
|
||||||
feature = "c_variadic",
|
feature = "c_variadic",
|
||||||
reason = "the `c_variadic` feature has not been properly tested on \
|
reason = "the `c_variadic` feature has not been properly tested on \
|
||||||
|
@ -296,7 +296,7 @@ impl<'f> fmt::Debug for VaListImpl<'f> {
|
||||||
not(target_os = "uefi"),
|
not(target_os = "uefi"),
|
||||||
not(windows),
|
not(windows),
|
||||||
))]
|
))]
|
||||||
#[repr(C)]
|
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[unstable(
|
#[unstable(
|
||||||
feature = "c_variadic",
|
feature = "c_variadic",
|
||||||
|
@ -316,7 +316,7 @@ pub struct VaListImpl<'f> {
|
||||||
|
|
||||||
/// PowerPC ABI implementation of a `va_list`.
|
/// PowerPC ABI implementation of a `va_list`.
|
||||||
#[cfg(all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)))]
|
#[cfg(all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)))]
|
||||||
#[repr(C)]
|
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[unstable(
|
#[unstable(
|
||||||
feature = "c_variadic",
|
feature = "c_variadic",
|
||||||
|
@ -336,7 +336,7 @@ pub struct VaListImpl<'f> {
|
||||||
|
|
||||||
/// s390x ABI implementation of a `va_list`.
|
/// s390x ABI implementation of a `va_list`.
|
||||||
#[cfg(target_arch = "s390x")]
|
#[cfg(target_arch = "s390x")]
|
||||||
#[repr(C)]
|
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[unstable(
|
#[unstable(
|
||||||
feature = "c_variadic",
|
feature = "c_variadic",
|
||||||
|
@ -355,7 +355,7 @@ pub struct VaListImpl<'f> {
|
||||||
|
|
||||||
/// x86_64 ABI implementation of a `va_list`.
|
/// x86_64 ABI implementation of a `va_list`.
|
||||||
#[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))]
|
#[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))]
|
||||||
#[repr(C)]
|
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[unstable(
|
#[unstable(
|
||||||
feature = "c_variadic",
|
feature = "c_variadic",
|
||||||
|
@ -373,7 +373,7 @@ pub struct VaListImpl<'f> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper for a `va_list`
|
/// A wrapper for a `va_list`
|
||||||
#[repr(transparent)]
|
#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[unstable(
|
#[unstable(
|
||||||
feature = "c_variadic",
|
feature = "c_variadic",
|
||||||
|
|
|
@ -232,7 +232,7 @@ impl fmt::Debug for Context<'_> {
|
||||||
///
|
///
|
||||||
/// [`Future::poll()`]: core::future::Future::poll
|
/// [`Future::poll()`]: core::future::Future::poll
|
||||||
/// [`Poll::Pending`]: core::task::Poll::Pending
|
/// [`Poll::Pending`]: core::task::Poll::Pending
|
||||||
#[repr(transparent)]
|
#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||||
pub struct Waker {
|
pub struct Waker {
|
||||||
waker: RawWaker,
|
waker: RawWaker,
|
||||||
|
|
|
@ -88,7 +88,7 @@ impl_element! { isize }
|
||||||
/// The layout of this type is unspecified, and may change between platforms
|
/// The layout of this type is unspecified, and may change between platforms
|
||||||
/// and/or Rust versions, and code should not assume that it is equivalent to
|
/// and/or Rust versions, and code should not assume that it is equivalent to
|
||||||
/// `[T; LANES]`.
|
/// `[T; LANES]`.
|
||||||
#[repr(transparent)]
|
#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435
|
||||||
pub struct Mask<T, const LANES: usize>(mask_impl::Mask<T, LANES>)
|
pub struct Mask<T, const LANES: usize>(mask_impl::Mask<T, LANES>)
|
||||||
where
|
where
|
||||||
T: MaskElement,
|
T: MaskElement,
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet};
|
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet};
|
||||||
use rustc_hir::intravisit::{walk_item, Visitor};
|
use rustc_hir::intravisit::{walk_body, walk_item, Visitor};
|
||||||
use rustc_hir::{Node, CRATE_HIR_ID};
|
use rustc_hir::{Node, CRATE_HIR_ID};
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
@ -106,6 +106,7 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> {
|
||||||
exact_paths: DefIdMap<Vec<Symbol>>,
|
exact_paths: DefIdMap<Vec<Symbol>>,
|
||||||
modules: Vec<Module<'tcx>>,
|
modules: Vec<Module<'tcx>>,
|
||||||
is_importable_from_parent: bool,
|
is_importable_from_parent: bool,
|
||||||
|
inside_body: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
|
@ -129,6 +130,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
exact_paths: Default::default(),
|
exact_paths: Default::default(),
|
||||||
modules: vec![om],
|
modules: vec![om],
|
||||||
is_importable_from_parent: true,
|
is_importable_from_parent: true,
|
||||||
|
inside_body: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,6 +370,26 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
import_id: Option<LocalDefId>,
|
import_id: Option<LocalDefId>,
|
||||||
) {
|
) {
|
||||||
debug!("visiting item {:?}", item);
|
debug!("visiting item {:?}", item);
|
||||||
|
if self.inside_body {
|
||||||
|
// Only impls can be "seen" outside a body. For example:
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// struct Bar;
|
||||||
|
//
|
||||||
|
// fn foo() {
|
||||||
|
// impl Bar { fn bar() {} }
|
||||||
|
// }
|
||||||
|
// Bar::bar();
|
||||||
|
// ```
|
||||||
|
if let hir::ItemKind::Impl(impl_) = item.kind &&
|
||||||
|
// Don't duplicate impls when inlining or if it's implementing a trait, we'll pick
|
||||||
|
// them up regardless of where they're located.
|
||||||
|
impl_.of_trait.is_none()
|
||||||
|
{
|
||||||
|
self.add_to_current_mod(item, None, None);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
let name = renamed.unwrap_or(item.ident.name);
|
let name = renamed.unwrap_or(item.ident.name);
|
||||||
let tcx = self.cx.tcx;
|
let tcx = self.cx.tcx;
|
||||||
|
|
||||||
|
@ -564,4 +586,10 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> {
|
||||||
fn visit_lifetime(&mut self, _: &hir::Lifetime) {
|
fn visit_lifetime(&mut self, _: &hir::Lifetime) {
|
||||||
// Unneeded.
|
// Unneeded.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_body(&mut self, b: &'tcx hir::Body<'tcx>) {
|
||||||
|
let prev = mem::replace(&mut self.inside_body, true);
|
||||||
|
walk_body(self, b);
|
||||||
|
self.inside_body = prev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
36
tests/rustdoc/nested-items-issue-111415.rs
Normal file
36
tests/rustdoc/nested-items-issue-111415.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Regression test for <https://github.com/rust-lang/rust/issues/111415>.
|
||||||
|
// This test ensures that only impl blocks are documented in bodies.
|
||||||
|
|
||||||
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
// @has 'foo/index.html'
|
||||||
|
// Checking there are only three sections.
|
||||||
|
// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3
|
||||||
|
// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs'
|
||||||
|
// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Functions'
|
||||||
|
// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits'
|
||||||
|
// Checking that there are only three items.
|
||||||
|
// @count - '//*[@id="main-content"]//*[@class="item-name"]' 3
|
||||||
|
// @has - '//*[@id="main-content"]//a[@href="struct.Bar.html"]' 'Bar'
|
||||||
|
// @has - '//*[@id="main-content"]//a[@href="fn.foo.html"]' 'foo'
|
||||||
|
// @has - '//*[@id="main-content"]//a[@href="trait.Foo.html"]' 'Foo'
|
||||||
|
|
||||||
|
// Now checking that the `foo` method is visible in `Bar` page.
|
||||||
|
// @has 'foo/struct.Bar.html'
|
||||||
|
// @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'pub fn foo()'
|
||||||
|
// @has - '//*[@id="method.bar"]/*[@class="code-header"]' 'fn bar()'
|
||||||
|
pub struct Bar;
|
||||||
|
|
||||||
|
pub trait Foo {
|
||||||
|
fn bar() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn foo() {
|
||||||
|
pub mod inaccessible {}
|
||||||
|
pub fn inner() {}
|
||||||
|
pub const BAR: u32 = 0;
|
||||||
|
impl Bar {
|
||||||
|
pub fn foo() {}
|
||||||
|
}
|
||||||
|
impl Foo for Bar {}
|
||||||
|
}
|
23
tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs
Normal file
23
tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// compile-flags: -Zdrop-tracking-mir
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
use std::future::Future;
|
||||||
|
|
||||||
|
trait Client {
|
||||||
|
type Connecting<'a>: Future + Send
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
|
||||||
|
fn connect(&'_ self) -> Self::Connecting<'a>;
|
||||||
|
//~^ ERROR use of undeclared lifetime name `'a`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
|
||||||
|
where
|
||||||
|
C: Client + Send + Sync,
|
||||||
|
{
|
||||||
|
async move { c.connect().await }
|
||||||
|
//~^ ERROR `C` does not live long enough
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
24
tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr
Normal file
24
tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
error[E0261]: use of undeclared lifetime name `'a`
|
||||||
|
--> $DIR/erase-error-in-mir-drop-tracking.rs:11:46
|
||||||
|
|
|
||||||
|
LL | fn connect(&'_ self) -> Self::Connecting<'a>;
|
||||||
|
| ^^ undeclared lifetime
|
||||||
|
|
|
||||||
|
help: consider introducing lifetime `'a` here
|
||||||
|
|
|
||||||
|
LL | fn connect<'a>(&'_ self) -> Self::Connecting<'a>;
|
||||||
|
| ++++
|
||||||
|
help: consider introducing lifetime `'a` here
|
||||||
|
|
|
||||||
|
LL | trait Client<'a> {
|
||||||
|
| ++++
|
||||||
|
|
||||||
|
error: `C` does not live long enough
|
||||||
|
--> $DIR/erase-error-in-mir-drop-tracking.rs:19:5
|
||||||
|
|
|
||||||
|
LL | async move { c.connect().await }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0261`.
|
18
tests/ui/generator/drop-tracking-error-body.rs
Normal file
18
tests/ui/generator/drop-tracking-error-body.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// compile-flags: -Zdrop-tracking-mir --edition=2021
|
||||||
|
|
||||||
|
#![feature(generators)]
|
||||||
|
|
||||||
|
pub async fn async_bad_body() {
|
||||||
|
match true {} //~ ERROR non-exhaustive patterns: type `bool` is non-empty
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generator_bad_body() {
|
||||||
|
|| {
|
||||||
|
// 'non-exhaustive pattern' only seems to be reported once, so this annotation doesn't work
|
||||||
|
// keep the function around so we can make sure it doesn't ICE
|
||||||
|
match true {}; // ERROR non-exhaustive patterns: type `bool` is non-empty
|
||||||
|
yield ();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
17
tests/ui/generator/drop-tracking-error-body.stderr
Normal file
17
tests/ui/generator/drop-tracking-error-body.stderr
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0004]: non-exhaustive patterns: type `bool` is non-empty
|
||||||
|
--> $DIR/drop-tracking-error-body.rs:6:11
|
||||||
|
|
|
||||||
|
LL | match true {}
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= note: the matched value is of type `bool`
|
||||||
|
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
||||||
|
|
|
||||||
|
LL ~ match true {
|
||||||
|
LL + _ => todo!(),
|
||||||
|
LL ~ }
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0004`.
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0046]: not all trait items implemented, missing: `Error`
|
error[E0046]: not all trait items implemented, missing: `Error`
|
||||||
--> $DIR/issue-103181-1.rs:9:5
|
--> $DIR/issue-103181-1.rs:11:5
|
||||||
|
|
|
|
||||||
LL | type Error;
|
LL | type Error;
|
||||||
| ---------- `Error` from trait
|
| ---------- `Error` from trait
|
12
tests/ui/impl-trait/issue-103181-1.next.stderr
Normal file
12
tests/ui/impl-trait/issue-103181-1.next.stderr
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0046]: not all trait items implemented, missing: `Error`
|
||||||
|
--> $DIR/issue-103181-1.rs:11:5
|
||||||
|
|
|
||||||
|
LL | type Error;
|
||||||
|
| ---------- `Error` from trait
|
||||||
|
LL | }
|
||||||
|
LL | impl HttpBody for () {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ missing `Error` in implementation
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0046`.
|
|
@ -1,3 +1,5 @@
|
||||||
|
// revisions: current next
|
||||||
|
//[next] compile-flags: -Ztrait-solver=next
|
||||||
// edition:2021
|
// edition:2021
|
||||||
|
|
||||||
mod hyper {
|
mod hyper {
|
||||||
|
|
15
tests/ui/suggestions/issue-99597.rs
Normal file
15
tests/ui/suggestions/issue-99597.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
trait T1 { }
|
||||||
|
|
||||||
|
trait T2 {
|
||||||
|
fn test(&self) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn go(s: &impl T1) {
|
||||||
|
//~^ SUGGESTION (
|
||||||
|
s.test();
|
||||||
|
//~^ ERROR no method named `test`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { }
|
15
tests/ui/suggestions/issue-99597.stderr
Normal file
15
tests/ui/suggestions/issue-99597.stderr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
error[E0599]: no method named `test` found for reference `&impl T1` in the current scope
|
||||||
|
--> $DIR/issue-99597.rs:11:7
|
||||||
|
|
|
||||||
|
LL | s.test();
|
||||||
|
| ^^^^ method not found in `&impl T1`
|
||||||
|
|
|
||||||
|
= help: items from traits can only be used if the type parameter is bounded by the trait
|
||||||
|
help: the following trait defines an item `test`, perhaps you need to restrict type parameter `impl T1` with it:
|
||||||
|
|
|
||||||
|
LL | fn go(s: &(impl T1 + T2)) {
|
||||||
|
| + +++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0599`.
|
Loading…
Add table
Add a link
Reference in a new issue