mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 19:58:32 +00:00
Auto merge of #91792 - matthiaskrgr:rollup-2epg7jq, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #91617 (Improve the readability of `List<T>`.) - #91640 (Simplify collection of in-band lifetimes) - #91682 (rustdoc: Show type layout for type aliases) - #91711 (Improve `std::iter::zip` example) - #91717 (Add deprecation warning for --passes) - #91718 (give more help in the unaligned_references lint) - #91782 (Correct since attribute for `is_symlink` feature) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
b8dc6aa673
@ -247,12 +247,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
AnonymousLifetimeMode::PassThrough,
|
AnonymousLifetimeMode::PassThrough,
|
||||||
|this, idty| {
|
|this, idty| {
|
||||||
let ret_id = asyncness.opt_return_id();
|
let ret_id = asyncness.opt_return_id();
|
||||||
this.lower_fn_decl(
|
this.lower_fn_decl(&decl, Some((fn_def_id, idty)), true, ret_id)
|
||||||
&decl,
|
|
||||||
Some((fn_def_id.to_def_id(), idty)),
|
|
||||||
true,
|
|
||||||
ret_id,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let sig = hir::FnSig {
|
let sig = hir::FnSig {
|
||||||
@ -1264,7 +1259,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
|this, idty| {
|
|this, idty| {
|
||||||
this.lower_fn_decl(
|
this.lower_fn_decl(
|
||||||
&sig.decl,
|
&sig.decl,
|
||||||
Some((fn_def_id.to_def_id(), idty)),
|
Some((fn_def_id, idty)),
|
||||||
impl_trait_return_allow,
|
impl_trait_return_allow,
|
||||||
is_async,
|
is_async,
|
||||||
)
|
)
|
||||||
|
@ -228,7 +228,7 @@ enum ImplTraitContext<'b, 'a> {
|
|||||||
ReturnPositionOpaqueTy {
|
ReturnPositionOpaqueTy {
|
||||||
/// `DefId` for the parent function, used to look up necessary
|
/// `DefId` for the parent function, used to look up necessary
|
||||||
/// information later.
|
/// information later.
|
||||||
fn_def_id: DefId,
|
fn_def_id: LocalDefId,
|
||||||
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
|
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
|
||||||
origin: hir::OpaqueTyOrigin,
|
origin: hir::OpaqueTyOrigin,
|
||||||
},
|
},
|
||||||
@ -646,31 +646,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
/// parameter while `f` is running (and restored afterwards).
|
/// parameter while `f` is running (and restored afterwards).
|
||||||
fn collect_in_band_defs<T>(
|
fn collect_in_band_defs<T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
parent_def_id: LocalDefId,
|
f: impl FnOnce(&mut Self) -> T,
|
||||||
anonymous_lifetime_mode: AnonymousLifetimeMode,
|
) -> (Vec<(Span, ParamName)>, T) {
|
||||||
f: impl FnOnce(&mut Self) -> (Vec<hir::GenericParam<'hir>>, T),
|
let was_collecting = std::mem::replace(&mut self.is_collecting_in_band_lifetimes, true);
|
||||||
) -> (Vec<hir::GenericParam<'hir>>, T) {
|
let len = self.lifetimes_to_define.len();
|
||||||
assert!(!self.is_collecting_in_band_lifetimes);
|
|
||||||
assert!(self.lifetimes_to_define.is_empty());
|
|
||||||
let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;
|
|
||||||
|
|
||||||
self.anonymous_lifetime_mode = anonymous_lifetime_mode;
|
let res = f(self);
|
||||||
self.is_collecting_in_band_lifetimes = true;
|
|
||||||
|
|
||||||
let (in_band_ty_params, res) = f(self);
|
let lifetimes_to_define = self.lifetimes_to_define.split_off(len);
|
||||||
|
self.is_collecting_in_band_lifetimes = was_collecting;
|
||||||
self.is_collecting_in_band_lifetimes = false;
|
(lifetimes_to_define, res)
|
||||||
self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
|
|
||||||
|
|
||||||
let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
|
|
||||||
|
|
||||||
let params = lifetimes_to_define
|
|
||||||
.into_iter()
|
|
||||||
.map(|(span, hir_name)| self.lifetime_to_generic_param(span, hir_name, parent_def_id))
|
|
||||||
.chain(in_band_ty_params.into_iter())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
(params, res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a lifetime into a new generic parameter.
|
/// Converts a lifetime into a new generic parameter.
|
||||||
@ -785,27 +770,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
anonymous_lifetime_mode: AnonymousLifetimeMode,
|
anonymous_lifetime_mode: AnonymousLifetimeMode,
|
||||||
f: impl FnOnce(&mut Self, &mut Vec<hir::GenericParam<'hir>>) -> T,
|
f: impl FnOnce(&mut Self, &mut Vec<hir::GenericParam<'hir>>) -> T,
|
||||||
) -> (hir::Generics<'hir>, T) {
|
) -> (hir::Generics<'hir>, T) {
|
||||||
let (in_band_defs, (mut lowered_generics, res)) =
|
let (lifetimes_to_define, (mut lowered_generics, impl_trait_defs, res)) = self
|
||||||
self.with_in_scope_lifetime_defs(&generics.params, |this| {
|
.collect_in_band_defs(|this| {
|
||||||
this.collect_in_band_defs(parent_def_id, anonymous_lifetime_mode, |this| {
|
this.with_anonymous_lifetime_mode(anonymous_lifetime_mode, |this| {
|
||||||
let mut params = Vec::new();
|
this.with_in_scope_lifetime_defs(&generics.params, |this| {
|
||||||
// Note: it is necessary to lower generics *before* calling `f`.
|
let mut impl_trait_defs = Vec::new();
|
||||||
// When lowering `async fn`, there's a final step when lowering
|
// Note: it is necessary to lower generics *before* calling `f`.
|
||||||
// the return type that assumes that all in-scope lifetimes have
|
// When lowering `async fn`, there's a final step when lowering
|
||||||
// already been added to either `in_scope_lifetimes` or
|
// the return type that assumes that all in-scope lifetimes have
|
||||||
// `lifetimes_to_define`. If we swapped the order of these two,
|
// already been added to either `in_scope_lifetimes` or
|
||||||
// in-band-lifetimes introduced by generics or where-clauses
|
// `lifetimes_to_define`. If we swapped the order of these two,
|
||||||
// wouldn't have been added yet.
|
// in-band-lifetimes introduced by generics or where-clauses
|
||||||
let generics = this.lower_generics_mut(
|
// wouldn't have been added yet.
|
||||||
generics,
|
let generics = this.lower_generics_mut(
|
||||||
ImplTraitContext::Universal(&mut params, this.current_hir_id_owner),
|
generics,
|
||||||
);
|
ImplTraitContext::Universal(
|
||||||
let res = f(this, &mut params);
|
&mut impl_trait_defs,
|
||||||
(params, (generics, res))
|
this.current_hir_id_owner,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
let res = f(this, &mut impl_trait_defs);
|
||||||
|
(generics, impl_trait_defs, res)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
lowered_generics.params.extend(in_band_defs);
|
lowered_generics.params.extend(
|
||||||
|
lifetimes_to_define
|
||||||
|
.into_iter()
|
||||||
|
.map(|(span, hir_name)| {
|
||||||
|
self.lifetime_to_generic_param(span, hir_name, parent_def_id)
|
||||||
|
})
|
||||||
|
.chain(impl_trait_defs),
|
||||||
|
);
|
||||||
|
|
||||||
let lowered_generics = lowered_generics.into_generics(self.arena);
|
let lowered_generics = lowered_generics.into_generics(self.arena);
|
||||||
(lowered_generics, res)
|
(lowered_generics, res)
|
||||||
@ -1380,7 +1377,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
fn lower_opaque_impl_trait(
|
fn lower_opaque_impl_trait(
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
fn_def_id: Option<DefId>,
|
fn_def_id: Option<LocalDefId>,
|
||||||
origin: hir::OpaqueTyOrigin,
|
origin: hir::OpaqueTyOrigin,
|
||||||
opaque_ty_node_id: NodeId,
|
opaque_ty_node_id: NodeId,
|
||||||
capturable_lifetimes: Option<&FxHashSet<hir::LifetimeName>>,
|
capturable_lifetimes: Option<&FxHashSet<hir::LifetimeName>>,
|
||||||
@ -1452,7 +1449,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
span: lctx.lower_span(span),
|
span: lctx.lower_span(span),
|
||||||
},
|
},
|
||||||
bounds: hir_bounds,
|
bounds: hir_bounds,
|
||||||
impl_trait_fn: fn_def_id,
|
|
||||||
origin,
|
origin,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1522,7 +1518,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
fn lower_fn_decl(
|
fn lower_fn_decl(
|
||||||
&mut self,
|
&mut self,
|
||||||
decl: &FnDecl,
|
decl: &FnDecl,
|
||||||
mut in_band_ty_params: Option<(DefId, &mut Vec<hir::GenericParam<'hir>>)>,
|
mut in_band_ty_params: Option<(LocalDefId, &mut Vec<hir::GenericParam<'hir>>)>,
|
||||||
impl_trait_return_allow: bool,
|
impl_trait_return_allow: bool,
|
||||||
make_ret_async: Option<NodeId>,
|
make_ret_async: Option<NodeId>,
|
||||||
) -> &'hir hir::FnDecl<'hir> {
|
) -> &'hir hir::FnDecl<'hir> {
|
||||||
@ -1580,7 +1576,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
Some((def_id, _)) if impl_trait_return_allow => {
|
Some((def_id, _)) if impl_trait_return_allow => {
|
||||||
ImplTraitContext::ReturnPositionOpaqueTy {
|
ImplTraitContext::ReturnPositionOpaqueTy {
|
||||||
fn_def_id: def_id,
|
fn_def_id: def_id,
|
||||||
origin: hir::OpaqueTyOrigin::FnReturn,
|
origin: hir::OpaqueTyOrigin::FnReturn(def_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => ImplTraitContext::disallowed(),
|
_ => ImplTraitContext::disallowed(),
|
||||||
@ -1635,7 +1631,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
fn lower_async_fn_ret_ty(
|
fn lower_async_fn_ret_ty(
|
||||||
&mut self,
|
&mut self,
|
||||||
output: &FnRetTy,
|
output: &FnRetTy,
|
||||||
fn_def_id: DefId,
|
fn_def_id: LocalDefId,
|
||||||
opaque_ty_node_id: NodeId,
|
opaque_ty_node_id: NodeId,
|
||||||
) -> hir::FnRetTy<'hir> {
|
) -> hir::FnRetTy<'hir> {
|
||||||
debug!(
|
debug!(
|
||||||
@ -1689,18 +1685,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
// this is because the elided lifetimes from the return type
|
// this is because the elided lifetimes from the return type
|
||||||
// should be figured out using the ordinary elision rules, and
|
// should be figured out using the ordinary elision rules, and
|
||||||
// this desugaring achieves that.
|
// this desugaring achieves that.
|
||||||
//
|
|
||||||
// The variable `input_lifetimes_count` tracks the number of
|
|
||||||
// lifetime parameters to the opaque type *not counting* those
|
|
||||||
// lifetimes elided in the return type. This includes those
|
|
||||||
// that are explicitly declared (`in_scope_lifetimes`) and
|
|
||||||
// those elided lifetimes we found in the arguments (current
|
|
||||||
// content of `lifetimes_to_define`). Next, we will process
|
|
||||||
// the return type, which will cause `lifetimes_to_define` to
|
|
||||||
// grow.
|
|
||||||
let input_lifetimes_count = self.in_scope_lifetimes.len() + self.lifetimes_to_define.len();
|
|
||||||
|
|
||||||
let mut lifetime_params = Vec::new();
|
debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", self.in_scope_lifetimes);
|
||||||
|
debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", self.lifetimes_to_define);
|
||||||
|
|
||||||
|
// Calculate all the lifetimes that should be captured
|
||||||
|
// by the opaque type. This should include all in-scope
|
||||||
|
// lifetime parameters, including those defined in-band.
|
||||||
|
//
|
||||||
|
// `lifetime_params` is a vector of tuple (span, parameter name, lifetime name).
|
||||||
|
|
||||||
|
// Input lifetime like `'a` or `'1`:
|
||||||
|
let mut lifetime_params: Vec<_> = self
|
||||||
|
.in_scope_lifetimes
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.map(|name| (name.ident().span, name, hir::LifetimeName::Param(name)))
|
||||||
|
.chain(
|
||||||
|
self.lifetimes_to_define
|
||||||
|
.iter()
|
||||||
|
.map(|&(span, name)| (span, name, hir::LifetimeName::Param(name))),
|
||||||
|
)
|
||||||
|
.collect();
|
||||||
|
|
||||||
self.with_hir_id_owner(opaque_ty_node_id, |this| {
|
self.with_hir_id_owner(opaque_ty_node_id, |this| {
|
||||||
// We have to be careful to get elision right here. The
|
// We have to be careful to get elision right here. The
|
||||||
// idea is that we create a lifetime parameter for each
|
// idea is that we create a lifetime parameter for each
|
||||||
@ -1710,34 +1717,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
//
|
//
|
||||||
// Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
|
// Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
|
||||||
// hence the elision takes place at the fn site.
|
// hence the elision takes place at the fn site.
|
||||||
let future_bound = this
|
let (lifetimes_to_define, future_bound) =
|
||||||
.with_anonymous_lifetime_mode(AnonymousLifetimeMode::CreateParameter, |this| {
|
this.with_anonymous_lifetime_mode(AnonymousLifetimeMode::CreateParameter, |this| {
|
||||||
this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span)
|
this.collect_in_band_defs(|this| {
|
||||||
|
this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span)
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound);
|
debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound);
|
||||||
|
debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", lifetimes_to_define);
|
||||||
|
|
||||||
// Calculate all the lifetimes that should be captured
|
lifetime_params.extend(
|
||||||
// by the opaque type. This should include all in-scope
|
// Output lifetime like `'_`:
|
||||||
// lifetime parameters, including those defined in-band.
|
lifetimes_to_define
|
||||||
//
|
.into_iter()
|
||||||
// Note: this must be done after lowering the output type,
|
.map(|(span, name)| (span, name, hir::LifetimeName::Implicit(false))),
|
||||||
// as the output type may introduce new in-band lifetimes.
|
);
|
||||||
lifetime_params = this
|
|
||||||
.in_scope_lifetimes
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(|name| (name.ident().span, name))
|
|
||||||
.chain(this.lifetimes_to_define.iter().cloned())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", this.in_scope_lifetimes);
|
|
||||||
debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", this.lifetimes_to_define);
|
|
||||||
debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params);
|
debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params);
|
||||||
|
|
||||||
let generic_params =
|
let generic_params =
|
||||||
this.arena.alloc_from_iter(lifetime_params.iter().map(|(span, hir_name)| {
|
this.arena.alloc_from_iter(lifetime_params.iter().map(|&(span, hir_name, _)| {
|
||||||
this.lifetime_to_generic_param(*span, *hir_name, opaque_ty_def_id)
|
this.lifetime_to_generic_param(span, hir_name, opaque_ty_def_id)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let opaque_ty_item = hir::OpaqueTy {
|
let opaque_ty_item = hir::OpaqueTy {
|
||||||
@ -1747,8 +1746,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
span: this.lower_span(span),
|
span: this.lower_span(span),
|
||||||
},
|
},
|
||||||
bounds: arena_vec![this; future_bound],
|
bounds: arena_vec![this; future_bound],
|
||||||
impl_trait_fn: Some(fn_def_id),
|
origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
|
||||||
origin: hir::OpaqueTyOrigin::AsyncFn,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
|
trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
|
||||||
@ -1771,25 +1769,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
//
|
//
|
||||||
// For the "output" lifetime parameters, we just want to
|
// For the "output" lifetime parameters, we just want to
|
||||||
// generate `'_`.
|
// generate `'_`.
|
||||||
let mut generic_args = Vec::with_capacity(lifetime_params.len());
|
let generic_args =
|
||||||
generic_args.extend(lifetime_params[..input_lifetimes_count].iter().map(
|
self.arena.alloc_from_iter(lifetime_params.into_iter().map(|(span, _, name)| {
|
||||||
|&(span, hir_name)| {
|
|
||||||
// Input lifetime like `'a` or `'1`:
|
|
||||||
GenericArg::Lifetime(hir::Lifetime {
|
GenericArg::Lifetime(hir::Lifetime {
|
||||||
hir_id: self.next_id(),
|
hir_id: self.next_id(),
|
||||||
span: self.lower_span(span),
|
span: self.lower_span(span),
|
||||||
name: hir::LifetimeName::Param(hir_name),
|
name,
|
||||||
})
|
})
|
||||||
},
|
}));
|
||||||
));
|
|
||||||
generic_args.extend(lifetime_params[input_lifetimes_count..].iter().map(|&(span, _)|
|
|
||||||
// Output lifetime like `'_`.
|
|
||||||
GenericArg::Lifetime(hir::Lifetime {
|
|
||||||
hir_id: self.next_id(),
|
|
||||||
span: self.lower_span(span),
|
|
||||||
name: hir::LifetimeName::Implicit(false),
|
|
||||||
})));
|
|
||||||
let generic_args = self.arena.alloc_from_iter(generic_args);
|
|
||||||
|
|
||||||
// Create the `Foo<...>` reference itself. Note that the `type
|
// Create the `Foo<...>` reference itself. Note that the `type
|
||||||
// Foo = impl Trait` is, internally, created as a child of the
|
// Foo = impl Trait` is, internally, created as a child of the
|
||||||
@ -1805,7 +1792,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
fn lower_async_fn_output_type_to_future_bound(
|
fn lower_async_fn_output_type_to_future_bound(
|
||||||
&mut self,
|
&mut self,
|
||||||
output: &FnRetTy,
|
output: &FnRetTy,
|
||||||
fn_def_id: DefId,
|
fn_def_id: LocalDefId,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> hir::GenericBound<'hir> {
|
) -> hir::GenericBound<'hir> {
|
||||||
// Compute the `T` in `Future<Output = T>` from the return type.
|
// Compute the `T` in `Future<Output = T>` from the return type.
|
||||||
@ -1816,7 +1803,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
// generates.
|
// generates.
|
||||||
let context = ImplTraitContext::ReturnPositionOpaqueTy {
|
let context = ImplTraitContext::ReturnPositionOpaqueTy {
|
||||||
fn_def_id,
|
fn_def_id,
|
||||||
origin: hir::OpaqueTyOrigin::FnReturn,
|
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
||||||
};
|
};
|
||||||
self.lower_ty(ty, context)
|
self.lower_ty(ty, context)
|
||||||
}
|
}
|
||||||
@ -2453,17 +2440,12 @@ impl<'hir> GenericArgsCtor<'hir> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug")]
|
||||||
fn lifetimes_from_impl_trait_bounds(
|
fn lifetimes_from_impl_trait_bounds(
|
||||||
opaque_ty_id: NodeId,
|
opaque_ty_id: NodeId,
|
||||||
bounds: hir::GenericBounds<'_>,
|
bounds: hir::GenericBounds<'_>,
|
||||||
lifetimes_to_include: Option<&FxHashSet<hir::LifetimeName>>,
|
lifetimes_to_include: Option<&FxHashSet<hir::LifetimeName>>,
|
||||||
) -> Vec<(hir::LifetimeName, Span)> {
|
) -> Vec<(hir::LifetimeName, Span)> {
|
||||||
debug!(
|
|
||||||
"lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \
|
|
||||||
bounds={:#?})",
|
|
||||||
opaque_ty_id, bounds,
|
|
||||||
);
|
|
||||||
|
|
||||||
// This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that
|
// This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that
|
||||||
// appear in the bounds, excluding lifetimes that are created within the bounds.
|
// appear in the bounds, excluding lifetimes that are created within the bounds.
|
||||||
// E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
|
// E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
|
||||||
|
@ -173,7 +173,7 @@ fn check_opaque_type_parameter_valid(
|
|||||||
// fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
|
// fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
|
||||||
//
|
//
|
||||||
// which would error here on all of the `'static` args.
|
// which would error here on all of the `'static` args.
|
||||||
OpaqueTyOrigin::FnReturn | OpaqueTyOrigin::AsyncFn => return true,
|
OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return true,
|
||||||
// Check these
|
// Check these
|
||||||
OpaqueTyOrigin::TyAlias => {}
|
OpaqueTyOrigin::TyAlias => {}
|
||||||
}
|
}
|
||||||
|
@ -2248,7 +2248,6 @@ pub struct BareFnTy<'hir> {
|
|||||||
pub struct OpaqueTy<'hir> {
|
pub struct OpaqueTy<'hir> {
|
||||||
pub generics: Generics<'hir>,
|
pub generics: Generics<'hir>,
|
||||||
pub bounds: GenericBounds<'hir>,
|
pub bounds: GenericBounds<'hir>,
|
||||||
pub impl_trait_fn: Option<DefId>,
|
|
||||||
pub origin: OpaqueTyOrigin,
|
pub origin: OpaqueTyOrigin,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2256,9 +2255,9 @@ pub struct OpaqueTy<'hir> {
|
|||||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||||
pub enum OpaqueTyOrigin {
|
pub enum OpaqueTyOrigin {
|
||||||
/// `-> impl Trait`
|
/// `-> impl Trait`
|
||||||
FnReturn,
|
FnReturn(LocalDefId),
|
||||||
/// `async fn`
|
/// `async fn`
|
||||||
AsyncFn,
|
AsyncFn(LocalDefId),
|
||||||
/// type aliases: `type Foo = impl Trait;`
|
/// type aliases: `type Foo = impl Trait;`
|
||||||
TyAlias,
|
TyAlias,
|
||||||
}
|
}
|
||||||
@ -2809,7 +2808,9 @@ impl ItemKind<'_> {
|
|||||||
Some(match *self {
|
Some(match *self {
|
||||||
ItemKind::Fn(_, ref generics, _)
|
ItemKind::Fn(_, ref generics, _)
|
||||||
| ItemKind::TyAlias(_, ref generics)
|
| ItemKind::TyAlias(_, ref generics)
|
||||||
| ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. })
|
| ItemKind::OpaqueTy(OpaqueTy {
|
||||||
|
ref generics, origin: OpaqueTyOrigin::TyAlias, ..
|
||||||
|
})
|
||||||
| ItemKind::Enum(_, ref generics)
|
| ItemKind::Enum(_, ref generics)
|
||||||
| ItemKind::Struct(_, ref generics)
|
| ItemKind::Struct(_, ref generics)
|
||||||
| ItemKind::Union(_, ref generics)
|
| ItemKind::Union(_, ref generics)
|
||||||
|
@ -107,7 +107,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||||||
kind:
|
kind:
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
bounds,
|
bounds,
|
||||||
origin: hir::OpaqueTyOrigin::AsyncFn,
|
origin: hir::OpaqueTyOrigin::AsyncFn(..),
|
||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
..
|
..
|
||||||
|
@ -276,7 +276,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
debug!(?concrete_ty);
|
debug!(?concrete_ty);
|
||||||
|
|
||||||
let first_own_region = match opaque_defn.origin {
|
let first_own_region = match opaque_defn.origin {
|
||||||
hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => {
|
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {
|
||||||
// We lower
|
// We lower
|
||||||
//
|
//
|
||||||
// fn foo<'l0..'ln>() -> impl Trait<'l0..'lm>
|
// fn foo<'l0..'ln>() -> impl Trait<'l0..'lm>
|
||||||
@ -461,35 +461,29 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
|||||||
if let Some(def_id) = def_id.as_local() {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
let parent_def_id = self.infcx.defining_use_anchor;
|
let parent_def_id = self.infcx.defining_use_anchor;
|
||||||
let (in_definition_scope, origin) = match tcx.hir().expect_item(def_id).kind
|
let item_kind = &tcx.hir().expect_item(def_id).kind;
|
||||||
{
|
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item_kind else {
|
||||||
|
span_bug!(
|
||||||
|
self.value_span,
|
||||||
|
"weird opaque type: {:#?}, {:#?}",
|
||||||
|
ty.kind(),
|
||||||
|
item_kind
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let in_definition_scope = match *origin {
|
||||||
|
// Async `impl Trait`
|
||||||
|
hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id,
|
||||||
// Anonymous `impl Trait`
|
// Anonymous `impl Trait`
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
|
||||||
impl_trait_fn: Some(parent),
|
|
||||||
origin,
|
|
||||||
..
|
|
||||||
}) => (parent == parent_def_id.to_def_id(), origin),
|
|
||||||
// Named `type Foo = impl Bar;`
|
// Named `type Foo = impl Bar;`
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
hir::OpaqueTyOrigin::TyAlias => {
|
||||||
impl_trait_fn: None,
|
may_define_opaque_type(tcx, parent_def_id, opaque_hir_id)
|
||||||
origin,
|
|
||||||
..
|
|
||||||
}) => {
|
|
||||||
(may_define_opaque_type(tcx, parent_def_id, opaque_hir_id), origin)
|
|
||||||
}
|
|
||||||
ref itemkind => {
|
|
||||||
span_bug!(
|
|
||||||
self.value_span,
|
|
||||||
"weird opaque type: {:#?}, {:#?}",
|
|
||||||
ty.kind(),
|
|
||||||
itemkind
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if in_definition_scope {
|
if in_definition_scope {
|
||||||
let opaque_type_key =
|
let opaque_type_key =
|
||||||
OpaqueTypeKey { def_id: def_id.to_def_id(), substs };
|
OpaqueTypeKey { def_id: def_id.to_def_id(), substs };
|
||||||
return self.fold_opaque_ty(ty, opaque_type_key, origin);
|
return self.fold_opaque_ty(ty, opaque_type_key, *origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
use crate::arena::Arena;
|
use crate::arena::Arena;
|
||||||
|
|
||||||
use rustc_serialize::{Encodable, Encoder};
|
use rustc_serialize::{Encodable, Encoder};
|
||||||
|
|
||||||
use std::alloc::Layout;
|
use std::alloc::Layout;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -12,49 +10,69 @@ use std::ops::Deref;
|
|||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
extern "C" {
|
/// `List<T>` is a bit like `&[T]`, but with some critical differences.
|
||||||
/// A dummy type used to force `List` to be unsized while not requiring references to it be wide
|
/// - IMPORTANT: Every `List<T>` is *required* to have unique contents. The
|
||||||
/// pointers.
|
/// type's correctness relies on this, *but it does not enforce it*.
|
||||||
type OpaqueListContents;
|
/// Therefore, any code that creates a `List<T>` must ensure uniqueness
|
||||||
}
|
/// itself. In practice this is achieved by interning.
|
||||||
|
/// - The length is stored within the `List<T>`, so `&List<Ty>` is a thin
|
||||||
/// A wrapper for slices with the additional invariant
|
/// pointer.
|
||||||
/// that the slice is interned and no other slice with
|
/// - Because of this, you cannot get a `List<T>` that is a sub-list of another
|
||||||
/// the same contents can exist in the same context.
|
/// `List<T>`. You can get a sub-slice `&[T]`, however.
|
||||||
/// This means we can use pointer for both
|
/// - `List<T>` can be used with `CopyTaggedPtr`, which is useful within
|
||||||
/// equality comparisons and hashing.
|
/// structs whose size must be minimized.
|
||||||
///
|
/// - Because of the uniqueness assumption, we can use the address of a
|
||||||
/// Unlike slices, the types contained in `List` are expected to be `Copy`
|
/// `List<T>` for faster equality comparisons and hashing.
|
||||||
/// and iterating over a `List` returns `T` instead of a reference.
|
/// - `T` must be `Copy`. This lets `List<T>` be stored in a dropless arena and
|
||||||
///
|
/// iterators return a `T` rather than a `&T`.
|
||||||
/// Note: `Slice` was already taken by the `Ty`.
|
/// - `T` must not be zero-sized.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct List<T> {
|
pub struct List<T> {
|
||||||
len: usize,
|
len: usize,
|
||||||
|
|
||||||
|
/// Although this claims to be a zero-length array, in practice `len`
|
||||||
|
/// elements are actually present.
|
||||||
data: [T; 0],
|
data: [T; 0],
|
||||||
|
|
||||||
opaque: OpaqueListContents,
|
opaque: OpaqueListContents,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'a, T: 'a> rustc_data_structures::tagged_ptr::Pointer for &'a List<T> {
|
extern "C" {
|
||||||
const BITS: usize = std::mem::align_of::<usize>().trailing_zeros() as usize;
|
/// A dummy type used to force `List` to be unsized while not requiring
|
||||||
#[inline]
|
/// references to it be wide pointers.
|
||||||
fn into_usize(self) -> usize {
|
type OpaqueListContents;
|
||||||
self as *const List<T> as usize
|
}
|
||||||
}
|
|
||||||
#[inline]
|
impl<T> List<T> {
|
||||||
unsafe fn from_usize(ptr: usize) -> Self {
|
/// Returns a reference to the (unique, static) empty list.
|
||||||
&*(ptr as *const List<T>)
|
#[inline(always)]
|
||||||
}
|
pub fn empty<'a>() -> &'a List<T> {
|
||||||
unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R {
|
#[repr(align(64))]
|
||||||
// Self: Copy so this is fine
|
struct MaxAlign;
|
||||||
let ptr = Self::from_usize(ptr);
|
|
||||||
f(&ptr)
|
assert!(mem::align_of::<T>() <= mem::align_of::<MaxAlign>());
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct InOrder<T, U>(T, U);
|
||||||
|
|
||||||
|
// The empty slice is static and contains a single `0` usize (for the
|
||||||
|
// length) that is 64-byte aligned, thus featuring the necessary
|
||||||
|
// trailing padding for elements with up to 64-byte alignment.
|
||||||
|
static EMPTY_SLICE: InOrder<usize, MaxAlign> = InOrder(0, MaxAlign);
|
||||||
|
unsafe { &*(&EMPTY_SLICE as *const _ as *const List<T>) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: Sync> Sync for List<T> {}
|
|
||||||
|
|
||||||
impl<T: Copy> List<T> {
|
impl<T: Copy> List<T> {
|
||||||
|
/// Allocates a list from `arena` and copies the contents of `slice` into it.
|
||||||
|
///
|
||||||
|
/// WARNING: the contents *must be unique*, such that no list with these
|
||||||
|
/// contents has been previously created. If not, operations such as `eq`
|
||||||
|
/// and `hash` might give incorrect results.
|
||||||
|
///
|
||||||
|
/// Panics if `T` is `Drop`, or `T` is zero-sized, or the slice is empty
|
||||||
|
/// (because the empty list exists statically, and is available via
|
||||||
|
/// `empty()`).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn from_arena<'tcx>(arena: &'tcx Arena<'tcx>, slice: &[T]) -> &'tcx List<T> {
|
pub(super) fn from_arena<'tcx>(arena: &'tcx Arena<'tcx>, slice: &[T]) -> &'tcx List<T> {
|
||||||
assert!(!mem::needs_drop::<T>());
|
assert!(!mem::needs_drop::<T>());
|
||||||
@ -73,7 +91,7 @@ impl<T: Copy> List<T> {
|
|||||||
.cast::<T>()
|
.cast::<T>()
|
||||||
.copy_from_nonoverlapping(slice.as_ptr(), slice.len());
|
.copy_from_nonoverlapping(slice.as_ptr(), slice.len());
|
||||||
|
|
||||||
&mut *mem
|
&*mem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,11 +125,24 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for &List<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: PartialEq> PartialEq for List<T> {
|
||||||
|
#[inline]
|
||||||
|
fn eq(&self, other: &List<T>) -> bool {
|
||||||
|
// Pointer equality implies list equality (due to the unique contents
|
||||||
|
// assumption).
|
||||||
|
ptr::eq(self, other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Eq> Eq for List<T> {}
|
||||||
|
|
||||||
impl<T> Ord for List<T>
|
impl<T> Ord for List<T>
|
||||||
where
|
where
|
||||||
T: Ord,
|
T: Ord,
|
||||||
{
|
{
|
||||||
fn cmp(&self, other: &List<T>) -> Ordering {
|
fn cmp(&self, other: &List<T>) -> Ordering {
|
||||||
|
// Pointer equality implies list equality (due to the unique contents
|
||||||
|
// assumption), but the contents must be compared otherwise.
|
||||||
if self == other { Ordering::Equal } else { <[T] as Ord>::cmp(&**self, &**other) }
|
if self == other { Ordering::Equal } else { <[T] as Ord>::cmp(&**self, &**other) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,6 +152,8 @@ where
|
|||||||
T: PartialOrd,
|
T: PartialOrd,
|
||||||
{
|
{
|
||||||
fn partial_cmp(&self, other: &List<T>) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &List<T>) -> Option<Ordering> {
|
||||||
|
// Pointer equality implies list equality (due to the unique contents
|
||||||
|
// assumption), but the contents must be compared otherwise.
|
||||||
if self == other {
|
if self == other {
|
||||||
Some(Ordering::Equal)
|
Some(Ordering::Equal)
|
||||||
} else {
|
} else {
|
||||||
@ -129,17 +162,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq> PartialEq for List<T> {
|
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &List<T>) -> bool {
|
|
||||||
ptr::eq(self, other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T: Eq> Eq for List<T> {}
|
|
||||||
|
|
||||||
impl<T> Hash for List<T> {
|
impl<T> Hash for List<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn hash<H: Hasher>(&self, s: &mut H) {
|
fn hash<H: Hasher>(&self, s: &mut H) {
|
||||||
|
// Pointer hashing is sufficient (due to the unique contents
|
||||||
|
// assumption).
|
||||||
(self as *const List<T>).hash(s)
|
(self as *const List<T>).hash(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,13 +195,24 @@ impl<'a, T: Copy> IntoIterator for &'a List<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> List<T> {
|
unsafe impl<T: Sync> Sync for List<T> {}
|
||||||
#[inline(always)]
|
|
||||||
pub fn empty<'a>() -> &'a List<T> {
|
unsafe impl<'a, T: 'a> rustc_data_structures::tagged_ptr::Pointer for &'a List<T> {
|
||||||
#[repr(align(64), C)]
|
const BITS: usize = std::mem::align_of::<usize>().trailing_zeros() as usize;
|
||||||
struct EmptySlice([u8; 64]);
|
|
||||||
static EMPTY_SLICE: EmptySlice = EmptySlice([0; 64]);
|
#[inline]
|
||||||
assert!(mem::align_of::<T>() <= 64);
|
fn into_usize(self) -> usize {
|
||||||
unsafe { &*(&EMPTY_SLICE as *const _ as *const List<T>) }
|
self as *const List<T> as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn from_usize(ptr: usize) -> &'a List<T> {
|
||||||
|
&*(ptr as *const List<T>)
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R {
|
||||||
|
// `Self` is `&'a List<T>` which impls `Copy`, so this is fine.
|
||||||
|
let ptr = Self::from_usize(ptr);
|
||||||
|
f(&ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2055,13 +2055,17 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition.
|
/// Yields the parent function's `LocalDefId` if `def_id` is an `impl Trait` definition.
|
||||||
pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
|
pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<LocalDefId> {
|
||||||
if let Some(def_id) = def_id.as_local() {
|
let def_id = def_id.as_local()?;
|
||||||
if let Node::Item(item) = tcx.hir().get(tcx.hir().local_def_id_to_hir_id(def_id)) {
|
if let Node::Item(item) = tcx.hir().get(tcx.hir().local_def_id_to_hir_id(def_id)) {
|
||||||
if let hir::ItemKind::OpaqueTy(ref opaque_ty) = item.kind {
|
if let hir::ItemKind::OpaqueTy(ref opaque_ty) = item.kind {
|
||||||
return opaque_ty.impl_trait_fn;
|
return match opaque_ty.origin {
|
||||||
}
|
hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => {
|
||||||
|
Some(parent)
|
||||||
|
}
|
||||||
|
hir::OpaqueTyOrigin::TyAlias => None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
@ -105,6 +105,11 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> {
|
|||||||
a misaligned reference is undefined behavior (even if that \
|
a misaligned reference is undefined behavior (even if that \
|
||||||
reference is never dereferenced)",
|
reference is never dereferenced)",
|
||||||
)
|
)
|
||||||
|
.help(
|
||||||
|
"copy the field contents to a local variable, or replace the \
|
||||||
|
reference with a raw pointer and use `read_unaligned`/`write_unaligned` \
|
||||||
|
(loads and stores via `*p` must be properly aligned even when using raw pointers)"
|
||||||
|
)
|
||||||
.emit()
|
.emit()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -968,7 +968,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||||||
let (generics, bounds) = match opaque_ty.kind {
|
let (generics, bounds) = match opaque_ty.kind {
|
||||||
// Named opaque `impl Trait` types are reached via `TyKind::Path`.
|
// Named opaque `impl Trait` types are reached via `TyKind::Path`.
|
||||||
// This arm is for `impl Trait` in the types of statics, constants and locals.
|
// This arm is for `impl Trait` in the types of statics, constants and locals.
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: None, .. }) => {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
|
origin: hir::OpaqueTyOrigin::TyAlias,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
intravisit::walk_ty(self, ty);
|
intravisit::walk_ty(self, ty);
|
||||||
|
|
||||||
// Elided lifetimes are not allowed in non-return
|
// Elided lifetimes are not allowed in non-return
|
||||||
@ -985,7 +988,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
// RPIT (return position impl trait)
|
// RPIT (return position impl trait)
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
impl_trait_fn: Some(_),
|
origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..),
|
||||||
ref generics,
|
ref generics,
|
||||||
bounds,
|
bounds,
|
||||||
..
|
..
|
||||||
@ -1695,7 +1698,11 @@ fn compute_object_lifetime_defaults(
|
|||||||
hir::ItemKind::Struct(_, ref generics)
|
hir::ItemKind::Struct(_, ref generics)
|
||||||
| hir::ItemKind::Union(_, ref generics)
|
| hir::ItemKind::Union(_, ref generics)
|
||||||
| hir::ItemKind::Enum(_, ref generics)
|
| hir::ItemKind::Enum(_, ref generics)
|
||||||
| hir::ItemKind::OpaqueTy(hir::OpaqueTy { ref generics, impl_trait_fn: None, .. })
|
| hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
|
ref generics,
|
||||||
|
origin: hir::OpaqueTyOrigin::TyAlias,
|
||||||
|
..
|
||||||
|
})
|
||||||
| hir::ItemKind::TyAlias(_, ref generics)
|
| hir::ItemKind::TyAlias(_, ref generics)
|
||||||
| hir::ItemKind::Trait(_, _, ref generics, ..) => {
|
| hir::ItemKind::Trait(_, _, ref generics, ..) => {
|
||||||
let result = object_lifetime_defaults_for_item(tcx, generics);
|
let result = object_lifetime_defaults_for_item(tcx, generics);
|
||||||
@ -2067,7 +2074,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||||||
..
|
..
|
||||||
}) = self.tcx.hir().get(parent_hir_id)
|
}) = self.tcx.hir().get(parent_hir_id)
|
||||||
{
|
{
|
||||||
if opaque.origin != hir::OpaqueTyOrigin::AsyncFn {
|
if !matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn(..)) {
|
||||||
continue 'lifetimes;
|
continue 'lifetimes;
|
||||||
}
|
}
|
||||||
// We want to do this only if the liftime identifier is already defined
|
// We want to do this only if the liftime identifier is already defined
|
||||||
|
@ -248,7 +248,7 @@ fn trait_of_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
|
|||||||
fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
// The param_env of an impl Trait type is its defining function's param_env
|
// The param_env of an impl Trait type is its defining function's param_env
|
||||||
if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
|
if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
|
||||||
return param_env(tcx, parent);
|
return param_env(tcx, parent.to_def_id());
|
||||||
}
|
}
|
||||||
// Compute the bounds on Self and the type parameters.
|
// Compute the bounds on Self and the type parameters.
|
||||||
|
|
||||||
@ -313,7 +313,7 @@ fn well_formed_types_in_env<'tcx>(
|
|||||||
|
|
||||||
// The environment of an impl Trait type is its defining function's environment.
|
// The environment of an impl Trait type is its defining function's environment.
|
||||||
if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
|
if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
|
||||||
return well_formed_types_in_env(tcx, parent);
|
return well_formed_types_in_env(tcx, parent.to_def_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the bounds on `Self` and the type parameters.
|
// Compute the bounds on `Self` and the type parameters.
|
||||||
|
@ -2336,9 +2336,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
let def_id = item_id.def_id.to_def_id();
|
let def_id = item_id.def_id.to_def_id();
|
||||||
|
|
||||||
match opaque_ty.kind {
|
match opaque_ty.kind {
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => self
|
||||||
self.impl_trait_ty_to_ty(def_id, lifetimes, impl_trait_fn.is_some())
|
.impl_trait_ty_to_ty(
|
||||||
}
|
def_id,
|
||||||
|
lifetimes,
|
||||||
|
matches!(
|
||||||
|
origin,
|
||||||
|
hir::OpaqueTyOrigin::FnReturn(..)
|
||||||
|
| hir::OpaqueTyOrigin::AsyncFn(..)
|
||||||
|
),
|
||||||
|
),
|
||||||
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
|
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -541,7 +541,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let ItemKind::OpaqueTy(hir::OpaqueTy {
|
if let ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn,
|
origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
|
||||||
..
|
..
|
||||||
}) = item.kind
|
}) = item.kind
|
||||||
{
|
{
|
||||||
@ -567,7 +567,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
|
|||||||
visitor.visit_item(&item);
|
visitor.visit_item(&item);
|
||||||
let is_async = match item.kind {
|
let is_async = match item.kind {
|
||||||
ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
|
ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
|
||||||
matches!(origin, hir::OpaqueTyOrigin::AsyncFn)
|
matches!(origin, hir::OpaqueTyOrigin::AsyncFn(..))
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
@ -604,7 +604,7 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
|
|||||||
) -> Result<(), ErrorReported> {
|
) -> Result<(), ErrorReported> {
|
||||||
if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() {
|
if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() {
|
||||||
match origin {
|
match origin {
|
||||||
hir::OpaqueTyOrigin::AsyncFn => async_opaque_type_cycle_error(tcx, span),
|
hir::OpaqueTyOrigin::AsyncFn(..) => async_opaque_type_cycle_error(tcx, span),
|
||||||
_ => opaque_type_cycle_error(tcx, def_id, span),
|
_ => opaque_type_cycle_error(tcx, def_id, span),
|
||||||
}
|
}
|
||||||
Err(ErrorReported)
|
Err(ErrorReported)
|
||||||
@ -635,7 +635,7 @@ fn check_opaque_meets_bounds<'tcx>(
|
|||||||
) {
|
) {
|
||||||
match origin {
|
match origin {
|
||||||
// Checked when type checking the function containing them.
|
// Checked when type checking the function containing them.
|
||||||
hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => return,
|
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => return,
|
||||||
// Can have different predicates to their defining use
|
// Can have different predicates to their defining use
|
||||||
hir::OpaqueTyOrigin::TyAlias => {}
|
hir::OpaqueTyOrigin::TyAlias => {}
|
||||||
}
|
}
|
||||||
|
@ -594,7 +594,11 @@ fn type_param_predicates(
|
|||||||
ItemKind::Fn(.., ref generics, _)
|
ItemKind::Fn(.., ref generics, _)
|
||||||
| ItemKind::Impl(hir::Impl { ref generics, .. })
|
| ItemKind::Impl(hir::Impl { ref generics, .. })
|
||||||
| ItemKind::TyAlias(_, ref generics)
|
| ItemKind::TyAlias(_, ref generics)
|
||||||
| ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. })
|
| ItemKind::OpaqueTy(OpaqueTy {
|
||||||
|
ref generics,
|
||||||
|
origin: hir::OpaqueTyOrigin::TyAlias,
|
||||||
|
..
|
||||||
|
})
|
||||||
| ItemKind::Enum(_, ref generics)
|
| ItemKind::Enum(_, ref generics)
|
||||||
| ItemKind::Struct(_, ref generics)
|
| ItemKind::Struct(_, ref generics)
|
||||||
| ItemKind::Union(_, ref generics) => generics,
|
| ItemKind::Union(_, ref generics) => generics,
|
||||||
@ -793,7 +797,10 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Desugared from `impl Trait`, so visited by the function's return type.
|
// Desugared from `impl Trait`, so visited by the function's return type.
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) => {}
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
|
origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..),
|
||||||
|
..
|
||||||
|
}) => {}
|
||||||
|
|
||||||
// Don't call `type_of` on opaque types, since that depends on type
|
// Don't call `type_of` on opaque types, since that depends on type
|
||||||
// checking function bodies. `check_item_type` ensures that it's called
|
// checking function bodies. `check_item_type` ensures that it's called
|
||||||
@ -1488,15 +1495,18 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
|||||||
Some(tcx.typeck_root_def_id(def_id))
|
Some(tcx.typeck_root_def_id(def_id))
|
||||||
}
|
}
|
||||||
Node::Item(item) => match item.kind {
|
Node::Item(item) => match item.kind {
|
||||||
ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => {
|
ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
impl_trait_fn.or_else(|| {
|
origin:
|
||||||
let parent_id = tcx.hir().get_parent_item(hir_id);
|
hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
|
||||||
assert!(parent_id != hir_id && parent_id != CRATE_HIR_ID);
|
..
|
||||||
debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id);
|
}) => Some(fn_def_id.to_def_id()),
|
||||||
// Opaque types are always nested within another item, and
|
ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
|
||||||
// inherit the generics of the item.
|
let parent_id = tcx.hir().get_parent_item(hir_id);
|
||||||
Some(tcx.hir().local_def_id(parent_id).to_def_id())
|
assert!(parent_id != hir_id && parent_id != CRATE_HIR_ID);
|
||||||
})
|
debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id);
|
||||||
|
// Opaque types are always nested within another item, and
|
||||||
|
// inherit the generics of the item.
|
||||||
|
Some(tcx.hir().local_def_id(parent_id).to_def_id())
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
@ -2051,31 +2061,32 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
|||||||
generics
|
generics
|
||||||
}
|
}
|
||||||
ItemKind::OpaqueTy(OpaqueTy {
|
ItemKind::OpaqueTy(OpaqueTy {
|
||||||
bounds: _,
|
origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
|
||||||
impl_trait_fn,
|
..
|
||||||
ref generics,
|
|
||||||
origin: _,
|
|
||||||
}) => {
|
}) => {
|
||||||
if impl_trait_fn.is_some() {
|
// return-position impl trait
|
||||||
// return-position impl trait
|
//
|
||||||
//
|
// We don't inherit predicates from the parent here:
|
||||||
// We don't inherit predicates from the parent here:
|
// If we have, say `fn f<'a, T: 'a>() -> impl Sized {}`
|
||||||
// If we have, say `fn f<'a, T: 'a>() -> impl Sized {}`
|
// then the return type is `f::<'static, T>::{{opaque}}`.
|
||||||
// then the return type is `f::<'static, T>::{{opaque}}`.
|
//
|
||||||
//
|
// If we inherited the predicates of `f` then we would
|
||||||
// If we inherited the predicates of `f` then we would
|
// require that `T: 'static` to show that the return
|
||||||
// require that `T: 'static` to show that the return
|
// type is well-formed.
|
||||||
// type is well-formed.
|
//
|
||||||
//
|
// The only way to have something with this opaque type
|
||||||
// The only way to have something with this opaque type
|
// is from the return type of the containing function,
|
||||||
// is from the return type of the containing function,
|
// which will ensure that the function's predicates
|
||||||
// which will ensure that the function's predicates
|
// hold.
|
||||||
// hold.
|
return ty::GenericPredicates { parent: None, predicates: &[] };
|
||||||
return ty::GenericPredicates { parent: None, predicates: &[] };
|
}
|
||||||
} else {
|
ItemKind::OpaqueTy(OpaqueTy {
|
||||||
// type-alias impl trait
|
ref generics,
|
||||||
generics
|
origin: hir::OpaqueTyOrigin::TyAlias,
|
||||||
}
|
..
|
||||||
|
}) => {
|
||||||
|
// type-alias impl trait
|
||||||
|
generics
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => NO_GENERICS,
|
_ => NO_GENERICS,
|
||||||
|
@ -394,13 +394,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||||
tcx.mk_adt(def, substs)
|
tcx.mk_adt(def, substs)
|
||||||
}
|
}
|
||||||
ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }) => {
|
ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
|
||||||
find_opaque_ty_constraints(tcx, def_id)
|
find_opaque_ty_constraints(tcx, def_id)
|
||||||
}
|
}
|
||||||
// Opaque types desugared from `impl Trait`.
|
// Opaque types desugared from `impl Trait`.
|
||||||
ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: Some(owner), .. }) => {
|
ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), .. }) => {
|
||||||
let concrete_ty = tcx
|
let concrete_ty = tcx
|
||||||
.mir_borrowck(owner.expect_local())
|
.mir_borrowck(owner)
|
||||||
.concrete_opaque_types
|
.concrete_opaque_types
|
||||||
.get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
|
.get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
|
||||||
.copied()
|
.copied()
|
||||||
@ -413,7 +413,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
if let Some(ErrorReported) =
|
if let Some(ErrorReported) =
|
||||||
tcx.typeck(owner.expect_local()).tainted_by_errors
|
tcx.typeck(owner).tainted_by_errors
|
||||||
{
|
{
|
||||||
// Some error in the
|
// Some error in the
|
||||||
// owner fn prevented us from populating
|
// owner fn prevented us from populating
|
||||||
|
@ -45,15 +45,23 @@ impl<A: Iterator, B: Iterator> Zip<A, B> {
|
|||||||
///
|
///
|
||||||
/// let xs = [1, 2, 3];
|
/// let xs = [1, 2, 3];
|
||||||
/// let ys = [4, 5, 6];
|
/// let ys = [4, 5, 6];
|
||||||
/// for (x, y) in zip(&xs, &ys) {
|
///
|
||||||
/// println!("x:{}, y:{}", x, y);
|
/// let mut iter = zip(xs, ys);
|
||||||
/// }
|
///
|
||||||
|
/// assert_eq!(iter.next().unwrap(), (1, 4));
|
||||||
|
/// assert_eq!(iter.next().unwrap(), (2, 5));
|
||||||
|
/// assert_eq!(iter.next().unwrap(), (3, 6));
|
||||||
|
/// assert!(iter.next().is_none());
|
||||||
///
|
///
|
||||||
/// // Nested zips are also possible:
|
/// // Nested zips are also possible:
|
||||||
/// let zs = [7, 8, 9];
|
/// let zs = [7, 8, 9];
|
||||||
/// for ((x, y), z) in zip(zip(&xs, &ys), &zs) {
|
///
|
||||||
/// println!("x:{}, y:{}, z:{}", x, y, z);
|
/// let mut iter = zip(zip(xs, ys), zs);
|
||||||
/// }
|
///
|
||||||
|
/// assert_eq!(iter.next().unwrap(), ((1, 4), 7));
|
||||||
|
/// assert_eq!(iter.next().unwrap(), ((2, 5), 8));
|
||||||
|
/// assert_eq!(iter.next().unwrap(), ((3, 6), 9));
|
||||||
|
/// assert!(iter.next().is_none());
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "iter_zip", issue = "83574")]
|
#[unstable(feature = "iter_zip", issue = "83574")]
|
||||||
pub fn zip<A, B>(a: A, b: B) -> Zip<A::IntoIter, B::IntoIter>
|
pub fn zip<A, B>(a: A, b: B) -> Zip<A::IntoIter, B::IntoIter>
|
||||||
|
@ -1058,7 +1058,7 @@ impl Metadata {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "is_symlink", since = "1.57.0")]
|
#[stable(feature = "is_symlink", since = "1.58.0")]
|
||||||
pub fn is_symlink(&self) -> bool {
|
pub fn is_symlink(&self) -> bool {
|
||||||
self.file_type().is_symlink()
|
self.file_type().is_symlink()
|
||||||
}
|
}
|
||||||
|
@ -2817,7 +2817,7 @@ impl Path {
|
|||||||
/// check errors, call [`fs::symlink_metadata`] and handle its [`Result`]. Then call
|
/// check errors, call [`fs::symlink_metadata`] and handle its [`Result`]. Then call
|
||||||
/// [`fs::Metadata::is_symlink`] if it was [`Ok`].
|
/// [`fs::Metadata::is_symlink`] if it was [`Ok`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "is_symlink", since = "1.57.0")]
|
#[stable(feature = "is_symlink", since = "1.58.0")]
|
||||||
pub fn is_symlink(&self) -> bool {
|
pub fn is_symlink(&self) -> bool {
|
||||||
fs::symlink_metadata(self).map(|m| m.is_symlink()).unwrap_or(false)
|
fs::symlink_metadata(self).map(|m| m.is_symlink()).unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
@ -327,6 +327,19 @@ impl Options {
|
|||||||
return Err(0);
|
return Err(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let color = config::parse_color(matches);
|
||||||
|
let config::JsonConfig { json_rendered, json_unused_externs, .. } =
|
||||||
|
config::parse_json(matches);
|
||||||
|
let error_format = config::parse_error_format(matches, color, json_rendered);
|
||||||
|
|
||||||
|
let codegen_options = CodegenOptions::build(matches, error_format);
|
||||||
|
let debugging_opts = DebuggingOptions::build(matches, error_format);
|
||||||
|
|
||||||
|
let diag = new_handler(error_format, None, &debugging_opts);
|
||||||
|
|
||||||
|
// check for deprecated options
|
||||||
|
check_deprecated_options(matches, &diag);
|
||||||
|
|
||||||
if matches.opt_strs("passes") == ["list"] {
|
if matches.opt_strs("passes") == ["list"] {
|
||||||
println!("Available passes for running rustdoc:");
|
println!("Available passes for running rustdoc:");
|
||||||
for pass in passes::PASSES {
|
for pass in passes::PASSES {
|
||||||
@ -359,19 +372,6 @@ impl Options {
|
|||||||
return Err(0);
|
return Err(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let color = config::parse_color(matches);
|
|
||||||
let config::JsonConfig { json_rendered, json_unused_externs, .. } =
|
|
||||||
config::parse_json(matches);
|
|
||||||
let error_format = config::parse_error_format(matches, color, json_rendered);
|
|
||||||
|
|
||||||
let codegen_options = CodegenOptions::build(matches, error_format);
|
|
||||||
let debugging_opts = DebuggingOptions::build(matches, error_format);
|
|
||||||
|
|
||||||
let diag = new_handler(error_format, None, &debugging_opts);
|
|
||||||
|
|
||||||
// check for deprecated options
|
|
||||||
check_deprecated_options(matches, &diag);
|
|
||||||
|
|
||||||
let mut emit = Vec::new();
|
let mut emit = Vec::new();
|
||||||
for list in matches.opt_strs("emit") {
|
for list in matches.opt_strs("emit") {
|
||||||
for kind in list.split(',') {
|
for kind in list.split(',') {
|
||||||
|
@ -976,6 +976,7 @@ fn item_typedef(
|
|||||||
// associated items from the aliased type (see discussion in #32077), but
|
// associated items from the aliased type (see discussion in #32077), but
|
||||||
// we need #14072 to make sense of the generics.
|
// we need #14072 to make sense of the generics.
|
||||||
render_assoc_items(w, cx, it, def_id, AssocItemRender::All);
|
render_assoc_items(w, cx, it, def_id, AssocItemRender::All);
|
||||||
|
document_type_layout(w, cx, def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) {
|
fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) {
|
||||||
|
3
src/test/rustdoc-ui/issue-91713.rs
Normal file
3
src/test/rustdoc-ui/issue-91713.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// check-pass
|
||||||
|
// compile-flags: --passes list
|
||||||
|
// error-pattern: the `passes` flag is deprecated
|
4
src/test/rustdoc-ui/issue-91713.stderr
Normal file
4
src/test/rustdoc-ui/issue-91713.stderr
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
warning: the `passes` flag is deprecated
|
||||||
|
|
|
||||||
|
= note: see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information
|
||||||
|
|
31
src/test/rustdoc-ui/issue-91713.stdout
Normal file
31
src/test/rustdoc-ui/issue-91713.stdout
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
Available passes for running rustdoc:
|
||||||
|
check_doc_test_visibility - run various visibility-related lints on doctests
|
||||||
|
strip-hidden - strips all `#[doc(hidden)]` items from the output
|
||||||
|
unindent-comments - removes excess indentation on comments in order for markdown to like it
|
||||||
|
strip-private - strips all private items from a crate which cannot be seen externally, implies strip-priv-imports
|
||||||
|
strip-priv-imports - strips all private import statements (`use`, `extern crate`) from a crate
|
||||||
|
propagate-doc-cfg - propagates `#[doc(cfg(...))]` to child items
|
||||||
|
collect-intra-doc-links - resolves intra-doc links
|
||||||
|
check-code-block-syntax - validates syntax inside Rust code blocks
|
||||||
|
collect-trait-impls - retrieves trait impls for items in the crate
|
||||||
|
calculate-doc-coverage - counts the number of items with and without documentation
|
||||||
|
check-invalid-html-tags - detects invalid HTML tags in doc comments
|
||||||
|
check-bare-urls - detects URLs that are not hyperlinks
|
||||||
|
|
||||||
|
Default passes for rustdoc:
|
||||||
|
collect-trait-impls
|
||||||
|
unindent-comments
|
||||||
|
check_doc_test_visibility
|
||||||
|
strip-hidden (when not --document-hidden-items)
|
||||||
|
strip-private (when not --document-private-items)
|
||||||
|
strip-priv-imports (when --document-private-items)
|
||||||
|
collect-intra-doc-links
|
||||||
|
check-code-block-syntax
|
||||||
|
check-invalid-html-tags
|
||||||
|
propagate-doc-cfg
|
||||||
|
check-bare-urls
|
||||||
|
|
||||||
|
Passes run with `--show-coverage`:
|
||||||
|
strip-hidden (when not --document-hidden-items)
|
||||||
|
strip-private (when not --document-private-items)
|
||||||
|
calculate-doc-coverage
|
@ -50,6 +50,18 @@ pub struct GenericLifetimes<'a>(&'a str);
|
|||||||
// @has - '(unsized)'
|
// @has - '(unsized)'
|
||||||
pub struct Unsized([u8]);
|
pub struct Unsized([u8]);
|
||||||
|
|
||||||
|
// @has type_layout/type.TypeAlias.html 'Size: '
|
||||||
|
// @has - ' bytes'
|
||||||
|
pub type TypeAlias = X;
|
||||||
|
|
||||||
|
// @has type_layout/type.GenericTypeAlias.html 'Size: '
|
||||||
|
// @has - '8 bytes'
|
||||||
|
pub type GenericTypeAlias = (Generic<(u32, ())>, Generic<u32>);
|
||||||
|
|
||||||
|
// Regression test for the rustdoc equivalent of #85103.
|
||||||
|
// @has type_layout/type.Edges.html 'Encountered an error during type layout; the type failed to be normalized.'
|
||||||
|
pub type Edges<'a, E> = std::borrow::Cow<'a, [E]>;
|
||||||
|
|
||||||
// @!has type_layout/trait.MyTrait.html 'Size: '
|
// @!has type_layout/trait.MyTrait.html 'Size: '
|
||||||
pub trait MyTrait {}
|
pub trait MyTrait {}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// edition:2018
|
// edition:2018
|
||||||
// compile-flags: --crate-type lib
|
// compile-flags: --crate-type lib
|
||||||
|
|
||||||
|
#![feature(in_band_lifetimes)]
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
pub async fn simple_generic<T>() {}
|
pub async fn simple_generic<T>() {}
|
||||||
@ -71,6 +73,10 @@ pub fn call_with_ref_block<'a>(f: &'a (impl Foo + 'a)) -> impl Future<Output = (
|
|||||||
async move { f.foo() }
|
async move { f.foo() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn call_with_ref_block_in_band(f: &'a (impl Foo + 'a)) -> impl Future<Output = ()> + 'a {
|
||||||
|
async move { f.foo() }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn async_block_with_same_generic_params_unifies() {
|
pub fn async_block_with_same_generic_params_unifies() {
|
||||||
let mut a = call_generic_bound_block(FooType);
|
let mut a = call_generic_bound_block(FooType);
|
||||||
a = call_generic_bound_block(FooType);
|
a = call_generic_bound_block(FooType);
|
||||||
@ -85,4 +91,9 @@ pub fn async_block_with_same_generic_params_unifies() {
|
|||||||
let f_two = FooType;
|
let f_two = FooType;
|
||||||
let mut d = call_with_ref_block(&f_one);
|
let mut d = call_with_ref_block(&f_one);
|
||||||
d = call_with_ref_block(&f_two);
|
d = call_with_ref_block(&f_two);
|
||||||
|
|
||||||
|
let f_one = FooType;
|
||||||
|
let f_two = FooType;
|
||||||
|
let mut d = call_with_ref_block_in_band(&f_one);
|
||||||
|
d = call_with_ref_block_in_band(&f_two);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ LL | let _ = &p.b;
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
warning: reference to packed field is unaligned
|
warning: reference to packed field is unaligned
|
||||||
--> $DIR/issue-53114-safety-checks.rs:29:17
|
--> $DIR/issue-53114-safety-checks.rs:29:17
|
||||||
@ -18,6 +19,7 @@ LL | let (_,) = (&p.b,);
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
warning: reference to packed field is unaligned
|
warning: reference to packed field is unaligned
|
||||||
--> $DIR/issue-53114-safety-checks.rs:39:11
|
--> $DIR/issue-53114-safety-checks.rs:39:11
|
||||||
@ -28,6 +30,7 @@ LL | match &p.b { _ => { } }
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
warning: reference to packed field is unaligned
|
warning: reference to packed field is unaligned
|
||||||
--> $DIR/issue-53114-safety-checks.rs:45:12
|
--> $DIR/issue-53114-safety-checks.rs:45:12
|
||||||
@ -38,6 +41,7 @@ LL | match (&p.b,) { (_,) => { } }
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||||
--> $DIR/issue-53114-safety-checks.rs:26:13
|
--> $DIR/issue-53114-safety-checks.rs:26:13
|
||||||
|
@ -8,6 +8,7 @@ LL | println!("{}", foo.x);
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
= note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
warning: 1 warning emitted
|
warning: 1 warning emitted
|
||||||
|
@ -12,6 +12,7 @@ LL | #![deny(unaligned_references)]
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
error: reference to packed field is unaligned
|
error: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:24:17
|
--> $DIR/unaligned_references.rs:24:17
|
||||||
@ -22,6 +23,7 @@ LL | let _ = &good.data;
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
error: reference to packed field is unaligned
|
error: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:27:17
|
--> $DIR/unaligned_references.rs:27:17
|
||||||
@ -32,6 +34,7 @@ LL | let _ = &good.data as *const _;
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
error: reference to packed field is unaligned
|
error: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:29:27
|
--> $DIR/unaligned_references.rs:29:27
|
||||||
@ -42,6 +45,7 @@ LL | let _: *const _ = &good.data;
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
error: reference to packed field is unaligned
|
error: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:32:17
|
--> $DIR/unaligned_references.rs:32:17
|
||||||
@ -52,6 +56,7 @@ LL | let _ = good.data.clone();
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
error: reference to packed field is unaligned
|
error: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:35:17
|
--> $DIR/unaligned_references.rs:35:17
|
||||||
@ -62,6 +67,7 @@ LL | let _ = &good.data2[0];
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
error: reference to packed field is unaligned
|
error: reference to packed field is unaligned
|
||||||
--> $DIR/unaligned_references.rs:45:17
|
--> $DIR/unaligned_references.rs:45:17
|
||||||
@ -72,6 +78,7 @@ LL | let _ = &packed2.x;
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ LL | | }
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
= note: this error originates in the macro `unaligned_references_external_crate::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `unaligned_references_external_crate::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
@ -12,6 +12,7 @@ LL | #[deny(unaligned_references)]
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
error: reference to packed field is unaligned
|
error: reference to packed field is unaligned
|
||||||
--> $DIR/issue-27060.rs:18:13
|
--> $DIR/issue-27060.rs:18:13
|
||||||
@ -22,6 +23,7 @@ LL | let _ = &good.data2[0];
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
error: reference to packed field is unaligned
|
error: reference to packed field is unaligned
|
||||||
--> $DIR/issue-27060.rs:21:13
|
--> $DIR/issue-27060.rs:21:13
|
||||||
@ -32,6 +34,7 @@ LL | let _ = &good.data;
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
error: reference to packed field is unaligned
|
error: reference to packed field is unaligned
|
||||||
--> $DIR/issue-27060.rs:23:13
|
--> $DIR/issue-27060.rs:23:13
|
||||||
@ -42,6 +45,7 @@ LL | let _ = &good.data2[0];
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ LL | let brw = &foo.baz;
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
warning: 1 warning emitted
|
warning: 1 warning emitted
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ LL | let brw = &foo.baz;
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
warning: reference to packed field is unaligned
|
warning: reference to packed field is unaligned
|
||||||
--> $DIR/packed-struct-borrow-element.rs:30:15
|
--> $DIR/packed-struct-borrow-element.rs:30:15
|
||||||
@ -18,6 +19,7 @@ LL | let brw = &foo.baz;
|
|||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
|
||||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||||
|
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||||
|
|
||||||
warning: 2 warnings emitted
|
warning: 2 warnings emitted
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user