Auto merge of #75276 - JohnTitor:rollup-rz4hs0w, r=JohnTitor
Rollup of 7 pull requests Successful merges: - #75224 (Don't call a function in function-arguments-naked.rs) - #75237 (Display elided lifetime for non-reference type in doc) - #75250 (make MaybeUninit::as_(mut_)ptr const) - #75253 (clean up const-hacks in int endianess conversion functions) - #75259 (Add missing backtick) - #75267 (Small cleanup) - #75270 (fix a couple of clippy findings) Failed merges: r? @ghost
This commit is contained in:
commit
1d100ba26c
39 changed files with 170 additions and 127 deletions
|
@ -405,9 +405,11 @@ impl<T> MaybeUninit<T> {
|
||||||
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
|
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
|
||||||
/// until they are, it is advisable to avoid them.)
|
/// until they are, it is advisable to avoid them.)
|
||||||
#[stable(feature = "maybe_uninit", since = "1.36.0")]
|
#[stable(feature = "maybe_uninit", since = "1.36.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_maybe_uninit_as_ptr", issue = "75251")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn as_ptr(&self) -> *const T {
|
pub const fn as_ptr(&self) -> *const T {
|
||||||
unsafe { &*self.value as *const T }
|
// `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
|
||||||
|
self as *const _ as *const T
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a mutable pointer to the contained value. Reading from this pointer or turning it
|
/// Gets a mutable pointer to the contained value. Reading from this pointer or turning it
|
||||||
|
@ -442,9 +444,11 @@ impl<T> MaybeUninit<T> {
|
||||||
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
|
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
|
||||||
/// until they are, it is advisable to avoid them.)
|
/// until they are, it is advisable to avoid them.)
|
||||||
#[stable(feature = "maybe_uninit", since = "1.36.0")]
|
#[stable(feature = "maybe_uninit", since = "1.36.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_maybe_uninit_as_ptr", issue = "75251")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn as_mut_ptr(&mut self) -> *mut T {
|
pub const fn as_mut_ptr(&mut self) -> *mut T {
|
||||||
unsafe { &mut *self.value as *mut T }
|
// `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
|
||||||
|
self as *mut _ as *mut T
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts the value from the `MaybeUninit<T>` container. This is a great way
|
/// Extracts the value from the `MaybeUninit<T>` container. This is a great way
|
||||||
|
|
|
@ -2346,17 +2346,12 @@ assert_eq!(
|
||||||
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
|
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
|
||||||
// SAFETY: const sound because integers are plain old datatypes so we can always
|
// SAFETY: const sound because integers are plain old datatypes so we can always
|
||||||
// transmute them to arrays of bytes
|
// transmute them to arrays of bytes
|
||||||
#[allow_internal_unstable(const_fn_union)]
|
#[allow_internal_unstable(const_fn_transmute)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
|
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
|
||||||
#[repr(C)]
|
|
||||||
union Bytes {
|
|
||||||
val: $SelfT,
|
|
||||||
bytes: [u8; mem::size_of::<$SelfT>()],
|
|
||||||
}
|
|
||||||
// SAFETY: integers are plain old datatypes so we can always transmute them to
|
// SAFETY: integers are plain old datatypes so we can always transmute them to
|
||||||
// arrays of bytes
|
// arrays of bytes
|
||||||
unsafe { Bytes { val: self }.bytes }
|
unsafe { mem::transmute(self) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2464,16 +2459,11 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
|
||||||
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
|
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
|
||||||
// SAFETY: const sound because integers are plain old datatypes so we can always
|
// SAFETY: const sound because integers are plain old datatypes so we can always
|
||||||
// transmute to them
|
// transmute to them
|
||||||
#[allow_internal_unstable(const_fn_union)]
|
#[allow_internal_unstable(const_fn_transmute)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
|
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
|
||||||
#[repr(C)]
|
|
||||||
union Bytes {
|
|
||||||
val: $SelfT,
|
|
||||||
bytes: [u8; mem::size_of::<$SelfT>()],
|
|
||||||
}
|
|
||||||
// SAFETY: integers are plain old datatypes so we can always transmute to them
|
// SAFETY: integers are plain old datatypes so we can always transmute to them
|
||||||
unsafe { Bytes { bytes }.val }
|
unsafe { mem::transmute(bytes) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4368,17 +4358,12 @@ assert_eq!(
|
||||||
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
|
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
|
||||||
// SAFETY: const sound because integers are plain old datatypes so we can always
|
// SAFETY: const sound because integers are plain old datatypes so we can always
|
||||||
// transmute them to arrays of bytes
|
// transmute them to arrays of bytes
|
||||||
#[allow_internal_unstable(const_fn_union)]
|
#[allow_internal_unstable(const_fn_transmute)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
|
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
|
||||||
#[repr(C)]
|
|
||||||
union Bytes {
|
|
||||||
val: $SelfT,
|
|
||||||
bytes: [u8; mem::size_of::<$SelfT>()],
|
|
||||||
}
|
|
||||||
// SAFETY: integers are plain old datatypes so we can always transmute them to
|
// SAFETY: integers are plain old datatypes so we can always transmute them to
|
||||||
// arrays of bytes
|
// arrays of bytes
|
||||||
unsafe { Bytes { val: self }.bytes }
|
unsafe { mem::transmute(self) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4486,16 +4471,11 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
|
||||||
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
|
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
|
||||||
// SAFETY: const sound because integers are plain old datatypes so we can always
|
// SAFETY: const sound because integers are plain old datatypes so we can always
|
||||||
// transmute to them
|
// transmute to them
|
||||||
#[allow_internal_unstable(const_fn_union)]
|
#[allow_internal_unstable(const_fn_transmute)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
|
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
|
||||||
#[repr(C)]
|
|
||||||
union Bytes {
|
|
||||||
val: $SelfT,
|
|
||||||
bytes: [u8; mem::size_of::<$SelfT>()],
|
|
||||||
}
|
|
||||||
// SAFETY: integers are plain old datatypes so we can always transmute to them
|
// SAFETY: integers are plain old datatypes so we can always transmute to them
|
||||||
unsafe { Bytes { bytes }.val }
|
unsafe { mem::transmute(bytes) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::env;
|
||||||
|
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub fn get_concurrency() -> usize {
|
pub fn get_concurrency() -> usize {
|
||||||
return match env::var("RUST_TEST_THREADS") {
|
match env::var("RUST_TEST_THREADS") {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
let opt_n: Option<usize> = s.parse().ok();
|
let opt_n: Option<usize> = s.parse().ok();
|
||||||
match opt_n {
|
match opt_n {
|
||||||
|
@ -13,7 +13,7 @@ pub fn get_concurrency() -> usize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(..) => num_cpus(),
|
Err(..) => num_cpus(),
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
|
|
|
@ -378,7 +378,7 @@ impl Default for Generics {
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub struct WhereClause {
|
pub struct WhereClause {
|
||||||
/// `true` if we ate a `where` token: this can happen
|
/// `true` if we ate a `where` token: this can happen
|
||||||
/// if we parsed no predicates (e.g. `struct Foo where {}
|
/// if we parsed no predicates (e.g. `struct Foo where {}`).
|
||||||
/// This allows us to accurately pretty-print
|
/// This allows us to accurately pretty-print
|
||||||
/// in `nt_to_tokenstream`
|
/// in `nt_to_tokenstream`
|
||||||
pub has_where_token: bool,
|
pub has_where_token: bool,
|
||||||
|
|
|
@ -960,7 +960,7 @@ fn pointer_type_metadata(
|
||||||
fn param_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
|
fn param_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
|
||||||
debug!("param_type_metadata: {:?}", t);
|
debug!("param_type_metadata: {:?}", t);
|
||||||
let name = format!("{:?}", t);
|
let name = format!("{:?}", t);
|
||||||
return unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustDIBuilderCreateBasicType(
|
llvm::LLVMRustDIBuilderCreateBasicType(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
name.as_ptr().cast(),
|
name.as_ptr().cast(),
|
||||||
|
@ -968,7 +968,7 @@ fn param_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
|
||||||
Size::ZERO.bits(),
|
Size::ZERO.bits(),
|
||||||
DW_ATE_unsigned,
|
DW_ATE_unsigned,
|
||||||
)
|
)
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_unit_metadata(
|
pub fn compile_unit_metadata(
|
||||||
|
|
|
@ -490,7 +490,7 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
|
||||||
let _timer = sess.timer("copy_all_cgu_workproducts_to_incr_comp_cache_dir");
|
let _timer = sess.timer("copy_all_cgu_workproducts_to_incr_comp_cache_dir");
|
||||||
|
|
||||||
for module in compiled_modules.modules.iter().filter(|m| m.kind == ModuleKind::Regular) {
|
for module in compiled_modules.modules.iter().filter(|m| m.kind == ModuleKind::Regular) {
|
||||||
let path = module.object.as_ref().map(|path| path.clone());
|
let path = module.object.as_ref().cloned();
|
||||||
|
|
||||||
if let Some((id, product)) =
|
if let Some((id, product)) =
|
||||||
copy_cgu_workproduct_to_incr_comp_cache_dir(sess, &module.name, &path)
|
copy_cgu_workproduct_to_incr_comp_cache_dir(sess, &module.name, &path)
|
||||||
|
|
|
@ -85,11 +85,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
|
|
||||||
debug!("try_report_named_anon_conflict: ret ty {:?}", ty);
|
debug!("try_report_named_anon_conflict: ret ty {:?}", ty);
|
||||||
if sub == &ty::ReStatic
|
if sub == &ty::ReStatic
|
||||||
&& v.0
|
&& v.0.into_iter().find(|t| t.span.desugaring_kind().is_none()).is_some()
|
||||||
.into_iter()
|
|
||||||
.filter(|t| t.span.desugaring_kind().is_none())
|
|
||||||
.next()
|
|
||||||
.is_some()
|
|
||||||
{
|
{
|
||||||
// If the failure is due to a `'static` requirement coming from a `dyn` or
|
// If the failure is due to a `'static` requirement coming from a `dyn` or
|
||||||
// `impl` Trait that *isn't* caused by `async fn` desugaring, handle this case
|
// `impl` Trait that *isn't* caused by `async fn` desugaring, handle this case
|
||||||
|
|
|
@ -257,7 +257,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
param.param_ty.to_string(),
|
param.param_ty.to_string(),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
} else if let Some(_) = opaque
|
} else if opaque
|
||||||
.bounds
|
.bounds
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|arg| match arg {
|
.filter_map(|arg| match arg {
|
||||||
|
@ -269,6 +269,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.next()
|
.next()
|
||||||
|
.is_some()
|
||||||
{
|
{
|
||||||
} else {
|
} else {
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
|
|
|
@ -50,7 +50,7 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
|
||||||
ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
|
ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
|
||||||
ty::Covariant => self.relate(a, b),
|
ty::Covariant => self.relate(a, b),
|
||||||
// FIXME(#41044) -- not correct, need test
|
// FIXME(#41044) -- not correct, need test
|
||||||
ty::Bivariant => Ok(a.clone()),
|
ty::Bivariant => Ok(a),
|
||||||
ty::Contravariant => self.fields.lub(self.a_is_expected).relate(a, b),
|
ty::Contravariant => self.fields.lub(self.a_is_expected).relate(a, b),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
|
||||||
// very challenging, switch to invariance. This is obviously
|
// very challenging, switch to invariance. This is obviously
|
||||||
// overly conservative but works ok in practice.
|
// overly conservative but works ok in practice.
|
||||||
self.relate_with_variance(ty::Variance::Invariant, a, b)?;
|
self.relate_with_variance(ty::Variance::Invariant, a, b)?;
|
||||||
Ok(a.clone())
|
Ok(a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -719,7 +719,7 @@ where
|
||||||
self.a_scopes.pop().unwrap();
|
self.a_scopes.pop().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(a.clone())
|
Ok(a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -288,9 +288,9 @@ impl<'me, 'tcx> LeakCheck<'me, 'tcx> {
|
||||||
) -> TypeError<'tcx> {
|
) -> TypeError<'tcx> {
|
||||||
debug!("error: placeholder={:?}, other_region={:?}", placeholder, other_region);
|
debug!("error: placeholder={:?}, other_region={:?}", placeholder, other_region);
|
||||||
if self.overly_polymorphic {
|
if self.overly_polymorphic {
|
||||||
return TypeError::RegionsOverlyPolymorphic(placeholder.name, other_region);
|
TypeError::RegionsOverlyPolymorphic(placeholder.name, other_region)
|
||||||
} else {
|
} else {
|
||||||
return TypeError::RegionsInsufficientlyPolymorphic(placeholder.name, other_region);
|
TypeError::RegionsInsufficientlyPolymorphic(placeholder.name, other_region)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
|
||||||
match variance {
|
match variance {
|
||||||
ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
|
ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
|
||||||
ty::Covariant => self.relate(a, b),
|
ty::Covariant => self.relate(a, b),
|
||||||
ty::Bivariant => Ok(a.clone()),
|
ty::Bivariant => Ok(a),
|
||||||
ty::Contravariant => self.with_expected_switched(|this| this.relate(b, a)),
|
ty::Contravariant => self.with_expected_switched(|this| this.relate(b, a)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1074,7 +1074,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
// If `ty` is a `repr(transparent)` newtype, and the non-zero-sized type is a generic
|
// If `ty` is a `repr(transparent)` newtype, and the non-zero-sized type is a generic
|
||||||
// argument, which after substitution, is `()`, then this branch can be hit.
|
// argument, which after substitution, is `()`, then this branch can be hit.
|
||||||
FfiResult::FfiUnsafe { ty, .. } if is_return_type && ty.is_unit() => return,
|
FfiResult::FfiUnsafe { ty, .. } if is_return_type && ty.is_unit() => {}
|
||||||
FfiResult::FfiUnsafe { ty, reason, help } => {
|
FfiResult::FfiUnsafe { ty, reason, help } => {
|
||||||
self.emit_ffi_unsafe_type_lint(ty, sp, &reason, help.as_deref());
|
self.emit_ffi_unsafe_type_lint(ty, sp, &reason, help.as_deref());
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,7 @@ impl<'a, 'tcx> SpecializedEncoder<ExpnId> for EncodeContext<'a, 'tcx> {
|
||||||
fn specialized_encode(&mut self, expn: &ExpnId) -> Result<(), Self::Error> {
|
fn specialized_encode(&mut self, expn: &ExpnId) -> Result<(), Self::Error> {
|
||||||
rustc_span::hygiene::raw_encode_expn_id(
|
rustc_span::hygiene::raw_encode_expn_id(
|
||||||
*expn,
|
*expn,
|
||||||
&mut self.hygiene_ctxt,
|
&self.hygiene_ctxt,
|
||||||
ExpnDataEncodeMode::Metadata,
|
ExpnDataEncodeMode::Metadata,
|
||||||
self,
|
self,
|
||||||
)
|
)
|
||||||
|
|
|
@ -128,7 +128,7 @@ pub struct DropckOutlivesResult<'tcx> {
|
||||||
|
|
||||||
impl<'tcx> DropckOutlivesResult<'tcx> {
|
impl<'tcx> DropckOutlivesResult<'tcx> {
|
||||||
pub fn report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) {
|
pub fn report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) {
|
||||||
if let Some(overflow_ty) = self.overflows.iter().next() {
|
if let Some(overflow_ty) = self.overflows.get(0) {
|
||||||
let mut err = struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
tcx.sess,
|
tcx.sess,
|
||||||
span,
|
span,
|
||||||
|
|
|
@ -868,7 +868,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return normal_ret;
|
normal_ret
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds the span of arguments of a closure (within `maybe_closure_span`)
|
/// Finds the span of arguments of a closure (within `maybe_closure_span`)
|
||||||
|
|
|
@ -361,7 +361,7 @@ fn optimization_applies<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
trace!("SUCCESS: optimization applies!");
|
trace!("SUCCESS: optimization applies!");
|
||||||
return true;
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> MirPass<'tcx> for SimplifyArmIdentity {
|
impl<'tcx> MirPass<'tcx> for SimplifyArmIdentity {
|
||||||
|
|
|
@ -115,7 +115,7 @@ pub fn equal_up_to_regions(
|
||||||
T: Relate<'tcx>,
|
T: Relate<'tcx>,
|
||||||
{
|
{
|
||||||
self.relate(a.skip_binder(), b.skip_binder())?;
|
self.relate(a.skip_binder(), b.skip_binder())?;
|
||||||
Ok(a.clone())
|
Ok(a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,8 @@ pub struct Parser<'a> {
|
||||||
/// error.
|
/// error.
|
||||||
pub(super) unclosed_delims: Vec<UnmatchedBrace>,
|
pub(super) unclosed_delims: Vec<UnmatchedBrace>,
|
||||||
last_unexpected_token_span: Option<Span>,
|
last_unexpected_token_span: Option<Span>,
|
||||||
|
/// Span pointing at the `:` for the last type ascription the parser has seen, and whether it
|
||||||
|
/// looked like it could have been a mistyped path or literal `Option:Some(42)`).
|
||||||
pub last_type_ascription: Option<(Span, bool /* likely path typo */)>,
|
pub last_type_ascription: Option<(Span, bool /* likely path typo */)>,
|
||||||
/// If present, this `Parser` is not parsing Rust code but rather a macro call.
|
/// If present, this `Parser` is not parsing Rust code but rather a macro call.
|
||||||
subparser_name: Option<&'static str>,
|
subparser_name: Option<&'static str>,
|
||||||
|
|
|
@ -820,7 +820,7 @@ fn find_skips_from_snippet(
|
||||||
}
|
}
|
||||||
|
|
||||||
let r_start = str_style.map(|r| r + 1).unwrap_or(0);
|
let r_start = str_style.map(|r| r + 1).unwrap_or(0);
|
||||||
let r_end = str_style.map(|r| r).unwrap_or(0);
|
let r_end = str_style.unwrap_or(0);
|
||||||
let s = &snippet[r_start + 1..snippet.len() - r_end - 1];
|
let s = &snippet[r_start + 1..snippet.len() - r_end - 1];
|
||||||
(find_skips(s, str_style.is_some()), true)
|
(find_skips(s, str_style.is_some()), true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,7 +226,7 @@ impl<'a> PathSource<'a> {
|
||||||
ValueNS => "method or associated constant",
|
ValueNS => "method or associated constant",
|
||||||
MacroNS => bug!("associated macro"),
|
MacroNS => bug!("associated macro"),
|
||||||
},
|
},
|
||||||
PathSource::Expr(parent) => match &parent.as_ref().map(|p| &p.kind) {
|
PathSource::Expr(parent) => match parent.as_ref().map(|p| &p.kind) {
|
||||||
// "function" here means "anything callable" rather than `DefKind::Fn`,
|
// "function" here means "anything callable" rather than `DefKind::Fn`,
|
||||||
// this is not precise but usually more helpful than just "value".
|
// this is not precise but usually more helpful than just "value".
|
||||||
Some(ExprKind::Call(call_expr, _)) => match &call_expr.kind {
|
Some(ExprKind::Call(call_expr, _)) => match &call_expr.kind {
|
||||||
|
|
|
@ -702,7 +702,7 @@ impl<'tcx> SaveContext<'tcx> {
|
||||||
Res::Def(HirDefKind::ConstParam, def_id) => {
|
Res::Def(HirDefKind::ConstParam, def_id) => {
|
||||||
Some(Ref { kind: RefKind::Variable, span, ref_id: id_from_def_id(def_id) })
|
Some(Ref { kind: RefKind::Variable, span, ref_id: id_from_def_id(def_id) })
|
||||||
}
|
}
|
||||||
Res::Def(HirDefKind::Ctor(_, ..), def_id) => {
|
Res::Def(HirDefKind::Ctor(..), def_id) => {
|
||||||
// This is a reference to a tuple struct or an enum variant where the def_id points
|
// This is a reference to a tuple struct or an enum variant where the def_id points
|
||||||
// to an invisible constructor function. That is not a very useful
|
// to an invisible constructor function. That is not a very useful
|
||||||
// def, so adjust to point to the tuple struct or enum variant itself.
|
// def, so adjust to point to the tuple struct or enum variant itself.
|
||||||
|
|
|
@ -98,7 +98,7 @@ impl<'a> FileSearch<'a> {
|
||||||
p.push(RUST_LIB_DIR);
|
p.push(RUST_LIB_DIR);
|
||||||
p.push(&self.triple);
|
p.push(&self.triple);
|
||||||
p.push("bin");
|
p.push("bin");
|
||||||
if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p.clone()] }
|
if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1030,7 +1030,7 @@ pub fn decode_expn_id<
|
||||||
drop(expns);
|
drop(expns);
|
||||||
expn_id
|
expn_id
|
||||||
});
|
});
|
||||||
return Ok(expn_id);
|
Ok(expn_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decodes `SyntaxContext`, using the provided `HygieneDecodeContext`
|
// Decodes `SyntaxContext`, using the provided `HygieneDecodeContext`
|
||||||
|
@ -1103,7 +1103,7 @@ pub fn decode_syntax_context<
|
||||||
assert_eq!(dummy.dollar_crate_name, kw::Invalid);
|
assert_eq!(dummy.dollar_crate_name, kw::Invalid);
|
||||||
});
|
});
|
||||||
|
|
||||||
return Ok(new_ctxt);
|
Ok(new_ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn num_syntax_ctxts() -> usize {
|
pub fn num_syntax_ctxts() -> usize {
|
||||||
|
|
|
@ -187,7 +187,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn span(&self) -> Span {
|
pub fn span(&self) -> Span {
|
||||||
self.span.clone()
|
self.span
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reached_recursion_limit(&self) -> bool {
|
pub fn reached_recursion_limit(&self) -> bool {
|
||||||
|
|
|
@ -495,7 +495,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(span) {
|
if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||||
// Don't care about `&mut` because `DerefMut` is used less
|
// Don't care about `&mut` because `DerefMut` is used less
|
||||||
// often and user will not expect autoderef happens.
|
// often and user will not expect autoderef happens.
|
||||||
if src.starts_with("&") && !src.starts_with("&mut ") {
|
if src.starts_with('&') && !src.starts_with("&mut ") {
|
||||||
let derefs = "*".repeat(steps);
|
let derefs = "*".repeat(steps);
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
span,
|
span,
|
||||||
|
|
|
@ -141,7 +141,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||||
|
|
||||||
let predicates = self.tcx.predicates_of(adt_def.did).predicates;
|
let predicates = self.tcx.predicates_of(adt_def.did).predicates;
|
||||||
let where_clauses: Vec<_> = predicates
|
let where_clauses: Vec<_> = predicates
|
||||||
.into_iter()
|
.iter()
|
||||||
.map(|(wc, _)| wc.subst(self.tcx, bound_vars))
|
.map(|(wc, _)| wc.subst(self.tcx, bound_vars))
|
||||||
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner))
|
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner))
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -174,7 +174,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||||
phantom_data: adt_def.is_phantom_data(),
|
phantom_data: adt_def.is_phantom_data(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return struct_datum;
|
struct_datum
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fn_def_datum(
|
fn fn_def_datum(
|
||||||
|
@ -187,7 +187,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||||
|
|
||||||
let predicates = self.tcx.predicates_defined_on(def_id).predicates;
|
let predicates = self.tcx.predicates_defined_on(def_id).predicates;
|
||||||
let where_clauses: Vec<_> = predicates
|
let where_clauses: Vec<_> = predicates
|
||||||
.into_iter()
|
.iter()
|
||||||
.map(|(wc, _)| wc.subst(self.tcx, &bound_vars))
|
.map(|(wc, _)| wc.subst(self.tcx, &bound_vars))
|
||||||
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
|
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||||
parameters[0].assert_ty_ref(&self.interner).could_match(&self.interner, &lowered_ty)
|
parameters[0].assert_ty_ref(&self.interner).could_match(&self.interner, &lowered_ty)
|
||||||
});
|
});
|
||||||
|
|
||||||
let impls = matched_impls.map(|matched_impl| chalk_ir::ImplId(matched_impl)).collect();
|
let impls = matched_impls.map(chalk_ir::ImplId).collect();
|
||||||
impls
|
impls
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||||
ty::AdtKind::Struct | ty::AdtKind::Union => None,
|
ty::AdtKind::Struct | ty::AdtKind::Union => None,
|
||||||
ty::AdtKind::Enum => {
|
ty::AdtKind::Enum => {
|
||||||
let constraint = self.tcx.adt_sized_constraint(adt_def.did);
|
let constraint = self.tcx.adt_sized_constraint(adt_def.did);
|
||||||
if constraint.0.len() > 0 { unimplemented!() } else { Some(true) }
|
if !constraint.0.is_empty() { unimplemented!() } else { Some(true) }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -398,7 +398,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||||
ty::AdtKind::Struct | ty::AdtKind::Union => None,
|
ty::AdtKind::Struct | ty::AdtKind::Union => None,
|
||||||
ty::AdtKind::Enum => {
|
ty::AdtKind::Enum => {
|
||||||
let constraint = self.tcx.adt_sized_constraint(adt_def.did);
|
let constraint = self.tcx.adt_sized_constraint(adt_def.did);
|
||||||
if constraint.0.len() > 0 { unimplemented!() } else { Some(true) }
|
if !constraint.0.is_empty() { unimplemented!() } else { Some(true) }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -440,7 +440,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||||
FnOnce => self.tcx.lang_items().fn_once_trait(),
|
FnOnce => self.tcx.lang_items().fn_once_trait(),
|
||||||
Unsize => self.tcx.lang_items().unsize_trait(),
|
Unsize => self.tcx.lang_items().unsize_trait(),
|
||||||
};
|
};
|
||||||
def_id.map(|t| chalk_ir::TraitId(t))
|
def_id.map(chalk_ir::TraitId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_object_safe(&self, trait_id: chalk_ir::TraitId<RustInterner<'tcx>>) -> bool {
|
fn is_object_safe(&self, trait_id: chalk_ir::TraitId<RustInterner<'tcx>>) -> bool {
|
||||||
|
|
|
@ -443,7 +443,7 @@ fn opaque_type_projection_predicates(
|
||||||
|
|
||||||
let bounds = tcx.predicates_of(def_id);
|
let bounds = tcx.predicates_of(def_id);
|
||||||
let predicates =
|
let predicates =
|
||||||
util::elaborate_predicates(tcx, bounds.predicates.into_iter().map(|&(pred, _)| pred));
|
util::elaborate_predicates(tcx, bounds.predicates.iter().map(|&(pred, _)| pred));
|
||||||
|
|
||||||
let filtered_predicates = predicates.filter_map(|obligation| {
|
let filtered_predicates = predicates.filter_map(|obligation| {
|
||||||
let pred = obligation.predicate;
|
let pred = obligation.predicate;
|
||||||
|
|
|
@ -368,6 +368,6 @@ impl TypeRelation<'tcx> for SimpleEqRelation<'tcx> {
|
||||||
let anon_b = self.tcx.anonymize_late_bound_regions(&b);
|
let anon_b = self.tcx.anonymize_late_bound_regions(&b);
|
||||||
self.relate(anon_a.skip_binder(), anon_b.skip_binder())?;
|
self.relate(anon_a.skip_binder(), anon_b.skip_binder())?;
|
||||||
|
|
||||||
Ok(a.clone())
|
Ok(a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1114,7 +1114,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
tcx.sess.struct_span_err(pat.span, "`..` cannot be used in union patterns").emit();
|
tcx.sess.struct_span_err(pat.span, "`..` cannot be used in union patterns").emit();
|
||||||
}
|
}
|
||||||
} else if !etc && !unmentioned_fields.is_empty() {
|
} else if !etc && !unmentioned_fields.is_empty() {
|
||||||
unmentioned_err = Some(self.error_unmentioned_fields(pat.span, &unmentioned_fields));
|
unmentioned_err = Some(self.error_unmentioned_fields(pat, &unmentioned_fields));
|
||||||
}
|
}
|
||||||
match (inexistent_fields_err, unmentioned_err) {
|
match (inexistent_fields_err, unmentioned_err) {
|
||||||
(Some(mut i), Some(mut u)) => {
|
(Some(mut i), Some(mut u)) => {
|
||||||
|
@ -1299,7 +1299,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
fn error_unmentioned_fields(
|
fn error_unmentioned_fields(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
pat: &Pat<'_>,
|
||||||
unmentioned_fields: &[Ident],
|
unmentioned_fields: &[Ident],
|
||||||
) -> DiagnosticBuilder<'tcx> {
|
) -> DiagnosticBuilder<'tcx> {
|
||||||
let field_names = if unmentioned_fields.len() == 1 {
|
let field_names = if unmentioned_fields.len() == 1 {
|
||||||
|
@ -1312,23 +1312,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.join(", ");
|
.join(", ");
|
||||||
format!("fields {}", fields)
|
format!("fields {}", fields)
|
||||||
};
|
};
|
||||||
let mut diag = struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
self.tcx.sess,
|
self.tcx.sess,
|
||||||
span,
|
pat.span,
|
||||||
E0027,
|
E0027,
|
||||||
"pattern does not mention {}",
|
"pattern does not mention {}",
|
||||||
field_names
|
field_names
|
||||||
);
|
);
|
||||||
diag.span_label(span, format!("missing {}", field_names));
|
err.span_label(pat.span, format!("missing {}", field_names));
|
||||||
if self.tcx.sess.teach(&diag.get_code().unwrap()) {
|
if self.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||||
diag.note(
|
err.note(
|
||||||
"This error indicates that a pattern for a struct fails to specify a \
|
"This error indicates that a pattern for a struct fails to specify a \
|
||||||
sub-pattern for every one of the struct's fields. Ensure that each field \
|
sub-pattern for every one of the struct's fields. Ensure that each field \
|
||||||
from the struct's definition is mentioned in the pattern, or use `..` to \
|
from the struct's definition is mentioned in the pattern, or use `..` to \
|
||||||
ignore unwanted fields.",
|
ignore unwanted fields.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
diag
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_pat_box(
|
fn check_pat_box(
|
||||||
|
|
|
@ -200,13 +200,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// Gather up expressions we want to munge.
|
// Gather up expressions we want to munge.
|
||||||
let mut exprs = vec![expr];
|
let mut exprs = vec![expr];
|
||||||
|
|
||||||
loop {
|
while let hir::ExprKind::Field(ref expr, _)
|
||||||
match exprs.last().unwrap().kind {
|
|
||||||
hir::ExprKind::Field(ref expr, _)
|
|
||||||
| hir::ExprKind::Index(ref expr, _)
|
| hir::ExprKind::Index(ref expr, _)
|
||||||
| hir::ExprKind::Unary(hir::UnOp::UnDeref, ref expr) => exprs.push(&expr),
|
| hir::ExprKind::Unary(hir::UnOp::UnDeref, ref expr) = exprs.last().unwrap().kind
|
||||||
_ => break,
|
{
|
||||||
}
|
exprs.push(&expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("convert_place_derefs_to_mutable: exprs={:?}", exprs);
|
debug!("convert_place_derefs_to_mutable: exprs={:?}", exprs);
|
||||||
|
|
|
@ -583,7 +583,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
self.tcx()
|
self.tcx()
|
||||||
.sess
|
.sess
|
||||||
.delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT");
|
.delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT");
|
||||||
return Err(());
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -596,7 +596,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||||
ty::Tuple(substs) => Ok(substs.len()),
|
ty::Tuple(substs) => Ok(substs.len()),
|
||||||
_ => {
|
_ => {
|
||||||
self.tcx().sess.delay_span_bug(span, "tuple pattern not applied to a tuple");
|
self.tcx().sess.delay_span_bug(span, "tuple pattern not applied to a tuple");
|
||||||
return Err(());
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1395,10 +1395,13 @@ impl Clean<Type> for hir::Ty<'_> {
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
if let Some(lt) = lifetime.cloned() {
|
if let Some(lt) = lifetime.cloned() {
|
||||||
if !lt.is_elided() {
|
|
||||||
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
|
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
|
||||||
lt_substs.insert(lt_def_id.to_def_id(), lt.clean(cx));
|
let cleaned = if !lt.is_elided() {
|
||||||
}
|
lt.clean(cx)
|
||||||
|
} else {
|
||||||
|
self::types::Lifetime::elided()
|
||||||
|
};
|
||||||
|
lt_substs.insert(lt_def_id.to_def_id(), cleaned);
|
||||||
}
|
}
|
||||||
indices.lifetimes += 1;
|
indices.lifetimes += 1;
|
||||||
}
|
}
|
||||||
|
@ -1957,21 +1960,17 @@ impl Clean<GenericArgs> for hir::GenericArgs<'_> {
|
||||||
output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None },
|
output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None },
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let elide_lifetimes = self.args.iter().all(|arg| match arg {
|
|
||||||
hir::GenericArg::Lifetime(lt) => lt.is_elided(),
|
|
||||||
_ => true,
|
|
||||||
});
|
|
||||||
GenericArgs::AngleBracketed {
|
GenericArgs::AngleBracketed {
|
||||||
args: self
|
args: self
|
||||||
.args
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|arg| match arg {
|
.map(|arg| match arg {
|
||||||
hir::GenericArg::Lifetime(lt) if !elide_lifetimes => {
|
hir::GenericArg::Lifetime(lt) if !lt.is_elided() => {
|
||||||
Some(GenericArg::Lifetime(lt.clean(cx)))
|
GenericArg::Lifetime(lt.clean(cx))
|
||||||
}
|
}
|
||||||
hir::GenericArg::Lifetime(_) => None,
|
hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
|
||||||
hir::GenericArg::Type(ty) => Some(GenericArg::Type(ty.clean(cx))),
|
hir::GenericArg::Type(ty) => GenericArg::Type(ty.clean(cx)),
|
||||||
hir::GenericArg::Const(ct) => Some(GenericArg::Const(ct.clean(cx))),
|
hir::GenericArg::Const(ct) => GenericArg::Const(ct.clean(cx)),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
bindings: self.bindings.clean(cx),
|
bindings: self.bindings.clean(cx),
|
||||||
|
|
|
@ -750,6 +750,10 @@ impl Lifetime {
|
||||||
pub fn statik() -> Lifetime {
|
pub fn statik() -> Lifetime {
|
||||||
Lifetime("'static".to_string())
|
Lifetime("'static".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn elided() -> Lifetime {
|
||||||
|
Lifetime("'_".to_string())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
|
@ -2,9 +2,9 @@ use crate::clean::auto_trait::AutoTraitFinder;
|
||||||
use crate::clean::blanket_impl::BlanketImplFinder;
|
use crate::clean::blanket_impl::BlanketImplFinder;
|
||||||
use crate::clean::{
|
use crate::clean::{
|
||||||
inline, Clean, Crate, Deprecation, ExternalCrate, FnDecl, FnRetTy, Generic, GenericArg,
|
inline, Clean, Crate, Deprecation, ExternalCrate, FnDecl, FnRetTy, Generic, GenericArg,
|
||||||
GenericArgs, GenericBound, Generics, GetDefId, ImportSource, Item, ItemEnum, MacroKind, Path,
|
GenericArgs, GenericBound, Generics, GetDefId, ImportSource, Item, ItemEnum, Lifetime,
|
||||||
PathSegment, Primitive, PrimitiveType, ResolvedPath, Span, Stability, Type, TypeBinding,
|
MacroKind, Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Span, Stability, Type,
|
||||||
TypeKind, Visibility, WherePredicate,
|
TypeBinding, TypeKind, Visibility, WherePredicate,
|
||||||
};
|
};
|
||||||
use crate::core::DocContext;
|
use crate::core::DocContext;
|
||||||
|
|
||||||
|
@ -121,7 +121,10 @@ pub fn external_generic_args(
|
||||||
let args: Vec<_> = substs
|
let args: Vec<_> = substs
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|kind| match kind.unpack() {
|
.filter_map(|kind| match kind.unpack() {
|
||||||
GenericArgKind::Lifetime(lt) => lt.clean(cx).map(GenericArg::Lifetime),
|
GenericArgKind::Lifetime(lt) => match lt {
|
||||||
|
ty::ReLateBound(_, ty::BrAnon(_)) => Some(GenericArg::Lifetime(Lifetime::elided())),
|
||||||
|
_ => lt.clean(cx).map(GenericArg::Lifetime),
|
||||||
|
},
|
||||||
GenericArgKind::Type(_) if skip_self => {
|
GenericArgKind::Type(_) if skip_self => {
|
||||||
skip_self = false;
|
skip_self = false;
|
||||||
None
|
None
|
||||||
|
|
|
@ -69,14 +69,14 @@ impl DocFS {
|
||||||
let sender = self.errors.clone().expect("can't write after closing");
|
let sender = self.errors.clone().expect("can't write after closing");
|
||||||
rayon::spawn(move || {
|
rayon::spawn(move || {
|
||||||
fs::write(&path, contents).unwrap_or_else(|e| {
|
fs::write(&path, contents).unwrap_or_else(|e| {
|
||||||
sender
|
sender.send(format!("\"{}\": {}", path.display(), e)).unwrap_or_else(|_| {
|
||||||
.send(format!("\"{}\": {}", path.display(), e))
|
panic!("failed to send error on \"{}\"", path.display())
|
||||||
.expect(&format!("failed to send error on \"{}\"", path.display()));
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Ok(())
|
|
||||||
} else {
|
} else {
|
||||||
Ok(try_err!(fs::write(&path, contents), path))
|
try_err!(fs::write(&path, contents), path);
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
// We have to ignore android because of this issue:
|
// We have to ignore android because of this issue:
|
||||||
// https://github.com/rust-lang/rust/issues/74847
|
// https://github.com/rust-lang/rust/issues/74847
|
||||||
// ignore-android
|
// ignore-android
|
||||||
|
//
|
||||||
|
// We need to use inline assembly, so just use one platform
|
||||||
|
// only-x86_64
|
||||||
|
|
||||||
// compile-flags:-g
|
// compile-flags:-g
|
||||||
|
|
||||||
|
@ -24,6 +27,7 @@
|
||||||
// lldb-command:continue
|
// lldb-command:continue
|
||||||
|
|
||||||
|
|
||||||
|
#![feature(asm)]
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
#![feature(omit_gdb_pretty_printer_section)]
|
#![feature(omit_gdb_pretty_printer_section)]
|
||||||
#![omit_gdb_pretty_printer_section]
|
#![omit_gdb_pretty_printer_section]
|
||||||
|
@ -33,8 +37,6 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[naked]
|
||||||
fn naked(x: usize, y: usize) {
|
extern "C" fn naked(x: usize, y: usize) {
|
||||||
zzz(); // #break
|
unsafe { asm!("ret"); } // #break
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zzz() { () }
|
|
||||||
|
|
11
src/test/rustdoc/auxiliary/elided-lifetime.rs
Normal file
11
src/test/rustdoc/auxiliary/elided-lifetime.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#![crate_name = "bar"]
|
||||||
|
|
||||||
|
pub struct Ref<'a>(&'a u32);
|
||||||
|
|
||||||
|
pub fn test5(a: &u32) -> Ref {
|
||||||
|
Ref(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn test6(a: &u32) -> Ref<'_> {
|
||||||
|
Ref(a)
|
||||||
|
}
|
43
src/test/rustdoc/elided-lifetime.rs
Normal file
43
src/test/rustdoc/elided-lifetime.rs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
// aux-build:elided-lifetime.rs
|
||||||
|
//
|
||||||
|
// rust-lang/rust#75225
|
||||||
|
//
|
||||||
|
// Since Rust 2018 we encourage writing out <'_> explicitly to make it clear
|
||||||
|
// that borrowing is occuring. Make sure rustdoc is following the same idiom.
|
||||||
|
|
||||||
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
pub struct Ref<'a>(&'a u32);
|
||||||
|
type ARef<'a> = Ref<'a>;
|
||||||
|
|
||||||
|
// @has foo/fn.test1.html
|
||||||
|
// @matches - "Ref</a><'_>"
|
||||||
|
pub fn test1(a: &u32) -> Ref {
|
||||||
|
Ref(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @has foo/fn.test2.html
|
||||||
|
// @matches - "Ref</a><'_>"
|
||||||
|
pub fn test2(a: &u32) -> Ref<'_> {
|
||||||
|
Ref(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @has foo/fn.test3.html
|
||||||
|
// @matches - "Ref</a><'_>"
|
||||||
|
pub fn test3(a: &u32) -> ARef {
|
||||||
|
Ref(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @has foo/fn.test4.html
|
||||||
|
// @matches - "Ref</a><'_>"
|
||||||
|
pub fn test4(a: &u32) -> ARef<'_> {
|
||||||
|
Ref(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure external paths in inlined docs also display elided lifetime
|
||||||
|
// @has foo/bar/fn.test5.html
|
||||||
|
// @matches - "Ref</a><'_>"
|
||||||
|
// @has foo/bar/fn.test6.html
|
||||||
|
// @matches - "Ref</a><'_>"
|
||||||
|
#[doc(inline)]
|
||||||
|
pub extern crate bar;
|
Loading…
Add table
Add a link
Reference in a new issue