Auto merge of #123147 - matthiaskrgr:rollup-2t5ot36, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #121943 (Clarify atomic bit validity) - #123075 (CFI: Fix drop and drop_in_place) - #123101 (Delegation: fix ICE on wrong `Self` instantiation) - #123130 (Load missing type of impl associated constant from trait definition) - #123133 (chore: fix some comments) - #123136 (Some wording improvement) - #123139 (`num::NonZero::get` can be 1 transmute instead of 2) - #123142 (Let nils know about changes to target docs) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
d779a7a25f
@ -151,8 +151,8 @@ toolchain.
|
|||||||
directory and uncomment the line `MSYS2_PATH_TYPE=inherit`.
|
directory and uncomment the line `MSYS2_PATH_TYPE=inherit`.
|
||||||
|
|
||||||
You could install and use MSYS2's version of git instead with `pacman`,
|
You could install and use MSYS2's version of git instead with `pacman`,
|
||||||
however this is not recommended as it's excrutiatingly slow, and not frequently
|
however this is not recommended as it's excruciatingly slow, and not frequently
|
||||||
tested for compatability.
|
tested for compatibility.
|
||||||
|
|
||||||
3. Start a MINGW64 or MINGW32 shell (depending on whether you want 32-bit
|
3. Start a MINGW64 or MINGW32 shell (depending on whether you want 32-bit
|
||||||
or 64-bit Rust) either from your start menu, or by running `mingw64.exe`
|
or 64-bit Rust) either from your start menu, or by running `mingw64.exe`
|
||||||
|
@ -75,7 +75,7 @@ pub(crate) struct FixupContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The default amount of fixing is minimal fixing. Fixups should be turned on
|
/// The default amount of fixing is minimal fixing. Fixups should be turned on
|
||||||
/// in a targetted fashion where needed.
|
/// in a targeted fashion where needed.
|
||||||
impl Default for FixupContext {
|
impl Default for FixupContext {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
FixupContext {
|
FixupContext {
|
||||||
|
@ -592,7 +592,7 @@ fn sanitize_promoted(&mut self, promoted_body: &'b Body<'tcx>, location: Locatio
|
|||||||
}
|
}
|
||||||
self.cx.borrowck_context.constraints.outlives_constraints.push(constraint)
|
self.cx.borrowck_context.constraints.outlives_constraints.push(constraint)
|
||||||
}
|
}
|
||||||
// If the region is live at at least one location in the promoted MIR,
|
// If the region is live at least one location in the promoted MIR,
|
||||||
// then add a liveness constraint to the main MIR for this region
|
// then add a liveness constraint to the main MIR for this region
|
||||||
// at the location provided as an argument to this method
|
// at the location provided as an argument to this method
|
||||||
//
|
//
|
||||||
|
@ -409,7 +409,7 @@ fn const_validate_mplace<'mir, 'tcx>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)
|
ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)
|
||||||
// Instead of just reporting the `InterpError` via the usual machinery, we give a more targetted
|
// Instead of just reporting the `InterpError` via the usual machinery, we give a more targeted
|
||||||
// error about the validation failure.
|
// error about the validation failure.
|
||||||
.map_err(|error| report_validation_error(&ecx, error, alloc_id))?;
|
.map_err(|error| report_validation_error(&ecx, error, alloc_id))?;
|
||||||
inner = true;
|
inner = true;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
/// Prohibit or lint against *bare* trait object types depending on the edition.
|
/// Prohibit or lint against *bare* trait object types depending on the edition.
|
||||||
///
|
///
|
||||||
/// *Bare* trait object types are ones that aren't preceeded by the keyword `dyn`.
|
/// *Bare* trait object types are ones that aren't preceded by the keyword `dyn`.
|
||||||
/// In edition 2021 and onward we emit a hard error for them.
|
/// In edition 2021 and onward we emit a hard error for them.
|
||||||
pub(super) fn prohibit_or_lint_bare_trait_object_ty(
|
pub(super) fn prohibit_or_lint_bare_trait_object_ty(
|
||||||
&self,
|
&self,
|
||||||
|
@ -2212,6 +2212,17 @@ fn check_delegation_constraints(&self, sig_id: DefId, span: Span, emit: bool) ->
|
|||||||
try_emit("delegation with early bound generics");
|
try_emit("delegation with early bound generics");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There is no way to instantiate `Self` param for caller if
|
||||||
|
// 1. callee is a trait method
|
||||||
|
// 2. delegation item isn't an associative item
|
||||||
|
if let DefKind::AssocFn = self.tcx().def_kind(sig_id)
|
||||||
|
&& let DefKind::Fn = self.tcx().def_kind(self.item_def_id())
|
||||||
|
&& self.tcx().associated_item(sig_id).container
|
||||||
|
== ty::AssocItemContainer::TraitContainer
|
||||||
|
{
|
||||||
|
try_emit("delegation to a trait method from a free function");
|
||||||
|
}
|
||||||
|
|
||||||
if self.tcx().asyncness(sig_id) == ty::Asyncness::Yes {
|
if self.tcx().asyncness(sig_id) == ty::Asyncness::Yes {
|
||||||
try_emit("delegation to async functions");
|
try_emit("delegation to async functions");
|
||||||
}
|
}
|
||||||
|
@ -83,20 +83,6 @@ macro_rules! type_error_struct {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If this `DefId` is a "primary tables entry", returns
|
|
||||||
/// `Some((body_id, body_ty, fn_sig))`. Otherwise, returns `None`.
|
|
||||||
///
|
|
||||||
/// If this function returns `Some`, then `typeck_results(def_id)` will
|
|
||||||
/// succeed; if it returns `None`, then `typeck_results(def_id)` may or
|
|
||||||
/// may not succeed. In some cases where this function returns `None`
|
|
||||||
/// (notably closures), `typeck_results(def_id)` would wind up
|
|
||||||
/// redirecting to the owning function.
|
|
||||||
fn primary_body_of(
|
|
||||||
node: Node<'_>,
|
|
||||||
) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnSig<'_>>)> {
|
|
||||||
Some((node.body_id()?, node.ty(), node.fn_sig()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
// Closures' typeck results come from their outermost function,
|
// Closures' typeck results come from their outermost function,
|
||||||
// as they are part of the same "inference environment".
|
// as they are part of the same "inference environment".
|
||||||
@ -106,7 +92,7 @@ fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(def_id) = def_id.as_local() {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
primary_body_of(tcx.hir_node_by_def_id(def_id)).is_some()
|
tcx.hir_node_by_def_id(def_id).body_id().is_some()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -163,7 +149,7 @@ fn typeck_with_fallback<'tcx>(
|
|||||||
let span = tcx.hir().span(id);
|
let span = tcx.hir().span(id);
|
||||||
|
|
||||||
// Figure out what primary body this item has.
|
// Figure out what primary body this item has.
|
||||||
let (body_id, body_ty, fn_sig) = primary_body_of(node).unwrap_or_else(|| {
|
let body_id = node.body_id().unwrap_or_else(|| {
|
||||||
span_bug!(span, "can't type-check body of {:?}", def_id);
|
span_bug!(span, "can't type-check body of {:?}", def_id);
|
||||||
});
|
});
|
||||||
let body = tcx.hir().body(body_id);
|
let body = tcx.hir().body(body_id);
|
||||||
@ -176,7 +162,7 @@ fn typeck_with_fallback<'tcx>(
|
|||||||
}
|
}
|
||||||
let mut fcx = FnCtxt::new(&root_ctxt, param_env, def_id);
|
let mut fcx = FnCtxt::new(&root_ctxt, param_env, def_id);
|
||||||
|
|
||||||
if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
|
if let Some(hir::FnSig { header, decl, .. }) = node.fn_sig() {
|
||||||
let fn_sig = if decl.output.get_infer_ret_ty().is_some() {
|
let fn_sig = if decl.output.get_infer_ret_ty().is_some() {
|
||||||
fcx.lowerer().lower_fn_ty(id, header.unsafety, header.abi, decl, None, None)
|
fcx.lowerer().lower_fn_ty(id, header.unsafety, header.abi, decl, None, None)
|
||||||
} else {
|
} else {
|
||||||
@ -191,42 +177,7 @@ fn typeck_with_fallback<'tcx>(
|
|||||||
|
|
||||||
check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params);
|
check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params);
|
||||||
} else {
|
} else {
|
||||||
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty {
|
let expected_type = infer_type_if_missing(&fcx, node);
|
||||||
Some(fcx.next_ty_var(TypeVariableOrigin {
|
|
||||||
kind: TypeVariableOriginKind::TypeInference,
|
|
||||||
span,
|
|
||||||
}))
|
|
||||||
} else if let Node::AnonConst(_) = node {
|
|
||||||
match tcx.parent_hir_node(id) {
|
|
||||||
Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), .. })
|
|
||||||
if anon_const.hir_id == id =>
|
|
||||||
{
|
|
||||||
Some(fcx.next_ty_var(TypeVariableOrigin {
|
|
||||||
kind: TypeVariableOriginKind::TypeInference,
|
|
||||||
span,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
|
|
||||||
| Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => {
|
|
||||||
asm.operands.iter().find_map(|(op, _op_sp)| match op {
|
|
||||||
hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => {
|
|
||||||
// Inline assembly constants must be integers.
|
|
||||||
Some(fcx.next_int_var())
|
|
||||||
}
|
|
||||||
hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == id => {
|
|
||||||
Some(fcx.next_ty_var(TypeVariableOrigin {
|
|
||||||
kind: TypeVariableOriginKind::MiscVariable,
|
|
||||||
span,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let expected_type = expected_type.unwrap_or_else(fallback);
|
let expected_type = expected_type.unwrap_or_else(fallback);
|
||||||
|
|
||||||
let expected_type = fcx.normalize(body.value.span, expected_type);
|
let expected_type = fcx.normalize(body.value.span, expected_type);
|
||||||
@ -296,6 +247,59 @@ fn typeck_with_fallback<'tcx>(
|
|||||||
typeck_results
|
typeck_results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Option<Ty<'tcx>> {
|
||||||
|
let tcx = fcx.tcx;
|
||||||
|
let def_id = fcx.body_id;
|
||||||
|
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = node.ty() {
|
||||||
|
if let Some(item) = tcx.opt_associated_item(def_id.into())
|
||||||
|
&& let ty::AssocKind::Const = item.kind
|
||||||
|
&& let ty::ImplContainer = item.container
|
||||||
|
&& let Some(trait_item) = item.trait_item_def_id
|
||||||
|
{
|
||||||
|
let args =
|
||||||
|
tcx.impl_trait_ref(item.container_id(tcx)).unwrap().instantiate_identity().args;
|
||||||
|
Some(tcx.type_of(trait_item).instantiate(tcx, args))
|
||||||
|
} else {
|
||||||
|
Some(fcx.next_ty_var(TypeVariableOrigin {
|
||||||
|
kind: TypeVariableOriginKind::TypeInference,
|
||||||
|
span,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
} else if let Node::AnonConst(_) = node {
|
||||||
|
let id = tcx.local_def_id_to_hir_id(def_id);
|
||||||
|
match tcx.parent_hir_node(id) {
|
||||||
|
Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), span, .. })
|
||||||
|
if anon_const.hir_id == id =>
|
||||||
|
{
|
||||||
|
Some(fcx.next_ty_var(TypeVariableOrigin {
|
||||||
|
kind: TypeVariableOriginKind::TypeInference,
|
||||||
|
span,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), span, .. })
|
||||||
|
| Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), span, .. }) => {
|
||||||
|
asm.operands.iter().find_map(|(op, _op_sp)| match op {
|
||||||
|
hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => {
|
||||||
|
// Inline assembly constants must be integers.
|
||||||
|
Some(fcx.next_int_var())
|
||||||
|
}
|
||||||
|
hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == id => {
|
||||||
|
Some(fcx.next_ty_var(TypeVariableOrigin {
|
||||||
|
kind: TypeVariableOriginKind::MiscVariable,
|
||||||
|
span,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
expected_type
|
||||||
|
}
|
||||||
|
|
||||||
/// When `check_fn` is invoked on a coroutine (i.e., a body that
|
/// When `check_fn` is invoked on a coroutine (i.e., a body that
|
||||||
/// includes yield), it returns back some information about the yield
|
/// includes yield), it returns back some information about the yield
|
||||||
/// points.
|
/// points.
|
||||||
|
@ -2768,7 +2768,7 @@ fn parse_for_head(&mut self) -> PResult<'a, (P<Pat>, P<Expr>)> {
|
|||||||
};
|
};
|
||||||
return if self.token.kind == token::CloseDelim(Delimiter::Parenthesis) {
|
return if self.token.kind == token::CloseDelim(Delimiter::Parenthesis) {
|
||||||
// We know for sure we have seen `for ($SOMETHING in $EXPR)`, so we recover the
|
// We know for sure we have seen `for ($SOMETHING in $EXPR)`, so we recover the
|
||||||
// parser state and emit a targetted suggestion.
|
// parser state and emit a targeted suggestion.
|
||||||
let span = vec![start_span, self.token.span];
|
let span = vec![start_span, self.token.span];
|
||||||
let right = self.prev_token.span.between(self.look_ahead(1, |t| t.span));
|
let right = self.prev_token.span.between(self.look_ahead(1, |t| t.span));
|
||||||
self.bump(); // )
|
self.bump(); // )
|
||||||
|
@ -1112,8 +1112,36 @@ pub fn typeid_for_instance<'tcx>(
|
|||||||
mut instance: Instance<'tcx>,
|
mut instance: Instance<'tcx>,
|
||||||
options: TypeIdOptions,
|
options: TypeIdOptions,
|
||||||
) -> String {
|
) -> String {
|
||||||
if matches!(instance.def, ty::InstanceDef::Virtual(..)) {
|
if (matches!(instance.def, ty::InstanceDef::Virtual(..))
|
||||||
instance.args = strip_receiver_auto(tcx, instance.args)
|
&& Some(instance.def_id()) == tcx.lang_items().drop_in_place_fn())
|
||||||
|
|| matches!(instance.def, ty::InstanceDef::DropGlue(..))
|
||||||
|
{
|
||||||
|
// Adjust the type ids of DropGlues
|
||||||
|
//
|
||||||
|
// DropGlues may have indirect calls to one or more given types drop function. Rust allows
|
||||||
|
// for types to be erased to any trait object and retains the drop function for the original
|
||||||
|
// type, which means at the indirect call sites in DropGlues, when typeid_for_fnabi is
|
||||||
|
// called a second time, it only has information after type erasure and it could be a call
|
||||||
|
// on any arbitrary trait object. Normalize them to a synthesized Drop trait object, both on
|
||||||
|
// declaration/definition, and during code generation at call sites so they have the same
|
||||||
|
// type id and match.
|
||||||
|
//
|
||||||
|
// FIXME(rcvalle): This allows a drop call on any trait object to call the drop function of
|
||||||
|
// any other type.
|
||||||
|
//
|
||||||
|
let def_id = tcx
|
||||||
|
.lang_items()
|
||||||
|
.drop_trait()
|
||||||
|
.unwrap_or_else(|| bug!("typeid_for_instance: couldn't get drop_trait lang item"));
|
||||||
|
let predicate = ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef {
|
||||||
|
def_id: def_id,
|
||||||
|
args: List::empty(),
|
||||||
|
});
|
||||||
|
let predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(predicate)]);
|
||||||
|
let self_ty = Ty::new_dynamic(tcx, predicates, tcx.lifetimes.re_erased, ty::Dyn);
|
||||||
|
instance.args = tcx.mk_args_trait(self_ty, List::empty());
|
||||||
|
} else if matches!(instance.def, ty::InstanceDef::Virtual(..)) {
|
||||||
|
instance.args = strip_receiver_auto(tcx, instance.args);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(impl_id) = tcx.impl_of_method(instance.def_id())
|
if let Some(impl_id) = tcx.impl_of_method(instance.def_id())
|
||||||
|
@ -20,7 +20,15 @@
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// Types implementing this trait must be primitves that are valid when zeroed.
|
/// Types implementing this trait must be primitives that are valid when zeroed.
|
||||||
|
///
|
||||||
|
/// The associated `Self::NonZeroInner` type must have the same size+align as `Self`,
|
||||||
|
/// but with a niche and bit validity making it so the following `transmutes` are sound:
|
||||||
|
///
|
||||||
|
/// - `Self::NonZeroInner` to `Option<Self::NonZeroInner>`
|
||||||
|
/// - `Option<Self::NonZeroInner>` to `Self`
|
||||||
|
///
|
||||||
|
/// (And, consequently, `Self::NonZeroInner` to `Self`.)
|
||||||
#[unstable(
|
#[unstable(
|
||||||
feature = "nonzero_internals",
|
feature = "nonzero_internals",
|
||||||
reason = "implementation detail which may disappear or be replaced at any time",
|
reason = "implementation detail which may disappear or be replaced at any time",
|
||||||
@ -434,17 +442,11 @@ pub const fn get(self) -> T {
|
|||||||
// of some not-inlined function, LLVM don't have range metadata
|
// of some not-inlined function, LLVM don't have range metadata
|
||||||
// to understand that the value cannot be zero.
|
// to understand that the value cannot be zero.
|
||||||
//
|
//
|
||||||
// SAFETY: `Self` is guaranteed to have the same layout as `Option<Self>`.
|
// For now, using the transmute `assume`s the range at runtime.
|
||||||
match unsafe { intrinsics::transmute_unchecked(self) } {
|
//
|
||||||
None => {
|
// SAFETY: `ZeroablePrimitive` guarantees that the size and bit validity
|
||||||
// SAFETY: `NonZero` is guaranteed to only contain non-zero values, so this is unreachable.
|
// of `.0` is such that this transmute is sound.
|
||||||
unsafe { intrinsics::unreachable() }
|
unsafe { intrinsics::transmute_unchecked(self) }
|
||||||
}
|
|
||||||
Some(Self(inner)) => {
|
|
||||||
// SAFETY: `T::NonZeroInner` is guaranteed to have the same layout as `T`.
|
|
||||||
unsafe { intrinsics::transmute_unchecked(inner) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,7 +806,7 @@
|
|||||||
//!
|
//!
|
||||||
//! As a consequence, the struct *must not* be [`#[repr(packed)]`][packed].
|
//! As a consequence, the struct *must not* be [`#[repr(packed)]`][packed].
|
||||||
//!
|
//!
|
||||||
//! 3. *Structural Notice of Destruction.* You must uphold the the
|
//! 3. *Structural Notice of Destruction.* You must uphold the
|
||||||
//! [`Drop` guarantee][drop-guarantee]: once your struct is pinned, the struct's storage cannot
|
//! [`Drop` guarantee][drop-guarantee]: once your struct is pinned, the struct's storage cannot
|
||||||
//! be re-used without calling the structurally-pinned fields' destructors, as well.
|
//! be re-used without calling the structurally-pinned fields' destructors, as well.
|
||||||
//!
|
//!
|
||||||
|
@ -243,7 +243,7 @@
|
|||||||
|
|
||||||
/// A boolean type which can be safely shared between threads.
|
/// A boolean type which can be safely shared between threads.
|
||||||
///
|
///
|
||||||
/// This type has the same in-memory representation as a [`bool`].
|
/// This type has the same size, alignment, and bit validity as a [`bool`].
|
||||||
///
|
///
|
||||||
/// **Note**: This type is only available on platforms that support atomic
|
/// **Note**: This type is only available on platforms that support atomic
|
||||||
/// loads and stores of `u8`.
|
/// loads and stores of `u8`.
|
||||||
@ -272,7 +272,7 @@ unsafe impl Sync for AtomicBool {}
|
|||||||
|
|
||||||
/// A raw pointer type which can be safely shared between threads.
|
/// A raw pointer type which can be safely shared between threads.
|
||||||
///
|
///
|
||||||
/// This type has the same in-memory representation as a `*mut T`.
|
/// This type has the same size and bit validity as a `*mut T`.
|
||||||
///
|
///
|
||||||
/// **Note**: This type is only available on platforms that support atomic
|
/// **Note**: This type is only available on platforms that support atomic
|
||||||
/// loads and stores of pointers. Its size depends on the target pointer's size.
|
/// loads and stores of pointers. Its size depends on the target pointer's size.
|
||||||
@ -2121,7 +2121,7 @@ macro_rules! atomic_int {
|
|||||||
$int_type:ident $atomic_type:ident) => {
|
$int_type:ident $atomic_type:ident) => {
|
||||||
/// An integer type which can be safely shared between threads.
|
/// An integer type which can be safely shared between threads.
|
||||||
///
|
///
|
||||||
/// This type has the same in-memory representation as the underlying
|
/// This type has the same size and bit validity as the underlying
|
||||||
/// integer type, [`
|
/// integer type, [`
|
||||||
#[doc = $s_int_type]
|
#[doc = $s_int_type]
|
||||||
/// `].
|
/// `].
|
||||||
|
@ -385,7 +385,7 @@ pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {
|
|||||||
/// See the [`OpenOptions::open`] function for more details.
|
/// See the [`OpenOptions::open`] function for more details.
|
||||||
///
|
///
|
||||||
/// See also [`std::fs::write()`][self::write] for a simple function to
|
/// See also [`std::fs::write()`][self::write] for a simple function to
|
||||||
/// create a file with a given data.
|
/// create a file with some given data.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -1036,7 +1036,7 @@ pub fn truncate(&mut self, truncate: bool) -> &mut Self {
|
|||||||
/// [`OpenOptions::append`] access must be used.
|
/// [`OpenOptions::append`] access must be used.
|
||||||
///
|
///
|
||||||
/// See also [`std::fs::write()`][self::write] for a simple function to
|
/// See also [`std::fs::write()`][self::write] for a simple function to
|
||||||
/// create a file with a given data.
|
/// create a file with some given data.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
// Verifies that type metadata identifiers for drop functions are emitted correctly.
|
||||||
|
//
|
||||||
|
//@ needs-sanitizer-cfi
|
||||||
|
//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
|
||||||
|
|
||||||
|
#![crate_type="lib"]
|
||||||
|
|
||||||
|
// CHECK-LABEL: define{{.*}}4core3ptr47drop_in_place$LT$dyn$u20$core..marker..Send$GT$
|
||||||
|
// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||||
|
// CHECK: call i1 @llvm.type.test(ptr {{%.+}}, metadata !"_ZTSFvPu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops4drop4Dropu6regionEE")
|
||||||
|
|
||||||
|
struct EmptyDrop;
|
||||||
|
// CHECK: define{{.*}}4core3ptr{{[0-9]+}}drop_in_place$LT${{.*}}EmptyDrop$GT${{.*}}!type ![[TYPE1]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||||
|
|
||||||
|
struct NonEmptyDrop;
|
||||||
|
|
||||||
|
impl Drop for NonEmptyDrop {
|
||||||
|
fn drop(&mut self) {}
|
||||||
|
// CHECK: define{{.*}}4core3ptr{{[0-9]+}}drop_in_place$LT${{.*}}NonEmptyDrop$GT${{.*}}!type ![[TYPE1]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn foo() {
|
||||||
|
let _ = Box::new(EmptyDrop) as Box<dyn Send>;
|
||||||
|
let _ = Box::new(NonEmptyDrop) as Box<dyn Send>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops4drop4Dropu6regionEE"}
|
@ -29,6 +29,8 @@ impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b
|
|||||||
trait Freeze { }
|
trait Freeze { }
|
||||||
#[lang="drop_in_place"]
|
#[lang="drop_in_place"]
|
||||||
fn drop_in_place_fn<T>() { }
|
fn drop_in_place_fn<T>() { }
|
||||||
|
#[lang="drop"]
|
||||||
|
trait Drop { fn drop(&mut self); }
|
||||||
|
|
||||||
pub trait Trait1 {
|
pub trait Trait1 {
|
||||||
fn foo(&self);
|
fn foo(&self);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Check that the targetted element has the expected styles.
|
// Check that the targeted element has the expected styles.
|
||||||
go-to: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html#method.a_method"
|
go-to: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html#method.a_method"
|
||||||
show-text: true
|
show-text: true
|
||||||
|
|
||||||
|
28
tests/ui/consts/missing_assoc_const_type.rs
Normal file
28
tests/ui/consts/missing_assoc_const_type.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//! Test that we compute the right type for associated constants
|
||||||
|
//! of impls, even if the type is missing. We know it from the trait
|
||||||
|
//! declaration after all.
|
||||||
|
|
||||||
|
trait Range {
|
||||||
|
const FIRST: u8;
|
||||||
|
const LAST: u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TwoDigits;
|
||||||
|
impl Range for TwoDigits {
|
||||||
|
const FIRST: = 10;
|
||||||
|
//~^ ERROR: missing type for `const` item
|
||||||
|
const LAST: u8 = 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn digits(x: u8) -> usize {
|
||||||
|
match x {
|
||||||
|
TwoDigits::FIRST..=TwoDigits::LAST => 0,
|
||||||
|
0..=9 | 100..=255 => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const FOOMP: [(); {
|
||||||
|
digits(42)
|
||||||
|
}] = [];
|
||||||
|
|
||||||
|
fn main() {}
|
8
tests/ui/consts/missing_assoc_const_type.stderr
Normal file
8
tests/ui/consts/missing_assoc_const_type.stderr
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
error: missing type for `const` item
|
||||||
|
--> $DIR/missing_assoc_const_type.rs:12:17
|
||||||
|
|
|
||||||
|
LL | const FIRST: = 10;
|
||||||
|
| ^ help: provide a type for the associated constant: `u8`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
21
tests/ui/consts/missing_assoc_const_type2.rs
Normal file
21
tests/ui/consts/missing_assoc_const_type2.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//! Test that we compute the right type for associated constants
|
||||||
|
//! of impls, even if the type is missing. We know it from the trait
|
||||||
|
//! declaration after all.
|
||||||
|
|
||||||
|
trait Range {
|
||||||
|
const FIRST: u8;
|
||||||
|
const LAST: u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TwoDigits;
|
||||||
|
impl Range for TwoDigits {
|
||||||
|
const FIRST: = 10;
|
||||||
|
//~^ ERROR: missing type
|
||||||
|
const LAST: u8 = 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FOOMP: [(); {
|
||||||
|
TwoDigits::FIRST as usize
|
||||||
|
}] = [(); 10];
|
||||||
|
|
||||||
|
fn main() {}
|
8
tests/ui/consts/missing_assoc_const_type2.stderr
Normal file
8
tests/ui/consts/missing_assoc_const_type2.stderr
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
error: missing type for `const` item
|
||||||
|
--> $DIR/missing_assoc_const_type2.rs:12:17
|
||||||
|
|
|
||||||
|
LL | const FIRST: = 10;
|
||||||
|
| ^ help: provide a type for the associated constant: `u8`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
#![feature(fn_delegation)]
|
#![feature(fn_delegation)]
|
||||||
//~^ WARN the feature `fn_delegation` is incomplete
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
trait Trait {
|
trait Trait {
|
||||||
const C: u32 = 0;
|
const C: u32 = 0;
|
||||||
@ -34,14 +34,6 @@ impl Trait for S {
|
|||||||
|
|
||||||
reuse foo { &self.0 }
|
reuse foo { &self.0 }
|
||||||
//~^ ERROR cannot find function `foo` in this scope
|
//~^ ERROR cannot find function `foo` in this scope
|
||||||
reuse F::foo { &self.0 }
|
|
||||||
//~^ ERROR cannot find function `foo` in `F`
|
|
||||||
//~| ERROR duplicate definitions with name `foo`
|
|
||||||
}
|
|
||||||
|
|
||||||
impl S {
|
|
||||||
reuse F::foo { &self.0 }
|
|
||||||
//~^ ERROR cannot find function `foo` in `F`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -25,18 +25,6 @@ LL | reuse <F as Trait>::baz;
|
|||||||
| | help: there is an associated function with a similar name: `bar`
|
| | help: there is an associated function with a similar name: `bar`
|
||||||
| not a member of trait `Trait`
|
| not a member of trait `Trait`
|
||||||
|
|
||||||
error[E0201]: duplicate definitions with name `foo`:
|
|
||||||
--> $DIR/bad-resolve.rs:37:5
|
|
||||||
|
|
|
||||||
LL | fn foo(&self, x: i32) -> i32 { x }
|
|
||||||
| ---------------------------------- item in trait
|
|
||||||
...
|
|
||||||
LL | reuse foo { &self.0 }
|
|
||||||
| --------------------- previous definition here
|
|
||||||
LL |
|
|
||||||
LL | reuse F::foo { &self.0 }
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definition
|
|
||||||
|
|
||||||
error[E0423]: expected function, found associated constant `Trait::C`
|
error[E0423]: expected function, found associated constant `Trait::C`
|
||||||
--> $DIR/bad-resolve.rs:24:11
|
--> $DIR/bad-resolve.rs:24:11
|
||||||
|
|
|
|
||||||
@ -66,27 +54,6 @@ error[E0425]: cannot find function `foo` in this scope
|
|||||||
LL | reuse foo { &self.0 }
|
LL | reuse foo { &self.0 }
|
||||||
| ^^^ not found in this scope
|
| ^^^ not found in this scope
|
||||||
|
|
||||||
error[E0425]: cannot find function `foo` in `F`
|
|
||||||
--> $DIR/bad-resolve.rs:37:14
|
|
||||||
|
|
|
||||||
LL | reuse F::foo { &self.0 }
|
|
||||||
| ^^^ not found in `F`
|
|
||||||
|
|
||||||
error[E0425]: cannot find function `foo` in `F`
|
|
||||||
--> $DIR/bad-resolve.rs:43:14
|
|
||||||
|
|
|
||||||
LL | reuse F::foo { &self.0 }
|
|
||||||
| ^^^ not found in `F`
|
|
||||||
|
|
||||||
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/bad-resolve.rs:1:12
|
|
||||||
|
|
|
||||||
LL | #![feature(fn_delegation)]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0046]: not all trait items implemented, missing: `Type`
|
error[E0046]: not all trait items implemented, missing: `Type`
|
||||||
--> $DIR/bad-resolve.rs:22:1
|
--> $DIR/bad-resolve.rs:22:1
|
||||||
|
|
|
|
||||||
@ -96,7 +63,7 @@ LL | type Type;
|
|||||||
LL | impl Trait for S {
|
LL | impl Trait for S {
|
||||||
| ^^^^^^^^^^^^^^^^ missing `Type` in implementation
|
| ^^^^^^^^^^^^^^^^ missing `Type` in implementation
|
||||||
|
|
||||||
error: aborting due to 11 previous errors; 1 warning emitted
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0046, E0201, E0324, E0407, E0423, E0425, E0575, E0576.
|
Some errors have detailed explanations: E0046, E0324, E0407, E0423, E0425, E0575, E0576.
|
||||||
For more information about an error, try `rustc --explain E0046`.
|
For more information about an error, try `rustc --explain E0046`.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#![feature(fn_delegation)]
|
#![feature(fn_delegation)]
|
||||||
//~^ WARN the feature `fn_delegation` is incomplete
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
trait Trait {
|
trait Trait {
|
||||||
fn foo(&self) -> u32 { 0 }
|
fn foo(&self) -> u32 { 0 }
|
||||||
|
@ -9,15 +9,6 @@ LL | reuse to_reuse::foo { self }
|
|||||||
LL | reuse Trait::foo;
|
LL | reuse Trait::foo;
|
||||||
| ^^^^^^^^^^^^^^^^^ duplicate definition
|
| ^^^^^^^^^^^^^^^^^ duplicate definition
|
||||||
|
|
||||||
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/duplicate-definition-inside-trait-impl.rs:1:12
|
|
||||||
|
|
|
||||||
LL | #![feature(fn_delegation)]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0201`.
|
For more information about this error, try `rustc --explain E0201`.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//@ run-pass
|
//@ run-pass
|
||||||
|
|
||||||
#![feature(fn_delegation)]
|
#![feature(fn_delegation)]
|
||||||
//~^ WARN the feature `fn_delegation` is incomplete
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
trait ToReuse {
|
trait ToReuse {
|
||||||
fn foo(&self, x: i32) -> i32 { x }
|
fn foo(&self, x: i32) -> i32 { x }
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/explicit-paths-in-traits-pass.rs:3:12
|
|
||||||
|
|
|
||||||
LL | #![feature(fn_delegation)]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
warning: 1 warning emitted
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
//@ run-pass
|
//@ run-pass
|
||||||
|
|
||||||
#![feature(fn_delegation)]
|
#![feature(fn_delegation)]
|
||||||
//~^ WARN the feature `fn_delegation` is incomplete
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
trait Trait {
|
trait Trait {
|
||||||
fn bar(&self, x: i32) -> i32 { x }
|
fn bar(&self, x: i32) -> i32 { x }
|
||||||
@ -10,7 +10,6 @@ fn description(&self) -> &str {
|
|||||||
}
|
}
|
||||||
fn static_method(x: i32) -> i32 { x }
|
fn static_method(x: i32) -> i32 { x }
|
||||||
fn static_method2(x: i32, y: i32) -> i32 { x + y }
|
fn static_method2(x: i32, y: i32) -> i32 { x + y }
|
||||||
fn baz<'a>(&self, x: &'a i32) -> &'a i32 { x }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct F;
|
struct F;
|
||||||
@ -29,11 +28,9 @@ impl Trait for S {
|
|||||||
reuse Trait::description { &self.0 }
|
reuse Trait::description { &self.0 }
|
||||||
reuse <F as Trait>::static_method;
|
reuse <F as Trait>::static_method;
|
||||||
reuse <F as Trait>::static_method2 { S::static_method(self) }
|
reuse <F as Trait>::static_method2 { S::static_method(self) }
|
||||||
reuse Trait::baz { &self.0 }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl S {
|
impl S {
|
||||||
reuse Trait::baz { &self.0 }
|
|
||||||
reuse <F as Trait>::static_method { to_reuse::foo(self) }
|
reuse <F as Trait>::static_method { to_reuse::foo(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,16 +46,8 @@ fn main() {
|
|||||||
assert_eq!(42, <S as Trait>::static_method(42));
|
assert_eq!(42, <S as Trait>::static_method(42));
|
||||||
assert_eq!(21, S::static_method2(10, 10));
|
assert_eq!(21, S::static_method2(10, 10));
|
||||||
|
|
||||||
reuse <S as Trait>::static_method;
|
|
||||||
reuse <S as Trait>::static_method2 { static_method(self) }
|
|
||||||
#[inline]
|
#[inline]
|
||||||
reuse to_reuse::foo;
|
reuse to_reuse::foo;
|
||||||
assert_eq!(42, static_method(42));
|
|
||||||
assert_eq!(21, static_method2(10, 10));
|
|
||||||
assert_eq!(43, foo(42));
|
assert_eq!(43, foo(42));
|
||||||
assert_eq!(15, zero_args());
|
assert_eq!(15, zero_args());
|
||||||
|
|
||||||
let x: i32 = 15;
|
|
||||||
assert_eq!(&x, <S as Trait>::baz(&s, &x));
|
|
||||||
assert_eq!(&x, S::baz(&s, &x));
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/explicit-paths-pass.rs:3:12
|
|
||||||
|
|
|
||||||
LL | #![feature(fn_delegation)]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
warning: 1 warning emitted
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
//@ run-pass
|
//@ run-pass
|
||||||
|
|
||||||
#![feature(fn_delegation)]
|
#![feature(fn_delegation)]
|
||||||
//~^ WARN the feature `fn_delegation` is incomplete
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
mod to_reuse {
|
mod to_reuse {
|
||||||
use crate::S;
|
use crate::S;
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/explicit-paths-signature-pass.rs:3:12
|
|
||||||
|
|
|
||||||
LL | #![feature(fn_delegation)]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
warning: 1 warning emitted
|
|
||||||
|
|
@ -1,25 +1,84 @@
|
|||||||
#![feature(fn_delegation)]
|
#![feature(fn_delegation)]
|
||||||
//~^ WARN the feature `fn_delegation` is incomplete
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
trait Trait {
|
trait Trait {
|
||||||
fn bar(&self) -> i32 { 42 }
|
fn foo1(&self, x: i32) -> i32 { x }
|
||||||
|
fn foo2(x: i32) -> i32 { x }
|
||||||
}
|
}
|
||||||
|
|
||||||
struct F;
|
struct F;
|
||||||
impl Trait for F {}
|
impl Trait for F {}
|
||||||
|
|
||||||
struct S(F);
|
struct S(F);
|
||||||
|
|
||||||
impl Trait for S {
|
pub mod to_reuse {
|
||||||
reuse <F as Trait>::bar;
|
pub fn foo3() {}
|
||||||
//~^ ERROR mismatched types
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct S2(F);
|
impl F {
|
||||||
|
fn foo4(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
impl Trait for S2 {
|
mod fn_to_other {
|
||||||
reuse <S2 as Trait>::bar { &self.0 }
|
use super::*;
|
||||||
//~^ ERROR mismatched types
|
|
||||||
|
reuse Trait::foo1;
|
||||||
|
//~^ ERROR delegation to a trait method from a free function is not supported yet
|
||||||
|
reuse <S as Trait>::foo2;
|
||||||
|
//~^ ERROR delegation to a trait method from a free function is not supported yet
|
||||||
|
reuse to_reuse::foo3;
|
||||||
|
reuse S::foo4;
|
||||||
|
//~^ ERROR cannot find function `foo4` in `S`
|
||||||
|
}
|
||||||
|
|
||||||
|
mod inherent_impl_assoc_fn_to_other {
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
impl S {
|
||||||
|
reuse Trait::foo1 { &self.0 }
|
||||||
|
reuse <S as Trait>::foo2;
|
||||||
|
reuse to_reuse::foo3;
|
||||||
|
reuse F::foo4 { &self.0 }
|
||||||
|
//~^ ERROR cannot find function `foo4` in `F`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod trait_impl_assoc_fn_to_other {
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
impl Trait for S {
|
||||||
|
reuse Trait::foo1 { &self.0 }
|
||||||
|
reuse <F as Trait>::foo2;
|
||||||
|
reuse to_reuse::foo3;
|
||||||
|
//~^ ERROR method `foo3` is not a member of trait `Trait`
|
||||||
|
reuse F::foo4 { &self.0 }
|
||||||
|
//~^ ERROR method `foo4` is not a member of trait `Trait`
|
||||||
|
//~| ERROR cannot find function `foo4` in `F`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod trait_assoc_fn_to_other {
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
trait Trait2 : Trait {
|
||||||
|
reuse <F as Trait>::foo1 { self }
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
reuse <F as Trait>::foo2;
|
||||||
|
reuse to_reuse::foo3;
|
||||||
|
reuse F::foo4 { &F }
|
||||||
|
//~^ ERROR cannot find function `foo4` in `F`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod type_mismatch {
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
struct S2;
|
||||||
|
impl Trait for S {
|
||||||
|
//~^ ERROR conflicting implementations of trait `Trait` for type `S`
|
||||||
|
reuse <S2 as Trait>::foo1;
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| ERROR the trait bound `S2: Trait` is not satisfied
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,38 +1,129 @@
|
|||||||
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
|
error[E0407]: method `foo3` is not a member of trait `Trait`
|
||||||
--> $DIR/explicit-paths.rs:1:12
|
--> $DIR/explicit-paths.rs:51:9
|
||||||
|
|
|
|
||||||
LL | #![feature(fn_delegation)]
|
LL | reuse to_reuse::foo3;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^----^
|
||||||
|
| | |
|
||||||
|
| | help: there is an associated function with a similar name: `foo1`
|
||||||
|
| not a member of trait `Trait`
|
||||||
|
|
||||||
|
error[E0407]: method `foo4` is not a member of trait `Trait`
|
||||||
|
--> $DIR/explicit-paths.rs:53:9
|
||||||
|
|
|
|
||||||
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
|
LL | reuse F::foo4 { &self.0 }
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
| ^^^^^^^^^----^^^^^^^^^^^^
|
||||||
|
| | |
|
||||||
|
| | help: there is an associated function with a similar name: `foo1`
|
||||||
|
| not a member of trait `Trait`
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `foo4` in `S`
|
||||||
|
--> $DIR/explicit-paths.rs:29:14
|
||||||
|
|
|
||||||
|
LL | reuse S::foo4;
|
||||||
|
| ^^^^ not found in `S`
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `foo4` in `F`
|
||||||
|
--> $DIR/explicit-paths.rs:40:18
|
||||||
|
|
|
||||||
|
LL | reuse F::foo4 { &self.0 }
|
||||||
|
| ^^^^ not found in `F`
|
||||||
|
|
|
||||||
|
note: function `fn_to_other::foo4` exists but is inaccessible
|
||||||
|
--> $DIR/explicit-paths.rs:29:5
|
||||||
|
|
|
||||||
|
LL | reuse S::foo4;
|
||||||
|
| ^^^^^^^^^^^^^^ not accessible
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `foo4` in `F`
|
||||||
|
--> $DIR/explicit-paths.rs:53:18
|
||||||
|
|
|
||||||
|
LL | reuse F::foo4 { &self.0 }
|
||||||
|
| ^^^^ not found in `F`
|
||||||
|
|
|
||||||
|
note: function `fn_to_other::foo4` exists but is inaccessible
|
||||||
|
--> $DIR/explicit-paths.rs:29:5
|
||||||
|
|
|
||||||
|
LL | reuse S::foo4;
|
||||||
|
| ^^^^^^^^^^^^^^ not accessible
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `foo4` in `F`
|
||||||
|
--> $DIR/explicit-paths.rs:67:18
|
||||||
|
|
|
||||||
|
LL | reuse F::foo4 { &F }
|
||||||
|
| ^^^^ not found in `F`
|
||||||
|
|
|
||||||
|
note: function `fn_to_other::foo4` exists but is inaccessible
|
||||||
|
--> $DIR/explicit-paths.rs:29:5
|
||||||
|
|
|
||||||
|
LL | reuse S::foo4;
|
||||||
|
| ^^^^^^^^^^^^^^ not accessible
|
||||||
|
|
||||||
|
error[E0119]: conflicting implementations of trait `Trait` for type `S`
|
||||||
|
--> $DIR/explicit-paths.rs:76:5
|
||||||
|
|
|
||||||
|
LL | impl Trait for S {
|
||||||
|
| ---------------- first implementation here
|
||||||
|
...
|
||||||
|
LL | impl Trait for S {
|
||||||
|
| ^^^^^^^^^^^^^^^^ conflicting implementation for `S`
|
||||||
|
|
||||||
|
error: delegation to a trait method from a free function is not supported yet
|
||||||
|
--> $DIR/explicit-paths.rs:24:18
|
||||||
|
|
|
||||||
|
LL | fn foo1(&self, x: i32) -> i32 { x }
|
||||||
|
| ----------------------------- callee defined here
|
||||||
|
...
|
||||||
|
LL | reuse Trait::foo1;
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error: delegation to a trait method from a free function is not supported yet
|
||||||
|
--> $DIR/explicit-paths.rs:26:25
|
||||||
|
|
|
||||||
|
LL | fn foo2(x: i32) -> i32 { x }
|
||||||
|
| ---------------------- callee defined here
|
||||||
|
...
|
||||||
|
LL | reuse <S as Trait>::foo2;
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/explicit-paths.rs:14:25
|
--> $DIR/explicit-paths.rs:63:36
|
||||||
|
|
|
|
||||||
LL | reuse <F as Trait>::bar;
|
LL | trait Trait2 : Trait {
|
||||||
| --------------^^^
|
| -------------------- found this type parameter
|
||||||
| | |
|
LL | reuse <F as Trait>::foo1 { self }
|
||||||
| | expected `&F`, found `&S`
|
| ^^^^ expected `&F`, found `&Self`
|
||||||
| arguments to this function are incorrect
|
|
||||||
|
|
|
|
||||||
= note: expected reference `&F`
|
= note: expected reference `&F`
|
||||||
|
found reference `&Self`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `S2: Trait` is not satisfied
|
||||||
|
--> $DIR/explicit-paths.rs:78:16
|
||||||
|
|
|
||||||
|
LL | reuse <S2 as Trait>::foo1;
|
||||||
|
| ^^ the trait `Trait` is not implemented for `S2`
|
||||||
|
|
|
||||||
|
= help: the following other types implement trait `Trait`:
|
||||||
|
F
|
||||||
|
S
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/explicit-paths.rs:78:30
|
||||||
|
|
|
||||||
|
LL | reuse <S2 as Trait>::foo1;
|
||||||
|
| ---------------^^^^
|
||||||
|
| | |
|
||||||
|
| | expected `&S2`, found `&S`
|
||||||
|
| arguments to this function are incorrect
|
||||||
|
|
|
||||||
|
= note: expected reference `&S2`
|
||||||
found reference `&S`
|
found reference `&S`
|
||||||
note: method defined here
|
note: method defined here
|
||||||
--> $DIR/explicit-paths.rs:5:8
|
--> $DIR/explicit-paths.rs:5:8
|
||||||
|
|
|
|
||||||
LL | fn bar(&self) -> i32 { 42 }
|
LL | fn foo1(&self, x: i32) -> i32 { x }
|
||||||
| ^^^ -----
|
| ^^^^ -----
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to 12 previous errors
|
||||||
--> $DIR/explicit-paths.rs:21:32
|
|
||||||
|
|
|
||||||
LL | reuse <S2 as Trait>::bar { &self.0 }
|
|
||||||
| ^^^^^^^ expected `&S2`, found `&F`
|
|
||||||
|
|
|
||||||
= note: expected reference `&S2`
|
|
||||||
found reference `&F`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors; 1 warning emitted
|
Some errors have detailed explanations: E0119, E0277, E0308, E0407, E0425.
|
||||||
|
For more information about an error, try `rustc --explain E0119`.
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#![feature(c_variadic)]
|
#![feature(c_variadic)]
|
||||||
#![feature(fn_delegation)]
|
#![feature(fn_delegation)]
|
||||||
//~^ WARN the feature `fn_delegation` is incomplete
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
mod generics {
|
mod generics {
|
||||||
trait GenericTrait<T> {
|
trait GenericTrait<T> {
|
||||||
|
@ -1,12 +1,3 @@
|
|||||||
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/not-supported.rs:2:12
|
|
||||||
|
|
|
||||||
LL | #![feature(fn_delegation)]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error: delegation with early bound generics is not supported yet
|
error: delegation with early bound generics is not supported yet
|
||||||
--> $DIR/not-supported.rs:16:29
|
--> $DIR/not-supported.rs:16:29
|
||||||
|
|
|
|
||||||
@ -178,7 +169,7 @@ LL | pub reuse to_reuse2::foo;
|
|||||||
LL | reuse to_reuse1::foo;
|
LL | reuse to_reuse1::foo;
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: aborting due to 19 previous errors; 1 warning emitted
|
error: aborting due to 19 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0049, E0195.
|
Some errors have detailed explanations: E0049, E0195.
|
||||||
For more information about an error, try `rustc --explain E0049`.
|
For more information about an error, try `rustc --explain E0049`.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#![feature(decl_macro)]
|
#![feature(decl_macro)]
|
||||||
#![feature(fn_delegation)]
|
#![feature(fn_delegation)]
|
||||||
//~^ WARN the feature `fn_delegation` is incomplete
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
macro_rules! reuse { {} => {} }
|
macro_rules! reuse { {} => {} }
|
||||||
|
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/parse.rs:4:12
|
|
||||||
|
|
|
||||||
LL | #![feature(fn_delegation)]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
warning: 1 warning emitted
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
//@ run-pass
|
//@ run-pass
|
||||||
|
|
||||||
#![feature(fn_delegation)]
|
#![feature(fn_delegation)]
|
||||||
//~^ WARN the feature `fn_delegation` is incomplete
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
mod to_reuse {
|
mod to_reuse {
|
||||||
pub fn foo(x: i32) -> i32 { x }
|
pub fn foo(x: i32) -> i32 { x }
|
||||||
|
@ -1,12 +1,3 @@
|
|||||||
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/target-expr-pass.rs:3:12
|
|
||||||
|
|
|
||||||
LL | #![feature(fn_delegation)]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
warning: trait `Trait` is never used
|
warning: trait `Trait` is never used
|
||||||
--> $DIR/target-expr-pass.rs:17:7
|
--> $DIR/target-expr-pass.rs:17:7
|
||||||
|
|
|
|
||||||
@ -27,5 +18,5 @@ warning: struct `S` is never constructed
|
|||||||
LL | struct S(F);
|
LL | struct S(F);
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
warning: 4 warnings emitted
|
warning: 3 warnings emitted
|
||||||
|
|
||||||
|
@ -14,8 +14,9 @@ fn foo(x: i32) -> i32 { x }
|
|||||||
|
|
||||||
fn bar<T: Default>(_: T) {
|
fn bar<T: Default>(_: T) {
|
||||||
reuse Trait::static_method {
|
reuse Trait::static_method {
|
||||||
//~^ ERROR delegation with early bound generics is not supported yet
|
//~^ ERROR delegation to a trait method from a free function is not supported yet
|
||||||
//~| ERROR mismatched types
|
//~| ERROR delegation with early bound generics is not supported yet
|
||||||
|
//~| ERROR mismatched types
|
||||||
let _ = T::Default();
|
let _ = T::Default();
|
||||||
//~^ ERROR can't use generic parameters from outer item
|
//~^ ERROR can't use generic parameters from outer item
|
||||||
}
|
}
|
||||||
@ -24,6 +25,7 @@ fn bar<T: Default>(_: T) {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let y = 0;
|
let y = 0;
|
||||||
reuse <S as Trait>::static_method {
|
reuse <S as Trait>::static_method {
|
||||||
|
//~^ ERROR delegation to a trait method from a free function is not supported yet
|
||||||
let x = y;
|
let x = y;
|
||||||
//~^ ERROR can't capture dynamic environment in a fn item
|
//~^ ERROR can't capture dynamic environment in a fn item
|
||||||
foo(self);
|
foo(self);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0401]: can't use generic parameters from outer item
|
error[E0401]: can't use generic parameters from outer item
|
||||||
--> $DIR/target-expr.rs:19:17
|
--> $DIR/target-expr.rs:20:17
|
||||||
|
|
|
|
||||||
LL | fn bar<T: Default>(_: T) {
|
LL | fn bar<T: Default>(_: T) {
|
||||||
| - type parameter from outer item
|
| - type parameter from outer item
|
||||||
@ -10,7 +10,7 @@ LL | let _ = T::Default();
|
|||||||
| ^^^^^^^^^^ use of generic parameter from outer item
|
| ^^^^^^^^^^ use of generic parameter from outer item
|
||||||
|
|
||||||
error[E0434]: can't capture dynamic environment in a fn item
|
error[E0434]: can't capture dynamic environment in a fn item
|
||||||
--> $DIR/target-expr.rs:27:17
|
--> $DIR/target-expr.rs:29:17
|
||||||
|
|
|
|
||||||
LL | let x = y;
|
LL | let x = y;
|
||||||
| ^
|
| ^
|
||||||
@ -18,7 +18,7 @@ LL | let x = y;
|
|||||||
= help: use the `|| { ... }` closure form instead
|
= help: use the `|| { ... }` closure form instead
|
||||||
|
|
||||||
error[E0424]: expected value, found module `self`
|
error[E0424]: expected value, found module `self`
|
||||||
--> $DIR/target-expr.rs:34:5
|
--> $DIR/target-expr.rs:36:5
|
||||||
|
|
|
|
||||||
LL | fn main() {
|
LL | fn main() {
|
||||||
| ---- this function can't have a `self` parameter
|
| ---- this function can't have a `self` parameter
|
||||||
@ -27,13 +27,13 @@ LL | self.0;
|
|||||||
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
|
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
|
||||||
|
|
||||||
error[E0425]: cannot find value `x` in this scope
|
error[E0425]: cannot find value `x` in this scope
|
||||||
--> $DIR/target-expr.rs:36:13
|
--> $DIR/target-expr.rs:38:13
|
||||||
|
|
|
|
||||||
LL | let z = x;
|
LL | let z = x;
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
help: the binding `x` is available in a different scope in the same function
|
help: the binding `x` is available in a different scope in the same function
|
||||||
--> $DIR/target-expr.rs:27:13
|
--> $DIR/target-expr.rs:29:13
|
||||||
|
|
|
|
||||||
LL | let x = y;
|
LL | let x = y;
|
||||||
| ^
|
| ^
|
||||||
@ -47,6 +47,24 @@ LL | fn static_method(x: i32) -> i32 { x }
|
|||||||
LL | reuse Trait::static_method {
|
LL | reuse Trait::static_method {
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: delegation to a trait method from a free function is not supported yet
|
||||||
|
--> $DIR/target-expr.rs:16:18
|
||||||
|
|
|
||||||
|
LL | fn static_method(x: i32) -> i32 { x }
|
||||||
|
| ------------------------------- callee defined here
|
||||||
|
...
|
||||||
|
LL | reuse Trait::static_method {
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: delegation to a trait method from a free function is not supported yet
|
||||||
|
--> $DIR/target-expr.rs:27:25
|
||||||
|
|
|
||||||
|
LL | fn static_method(x: i32) -> i32 { x }
|
||||||
|
| ------------------------------- callee defined here
|
||||||
|
...
|
||||||
|
LL | reuse <S as Trait>::static_method {
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/target-expr.rs:16:32
|
--> $DIR/target-expr.rs:16:32
|
||||||
|
|
|
|
||||||
@ -54,12 +72,13 @@ LL | reuse Trait::static_method {
|
|||||||
| ________________________________^
|
| ________________________________^
|
||||||
LL | |
|
LL | |
|
||||||
LL | |
|
LL | |
|
||||||
|
LL | |
|
||||||
LL | | let _ = T::Default();
|
LL | | let _ = T::Default();
|
||||||
LL | |
|
LL | |
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_____^ expected `i32`, found `()`
|
| |_____^ expected `i32`, found `()`
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0308, E0401, E0424, E0425, E0434.
|
Some errors have detailed explanations: E0308, E0401, E0424, E0425, E0434.
|
||||||
For more information about an error, try `rustc --explain E0308`.
|
For more information about an error, try `rustc --explain E0308`.
|
||||||
|
20
tests/ui/sanitizer/cfi-drop-in-place.rs
Normal file
20
tests/ui/sanitizer/cfi-drop-in-place.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Verifies that drops can be called on arbitrary trait objects.
|
||||||
|
//
|
||||||
|
// FIXME(#122848): Remove only-linux when fixed.
|
||||||
|
//@ only-linux
|
||||||
|
//@ needs-sanitizer-cfi
|
||||||
|
//@ compile-flags: -Clto -Copt-level=0 -Cprefer-dynamic=off -Ctarget-feature=-crt-static -Zsanitizer=cfi
|
||||||
|
//@ run-pass
|
||||||
|
|
||||||
|
struct EmptyDrop;
|
||||||
|
|
||||||
|
struct NonEmptyDrop;
|
||||||
|
|
||||||
|
impl Drop for NonEmptyDrop {
|
||||||
|
fn drop(&mut self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _ = Box::new(EmptyDrop) as Box<dyn Send>;
|
||||||
|
let _ = Box::new(NonEmptyDrop) as Box<dyn Send>;
|
||||||
|
}
|
@ -546,6 +546,15 @@ help: use type parameters instead
|
|||||||
LL | fn fn_test10<T>(&self, _x : T) { }
|
LL | fn fn_test10<T>(&self, _x : T) { }
|
||||||
| +++ ~
|
| +++ ~
|
||||||
|
|
||||||
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
|
||||||
|
--> $DIR/typeck_type_placeholder_item.rs:194:14
|
||||||
|
|
|
||||||
|
LL | const D: _ = 42;
|
||||||
|
| ^
|
||||||
|
| |
|
||||||
|
| not allowed in type signatures
|
||||||
|
| help: replace with the correct type: `i32`
|
||||||
|
|
||||||
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
|
||||||
--> $DIR/typeck_type_placeholder_item.rs:217:31
|
--> $DIR/typeck_type_placeholder_item.rs:217:31
|
||||||
|
|
|
|
||||||
@ -574,19 +583,7 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
|
|||||||
--> $DIR/typeck_type_placeholder_item.rs:209:14
|
--> $DIR/typeck_type_placeholder_item.rs:209:14
|
||||||
|
|
|
|
||||||
LL | const D: _ = 42;
|
LL | const D: _ = 42;
|
||||||
| ^
|
| ^ not allowed in type signatures
|
||||||
| |
|
|
||||||
| not allowed in type signatures
|
|
||||||
| help: replace with the correct type: `i32`
|
|
||||||
|
|
||||||
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
|
|
||||||
--> $DIR/typeck_type_placeholder_item.rs:194:14
|
|
||||||
|
|
|
||||||
LL | const D: _ = 42;
|
|
||||||
| ^
|
|
||||||
| |
|
|
||||||
| not allowed in type signatures
|
|
||||||
| help: replace with the correct type: `i32`
|
|
||||||
|
|
||||||
error[E0046]: not all trait items implemented, missing: `F`
|
error[E0046]: not all trait items implemented, missing: `F`
|
||||||
--> $DIR/typeck_type_placeholder_item.rs:200:1
|
--> $DIR/typeck_type_placeholder_item.rs:200:1
|
||||||
|
@ -717,6 +717,9 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
|
|||||||
[mentions."src/doc/unstable-book/src/compiler-flags/check-cfg.md"]
|
[mentions."src/doc/unstable-book/src/compiler-flags/check-cfg.md"]
|
||||||
cc = ["@Urgau"]
|
cc = ["@Urgau"]
|
||||||
|
|
||||||
|
[mentions."src/doc/rustc/src/platform-support"]
|
||||||
|
cc = ["@Nilstrieb"]
|
||||||
|
|
||||||
[mentions."tests/codegen/sanitizer"]
|
[mentions."tests/codegen/sanitizer"]
|
||||||
cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
|
cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user