mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-16 04:55:22 +03:00
Auto merge of #156613 - JonathanBrouwer:rollup-cKseJsM, r=<try>
Rollup of 12 pull requests try-job: dist-various-1 try-job: test-various try-job: x86_64-gnu-aux try-job: x86_64-gnu-llvm-21-3 try-job: x86_64-msvc-1 try-job: aarch64-apple try-job: x86_64-mingw-1 try-job: i686-msvc-2
This commit is contained in:
@@ -3867,6 +3867,19 @@ pub struct Fn {
|
||||
pub eii_impls: ThinVec<EiiImpl>,
|
||||
}
|
||||
|
||||
impl Fn {
|
||||
pub fn is_pin_drop_sugar(&self) -> bool {
|
||||
self.ident.name == sym::drop
|
||||
&& self
|
||||
.sig
|
||||
.decl
|
||||
.inputs
|
||||
.first()
|
||||
.and_then(|param| param.to_self())
|
||||
.is_some_and(|eself| matches!(eself.node, SelfKind::Pinned(None, Mutability::Mut)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
|
||||
pub struct EiiImpl {
|
||||
pub node_id: NodeId,
|
||||
|
||||
@@ -1192,6 +1192,52 @@ fn lower_trait_impl_header(
|
||||
})
|
||||
}
|
||||
|
||||
fn resolve_pin_drop_sugar_impl_item(
|
||||
&self,
|
||||
i: &AssocItem,
|
||||
ident: Ident,
|
||||
span: Span,
|
||||
) -> (Ident, Result<DefId, ErrorGuaranteed>) {
|
||||
let trait_item_def_id = self
|
||||
.get_partial_res(i.id)
|
||||
.and_then(|r| r.expect_full_res().opt_def_id())
|
||||
.ok_or_else(|| {
|
||||
self.dcx().span_delayed_bug(span, "could not resolve trait item being implemented")
|
||||
});
|
||||
|
||||
let is_pin_drop_sugar = match &i.kind {
|
||||
AssocItemKind::Fn(fn_kind) => fn_kind.is_pin_drop_sugar(),
|
||||
_ => false,
|
||||
};
|
||||
let def_id = match trait_item_def_id {
|
||||
Ok(def_id) => def_id,
|
||||
Err(guar) => return (ident, Err(guar)),
|
||||
};
|
||||
if !is_pin_drop_sugar {
|
||||
return (ident, Ok(def_id));
|
||||
}
|
||||
|
||||
let is_drop_pin_drop = self
|
||||
.tcx
|
||||
.lang_items()
|
||||
.drop_trait()
|
||||
.is_some_and(|drop_trait| self.tcx.parent(def_id) == drop_trait);
|
||||
if is_drop_pin_drop {
|
||||
// Associated item collection still derives the impl item's name from HIR.
|
||||
return (Ident::new(sym::pin_drop, ident.span), Ok(def_id));
|
||||
}
|
||||
|
||||
let guar = self
|
||||
.dcx()
|
||||
.struct_span_err(
|
||||
i.span,
|
||||
"method `drop` with `&pin mut self` is only supported for the `Drop` trait",
|
||||
)
|
||||
.with_span_label(i.span, "not a `Drop::pin_drop` implementation")
|
||||
.emit();
|
||||
(ident, Err(guar))
|
||||
}
|
||||
|
||||
fn lower_impl_item(
|
||||
&mut self,
|
||||
i: &AssocItem,
|
||||
@@ -1309,26 +1355,19 @@ fn lower_impl_item(
|
||||
};
|
||||
|
||||
let span = self.lower_span(i.span);
|
||||
let (effective_ident, impl_kind) = if is_in_trait_impl {
|
||||
let (effective_ident, trait_item_def_id) =
|
||||
self.resolve_pin_drop_sugar_impl_item(i, ident, span);
|
||||
(effective_ident, ImplItemImplKind::Trait { defaultness, trait_item_def_id })
|
||||
} else {
|
||||
(ident, ImplItemImplKind::Inherent { vis_span: self.lower_span(i.vis.span) })
|
||||
};
|
||||
|
||||
let item = hir::ImplItem {
|
||||
owner_id: hir_id.expect_owner(),
|
||||
ident: self.lower_ident(ident),
|
||||
ident: self.lower_ident(effective_ident),
|
||||
generics,
|
||||
impl_kind: if is_in_trait_impl {
|
||||
ImplItemImplKind::Trait {
|
||||
defaultness,
|
||||
trait_item_def_id: self
|
||||
.get_partial_res(i.id)
|
||||
.and_then(|r| r.expect_full_res().opt_def_id())
|
||||
.ok_or_else(|| {
|
||||
self.dcx().span_delayed_bug(
|
||||
span,
|
||||
"could not resolve trait item being implemented",
|
||||
)
|
||||
}),
|
||||
}
|
||||
} else {
|
||||
ImplItemImplKind::Inherent { vis_span: self.lower_span(i.vis.span) }
|
||||
},
|
||||
impl_kind,
|
||||
kind,
|
||||
span,
|
||||
has_delayed_lints: !self.delayed_lints.is_empty(),
|
||||
|
||||
@@ -152,7 +152,20 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
|
||||
cx.size_and_align_of(Ty::new_mut_ptr(cx.tcx, pointee_type))
|
||||
);
|
||||
|
||||
let pointee_type_di_node = type_di_node(cx, pointee_type);
|
||||
let pointee_type_di_node = match pointee_type.kind() {
|
||||
// `&[T]` will look like `{ data_ptr: *const T, length: usize }`
|
||||
ty::Slice(element_type) => type_di_node(cx, *element_type),
|
||||
// `&str` will look like `{ data_ptr: *const u8, length: usize }`
|
||||
ty::Str => type_di_node(cx, cx.tcx.types.u8),
|
||||
|
||||
// `&dyn K` will look like `{ pointer: _, vtable: _}`
|
||||
// any Adt `Foo` containing an unsized type (eg `&[_]` or `&dyn _`)
|
||||
// will look like `{ data_ptr: *const Foo, length: usize }`
|
||||
// and thin pointers `&Foo` will just look like `*const Foo`.
|
||||
//
|
||||
// in all those cases, we just use the pointee_type
|
||||
_ => type_di_node(cx, pointee_type),
|
||||
};
|
||||
|
||||
return_if_di_node_created_in_meantime!(cx, unique_type_id);
|
||||
|
||||
@@ -389,26 +402,11 @@ fn build_dyn_type_di_node<'ll, 'tcx>(
|
||||
}
|
||||
|
||||
/// Create debuginfo for `[T]` and `str`. These are unsized.
|
||||
///
|
||||
/// NOTE: We currently emit just emit the debuginfo for the element type here
|
||||
/// (i.e. `T` for slices and `u8` for `str`), so that we end up with
|
||||
/// `*const T` for the `data_ptr` field of the corresponding wide-pointer
|
||||
/// debuginfo of `&[T]`.
|
||||
///
|
||||
/// It would be preferable and more accurate if we emitted a DIArray of T
|
||||
/// without an upper bound instead. That is, LLVM already supports emitting
|
||||
/// debuginfo of arrays of unknown size. But GDB currently seems to end up
|
||||
/// in an infinite loop when confronted with such a type.
|
||||
///
|
||||
/// As a side effect of the current encoding every instance of a type like
|
||||
/// `struct Foo { unsized_field: [u8] }` will look like
|
||||
/// `struct Foo { unsized_field: u8 }` in debuginfo. If the length of the
|
||||
/// slice is zero, then accessing `unsized_field` in the debugger would
|
||||
/// result in an out-of-bounds access.
|
||||
fn build_slice_type_di_node<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
slice_type: Ty<'tcx>,
|
||||
unique_type_id: UniqueTypeId<'tcx>,
|
||||
span: Span,
|
||||
) -> DINodeCreationResult<'ll> {
|
||||
let element_type = match slice_type.kind() {
|
||||
ty::Slice(element_type) => *element_type,
|
||||
@@ -423,7 +421,20 @@ fn build_slice_type_di_node<'ll, 'tcx>(
|
||||
|
||||
let element_type_di_node = type_di_node(cx, element_type);
|
||||
return_if_di_node_created_in_meantime!(cx, unique_type_id);
|
||||
DINodeCreationResult { di_node: element_type_di_node, already_stored_in_typemap: false }
|
||||
let (size, align) = cx.spanned_size_and_align_of(slice_type, span);
|
||||
let subrange = unsafe { llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0, -1) };
|
||||
let subscripts = &[subrange];
|
||||
let di_node = unsafe {
|
||||
llvm::LLVMDIBuilderCreateArrayType(
|
||||
DIB(cx),
|
||||
size.bits(),
|
||||
align.bits() as u32,
|
||||
element_type_di_node,
|
||||
subscripts.as_ptr(),
|
||||
subscripts.len() as c_uint,
|
||||
)
|
||||
};
|
||||
DINodeCreationResult { di_node, already_stored_in_typemap: false }
|
||||
}
|
||||
|
||||
/// Get the debuginfo node for the given type.
|
||||
@@ -454,7 +465,7 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>(
|
||||
}
|
||||
ty::Tuple(elements) if elements.is_empty() => build_basic_type_di_node(cx, t),
|
||||
ty::Array(..) => build_fixed_size_array_di_node(cx, unique_type_id, t, span),
|
||||
ty::Slice(_) | ty::Str => build_slice_type_di_node(cx, t, unique_type_id),
|
||||
ty::Slice(_) | ty::Str => build_slice_type_di_node(cx, t, unique_type_id, span),
|
||||
ty::Dynamic(..) => build_dyn_type_di_node(cx, t, unique_type_id),
|
||||
ty::Foreign(..) => build_foreign_type_di_node(cx, t, unique_type_id),
|
||||
ty::RawPtr(pointee_type, _) | ty::Ref(_, pointee_type, _) => {
|
||||
|
||||
@@ -66,7 +66,10 @@ fn llvm_arg_to_arg_name(full_arg: &str) -> &str {
|
||||
|
||||
let cg_opts = sess.opts.cg.llvm_args.iter().map(AsRef::as_ref);
|
||||
let tg_opts = sess.target.llvm_args.iter().map(AsRef::as_ref);
|
||||
let sess_args = cg_opts.chain(tg_opts);
|
||||
// Target-spec args are passed to LLVM before user `-Cllvm-args`. LLVM's
|
||||
// `cl::opt` parser is last-wins, so this lets `-Cllvm-args=...` override
|
||||
// a value already set in the target spec (e.g. `-wasm-use-legacy-eh`).
|
||||
let sess_args = tg_opts.chain(cg_opts);
|
||||
|
||||
let user_specified_args: FxHashSet<_> =
|
||||
sess_args.clone().map(|s| llvm_arg_to_arg_name(s)).filter(|s| !s.is_empty()).collect();
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
use rustc_span::{ErrorGuaranteed, Span, kw};
|
||||
|
||||
use crate::collect::ItemCtxt;
|
||||
use crate::errors::DelegationSelfTypeNotSpecified;
|
||||
use crate::hir_ty_lowering::HirTyLowerer;
|
||||
|
||||
type RemapTable = FxHashMap<u32, u32>;
|
||||
@@ -284,6 +285,12 @@ fn get_delegation_self_ty_or_err(tcx: TyCtxt<'_>, delegation_id: LocalDefId) ->
|
||||
ctx.lower_ty(tcx.hir_node(id).expect_ty())
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
// It is possible to attempt to get self type when it is used in signature
|
||||
// (i.e., `fn default() -> Self`), so emit error here in addition to possible
|
||||
// `mismatched types` error (see #156388).
|
||||
let err = DelegationSelfTypeNotSpecified { span: tcx.def_span(delegation_id) };
|
||||
tcx.dcx().emit_err(err);
|
||||
|
||||
Ty::new_error_with_message(
|
||||
tcx,
|
||||
tcx.def_span(delegation_id),
|
||||
|
||||
@@ -1670,6 +1670,14 @@ pub(crate) struct UnsupportedDelegation<'a> {
|
||||
pub callee_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("delegation self type is not specified")]
|
||||
#[help("consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`")]
|
||||
pub(crate) struct DelegationSelfTypeNotSpecified {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("method should be `async` or return a future, but it is synchronous")]
|
||||
pub(crate) struct MethodShouldReturnFuture {
|
||||
|
||||
@@ -207,6 +207,7 @@ fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
// We keep async drop unexpanded to poll-loop here, to expand it later, at StateTransform -
|
||||
// into states expand.
|
||||
// call_destructor_only - to call only AsyncDrop::drop, not full async_drop_in_place glue
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn build_async_drop(
|
||||
&mut self,
|
||||
place: Place<'tcx>,
|
||||
@@ -221,14 +222,8 @@ fn build_async_drop(
|
||||
let span = self.source_info.span;
|
||||
|
||||
let pin_obj_bb = bb.unwrap_or_else(|| {
|
||||
self.elaborator.patch().new_block(BasicBlockData::new(
|
||||
Some(Terminator {
|
||||
// Temporary terminator, will be replaced by patch
|
||||
source_info: self.source_info,
|
||||
kind: TerminatorKind::Return,
|
||||
}),
|
||||
false,
|
||||
))
|
||||
// Temporary terminator, will be replaced by patch
|
||||
self.new_block(unwind, TerminatorKind::Return)
|
||||
});
|
||||
|
||||
let (fut_ty, drop_fn_def_id, trait_args) = if call_destructor_only {
|
||||
@@ -565,6 +560,7 @@ fn move_paths_for_fields(
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn drop_subpath(
|
||||
&mut self,
|
||||
place: Place<'tcx>,
|
||||
@@ -574,8 +570,6 @@ fn drop_subpath(
|
||||
dropline: Option<BasicBlock>,
|
||||
) -> BasicBlock {
|
||||
if let Some(path) = path {
|
||||
debug!("drop_subpath: for std field {:?}", place);
|
||||
|
||||
DropCtxt {
|
||||
elaborator: self.elaborator,
|
||||
source_info: self.source_info,
|
||||
@@ -587,8 +581,6 @@ fn drop_subpath(
|
||||
}
|
||||
.elaborated_drop_block()
|
||||
} else {
|
||||
debug!("drop_subpath: for rest field {:?}", place);
|
||||
|
||||
DropCtxt {
|
||||
elaborator: self.elaborator,
|
||||
source_info: self.source_info,
|
||||
@@ -596,8 +588,7 @@ fn drop_subpath(
|
||||
succ,
|
||||
unwind,
|
||||
dropline,
|
||||
// Using `self.path` here to condition the drop on
|
||||
// our own drop flag.
|
||||
// Using `self.path` here to condition the drop on our own drop flag.
|
||||
path: self.path,
|
||||
}
|
||||
.complete_drop(succ, unwind)
|
||||
@@ -614,6 +605,7 @@ fn drop_subpath(
|
||||
/// `dropline_ladder` is a similar list of steps in reverse order,
|
||||
/// which is called if the matching step of the drop glue will contain async drop
|
||||
/// (expanded later to Yield) and the containing coroutine will be dropped at this point.
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn drop_halfladder(
|
||||
&mut self,
|
||||
unwind_ladder: &[Unwind],
|
||||
@@ -679,6 +671,7 @@ fn drop_ladder_bottom(&mut self) -> (BasicBlock, Unwind, Option<BasicBlock>) {
|
||||
///
|
||||
/// NOTE: this does not clear the master drop flag, so you need
|
||||
/// to point succ/unwind on a `drop_ladder_bottom`.
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn drop_ladder(
|
||||
&mut self,
|
||||
fields: Vec<(Place<'tcx>, Option<D::Path>)>,
|
||||
@@ -686,7 +679,6 @@ fn drop_ladder(
|
||||
unwind: Unwind,
|
||||
dropline: Option<BasicBlock>,
|
||||
) -> (BasicBlock, Unwind, Option<BasicBlock>) {
|
||||
debug!("drop_ladder({:?}, {:?})", self, fields);
|
||||
assert!(
|
||||
if unwind.is_cleanup() { dropline.is_none() } else { true },
|
||||
"Dropline is set for cleanup drop ladder"
|
||||
@@ -723,9 +715,8 @@ fn drop_ladder(
|
||||
)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn open_drop_for_tuple(&mut self, tys: &[Ty<'tcx>]) -> BasicBlock {
|
||||
debug!("open_drop_for_tuple({:?}, {:?})", self, tys);
|
||||
|
||||
let fields = tys
|
||||
.iter()
|
||||
.enumerate()
|
||||
@@ -769,18 +760,14 @@ fn open_drop_for_box_contents(
|
||||
|
||||
let do_drop_bb = self.drop_subpath(interior, interior_path, succ, unwind, dropline);
|
||||
|
||||
let setup_bbd = BasicBlockData::new_stmts(
|
||||
self.new_block_with_statements(
|
||||
unwind,
|
||||
vec![self.assign(
|
||||
Place::from(ptr_local),
|
||||
Rvalue::Cast(CastKind::Transmute, Operand::Copy(nonnull_place), ptr_ty),
|
||||
)],
|
||||
Some(Terminator {
|
||||
kind: TerminatorKind::Goto { target: do_drop_bb },
|
||||
source_info: self.source_info,
|
||||
}),
|
||||
unwind.is_cleanup(),
|
||||
);
|
||||
self.elaborator.patch().new_block(setup_bbd)
|
||||
TerminatorKind::Goto { target: do_drop_bb },
|
||||
)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", ret)]
|
||||
@@ -790,17 +777,11 @@ fn open_drop_for_adt(
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> BasicBlock {
|
||||
if adt.variants().is_empty() {
|
||||
return self.elaborator.patch().new_block(BasicBlockData::new(
|
||||
Some(Terminator {
|
||||
source_info: self.source_info,
|
||||
kind: TerminatorKind::Unreachable,
|
||||
}),
|
||||
self.unwind.is_cleanup(),
|
||||
));
|
||||
return self.new_block(self.unwind, TerminatorKind::Unreachable);
|
||||
}
|
||||
|
||||
let skip_contents = adt.is_union() || adt.is_manually_drop();
|
||||
let contents_drop = if skip_contents {
|
||||
let (contents_succ, contents_unwind, contents_dropline) = if skip_contents {
|
||||
if adt.has_dtor(self.tcx()) && self.elaborator.get_drop_flag(self.path).is_some() {
|
||||
// the top-level drop flag is usually cleared by open_drop_for_adt_contents
|
||||
// types with destructors would still need an empty drop ladder to clear it
|
||||
@@ -819,21 +800,19 @@ fn open_drop_for_adt(
|
||||
if adt.has_dtor(self.tcx()) {
|
||||
let destructor_block = if adt.is_box() {
|
||||
// we need to drop the inside of the box before running the destructor
|
||||
let succ = self.destructor_call_block_sync((contents_drop.0, contents_drop.1));
|
||||
let unwind = contents_drop
|
||||
.1
|
||||
.map(|unwind| self.destructor_call_block_sync((unwind, Unwind::InCleanup)));
|
||||
let dropline = contents_drop
|
||||
.2
|
||||
.map(|dropline| self.destructor_call_block_sync((dropline, contents_drop.1)));
|
||||
let succ = self.destructor_call_block_sync(contents_succ, contents_unwind);
|
||||
let unwind = contents_unwind
|
||||
.map(|unwind| self.destructor_call_block_sync(unwind, Unwind::InCleanup));
|
||||
let dropline = contents_dropline
|
||||
.map(|dropline| self.destructor_call_block_sync(dropline, contents_unwind));
|
||||
self.open_drop_for_box_contents(adt, args, succ, unwind, dropline)
|
||||
} else {
|
||||
self.destructor_call_block(contents_drop)
|
||||
self.destructor_call_block(contents_succ, contents_unwind, contents_dropline)
|
||||
};
|
||||
|
||||
self.drop_flag_test_block(destructor_block, contents_drop.0, contents_drop.1)
|
||||
self.drop_flag_test_block(destructor_block, contents_succ, contents_unwind)
|
||||
} else {
|
||||
contents_drop.0
|
||||
contents_succ
|
||||
}
|
||||
}
|
||||
|
||||
@@ -976,26 +955,22 @@ fn adt_switch_block(
|
||||
let discr_ty = adt.repr().discr_type().to_ty(self.tcx());
|
||||
let discr = Place::from(self.new_temp(discr_ty));
|
||||
let discr_rv = Rvalue::Discriminant(self.place);
|
||||
let switch_block = BasicBlockData::new_stmts(
|
||||
let switch_block = self.new_block_with_statements(
|
||||
unwind,
|
||||
vec![self.assign(discr, discr_rv)],
|
||||
Some(Terminator {
|
||||
source_info: self.source_info,
|
||||
kind: TerminatorKind::SwitchInt {
|
||||
discr: Operand::Move(discr),
|
||||
targets: SwitchTargets::new(
|
||||
values.iter().copied().zip(blocks.iter().copied()),
|
||||
*blocks.last().unwrap(),
|
||||
),
|
||||
},
|
||||
}),
|
||||
unwind.is_cleanup(),
|
||||
TerminatorKind::SwitchInt {
|
||||
discr: Operand::Move(discr),
|
||||
targets: SwitchTargets::new(
|
||||
values.iter().copied().zip(blocks.iter().copied()),
|
||||
*blocks.last().unwrap(),
|
||||
),
|
||||
},
|
||||
);
|
||||
let switch_block = self.elaborator.patch().new_block(switch_block);
|
||||
self.drop_flag_test_block(switch_block, succ, unwind)
|
||||
}
|
||||
|
||||
fn destructor_call_block_sync(&mut self, (succ, unwind): (BasicBlock, Unwind)) -> BasicBlock {
|
||||
debug!("destructor_call_block_sync({:?}, {:?})", self, succ);
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn destructor_call_block_sync(&mut self, succ: BasicBlock, unwind: Unwind) -> BasicBlock {
|
||||
let tcx = self.tcx();
|
||||
let drop_trait = tcx.require_lang_item(LangItem::Drop, DUMMY_SP);
|
||||
let drop_fn = tcx.associated_item_def_ids(drop_trait)[0];
|
||||
@@ -1005,7 +980,8 @@ fn destructor_call_block_sync(&mut self, (succ, unwind): (BasicBlock, Unwind)) -
|
||||
let ref_place = self.new_temp(ref_ty);
|
||||
let unit_temp = Place::from(self.new_temp(tcx.types.unit));
|
||||
|
||||
let result = BasicBlockData::new_stmts(
|
||||
self.new_block_with_statements(
|
||||
unwind,
|
||||
vec![self.assign(
|
||||
Place::from(ref_place),
|
||||
Rvalue::Ref(
|
||||
@@ -1014,40 +990,31 @@ fn destructor_call_block_sync(&mut self, (succ, unwind): (BasicBlock, Unwind)) -
|
||||
self.place,
|
||||
),
|
||||
)],
|
||||
Some(Terminator {
|
||||
kind: TerminatorKind::Call {
|
||||
func: Operand::function_handle(
|
||||
tcx,
|
||||
drop_fn,
|
||||
[ty.into()],
|
||||
self.source_info.span,
|
||||
),
|
||||
args: [Spanned { node: Operand::Move(Place::from(ref_place)), span: DUMMY_SP }]
|
||||
.into(),
|
||||
destination: unit_temp,
|
||||
target: Some(succ),
|
||||
unwind: unwind.into_action(),
|
||||
call_source: CallSource::Misc,
|
||||
fn_span: self.source_info.span,
|
||||
},
|
||||
source_info: self.source_info,
|
||||
}),
|
||||
unwind.is_cleanup(),
|
||||
);
|
||||
|
||||
self.elaborator.patch().new_block(result)
|
||||
TerminatorKind::Call {
|
||||
func: Operand::function_handle(tcx, drop_fn, [ty.into()], self.source_info.span),
|
||||
args: [Spanned { node: Operand::Move(Place::from(ref_place)), span: DUMMY_SP }]
|
||||
.into(),
|
||||
destination: unit_temp,
|
||||
target: Some(succ),
|
||||
unwind: unwind.into_action(),
|
||||
call_source: CallSource::Misc,
|
||||
fn_span: self.source_info.span,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn destructor_call_block(
|
||||
&mut self,
|
||||
(succ, unwind, dropline): (BasicBlock, Unwind, Option<BasicBlock>),
|
||||
succ: BasicBlock,
|
||||
unwind: Unwind,
|
||||
dropline: Option<BasicBlock>,
|
||||
) -> BasicBlock {
|
||||
debug!("destructor_call_block({:?}, {:?})", self, succ);
|
||||
let ty = self.place_ty(self.place);
|
||||
if !unwind.is_cleanup() && self.check_if_can_async_drop(ty, true) {
|
||||
self.build_async_drop(self.place, ty, None, succ, unwind, dropline, true)
|
||||
} else {
|
||||
self.destructor_call_block_sync((succ, unwind))
|
||||
self.destructor_call_block_sync(succ, unwind)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1080,7 +1047,8 @@ fn drop_loop(
|
||||
let can_go = Place::from(self.new_temp(tcx.types.bool));
|
||||
let one = self.constant_usize(1);
|
||||
|
||||
let drop_block = BasicBlockData::new_stmts(
|
||||
let drop_block = self.new_block_with_statements(
|
||||
unwind,
|
||||
vec![
|
||||
self.assign(
|
||||
ptr,
|
||||
@@ -1091,27 +1059,18 @@ fn drop_loop(
|
||||
Rvalue::BinaryOp(BinOp::Add, Box::new((move_(cur.into()), one))),
|
||||
),
|
||||
],
|
||||
Some(Terminator {
|
||||
source_info: self.source_info,
|
||||
// this gets overwritten by drop elaboration.
|
||||
kind: TerminatorKind::Unreachable,
|
||||
}),
|
||||
unwind.is_cleanup(),
|
||||
// this gets overwritten by drop elaboration.
|
||||
TerminatorKind::Unreachable,
|
||||
);
|
||||
let drop_block = self.elaborator.patch().new_block(drop_block);
|
||||
|
||||
let loop_block = BasicBlockData::new_stmts(
|
||||
let loop_block = self.new_block_with_statements(
|
||||
unwind,
|
||||
vec![self.assign(
|
||||
can_go,
|
||||
Rvalue::BinaryOp(BinOp::Eq, Box::new((copy(Place::from(cur)), copy(len.into())))),
|
||||
)],
|
||||
Some(Terminator {
|
||||
source_info: self.source_info,
|
||||
kind: TerminatorKind::if_(move_(can_go), succ, drop_block),
|
||||
}),
|
||||
unwind.is_cleanup(),
|
||||
TerminatorKind::if_(move_(can_go), succ, drop_block),
|
||||
);
|
||||
let loop_block = self.elaborator.patch().new_block(loop_block);
|
||||
|
||||
let place = tcx.mk_place_deref(ptr);
|
||||
if !unwind.is_cleanup() && self.check_if_can_async_drop(ety, false) {
|
||||
@@ -1140,13 +1099,13 @@ fn drop_loop(
|
||||
loop_block
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn open_drop_for_array(
|
||||
&mut self,
|
||||
array_ty: Ty<'tcx>,
|
||||
ety: Ty<'tcx>,
|
||||
opt_size: Option<u64>,
|
||||
) -> BasicBlock {
|
||||
debug!("open_drop_for_array({:?}, {:?}, {:?})", array_ty, ety, opt_size);
|
||||
let tcx = self.tcx();
|
||||
|
||||
if let Some(size) = opt_size {
|
||||
@@ -1215,7 +1174,15 @@ enum ProjectionKind<Path> {
|
||||
let slice_ptr_ty = Ty::new_mut_ptr(tcx, slice_ty);
|
||||
let slice_ptr = self.new_temp(slice_ptr_ty);
|
||||
|
||||
let mut delegate_block = BasicBlockData::new_stmts(
|
||||
let array_place = mem::replace(
|
||||
&mut self.place,
|
||||
Place::from(slice_ptr).project_deeper(&[PlaceElem::Deref], tcx),
|
||||
);
|
||||
let slice_block = self.drop_loop_trio_for_slice(ety);
|
||||
self.place = array_place;
|
||||
|
||||
self.new_block_with_statements(
|
||||
self.unwind,
|
||||
vec![
|
||||
self.assign(Place::from(array_ptr), Rvalue::RawPtr(RawPtrKind::Mut, self.place)),
|
||||
self.assign(
|
||||
@@ -1230,28 +1197,14 @@ enum ProjectionKind<Path> {
|
||||
),
|
||||
),
|
||||
],
|
||||
None,
|
||||
self.unwind.is_cleanup(),
|
||||
);
|
||||
|
||||
let array_place = mem::replace(
|
||||
&mut self.place,
|
||||
Place::from(slice_ptr).project_deeper(&[PlaceElem::Deref], tcx),
|
||||
);
|
||||
let slice_block = self.drop_loop_trio_for_slice(ety);
|
||||
self.place = array_place;
|
||||
|
||||
delegate_block.terminator = Some(Terminator {
|
||||
source_info: self.source_info,
|
||||
kind: TerminatorKind::Goto { target: slice_block },
|
||||
});
|
||||
self.elaborator.patch().new_block(delegate_block)
|
||||
TerminatorKind::Goto { target: slice_block },
|
||||
)
|
||||
}
|
||||
|
||||
/// Creates a trio of drop-loops of `place`, which drops its contents, even
|
||||
/// in the case of 1 panic or in the case of coroutine drop
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn drop_loop_trio_for_slice(&mut self, ety: Ty<'tcx>) -> BasicBlock {
|
||||
debug!("drop_loop_trio_for_slice({:?})", ety);
|
||||
let tcx = self.tcx();
|
||||
let len = self.new_temp(tcx.types.usize);
|
||||
let cur = self.new_temp(tcx.types.usize);
|
||||
@@ -1274,7 +1227,8 @@ fn drop_loop_trio_for_slice(&mut self, ety: Ty<'tcx>) -> BasicBlock {
|
||||
};
|
||||
|
||||
let zero = self.constant_usize(0);
|
||||
let block = BasicBlockData::new_stmts(
|
||||
let drop_block = self.new_block_with_statements(
|
||||
unwind,
|
||||
vec![
|
||||
self.assign(
|
||||
len.into(),
|
||||
@@ -1285,14 +1239,9 @@ fn drop_loop_trio_for_slice(&mut self, ety: Ty<'tcx>) -> BasicBlock {
|
||||
),
|
||||
self.assign(cur.into(), Rvalue::Use(zero, WithRetag::Yes)),
|
||||
],
|
||||
Some(Terminator {
|
||||
source_info: self.source_info,
|
||||
kind: TerminatorKind::Goto { target: loop_block },
|
||||
}),
|
||||
unwind.is_cleanup(),
|
||||
TerminatorKind::Goto { target: loop_block },
|
||||
);
|
||||
|
||||
let drop_block = self.elaborator.patch().new_block(block);
|
||||
// FIXME(#34708): handle partially-dropped array/slice elements.
|
||||
let reset_block = self.drop_flag_reset_block(DropFlagMode::Deep, drop_block, unwind);
|
||||
self.drop_flag_test_block(reset_block, self.succ, unwind)
|
||||
@@ -1336,37 +1285,28 @@ fn open_drop(&mut self) -> BasicBlock {
|
||||
self.source_info.span,
|
||||
"open drop for unsafe binder shouldn't be encountered",
|
||||
);
|
||||
self.elaborator.patch().new_block(BasicBlockData::new(
|
||||
Some(Terminator {
|
||||
source_info: self.source_info,
|
||||
kind: TerminatorKind::Unreachable,
|
||||
}),
|
||||
self.unwind.is_cleanup(),
|
||||
))
|
||||
self.new_block(self.unwind, TerminatorKind::Unreachable)
|
||||
}
|
||||
|
||||
_ => span_bug!(self.source_info.span, "open drop from non-ADT `{:?}`", ty),
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn complete_drop(&mut self, succ: BasicBlock, unwind: Unwind) -> BasicBlock {
|
||||
debug!("complete_drop(succ={:?}, unwind={:?})", succ, unwind);
|
||||
|
||||
let drop_block = self.drop_block(succ, unwind);
|
||||
|
||||
self.drop_flag_test_block(drop_block, succ, unwind)
|
||||
}
|
||||
|
||||
/// Creates a block that resets the drop flag. If `mode` is deep, all children drop flags will
|
||||
/// also be cleared.
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn drop_flag_reset_block(
|
||||
&mut self,
|
||||
mode: DropFlagMode,
|
||||
succ: BasicBlock,
|
||||
unwind: Unwind,
|
||||
) -> BasicBlock {
|
||||
debug!("drop_flag_reset_block({:?},{:?})", self, mode);
|
||||
|
||||
if unwind.is_cleanup() {
|
||||
// The drop flag isn't read again on the unwind path, so don't
|
||||
// bother setting it.
|
||||
@@ -1378,25 +1318,23 @@ fn drop_flag_reset_block(
|
||||
block
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn elaborated_drop_block(&mut self) -> BasicBlock {
|
||||
debug!("elaborated_drop_block({:?})", self);
|
||||
let blk = self.drop_block_simple(self.succ, self.unwind);
|
||||
let blk = self.new_block(
|
||||
self.unwind,
|
||||
TerminatorKind::Drop {
|
||||
place: self.place,
|
||||
target: self.succ,
|
||||
unwind: self.unwind.into_action(),
|
||||
replace: false,
|
||||
drop: self.dropline,
|
||||
async_fut: None,
|
||||
},
|
||||
);
|
||||
self.elaborate_drop(blk);
|
||||
blk
|
||||
}
|
||||
|
||||
fn drop_block_simple(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock {
|
||||
let block = TerminatorKind::Drop {
|
||||
place: self.place,
|
||||
target,
|
||||
unwind: unwind.into_action(),
|
||||
replace: false,
|
||||
drop: self.dropline,
|
||||
async_fut: None,
|
||||
};
|
||||
self.new_block(unwind, block)
|
||||
}
|
||||
|
||||
fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock {
|
||||
let drop_ty = self.place_ty(self.place);
|
||||
if !unwind.is_cleanup() && self.check_if_can_async_drop(drop_ty, false) {
|
||||
@@ -1410,15 +1348,17 @@ fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock {
|
||||
false,
|
||||
)
|
||||
} else {
|
||||
let block = TerminatorKind::Drop {
|
||||
place: self.place,
|
||||
target,
|
||||
unwind: unwind.into_action(),
|
||||
replace: false,
|
||||
drop: None,
|
||||
async_fut: None,
|
||||
};
|
||||
self.new_block(unwind, block)
|
||||
self.new_block(
|
||||
unwind,
|
||||
TerminatorKind::Drop {
|
||||
place: self.place,
|
||||
target,
|
||||
unwind: unwind.into_action(),
|
||||
replace: false,
|
||||
drop: None,
|
||||
async_fut: None,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1432,6 +1372,7 @@ fn goto_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock {
|
||||
/// Depending on the required `DropStyle`, this might be a generated block with an `if`
|
||||
/// terminator (for dynamic/open drops), or it might be `on_set` or `on_unset` itself, in case
|
||||
/// the drop can be statically determined.
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn drop_flag_test_block(
|
||||
&mut self,
|
||||
on_set: BasicBlock,
|
||||
@@ -1439,11 +1380,6 @@ fn drop_flag_test_block(
|
||||
unwind: Unwind,
|
||||
) -> BasicBlock {
|
||||
let style = self.elaborator.drop_style(self.path, DropFlagMode::Shallow);
|
||||
debug!(
|
||||
"drop_flag_test_block({:?},{:?},{:?},{:?}) - {:?}",
|
||||
self, on_set, on_unset, unwind, style
|
||||
);
|
||||
|
||||
match style {
|
||||
DropStyle::Dead => on_unset,
|
||||
DropStyle::Static => on_set,
|
||||
@@ -1455,6 +1391,7 @@ fn drop_flag_test_block(
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
fn new_block(&mut self, unwind: Unwind, k: TerminatorKind<'tcx>) -> BasicBlock {
|
||||
self.elaborator.patch().new_block(BasicBlockData::new(
|
||||
Some(Terminator { source_info: self.source_info, kind: k }),
|
||||
@@ -1462,6 +1399,7 @@ fn new_block(&mut self, unwind: Unwind, k: TerminatorKind<'tcx>) -> BasicBlock {
|
||||
))
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self, statements), ret)]
|
||||
fn new_block_with_statements(
|
||||
&mut self,
|
||||
unwind: Unwind,
|
||||
|
||||
@@ -18,8 +18,8 @@ enum CheckingMode {
|
||||
}
|
||||
|
||||
fn get_checking_mode(tcx: TyCtxt<'_>) -> CheckingMode {
|
||||
// if any of the crate types is not rlib or dylib, we must check for existence.
|
||||
if tcx.crate_types().iter().any(|i| !matches!(i, CrateType::Rlib | CrateType::Dylib)) {
|
||||
// if any of the crate types is not rlib, we must check for existence.
|
||||
if tcx.crate_types().iter().any(|i| !matches!(i, CrateType::Rlib)) {
|
||||
CheckingMode::CheckExistence
|
||||
} else {
|
||||
CheckingMode::CheckDuplicates
|
||||
|
||||
@@ -3612,6 +3612,7 @@ fn resolve_impl_item(
|
||||
this.check_trait_item(
|
||||
item.id,
|
||||
*ident,
|
||||
*ident,
|
||||
&item.kind,
|
||||
ValueNS,
|
||||
item.span,
|
||||
@@ -3656,7 +3657,7 @@ fn resolve_impl_item(
|
||||
);
|
||||
self.resolve_define_opaques(define_opaque);
|
||||
}
|
||||
AssocItemKind::Fn(Fn { ident, generics, define_opaque, .. }) => {
|
||||
AssocItemKind::Fn(fn_kind @ Fn { ident, generics, define_opaque, .. }) => {
|
||||
debug!("resolve_implementation AssocItemKind::Fn");
|
||||
// We also need a new scope for the impl item type parameters.
|
||||
self.with_generic_param_rib(
|
||||
@@ -3666,10 +3667,16 @@ fn resolve_impl_item(
|
||||
LifetimeBinderKind::Function,
|
||||
generics.span,
|
||||
|this| {
|
||||
let effective_ident = if is_in_trait_impl && fn_kind.is_pin_drop_sugar() {
|
||||
Ident::new(sym::pin_drop, ident.span)
|
||||
} else {
|
||||
*ident
|
||||
};
|
||||
// If this is a trait impl, ensure the method
|
||||
// exists in trait
|
||||
this.check_trait_item(
|
||||
item.id,
|
||||
effective_ident,
|
||||
*ident,
|
||||
&item.kind,
|
||||
ValueNS,
|
||||
@@ -3701,6 +3708,7 @@ fn resolve_impl_item(
|
||||
this.check_trait_item(
|
||||
item.id,
|
||||
*ident,
|
||||
*ident,
|
||||
&item.kind,
|
||||
TypeNS,
|
||||
item.span,
|
||||
@@ -3726,6 +3734,7 @@ fn resolve_impl_item(
|
||||
this.check_trait_item(
|
||||
item.id,
|
||||
delegation.ident,
|
||||
delegation.ident,
|
||||
&item.kind,
|
||||
ValueNS,
|
||||
item.span,
|
||||
@@ -3750,6 +3759,7 @@ fn check_trait_item<F>(
|
||||
&mut self,
|
||||
id: NodeId,
|
||||
mut ident: Ident,
|
||||
mut reported_ident: Ident,
|
||||
kind: &AssocItemKind,
|
||||
ns: Namespace,
|
||||
span: Span,
|
||||
@@ -3763,6 +3773,7 @@ fn check_trait_item<F>(
|
||||
return;
|
||||
};
|
||||
ident.span.normalize_to_macros_2_0_and_adjust(module.expansion);
|
||||
reported_ident.span.normalize_to_macros_2_0_and_adjust(module.expansion);
|
||||
let key = BindingKey::new(IdentKey::new(ident), ns);
|
||||
let mut decl = self.r.resolution(module, key).and_then(|r| r.best_decl());
|
||||
debug!(?decl);
|
||||
@@ -3798,10 +3809,10 @@ fn check_trait_item<F>(
|
||||
|
||||
let Some(decl) = decl else {
|
||||
// We could not find the method: report an error.
|
||||
let candidate = self.find_similarly_named_assoc_item(ident.name, kind);
|
||||
let candidate = self.find_similarly_named_assoc_item(reported_ident.name, kind);
|
||||
let path = &self.current_trait_ref.as_ref().unwrap().1.path;
|
||||
let path_names = path_names_to_string(path);
|
||||
self.report_error(span, err(ident, path_names, candidate));
|
||||
self.report_error(span, err(reported_ident, path_names, candidate));
|
||||
feed_visibility(self, module.def_id());
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -118,6 +118,13 @@ macro_rules! args {
|
||||
// with unwinding.
|
||||
llvm_args: cvs!["-wasm-use-legacy-eh=false"],
|
||||
|
||||
// WASI's `sys::args::init` function ignores its arguments; instead,
|
||||
// `args::args()` makes the WASI API calls itself.
|
||||
//
|
||||
// Other Wasm targets make no use of `std::env` entirely.
|
||||
// Emscripten enables it explicitly.
|
||||
main_needs_argc_argv: false,
|
||||
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ pub(crate) fn target() -> Target {
|
||||
crt_static_respected: true,
|
||||
crt_static_default: true,
|
||||
crt_static_allows_dylibs: true,
|
||||
main_needs_argc_argv: true,
|
||||
panic_strategy: PanicStrategy::Unwind,
|
||||
no_default_libraries: false,
|
||||
families: cvs!["unix", "wasm"],
|
||||
|
||||
@@ -41,10 +41,6 @@ pub(crate) fn target() -> Target {
|
||||
// without a main function.
|
||||
options.crt_static_allows_dylibs = true;
|
||||
|
||||
// WASI's `sys::args::init` function ignores its arguments; instead,
|
||||
// `args::args()` makes the WASI API calls itself.
|
||||
options.main_needs_argc_argv = false;
|
||||
|
||||
// And, WASI mangles the name of "main" to distinguish between different
|
||||
// signatures.
|
||||
options.entry_name = "__main_void".into();
|
||||
|
||||
@@ -52,10 +52,6 @@ pub(crate) fn target() -> Target {
|
||||
// without a main function.
|
||||
options.crt_static_allows_dylibs = true;
|
||||
|
||||
// WASI's `sys::args::init` function ignores its arguments; instead,
|
||||
// `args::args()` makes the WASI API calls itself.
|
||||
options.main_needs_argc_argv = false;
|
||||
|
||||
// And, WASI mangles the name of "main" to distinguish between different
|
||||
// signatures.
|
||||
options.entry_name = "__main_void".into();
|
||||
|
||||
@@ -46,10 +46,6 @@ pub(crate) fn target() -> Target {
|
||||
// without a main function.
|
||||
options.crt_static_allows_dylibs = true;
|
||||
|
||||
// WASI's `sys::args::init` function ignores its arguments; instead,
|
||||
// `args::args()` makes the WASI API calls itself.
|
||||
options.main_needs_argc_argv = false;
|
||||
|
||||
// And, WASI mangles the name of "main" to distinguish between different
|
||||
// signatures.
|
||||
options.entry_name = "__main_void".into();
|
||||
|
||||
@@ -308,7 +308,10 @@ pub fn into_boxed_bytes(self: Box<Self>) -> Box<[u8]> {
|
||||
pub fn replace<P: Pattern>(&self, from: P, to: &str) -> String {
|
||||
// Fast path for replacing a single ASCII character with another.
|
||||
if let Some(from_byte) = match from.as_utf8_pattern() {
|
||||
Some(Utf8Pattern::StringPattern([from_byte])) => Some(*from_byte),
|
||||
Some(Utf8Pattern::StringPattern(s)) => match s.as_bytes() {
|
||||
[from_byte] => Some(*from_byte),
|
||||
_ => None,
|
||||
},
|
||||
Some(Utf8Pattern::CharPattern(c)) => c.as_ascii().map(|ascii_char| ascii_char.to_u8()),
|
||||
_ => None,
|
||||
} {
|
||||
|
||||
@@ -2654,7 +2654,7 @@ fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&'a str>
|
||||
|
||||
#[inline]
|
||||
fn as_utf8_pattern(&self) -> Option<Utf8Pattern<'_>> {
|
||||
Some(Utf8Pattern::StringPattern(self.as_bytes()))
|
||||
Some(Utf8Pattern::StringPattern(self.as_str()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&'a str>
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the pattern as utf-8 bytes if possible.
|
||||
/// Returns the pattern as UTF-8 if possible.
|
||||
fn as_utf8_pattern(&self) -> Option<Utf8Pattern<'_>> {
|
||||
None
|
||||
}
|
||||
@@ -172,7 +172,9 @@ fn as_utf8_pattern(&self) -> Option<Utf8Pattern<'_>> {
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||
pub enum Utf8Pattern<'a> {
|
||||
/// Type returned by String and str types.
|
||||
StringPattern(&'a [u8]),
|
||||
/// This stores `str` rather than bytes so callers cannot describe
|
||||
/// non-UTF-8 string patterns through this API.
|
||||
StringPattern(&'a str),
|
||||
/// Type returned by char types.
|
||||
CharPattern(char),
|
||||
}
|
||||
@@ -1049,7 +1051,7 @@ fn strip_suffix_of<'a>(self, haystack: &'a str) -> Option<&'a str>
|
||||
|
||||
#[inline]
|
||||
fn as_utf8_pattern(&self) -> Option<Utf8Pattern<'_>> {
|
||||
Some(Utf8Pattern::StringPattern(self.as_bytes()))
|
||||
Some(Utf8Pattern::StringPattern(*self))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -689,7 +689,7 @@ pub fn home_dir() -> Option<PathBuf> {
|
||||
/// [GetTempPath]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
|
||||
/// [appledoc]: https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/RaceConditions.html#//apple_ref/doc/uid/TP40002585-SW10
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```
|
||||
/// use std::env;
|
||||
///
|
||||
/// fn main() {
|
||||
|
||||
@@ -103,6 +103,7 @@ if gdb_version[0] < 7 or (gdb_version[0] == 7 and gdb_version[1] < 12):
|
||||
printer.add(RustType.StdString, StdStringProvider)
|
||||
printer.add(RustType.StdOsString, StdOsStringProvider)
|
||||
printer.add(RustType.StdStr, StdStrProvider)
|
||||
printer.add(RustType.StdBoxStr, StdBoxStrProvider)
|
||||
printer.add(RustType.StdSlice, StdSliceProvider)
|
||||
printer.add(RustType.StdVec, StdVecProvider)
|
||||
printer.add(RustType.StdVecDeque, StdVecDequeProvider)
|
||||
|
||||
@@ -142,6 +142,20 @@ class StdSliceProvider(printer_base):
|
||||
return "array"
|
||||
|
||||
|
||||
class StdBoxStrProvider(printer_base):
|
||||
def __init__(self, valobj):
|
||||
self._valobj = valobj
|
||||
self._length = int(valobj["length"])
|
||||
self._data_ptr = valobj["data_ptr"]
|
||||
|
||||
def to_string(self):
|
||||
return self._data_ptr.lazy_string(encoding="utf-8", length=self._length)
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
return "string"
|
||||
|
||||
|
||||
class StdVecProvider(printer_base):
|
||||
def __init__(self, valobj):
|
||||
self._valobj = valobj
|
||||
@@ -203,6 +217,12 @@ class StdRcProvider(printer_base):
|
||||
self._is_atomic = is_atomic
|
||||
self._ptr = unwrap_unique_or_non_null(valobj["ptr"])
|
||||
self._value = self._ptr["data" if is_atomic else "value"]
|
||||
# FIXME(shua): the debuginfo template type should be 'str' not 'u8'
|
||||
if self._ptr.type.target().name == "alloc::rc::RcInner<str>":
|
||||
length = self._valobj["ptr"]["pointer"]["length"]
|
||||
u8_ptr_ty = gdb.Type.pointer(gdb.lookup_type("u8"))
|
||||
ptr = self._value.address.reinterpret_cast(u8_ptr_ty)
|
||||
self._value = ptr.lazy_string(encoding="utf-8", length=length)
|
||||
self._strong = unwrap_scalar_wrappers(self._ptr["strong"])
|
||||
self._weak = unwrap_scalar_wrappers(self._ptr["weak"]) - 1
|
||||
|
||||
|
||||
@@ -37,12 +37,14 @@ class RustType(Enum):
|
||||
StdNonZeroNumber = 29
|
||||
StdPath = 30
|
||||
StdPathBuf = 31
|
||||
StdBoxStr = 32
|
||||
|
||||
|
||||
STD_STRING_REGEX = re.compile(r"^(alloc::([a-z_]+::)+)String$")
|
||||
STD_STR_REGEX = re.compile(r"^&(mut )?str$")
|
||||
STD_SLICE_REGEX = re.compile(r"^&(mut )?\[.+\]$")
|
||||
STD_OS_STRING_REGEX = re.compile(r"^(std::ffi::([a-z_]+::)+)OsString$")
|
||||
STD_BOX_STR_REGEX = re.compile(r"^(alloc::([a-z_]+::)+)Box<str,.+>$")
|
||||
STD_VEC_REGEX = re.compile(r"^(alloc::([a-z_]+::)+)Vec<.+>$")
|
||||
STD_VEC_DEQUE_REGEX = re.compile(r"^(alloc::([a-z_]+::)+)VecDeque<.+>$")
|
||||
STD_BTREE_SET_REGEX = re.compile(r"^(alloc::([a-z_]+::)+)BTreeSet<.+>$")
|
||||
@@ -67,6 +69,7 @@ STD_TYPE_TO_REGEX = {
|
||||
RustType.StdString: STD_STRING_REGEX,
|
||||
RustType.StdOsString: STD_OS_STRING_REGEX,
|
||||
RustType.StdStr: STD_STR_REGEX,
|
||||
RustType.StdBoxStr: STD_BOX_STR_REGEX,
|
||||
RustType.StdSlice: STD_SLICE_REGEX,
|
||||
RustType.StdVec: STD_VEC_REGEX,
|
||||
RustType.StdVecDeque: STD_VEC_DEQUE_REGEX,
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
use rustc_ast::visit::{Visitor, walk_crate, walk_expr, walk_item, walk_pat, walk_stmt, walk_ty};
|
||||
use rustc_ast::{Crate, Expr, Item, Pat, Stmt, Ty};
|
||||
use rustc_ast::visit::{
|
||||
AssocCtxt, Visitor, walk_assoc_item, walk_crate, walk_expr, walk_item, walk_pat, walk_stmt,
|
||||
walk_ty,
|
||||
};
|
||||
use rustc_ast::{AssocItem, Crate, Expr, Item, Pat, Stmt, Ty};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::{BytePos, Span};
|
||||
@@ -161,4 +164,14 @@ fn visit_ty(&mut self, ty: &'ast Ty) {
|
||||
walk_ty(self, ty);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_assoc_item(&mut self, item: &'ast AssocItem, ctxt: AssocCtxt) -> Self::Result {
|
||||
if item.span.from_expansion() {
|
||||
self.handle_new_span(item.span, || {
|
||||
rustc_ast_pretty::pprust::assoc_item_to_string(item)
|
||||
});
|
||||
} else {
|
||||
walk_assoc_item(self, item, ctxt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
//@ only-wasm32
|
||||
//@ assembly-output: emit-asm
|
||||
//@ compile-flags: -C target-feature=+exception-handling
|
||||
//@ compile-flags: -C panic=unwind
|
||||
//@ compile-flags: -C llvm-args=-wasm-use-legacy-eh=true
|
||||
|
||||
// Verifies that user-supplied `-Cllvm-args` can override an LLVM argument that
|
||||
// was set in the target spec. The `wasm32-unknown-unknown` target spec pins
|
||||
// `-wasm-use-legacy-eh=false`; this test asserts that passing the opposite
|
||||
// value via `-Cllvm-args` switches code generation back to the legacy
|
||||
// exception-handling instructions.
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
extern "C-unwind" {
|
||||
fn may_panic();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn log_number(number: usize);
|
||||
}
|
||||
|
||||
struct LogOnDrop;
|
||||
|
||||
impl Drop for LogOnDrop {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
log_number(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test_cleanup:
|
||||
#[no_mangle]
|
||||
pub fn test_cleanup() {
|
||||
let _log_on_drop = LogOnDrop;
|
||||
unsafe {
|
||||
may_panic();
|
||||
}
|
||||
|
||||
// CHECK-NOT: try_table
|
||||
// CHECK-NOT: catch_all_ref
|
||||
// CHECK-NOT: throw_ref
|
||||
// CHECK-NOT: call
|
||||
// CHECK: try
|
||||
// CHECK: call may_panic
|
||||
// CHECK: catch_all
|
||||
// CHECK: rethrow
|
||||
// CHECK: end_try
|
||||
}
|
||||
|
||||
// CHECK-LABEL: test_rtry:
|
||||
#[no_mangle]
|
||||
pub fn test_rtry() {
|
||||
unsafe {
|
||||
core::intrinsics::catch_unwind(
|
||||
|_| {
|
||||
may_panic();
|
||||
},
|
||||
core::ptr::null_mut(),
|
||||
|data, exception| {
|
||||
log_number(data as usize);
|
||||
log_number(exception as usize);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// CHECK-NOT: try_table
|
||||
// CHECK-NOT: catch_all_ref
|
||||
// CHECK-NOT: throw_ref
|
||||
// CHECK-NOT: call
|
||||
// CHECK: try
|
||||
// CHECK: call may_panic
|
||||
// CHECK: catch
|
||||
// CHECK: call log_number
|
||||
// CHECK: call log_number
|
||||
// CHECK-NOT: rethrow
|
||||
// CHECK: end_try
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
//@ compile-flags:-g -Copt-level=0 -C panic=abort
|
||||
|
||||
// Check that debug information for structs with embedded str and [u8] slices is distinct from
|
||||
// structs with embedded u8
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// CHECK: ![[U8:[0-9]+]] = !DIBasicType(name: "u8",
|
||||
|
||||
pub struct Foo {
|
||||
a: u32,
|
||||
b: str,
|
||||
}
|
||||
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "&{{[^"]+}}::Foo", {{.*}}elements: ![[FOO_REF_ELEMS:[0-9]+]]
|
||||
// CHECK: ![[FOO_REF_ELEMS]] = !{![[FOO_REF_PTR:[0-9]+]], ![[FOO_REF_LEN:[0-9]+]]}
|
||||
// CHECK: ![[FOO_REF_PTR]] = !DIDerivedType(tag: DW_TAG_member, name: "data_ptr", {{.*}}baseType: ![[FOO_PTR:[0-9]+]]
|
||||
// CHECK: ![[FOO_PTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[FOO:[0-9]+]]
|
||||
// CHECK: ![[FOO]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", {{.*}}elements: ![[FOO_ELEMS:[0-9]+]]
|
||||
// CHECK: ![[FOO_ELEMS]] = !{![[FOO_A:[0-9]+]], ![[FOO_B:[0-9]+]]}
|
||||
// CHECK: ![[FOO_A]] = !DIDerivedType(tag: DW_TAG_member, name: "a"
|
||||
// CHECK: ![[FOO_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b", {{.*}}baseType: ![[U8_SLICE:[0-9]+]]
|
||||
//
|
||||
// CHECK: ![[U8_SLICE]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[U8]], {{.*}}elements: ![[U8_SLICE_ELEMS:[0-9]+]]
|
||||
// CHECK: ![[U8_SLICE_ELEMS]] = !{![[U8_SLICE_RANGE:[0-9]+]]}
|
||||
// this is special to embedded slices, there is no upper bound on the number of elements,
|
||||
// that info is stored in the length metadata for a reference to the parent struct
|
||||
// CHECK: ![[U8_SLICE_RANGE]] = !DISubrange(count: -1, lowerBound: 0)
|
||||
//
|
||||
// CHECK: ![[FOO_REF_LEN]] = !DIDerivedType(tag: DW_TAG_member, name: "length", {{.*}}baseType: ![[USIZE:[0-9]+]]
|
||||
// CHECK: ![[USIZE]] = !DIBasicType(name: "usize"
|
||||
pub struct Bar {
|
||||
a: u32,
|
||||
b: [u8],
|
||||
}
|
||||
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "&{{[^"]+}}::Bar", {{.*}}elements: ![[BAR_REF_ELEMS:[0-9]+]]
|
||||
// CHECK: ![[BAR_REF_ELEMS]] = !{![[BAR_REF_PTR:[0-9]+]], ![[BAR_REF_LEN:[0-9]+]]}
|
||||
// CHECK: ![[BAR_REF_PTR]] = !DIDerivedType(tag: DW_TAG_member, name: "data_ptr", {{.*}}baseType: ![[BAR_PTR:[0-9]+]]
|
||||
// CHECK: ![[BAR_PTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[BAR:[0-9]+]]
|
||||
// CHECK: ![[BAR]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Bar", {{.*}}elements: ![[BAR_ELEMS:[0-9]+]]
|
||||
// CHECK: ![[BAR_ELEMS]] = !{![[BAR_A:[0-9]+]], ![[BAR_B:[0-9]+]]}
|
||||
// CHECK: ![[BAR_A]] = !DIDerivedType(tag: DW_TAG_member, name: "a"
|
||||
// CHECK: ![[BAR_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b", {{.*}}baseType: ![[U8_SLICE]]
|
||||
// CHECK: ![[BAR_REF_LEN]] = !DIDerivedType(tag: DW_TAG_member, name: "length", {{.*}}baseType: ![[USIZE:[0-9]+]]
|
||||
pub struct Baz {
|
||||
a: u32,
|
||||
b: u8,
|
||||
}
|
||||
// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type, name: "&{{[^"]+}}::Baz", {{.*}}baseType: ![[BAZ:[0-9]+]]
|
||||
// CHECK: ![[BAZ]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Baz", {{.*}}elements: ![[BAZ_ELEMS:[0-9]+]]
|
||||
// CHECK: ![[BAZ_ELEMS]] = !{![[BAZ_A:[0-9]+]], ![[BAZ_B:[0-9]+]]}
|
||||
// CHECK: ![[BAZ_A]] = !DIDerivedType(tag: DW_TAG_member, name: "a"
|
||||
// CHECK: ![[BAZ_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b", {{.*}}baseType: ![[U8]]
|
||||
|
||||
#[no_mangle]
|
||||
pub fn test<'a>(a: &'a Foo, b: &'a Bar, c: &'a Baz) -> &'a u8 {
|
||||
// just use this somehow so the debuginfo isn't removed
|
||||
&a.b.as_bytes()[0]
|
||||
}
|
||||
@@ -1,40 +1,20 @@
|
||||
Function name: context_mismatch_issue_147339::a (unused)
|
||||
Raw bytes (14): 0x[01, 01, 00, 02, 00, 0c, 27, 00, 35, 00, 00, 3b, 00, 3c]
|
||||
Function name: context_mismatch_issue_147339::_function (unused)
|
||||
Raw bytes (14): 0x[01, 01, 00, 02, 00, 14, 11, 00, 26, 00, 02, 11, 00, 12]
|
||||
Number of files: 1
|
||||
- file 0 => $DIR/context-mismatch-issue-147339.rs
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 2
|
||||
- Code(Zero) at (prev + 12, 39) to (start + 0, 53)
|
||||
- Code(Zero) at (prev + 0, 59) to (start + 0, 60)
|
||||
Highest counter ID seen: (none)
|
||||
|
||||
Function name: context_mismatch_issue_147339::b (unused)
|
||||
Raw bytes (14): 0x[01, 01, 00, 02, 00, 0c, 27, 00, 35, 00, 00, 3b, 00, 3c]
|
||||
Number of files: 1
|
||||
- file 0 => $DIR/context-mismatch-issue-147339.rs
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 2
|
||||
- Code(Zero) at (prev + 12, 39) to (start + 0, 53)
|
||||
- Code(Zero) at (prev + 0, 59) to (start + 0, 60)
|
||||
Highest counter ID seen: (none)
|
||||
|
||||
Function name: context_mismatch_issue_147339::c (unused)
|
||||
Raw bytes (14): 0x[01, 01, 00, 02, 00, 0c, 27, 00, 35, 00, 00, 3b, 00, 3c]
|
||||
Number of files: 1
|
||||
- file 0 => $DIR/context-mismatch-issue-147339.rs
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 2
|
||||
- Code(Zero) at (prev + 12, 39) to (start + 0, 53)
|
||||
- Code(Zero) at (prev + 0, 59) to (start + 0, 60)
|
||||
- Code(Zero) at (prev + 20, 17) to (start + 0, 38)
|
||||
- Code(Zero) at (prev + 2, 17) to (start + 0, 18)
|
||||
Highest counter ID seen: (none)
|
||||
|
||||
Function name: context_mismatch_issue_147339::main
|
||||
Raw bytes (14): 0x[01, 01, 00, 02, 01, 14, 01, 00, 0a, 01, 00, 0c, 00, 0d]
|
||||
Raw bytes (14): 0x[01, 01, 00, 02, 01, 1f, 01, 00, 0a, 01, 00, 0c, 00, 0d]
|
||||
Number of files: 1
|
||||
- file 0 => $DIR/context-mismatch-issue-147339.rs
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 2
|
||||
- Code(Counter(0)) at (prev + 20, 1) to (start + 0, 10)
|
||||
- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 10)
|
||||
- Code(Counter(0)) at (prev + 0, 12) to (start + 0, 13)
|
||||
Highest counter ID seen: c0
|
||||
|
||||
|
||||
@@ -6,23 +6,27 @@
|
||||
LL| |//
|
||||
LL| |// Reported in <https://github.com/rust-lang/rust/issues/147339>.
|
||||
LL| |
|
||||
LL| |macro_rules! foo {
|
||||
LL| | ($($m:ident $($f:ident $v:tt)+),*) => {
|
||||
LL| | $($(macro_rules! $f { () => { $v } })+)*
|
||||
LL| 0| $(macro_rules! $m { () => { $(fn $f() -> i32 { $v })+ } })*
|
||||
------------------
|
||||
| Unexecuted instantiation: context_mismatch_issue_147339::a
|
||||
------------------
|
||||
| Unexecuted instantiation: context_mismatch_issue_147339::b
|
||||
------------------
|
||||
| Unexecuted instantiation: context_mismatch_issue_147339::c
|
||||
------------------
|
||||
LL| | }
|
||||
LL| |macro_rules! outer_macro {
|
||||
LL| | (
|
||||
LL| | $v:tt
|
||||
LL| | ) => {
|
||||
LL| | macro_rules! _other_macro_that_mentions_v {
|
||||
LL| | () => {
|
||||
LL| | $v
|
||||
LL| | };
|
||||
LL| | }
|
||||
LL| | macro_rules! inner_macro {
|
||||
LL| | () => {
|
||||
LL| 0| fn _function() -> i32 {
|
||||
LL| | $v
|
||||
LL| 0| }
|
||||
LL| | };
|
||||
LL| | }
|
||||
LL| | };
|
||||
LL| |}
|
||||
LL| |
|
||||
LL| |foo!(m a 1 b 2, n c 3);
|
||||
LL| |m!();
|
||||
LL| |n!();
|
||||
LL| |outer_macro!(1);
|
||||
LL| |inner_macro!();
|
||||
LL| |
|
||||
LL| 1|fn main() {}
|
||||
|
||||
|
||||
@@ -6,15 +6,26 @@
|
||||
//
|
||||
// Reported in <https://github.com/rust-lang/rust/issues/147339>.
|
||||
|
||||
macro_rules! foo {
|
||||
($($m:ident $($f:ident $v:tt)+),*) => {
|
||||
$($(macro_rules! $f { () => { $v } })+)*
|
||||
$(macro_rules! $m { () => { $(fn $f() -> i32 { $v })+ } })*
|
||||
}
|
||||
macro_rules! outer_macro {
|
||||
(
|
||||
$v:tt
|
||||
) => {
|
||||
macro_rules! _other_macro_that_mentions_v {
|
||||
() => {
|
||||
$v
|
||||
};
|
||||
}
|
||||
macro_rules! inner_macro {
|
||||
() => {
|
||||
fn _function() -> i32 {
|
||||
$v
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
foo!(m a 1 b 2, n c 3);
|
||||
m!();
|
||||
n!();
|
||||
outer_macro!(1);
|
||||
inner_macro!();
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
//@ gdb-command:print str_in_rc
|
||||
//@ gdb-check:$5 = alloc::rc::Rc<&str, alloc::alloc::Global> {ptr: core::ptr::non_null::NonNull<alloc::rc::RcInner<&str>> {pointer: 0x[...]}, phantom: core::marker::PhantomData<alloc::rc::RcInner<&str>>, alloc: alloc::alloc::Global}
|
||||
|
||||
//@ gdb-command:print box_str
|
||||
//@ gdb-check:$6 = alloc::boxed::Box<str, alloc::alloc::Global> [87, 111, 114, 108, 100]
|
||||
|
||||
//@ gdb-command:print rc_str
|
||||
//@ gdb-check:$7 = alloc::rc::Rc<str, alloc::alloc::Global> {ptr: core::ptr::non_null::NonNull<alloc::rc::RcInner<str>> {pointer: alloc::rc::RcInner<str> {strong: core::cell::Cell<usize> {value: core::cell::UnsafeCell<usize> {value: 1}}, weak: core::cell::Cell<usize> {value: core::cell::UnsafeCell<usize> {value: 1}}, value: 0x[...]}}, phantom: core::marker::PhantomData<alloc::rc::RcInner<str>>, alloc: alloc::alloc::Global}
|
||||
|
||||
// === LLDB TESTS ==================================================================================
|
||||
//@ lldb-command:run
|
||||
//@ lldb-command:v plain_string
|
||||
@@ -40,6 +46,12 @@
|
||||
//@ lldb-command:v str_in_rc
|
||||
//@ lldb-check:(alloc::rc::Rc<&str, alloc::alloc::Global>) str_in_rc = strong=1, weak=0 { value = "Hello" { [0] = 'H' [1] = 'e' [2] = 'l' [3] = 'l' [4] = 'o' } }
|
||||
|
||||
//@ lldb-command:v box_str
|
||||
//@ lldb-check:(alloc::boxed::Box<unsigned char[], alloc::alloc::Global>) box_str = { __0 = { pointer = { pointer = { data_ptr = 0x[...] "World" length = 5 } } _marker = } __1 = }
|
||||
|
||||
//@ lldb-command:v rc_str
|
||||
//@ lldb-check:(alloc::rc::Rc<unsigned char[], alloc::alloc::Global>) rc_str = strong=1, weak=0 { value = "World" }
|
||||
|
||||
#![allow(unused_variables)]
|
||||
|
||||
pub struct Foo<'a> {
|
||||
@@ -53,6 +65,8 @@ fn main() {
|
||||
let str_in_tuple = ("Hello", "World");
|
||||
|
||||
let str_in_rc = std::rc::Rc::new("Hello");
|
||||
let box_str: Box<str> = "World".into();
|
||||
let rc_str: std::rc::Rc<str> = "World".into();
|
||||
zzz(); // #break
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// Ensure assoc items work for decl macros.
|
||||
// Regression test for <https://github.com/rust-lang/rust/issues/156075>.
|
||||
|
||||
//@ compile-flags: -Zunstable-options --generate-macro-expansion
|
||||
|
||||
#![crate_name = "foo"]
|
||||
#![feature(decl_macro)]
|
||||
|
||||
//@ has 'src/foo/assoc-items-decl-macro.rs.html'
|
||||
|
||||
pub macro first() {
|
||||
type P1 = bool;
|
||||
fn u1() {}
|
||||
}
|
||||
|
||||
trait C1 {
|
||||
type P1;
|
||||
fn u1();
|
||||
}
|
||||
|
||||
impl C1 for u32 {
|
||||
//@ matches - '//*[@class="expansion"]/*[@class="expanded"]' 'type P1 = bool;\nfn u1\(\) {}'
|
||||
first!();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Ensure assoc items work for macro rules.
|
||||
// Regression test for <https://github.com/rust-lang/rust/issues/156075>.
|
||||
|
||||
//@ compile-flags: -Zunstable-options --generate-macro-expansion
|
||||
|
||||
#![crate_name = "foo"]
|
||||
|
||||
//@ has 'src/foo/assoc-items-macro.rs.html'
|
||||
|
||||
macro_rules! first {
|
||||
() => {
|
||||
type P1 = bool;
|
||||
fn u1() {}
|
||||
}
|
||||
}
|
||||
|
||||
trait C1 {
|
||||
type P1;
|
||||
fn u1();
|
||||
}
|
||||
|
||||
impl C1 for u32 {
|
||||
//@ matches - '//*[@class="expansion"]/*[@class="expanded"]' 'type P1 = bool;\nfn u1\(\) {}'
|
||||
first!();
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
//@ compile-flags: -Z deduplicate-diagnostics=yes
|
||||
|
||||
#![feature(fn_delegation)]
|
||||
|
||||
trait Bound<T> {}
|
||||
@@ -19,12 +21,16 @@ impl<T> Bound<T> for usize {}
|
||||
|
||||
reuse Trait::static_method as error { self - 123 }
|
||||
//~^ ERROR: type annotations needed
|
||||
//~| ERROR: delegation self type is not specified
|
||||
reuse Trait::<'static, i32, 123>::static_method as error2;
|
||||
//~^ ERROR: type annotations needed
|
||||
//~| ERROR: delegation self type is not specified
|
||||
reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3;
|
||||
//~^ ERROR: type annotations needed
|
||||
//~| ERROR: delegation self type is not specified
|
||||
reuse Trait::static_method::<'static, Vec<i32>, false> as error4 { self + 4 }
|
||||
//~^ ERROR: type annotations needed
|
||||
//~| ERROR: delegation self type is not specified
|
||||
|
||||
reuse <String as Trait>::static_method as error5;
|
||||
//~^ ERROR: the trait bound `String: Trait<'a, T, X>` is not satisfied
|
||||
|
||||
@@ -1,21 +1,53 @@
|
||||
error: delegation self type is not specified
|
||||
--> $DIR/free-to-trait-static-reuse.rs:22:14
|
||||
|
|
||||
LL | reuse Trait::static_method as error { self - 123 }
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
|
||||
|
||||
error: delegation self type is not specified
|
||||
--> $DIR/free-to-trait-static-reuse.rs:25:35
|
||||
|
|
||||
LL | reuse Trait::<'static, i32, 123>::static_method as error2;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
|
||||
|
||||
error: delegation self type is not specified
|
||||
--> $DIR/free-to-trait-static-reuse.rs:28:35
|
||||
|
|
||||
LL | reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
|
||||
|
||||
error: delegation self type is not specified
|
||||
--> $DIR/free-to-trait-static-reuse.rs:31:14
|
||||
|
|
||||
LL | reuse Trait::static_method::<'static, Vec<i32>, false> as error4 { self + 4 }
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
|
||||
|
||||
error[E0277]: the trait bound `Struct: Bound<T>` is not satisfied
|
||||
--> $DIR/free-to-trait-static-reuse.rs:33:49
|
||||
--> $DIR/free-to-trait-static-reuse.rs:39:49
|
||||
|
|
||||
LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
|
||||
| ^^^^^^ unsatisfied trait bound
|
||||
|
|
||||
help: the trait `Bound<T>` is not implemented for `Struct`
|
||||
--> $DIR/free-to-trait-static-reuse.rs:32:1
|
||||
--> $DIR/free-to-trait-static-reuse.rs:38:1
|
||||
|
|
||||
LL | struct Struct;
|
||||
| ^^^^^^^^^^^^^
|
||||
help: the trait `Bound<T>` is implemented for `usize`
|
||||
--> $DIR/free-to-trait-static-reuse.rs:13:1
|
||||
--> $DIR/free-to-trait-static-reuse.rs:15:1
|
||||
|
|
||||
LL | impl<T> Bound<T> for usize {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `Trait`
|
||||
--> $DIR/free-to-trait-static-reuse.rs:7:11
|
||||
--> $DIR/free-to-trait-static-reuse.rs:9:11
|
||||
|
|
||||
LL | trait Trait<'a, T, const X: usize>
|
||||
| ----- required by a bound in this trait
|
||||
@@ -24,13 +56,13 @@ LL | Self: Bound<T>,
|
||||
| ^^^^^^^^ required by this bound in `Trait`
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/free-to-trait-static-reuse.rs:20:14
|
||||
--> $DIR/free-to-trait-static-reuse.rs:22:14
|
||||
|
|
||||
LL | reuse Trait::static_method as error { self - 123 }
|
||||
| ^^^^^^^^^^^^^ cannot infer type
|
||||
|
|
||||
note: multiple `impl`s satisfying `_: Trait<'a, T, X>` found
|
||||
--> $DIR/free-to-trait-static-reuse.rs:12:1
|
||||
--> $DIR/free-to-trait-static-reuse.rs:14:1
|
||||
|
|
||||
LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -39,13 +71,13 @@ LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/free-to-trait-static-reuse.rs:22:35
|
||||
--> $DIR/free-to-trait-static-reuse.rs:25:35
|
||||
|
|
||||
LL | reuse Trait::<'static, i32, 123>::static_method as error2;
|
||||
| ^^^^^^^^^^^^^ cannot infer type
|
||||
|
|
||||
note: multiple `impl`s satisfying `_: Trait<'static, i32, 123>` found
|
||||
--> $DIR/free-to-trait-static-reuse.rs:12:1
|
||||
--> $DIR/free-to-trait-static-reuse.rs:14:1
|
||||
|
|
||||
LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -54,13 +86,13 @@ LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/free-to-trait-static-reuse.rs:24:35
|
||||
--> $DIR/free-to-trait-static-reuse.rs:28:35
|
||||
|
|
||||
LL | reuse Trait::<'static, i32, 123>::static_method::<'static, String, false> as error3;
|
||||
| ^^^^^^^^^^^^^ cannot infer type
|
||||
|
|
||||
note: multiple `impl`s satisfying `_: Trait<'static, i32, 123>` found
|
||||
--> $DIR/free-to-trait-static-reuse.rs:12:1
|
||||
--> $DIR/free-to-trait-static-reuse.rs:14:1
|
||||
|
|
||||
LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -69,13 +101,13 @@ LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/free-to-trait-static-reuse.rs:26:14
|
||||
--> $DIR/free-to-trait-static-reuse.rs:31:14
|
||||
|
|
||||
LL | reuse Trait::static_method::<'static, Vec<i32>, false> as error4 { self + 4 }
|
||||
| ^^^^^^^^^^^^^ cannot infer type
|
||||
|
|
||||
note: multiple `impl`s satisfying `_: Trait<'a, T, X>` found
|
||||
--> $DIR/free-to-trait-static-reuse.rs:12:1
|
||||
--> $DIR/free-to-trait-static-reuse.rs:14:1
|
||||
|
|
||||
LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -84,13 +116,13 @@ LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `String: Trait<'a, T, X>` is not satisfied
|
||||
--> $DIR/free-to-trait-static-reuse.rs:29:8
|
||||
--> $DIR/free-to-trait-static-reuse.rs:35:8
|
||||
|
|
||||
LL | reuse <String as Trait>::static_method as error5;
|
||||
| ^^^^^^ the trait `Trait<'a, T, X>` is not implemented for `String`
|
||||
|
|
||||
help: the following other types implement trait `Trait<'a, T, X>`
|
||||
--> $DIR/free-to-trait-static-reuse.rs:12:1
|
||||
--> $DIR/free-to-trait-static-reuse.rs:14:1
|
||||
|
|
||||
LL | impl<'a, T, const X: usize> Trait<'a, T, X> for usize {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `usize`
|
||||
@@ -99,23 +131,23 @@ LL | impl<'a, T, const X: usize> Trait<'a, T, X> for Struct {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Struct`
|
||||
|
||||
error[E0277]: the trait bound `Struct: Bound<T>` is not satisfied
|
||||
--> $DIR/free-to-trait-static-reuse.rs:36:8
|
||||
--> $DIR/free-to-trait-static-reuse.rs:42:8
|
||||
|
|
||||
LL | reuse <Struct as Trait>::static_method as error6;
|
||||
| ^^^^^^ unsatisfied trait bound
|
||||
|
|
||||
help: the trait `Bound<T>` is not implemented for `Struct`
|
||||
--> $DIR/free-to-trait-static-reuse.rs:32:1
|
||||
--> $DIR/free-to-trait-static-reuse.rs:38:1
|
||||
|
|
||||
LL | struct Struct;
|
||||
| ^^^^^^^^^^^^^
|
||||
help: the trait `Bound<T>` is implemented for `usize`
|
||||
--> $DIR/free-to-trait-static-reuse.rs:13:1
|
||||
--> $DIR/free-to-trait-static-reuse.rs:15:1
|
||||
|
|
||||
LL | impl<T> Bound<T> for usize {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `Trait::static_method`
|
||||
--> $DIR/free-to-trait-static-reuse.rs:7:11
|
||||
--> $DIR/free-to-trait-static-reuse.rs:9:11
|
||||
|
|
||||
LL | Self: Bound<T>,
|
||||
| ^^^^^^^^ required by this bound in `Trait::static_method`
|
||||
@@ -123,7 +155,7 @@ LL | {
|
||||
LL | fn static_method<'c: 'c, U, const B: bool>(x: usize) {}
|
||||
| ------------- required by a bound in this associated function
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0283.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
//@ compile-flags: -Z deduplicate-diagnostics=yes
|
||||
|
||||
#![feature(fn_delegation)]
|
||||
|
||||
reuse Default::default;
|
||||
//~^ ERROR: delegation self type is not specified
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,10 @@
|
||||
error: delegation self type is not specified
|
||||
--> $DIR/self-ty-ice-156388.rs:5:16
|
||||
|
|
||||
LL | reuse Default::default;
|
||||
| ^^^^^^^
|
||||
|
|
||||
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
//@ compile-flags: -Z deduplicate-diagnostics=yes
|
||||
|
||||
#![feature(fn_delegation)]
|
||||
|
||||
trait Trait {
|
||||
@@ -14,6 +16,7 @@ fn foo(x: i32) -> i32 { x }
|
||||
fn bar<T: Default>(_: T) {
|
||||
reuse Trait::static_method {
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR: delegation self type is not specified
|
||||
let _ = T::Default();
|
||||
//~^ ERROR can't use generic parameters from outer item
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
error[E0401]: can't use generic parameters from outer item
|
||||
--> $DIR/target-expr.rs:17:17
|
||||
--> $DIR/target-expr.rs:20:17
|
||||
|
|
||||
LL | fn bar<T: Default>(_: T) {
|
||||
| - type parameter from outer item
|
||||
LL | reuse Trait::static_method {
|
||||
| ------------- generic parameter used in this inner delegated function
|
||||
LL |
|
||||
...
|
||||
LL | let _ = T::Default();
|
||||
| ^ use of generic parameter from outer item
|
||||
|
|
||||
= note: nested items are independent from their parent item for everything except for privacy and name resolution
|
||||
|
||||
error[E0434]: can't capture dynamic environment in a fn item
|
||||
--> $DIR/target-expr.rs:25:17
|
||||
--> $DIR/target-expr.rs:28:17
|
||||
|
|
||||
LL | let x = y;
|
||||
| ^
|
||||
@@ -20,7 +20,7 @@ LL | let x = y;
|
||||
= help: use the `|| { ... }` closure form instead
|
||||
|
||||
error[E0424]: expected value, found module `self`
|
||||
--> $DIR/target-expr.rs:32:5
|
||||
--> $DIR/target-expr.rs:35:5
|
||||
|
|
||||
LL | fn main() {
|
||||
| ---- this function can't have a `self` parameter
|
||||
@@ -29,29 +29,38 @@ LL | self.0;
|
||||
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
|
||||
|
||||
error[E0425]: cannot find value `x` in this scope
|
||||
--> $DIR/target-expr.rs:34:13
|
||||
--> $DIR/target-expr.rs:37:13
|
||||
|
|
||||
LL | let z = x;
|
||||
| ^
|
||||
|
|
||||
help: the binding `x` is available in a different scope in the same function
|
||||
--> $DIR/target-expr.rs:25:13
|
||||
--> $DIR/target-expr.rs:28:13
|
||||
|
|
||||
LL | let x = y;
|
||||
| ^
|
||||
|
||||
error: delegation self type is not specified
|
||||
--> $DIR/target-expr.rs:17:18
|
||||
|
|
||||
LL | reuse Trait::static_method {
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/target-expr.rs:15:32
|
||||
--> $DIR/target-expr.rs:17:32
|
||||
|
|
||||
LL | reuse Trait::static_method {
|
||||
| ________________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let _ = T::Default();
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_____^ expected `i32`, found `()`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0401, E0424, E0425, E0434.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
||||
@@ -1,41 +1,49 @@
|
||||
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:28:5: 28:24>::opaque_ret::{anon_assoc#0}`
|
||||
--> $DIR/unsupported.rs:29:25
|
||||
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:29:5: 29:24>::opaque_ret::{anon_assoc#0}`
|
||||
--> $DIR/unsupported.rs:30:25
|
||||
|
|
||||
LL | reuse to_reuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
|
||||
--> $DIR/unsupported.rs:29:25
|
||||
--> $DIR/unsupported.rs:30:25
|
||||
|
|
||||
LL | reuse to_reuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
= note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:28:5: 28:24>::opaque_ret::{anon_assoc#0}`, completing the cycle
|
||||
note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:28:5: 28:24>::opaque_ret` is compatible with trait definition
|
||||
--> $DIR/unsupported.rs:29:25
|
||||
= note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:29:5: 29:24>::opaque_ret::{anon_assoc#0}`, completing the cycle
|
||||
note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:29:5: 29:24>::opaque_ret` is compatible with trait definition
|
||||
--> $DIR/unsupported.rs:30:25
|
||||
|
|
||||
LL | reuse to_reuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:31:5: 31:25>::opaque_ret::{anon_assoc#0}`
|
||||
--> $DIR/unsupported.rs:32:24
|
||||
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret::{anon_assoc#0}`
|
||||
--> $DIR/unsupported.rs:33:24
|
||||
|
|
||||
LL | reuse ToReuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
|
||||
--> $DIR/unsupported.rs:32:24
|
||||
--> $DIR/unsupported.rs:33:24
|
||||
|
|
||||
LL | reuse ToReuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
= note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:31:5: 31:25>::opaque_ret::{anon_assoc#0}`, completing the cycle
|
||||
note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:31:5: 31:25>::opaque_ret` is compatible with trait definition
|
||||
--> $DIR/unsupported.rs:32:24
|
||||
= note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret::{anon_assoc#0}`, completing the cycle
|
||||
note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret` is compatible with trait definition
|
||||
--> $DIR/unsupported.rs:33:24
|
||||
|
|
||||
LL | reuse ToReuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: delegation self type is not specified
|
||||
--> $DIR/unsupported.rs:54:18
|
||||
|
|
||||
LL | reuse Trait::foo;
|
||||
| ^^^
|
||||
|
|
||||
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0391`.
|
||||
|
||||
@@ -1,41 +1,49 @@
|
||||
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:28:5: 28:24>::opaque_ret::{anon_assoc#0}`
|
||||
--> $DIR/unsupported.rs:29:25
|
||||
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:29:5: 29:24>::opaque_ret::{anon_assoc#0}`
|
||||
--> $DIR/unsupported.rs:30:25
|
||||
|
|
||||
LL | reuse to_reuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
|
||||
--> $DIR/unsupported.rs:29:25
|
||||
--> $DIR/unsupported.rs:30:25
|
||||
|
|
||||
LL | reuse to_reuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
= note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:28:5: 28:24>::opaque_ret::{anon_assoc#0}`, completing the cycle
|
||||
note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:28:5: 28:24>::opaque_ret` is compatible with trait definition
|
||||
--> $DIR/unsupported.rs:29:25
|
||||
= note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:29:5: 29:24>::opaque_ret::{anon_assoc#0}`, completing the cycle
|
||||
note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:29:5: 29:24>::opaque_ret` is compatible with trait definition
|
||||
--> $DIR/unsupported.rs:30:25
|
||||
|
|
||||
LL | reuse to_reuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:31:5: 31:25>::opaque_ret::{anon_assoc#0}`
|
||||
--> $DIR/unsupported.rs:32:24
|
||||
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret::{anon_assoc#0}`
|
||||
--> $DIR/unsupported.rs:33:24
|
||||
|
|
||||
LL | reuse ToReuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
|
||||
--> $DIR/unsupported.rs:32:24
|
||||
--> $DIR/unsupported.rs:33:24
|
||||
|
|
||||
LL | reuse ToReuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
= note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:31:5: 31:25>::opaque_ret::{anon_assoc#0}`, completing the cycle
|
||||
note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:31:5: 31:25>::opaque_ret` is compatible with trait definition
|
||||
--> $DIR/unsupported.rs:32:24
|
||||
= note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret::{anon_assoc#0}`, completing the cycle
|
||||
note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret` is compatible with trait definition
|
||||
--> $DIR/unsupported.rs:33:24
|
||||
|
|
||||
LL | reuse ToReuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: delegation self type is not specified
|
||||
--> $DIR/unsupported.rs:54:18
|
||||
|
|
||||
LL | reuse Trait::foo;
|
||||
| ^^^
|
||||
|
|
||||
= help: consider explicitly specifying self type: `reuse </* Type */ as Trait>::function`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0391`.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//@ compile-flags: -Z deduplicate-diagnostics=yes
|
||||
//@ revisions: current next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
@@ -51,6 +52,7 @@ const trait Trait {
|
||||
}
|
||||
|
||||
reuse Trait::foo;
|
||||
//~^ ERROR: delegation self type is not specified
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
//@ no-prefer-dynamic
|
||||
//@ needs-crate-type: dylib
|
||||
#![crate_type = "dylib"]
|
||||
#![feature(extern_item_impls)]
|
||||
|
||||
#[eii(eii1)] //~ ERROR `#[eii1]` required, but not found
|
||||
fn decl1(x: u64);
|
||||
@@ -0,0 +1,10 @@
|
||||
error: `#[eii1]` required, but not found
|
||||
--> $DIR/dylib_needs_impl.rs:6:7
|
||||
|
|
||||
LL | #[eii(eii1)]
|
||||
| ^^^^ expected because `#[eii1]` was declared here in crate `dylib_needs_impl`
|
||||
|
|
||||
= help: expected at least one implementation in crate `dylib_needs_impl` or any of its dependencies
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
@@ -17,6 +17,14 @@ fn pin_drop(&pin mut self) {} //~ ERROR pinned reference syntax is experimental
|
||||
//~^ ERROR use of unstable library feature `pin_ergonomics` [E0658]
|
||||
}
|
||||
|
||||
struct Sugar;
|
||||
|
||||
impl Drop for Sugar {
|
||||
//~^ ERROR not all trait items implemented, missing: `drop`
|
||||
fn drop(&pin mut self) {} //~ ERROR pinned reference syntax is experimental
|
||||
//~^ ERROR use of unstable library feature `pin_ergonomics` [E0658]
|
||||
}
|
||||
|
||||
fn foo(mut x: Pin<&mut Foo>) {
|
||||
Foo::foo_sugar(x.as_mut());
|
||||
Foo::foo_sugar_const(x.as_ref());
|
||||
|
||||
@@ -29,7 +29,17 @@ LL | fn pin_drop(&pin mut self) {}
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:23:14
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:24:14
|
||||
|
|
||||
LL | fn drop(&pin mut self) {}
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
|
||||
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:31:14
|
||||
|
|
||||
LL | let _y: &pin mut Foo = x;
|
||||
| ^^^
|
||||
@@ -39,7 +49,7 @@ LL | let _y: &pin mut Foo = x;
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:27:14
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:35:14
|
||||
|
|
||||
LL | let _y: &pin const Foo = x;
|
||||
| ^^^
|
||||
@@ -49,7 +59,7 @@ LL | let _y: &pin const Foo = x;
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:30:18
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:38:18
|
||||
|
|
||||
LL | fn foo_sugar(_: &pin mut Foo) {}
|
||||
| ^^^
|
||||
@@ -59,7 +69,7 @@ LL | fn foo_sugar(_: &pin mut Foo) {}
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:42:18
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:50:18
|
||||
|
|
||||
LL | fn baz_sugar(_: &pin const Foo) {}
|
||||
| ^^^
|
||||
@@ -69,7 +79,7 @@ LL | fn baz_sugar(_: &pin const Foo) {}
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:45:31
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:53:31
|
||||
|
|
||||
LL | let mut x: Pin<&mut _> = &pin mut Foo;
|
||||
| ^^^
|
||||
@@ -79,7 +89,7 @@ LL | let mut x: Pin<&mut _> = &pin mut Foo;
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:50:23
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:58:23
|
||||
|
|
||||
LL | let x: Pin<&_> = &pin const Foo;
|
||||
| ^^^
|
||||
@@ -89,7 +99,7 @@ LL | let x: Pin<&_> = &pin const Foo;
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:57:6
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:65:6
|
||||
|
|
||||
LL | &pin mut x: &pin mut i32,
|
||||
| ^^^
|
||||
@@ -99,7 +109,7 @@ LL | &pin mut x: &pin mut i32,
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:57:18
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:65:18
|
||||
|
|
||||
LL | &pin mut x: &pin mut i32,
|
||||
| ^^^
|
||||
@@ -109,7 +119,7 @@ LL | &pin mut x: &pin mut i32,
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:60:6
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:68:6
|
||||
|
|
||||
LL | &pin const y: &'a pin const i32,
|
||||
| ^^^
|
||||
@@ -119,7 +129,7 @@ LL | &pin const y: &'a pin const i32,
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:60:23
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:68:23
|
||||
|
|
||||
LL | &pin const y: &'a pin const i32,
|
||||
| ^^^
|
||||
@@ -129,7 +139,7 @@ LL | &pin const y: &'a pin const i32,
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:63:9
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:71:9
|
||||
|
|
||||
LL | ref pin mut z: i32,
|
||||
| ^^^
|
||||
@@ -139,7 +149,7 @@ LL | ref pin mut z: i32,
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:64:9
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:72:9
|
||||
|
|
||||
LL | ref pin const w: i32,
|
||||
| ^^^
|
||||
@@ -149,7 +159,7 @@ LL | ref pin const w: i32,
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:76:23
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:84:23
|
||||
|
|
||||
LL | fn foo_sugar(&pin mut self) {}
|
||||
| ^^^
|
||||
@@ -159,7 +169,7 @@ LL | fn foo_sugar(&pin mut self) {}
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:77:29
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:85:29
|
||||
|
|
||||
LL | fn foo_sugar_const(&pin const self) {}
|
||||
| ^^^
|
||||
@@ -169,7 +179,7 @@ LL | fn foo_sugar_const(&pin const self) {}
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:81:22
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:89:22
|
||||
|
|
||||
LL | fn pin_drop(&pin mut self) {}
|
||||
| ^^^
|
||||
@@ -179,7 +189,7 @@ LL | fn pin_drop(&pin mut self) {}
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:87:18
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:95:18
|
||||
|
|
||||
LL | let _y: &pin mut Foo = x;
|
||||
| ^^^
|
||||
@@ -189,7 +199,7 @@ LL | let _y: &pin mut Foo = x;
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:90:22
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:98:22
|
||||
|
|
||||
LL | fn foo_sugar(_: &pin mut Foo) {}
|
||||
| ^^^
|
||||
@@ -199,7 +209,7 @@ LL | fn foo_sugar(_: &pin mut Foo) {}
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:102:22
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:110:22
|
||||
|
|
||||
LL | fn baz_sugar(_: &pin const Foo) {}
|
||||
| ^^^
|
||||
@@ -209,7 +219,7 @@ LL | fn baz_sugar(_: &pin const Foo) {}
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:105:35
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:113:35
|
||||
|
|
||||
LL | let mut x: Pin<&mut _> = &pin mut Foo;
|
||||
| ^^^
|
||||
@@ -219,7 +229,7 @@ LL | let mut x: Pin<&mut _> = &pin mut Foo;
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:110:27
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:118:27
|
||||
|
|
||||
LL | let x: Pin<&_> = &pin const Foo;
|
||||
| ^^^
|
||||
@@ -229,7 +239,7 @@ LL | let x: Pin<&_> = &pin const Foo;
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:117:10
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:125:10
|
||||
|
|
||||
LL | &pin mut x: &pin mut i32,
|
||||
| ^^^
|
||||
@@ -239,7 +249,7 @@ LL | &pin mut x: &pin mut i32,
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:117:22
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:125:22
|
||||
|
|
||||
LL | &pin mut x: &pin mut i32,
|
||||
| ^^^
|
||||
@@ -249,7 +259,7 @@ LL | &pin mut x: &pin mut i32,
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:120:10
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:128:10
|
||||
|
|
||||
LL | &pin const y: &'a pin const i32,
|
||||
| ^^^
|
||||
@@ -259,7 +269,7 @@ LL | &pin const y: &'a pin const i32,
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:120:27
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:128:27
|
||||
|
|
||||
LL | &pin const y: &'a pin const i32,
|
||||
| ^^^
|
||||
@@ -269,7 +279,7 @@ LL | &pin const y: &'a pin const i32,
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:123:13
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:131:13
|
||||
|
|
||||
LL | ref pin mut z: i32,
|
||||
| ^^^
|
||||
@@ -279,7 +289,7 @@ LL | ref pin mut z: i32,
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: pinned reference syntax is experimental
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:124:13
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:132:13
|
||||
|
|
||||
LL | ref pin const w: i32,
|
||||
| ^^^
|
||||
@@ -308,6 +318,16 @@ LL | fn pin_drop(&pin mut self) {}
|
||||
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: use of unstable library feature `pin_ergonomics`
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:24:5
|
||||
|
|
||||
LL | fn drop(&pin mut self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
|
||||
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0046]: not all trait items implemented, missing: `drop`
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:14:1
|
||||
|
|
||||
@@ -316,8 +336,16 @@ LL | impl Drop for Foo {
|
||||
|
|
||||
= help: implement the missing item: `fn drop(&mut self) { todo!() }`
|
||||
|
||||
error[E0046]: not all trait items implemented, missing: `drop`
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:22:1
|
||||
|
|
||||
LL | impl Drop for Sugar {
|
||||
| ^^^^^^^^^^^^^^^^^^^ missing `drop` in implementation
|
||||
|
|
||||
= help: implement the missing item: `fn drop(&mut self) { todo!() }`
|
||||
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:34:9
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:42:9
|
||||
|
|
||||
LL | fn bar(x: Pin<&mut Foo>) {
|
||||
| - move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
|
||||
@@ -327,7 +355,7 @@ LL | foo(x);
|
||||
| ^ value used here after move
|
||||
|
|
||||
note: consider changing this parameter type in function `foo` to borrow instead if owning the value isn't necessary
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:20:15
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:28:15
|
||||
|
|
||||
LL | fn foo(mut x: Pin<&mut Foo>) {
|
||||
| --- ^^^^^^^^^^^^^ this parameter takes ownership of the value
|
||||
@@ -335,7 +363,7 @@ LL | fn foo(mut x: Pin<&mut Foo>) {
|
||||
| in this function
|
||||
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:39:5
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:47:5
|
||||
|
|
||||
LL | fn baz(mut x: Pin<&mut Foo>) {
|
||||
| ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
|
||||
@@ -354,7 +382,7 @@ help: consider reborrowing the `Pin` instead of moving it
|
||||
LL | x.as_mut().foo();
|
||||
| +++++++++
|
||||
|
||||
error: aborting due to 34 previous errors
|
||||
error: aborting due to 37 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0046, E0382, E0658.
|
||||
For more information about an error, try `rustc --explain E0046`.
|
||||
|
||||
@@ -25,11 +25,11 @@ mod pin_drop_only {
|
||||
struct Bar;
|
||||
|
||||
impl Drop for Foo {
|
||||
fn pin_drop(&pin mut self) {} // ok, only `pin_drop` is implemented
|
||||
fn pin_drop(&pin mut self) {} // ok, non-`#[pin_v2]` can also implement `pin_drop`
|
||||
}
|
||||
|
||||
impl Drop for Bar {
|
||||
fn pin_drop(&pin mut self) {} // ok, non-`#[pin_v2]` can also implement `pin_drop`
|
||||
fn pin_drop(&pin mut self) {} // ok, `#[pin_v2]` implements `pin_drop`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,16 +60,67 @@ impl Drop for Foo {} //~ ERROR not all trait items implemented, missing one of:
|
||||
impl Drop for Bar {} //~ ERROR not all trait items implemented, missing one of: `drop`, `pin_drop` [E0046]
|
||||
}
|
||||
|
||||
mod drop_wrong_type {
|
||||
mod drop_sugar {
|
||||
struct Foo;
|
||||
#[pin_v2]
|
||||
struct Bar;
|
||||
|
||||
impl Drop for Foo {
|
||||
fn drop(&pin mut self) {} //~ ERROR method `drop` has an incompatible type for trait [E0053]
|
||||
fn drop(&pin mut self) {} // ok, sugar for `pin_drop`
|
||||
}
|
||||
|
||||
impl Drop for Bar {
|
||||
fn drop(&pin mut self) {}
|
||||
fn drop(&pin mut self) {} // ok, sugar for `pin_drop`
|
||||
}
|
||||
}
|
||||
|
||||
mod drop_pin_const_wrong_type {
|
||||
struct Foo;
|
||||
#[pin_v2]
|
||||
struct Bar;
|
||||
|
||||
impl Drop for Foo {
|
||||
fn drop(&pin const self) {} //~ ERROR method `drop` has an incompatible type for trait [E0053]
|
||||
}
|
||||
|
||||
impl Drop for Bar {
|
||||
fn drop(&pin const self) {}
|
||||
//~^ ERROR method `drop` has an incompatible type for trait [E0053]
|
||||
//~| ERROR `Bar` must implement `pin_drop`
|
||||
}
|
||||
}
|
||||
|
||||
mod drop_with_lifetime_wrong_type {
|
||||
struct Foo;
|
||||
#[pin_v2]
|
||||
struct Bar;
|
||||
|
||||
impl Drop for Foo {
|
||||
fn drop<'a>(&'a pin mut self) {}
|
||||
//~^ ERROR method `drop` has an incompatible type for trait [E0053]
|
||||
}
|
||||
|
||||
impl Drop for Bar {
|
||||
fn drop<'a>(&'a pin mut self) {}
|
||||
//~^ ERROR method `drop` has an incompatible type for trait [E0053]
|
||||
//~| ERROR `Bar` must implement `pin_drop`
|
||||
}
|
||||
}
|
||||
|
||||
mod drop_explicit_pin_wrong_type {
|
||||
use std::pin::Pin;
|
||||
|
||||
struct Foo;
|
||||
#[pin_v2]
|
||||
struct Bar;
|
||||
|
||||
impl Drop for Foo {
|
||||
fn drop(self: Pin<&mut Self>) {}
|
||||
//~^ ERROR method `drop` has an incompatible type for trait [E0053]
|
||||
}
|
||||
|
||||
impl Drop for Bar {
|
||||
fn drop(self: Pin<&mut Self>) {}
|
||||
//~^ ERROR method `drop` has an incompatible type for trait [E0053]
|
||||
//~| ERROR `Bar` must implement `pin_drop`
|
||||
}
|
||||
@@ -124,4 +175,31 @@ fn pin_drop(&pin mut self) {
|
||||
}
|
||||
}
|
||||
|
||||
mod explicit_call_drop_sugar {
|
||||
struct Foo;
|
||||
|
||||
impl Drop for Foo {
|
||||
fn drop(&pin mut self) {
|
||||
Drop::drop(todo!()); //~ ERROR explicit use of destructor method [E0040]
|
||||
Drop::pin_drop(todo!()); //~ ERROR explicit use of destructor method [E0040]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod sugar_and_pin_drop {
|
||||
struct Foo;
|
||||
#[pin_v2]
|
||||
struct Bar;
|
||||
|
||||
impl Drop for Foo {
|
||||
fn drop(&pin mut self) {}
|
||||
fn pin_drop(&pin mut self) {} //~ ERROR duplicate definitions with name `pin_drop`
|
||||
}
|
||||
|
||||
impl Drop for Bar {
|
||||
fn drop(&pin mut self) {}
|
||||
fn pin_drop(&pin mut self) {} //~ ERROR duplicate definitions with name `pin_drop`
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -1,3 +1,27 @@
|
||||
error[E0201]: duplicate definitions with name `pin_drop`:
|
||||
--> $DIR/pinned-drop-check.rs:196:9
|
||||
|
|
||||
LL | fn drop(&pin mut self) {}
|
||||
| ------------------------- previous definition here
|
||||
LL | fn pin_drop(&pin mut self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definition
|
||||
|
|
||||
--> $SRC_DIR/core/src/ops/drop.rs:LL:COL
|
||||
|
|
||||
= note: item in trait
|
||||
|
||||
error[E0201]: duplicate definitions with name `pin_drop`:
|
||||
--> $DIR/pinned-drop-check.rs:201:9
|
||||
|
|
||||
LL | fn drop(&pin mut self) {}
|
||||
| ------------------------- previous definition here
|
||||
LL | fn pin_drop(&pin mut self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definition
|
||||
|
|
||||
--> $SRC_DIR/core/src/ops/drop.rs:LL:COL
|
||||
|
|
||||
= note: item in trait
|
||||
|
||||
error: `Bar` must implement `pin_drop`
|
||||
--> $DIR/pinned-drop-check.rs:18:9
|
||||
|
|
||||
@@ -55,56 +79,157 @@ LL | impl Drop for Bar {}
|
||||
| ^^^^^^^^^^^^^^^^^ missing one of `drop`, `pin_drop` in implementation
|
||||
|
||||
error: `Bar` must implement `pin_drop`
|
||||
--> $DIR/pinned-drop-check.rs:72:9
|
||||
--> $DIR/pinned-drop-check.rs:87:9
|
||||
|
|
||||
LL | fn drop(&pin mut self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | fn drop(&pin const self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: structurally pinned types must keep `Pin`'s safety contract
|
||||
note: `Bar` is marked `#[pin_v2]` here
|
||||
--> $DIR/pinned-drop-check.rs:65:5
|
||||
--> $DIR/pinned-drop-check.rs:79:5
|
||||
|
|
||||
LL | #[pin_v2]
|
||||
| ^^^^^^^^^
|
||||
help: implement `pin_drop` instead
|
||||
|
|
||||
LL | fn pin_drop(&pin mut self) {}
|
||||
| ++++
|
||||
LL - fn drop(&pin const self) {}
|
||||
LL + fn pin_drop(&pin mut self) {}
|
||||
|
|
||||
help: remove the `#[pin_v2]` attribute if it is not intended for structurally pinning
|
||||
|
|
||||
LL - #[pin_v2]
|
||||
|
|
||||
|
||||
error[E0053]: method `drop` has an incompatible type for trait
|
||||
--> $DIR/pinned-drop-check.rs:69:17
|
||||
--> $DIR/pinned-drop-check.rs:83:17
|
||||
|
|
||||
LL | fn drop(&pin mut self) {}
|
||||
| ^^^^^^^^^^^^^ expected `&mut drop_wrong_type::Foo`, found `Pin<&mut drop_wrong_type::Foo>`
|
||||
LL | fn drop(&pin const self) {}
|
||||
| ^^^^^^^^^^^^^^^ expected `&mut drop_pin_const_wrong_type::Foo`, found `Pin<&drop_pin_const_wrong_type::Foo>`
|
||||
|
|
||||
= note: expected signature `fn(&mut drop_wrong_type::Foo)`
|
||||
found signature `fn(Pin<&mut drop_wrong_type::Foo>)`
|
||||
= note: expected signature `fn(&mut drop_pin_const_wrong_type::Foo)`
|
||||
found signature `fn(Pin<&drop_pin_const_wrong_type::Foo>)`
|
||||
help: change the self-receiver type to match the trait
|
||||
|
|
||||
LL - fn drop(&pin mut self) {}
|
||||
LL - fn drop(&pin const self) {}
|
||||
LL + fn drop(&mut self) {}
|
||||
|
|
||||
|
||||
error[E0053]: method `drop` has an incompatible type for trait
|
||||
--> $DIR/pinned-drop-check.rs:72:17
|
||||
--> $DIR/pinned-drop-check.rs:87:17
|
||||
|
|
||||
LL | fn drop(&pin mut self) {}
|
||||
| ^^^^^^^^^^^^^ expected `&mut drop_wrong_type::Bar`, found `Pin<&mut drop_wrong_type::Bar>`
|
||||
LL | fn drop(&pin const self) {}
|
||||
| ^^^^^^^^^^^^^^^ expected `&mut drop_pin_const_wrong_type::Bar`, found `Pin<&drop_pin_const_wrong_type::Bar>`
|
||||
|
|
||||
= note: expected signature `fn(&mut drop_wrong_type::Bar)`
|
||||
found signature `fn(Pin<&mut drop_wrong_type::Bar>)`
|
||||
= note: expected signature `fn(&mut drop_pin_const_wrong_type::Bar)`
|
||||
found signature `fn(Pin<&drop_pin_const_wrong_type::Bar>)`
|
||||
help: change the self-receiver type to match the trait
|
||||
|
|
||||
LL - fn drop(&pin mut self) {}
|
||||
LL - fn drop(&pin const self) {}
|
||||
LL + fn drop(&mut self) {}
|
||||
|
|
||||
|
||||
error: `Bar` must implement `pin_drop`
|
||||
--> $DIR/pinned-drop-check.rs:104:9
|
||||
|
|
||||
LL | fn drop<'a>(&'a pin mut self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: structurally pinned types must keep `Pin`'s safety contract
|
||||
note: `Bar` is marked `#[pin_v2]` here
|
||||
--> $DIR/pinned-drop-check.rs:95:5
|
||||
|
|
||||
LL | #[pin_v2]
|
||||
| ^^^^^^^^^
|
||||
help: implement `pin_drop` instead
|
||||
|
|
||||
LL - fn drop<'a>(&'a pin mut self) {}
|
||||
LL + fn pin_drop(&pin mut self) {}
|
||||
|
|
||||
help: remove the `#[pin_v2]` attribute if it is not intended for structurally pinning
|
||||
|
|
||||
LL - #[pin_v2]
|
||||
|
|
||||
|
||||
error[E0053]: method `drop` has an incompatible type for trait
|
||||
--> $DIR/pinned-drop-check.rs:99:21
|
||||
|
|
||||
LL | fn drop<'a>(&'a pin mut self) {}
|
||||
| ^^^^^^^^^^^^^^^^ expected `&mut drop_with_lifetime_wrong_type::Foo`, found `Pin<&mut Foo>`
|
||||
|
|
||||
= note: expected signature `fn(&mut drop_with_lifetime_wrong_type::Foo)`
|
||||
found signature `fn(Pin<&mut drop_with_lifetime_wrong_type::Foo>)`
|
||||
help: change the self-receiver type to match the trait
|
||||
|
|
||||
LL - fn drop<'a>(&'a pin mut self) {}
|
||||
LL + fn drop<'a>(&mut self) {}
|
||||
|
|
||||
|
||||
error[E0053]: method `drop` has an incompatible type for trait
|
||||
--> $DIR/pinned-drop-check.rs:104:21
|
||||
|
|
||||
LL | fn drop<'a>(&'a pin mut self) {}
|
||||
| ^^^^^^^^^^^^^^^^ expected `&mut drop_with_lifetime_wrong_type::Bar`, found `Pin<&mut Bar>`
|
||||
|
|
||||
= note: expected signature `fn(&mut drop_with_lifetime_wrong_type::Bar)`
|
||||
found signature `fn(Pin<&mut drop_with_lifetime_wrong_type::Bar>)`
|
||||
help: change the self-receiver type to match the trait
|
||||
|
|
||||
LL - fn drop<'a>(&'a pin mut self) {}
|
||||
LL + fn drop<'a>(&mut self) {}
|
||||
|
|
||||
|
||||
error: `Bar` must implement `pin_drop`
|
||||
--> $DIR/pinned-drop-check.rs:123:9
|
||||
|
|
||||
LL | fn drop(self: Pin<&mut Self>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: structurally pinned types must keep `Pin`'s safety contract
|
||||
note: `Bar` is marked `#[pin_v2]` here
|
||||
--> $DIR/pinned-drop-check.rs:114:5
|
||||
|
|
||||
LL | #[pin_v2]
|
||||
| ^^^^^^^^^
|
||||
help: implement `pin_drop` instead
|
||||
|
|
||||
LL - fn drop(self: Pin<&mut Self>) {}
|
||||
LL + fn pin_drop(&pin mut self) {}
|
||||
|
|
||||
help: remove the `#[pin_v2]` attribute if it is not intended for structurally pinning
|
||||
|
|
||||
LL - #[pin_v2]
|
||||
|
|
||||
|
||||
error[E0053]: method `drop` has an incompatible type for trait
|
||||
--> $DIR/pinned-drop-check.rs:118:23
|
||||
|
|
||||
LL | fn drop(self: Pin<&mut Self>) {}
|
||||
| ^^^^^^^^^^^^^^ expected `&mut drop_explicit_pin_wrong_type::Foo`, found `Pin<&mut Foo>`
|
||||
|
|
||||
= note: expected signature `fn(&mut drop_explicit_pin_wrong_type::Foo)`
|
||||
found signature `fn(Pin<&mut drop_explicit_pin_wrong_type::Foo>)`
|
||||
help: change the self-receiver type to match the trait
|
||||
|
|
||||
LL - fn drop(self: Pin<&mut Self>) {}
|
||||
LL + fn drop(&mut self) {}
|
||||
|
|
||||
|
||||
error[E0053]: method `drop` has an incompatible type for trait
|
||||
--> $DIR/pinned-drop-check.rs:123:23
|
||||
|
|
||||
LL | fn drop(self: Pin<&mut Self>) {}
|
||||
| ^^^^^^^^^^^^^^ expected `&mut drop_explicit_pin_wrong_type::Bar`, found `Pin<&mut Bar>`
|
||||
|
|
||||
= note: expected signature `fn(&mut drop_explicit_pin_wrong_type::Bar)`
|
||||
found signature `fn(Pin<&mut drop_explicit_pin_wrong_type::Bar>)`
|
||||
help: change the self-receiver type to match the trait
|
||||
|
|
||||
LL - fn drop(self: Pin<&mut Self>) {}
|
||||
LL + fn drop(&mut self) {}
|
||||
|
|
||||
|
||||
error[E0053]: method `pin_drop` has an incompatible type for trait
|
||||
--> $DIR/pinned-drop-check.rs:84:21
|
||||
--> $DIR/pinned-drop-check.rs:135:21
|
||||
|
|
||||
LL | fn pin_drop(&mut self) {}
|
||||
| ^^^^^^^^^ expected `Pin<&mut pin_drop_wrong_type::Foo>`, found `&mut pin_drop_wrong_type::Foo`
|
||||
@@ -118,7 +243,7 @@ LL + fn pin_drop(self: Pin<&mut pin_drop_wrong_type::Foo>) {}
|
||||
|
|
||||
|
||||
error[E0053]: method `pin_drop` has an incompatible type for trait
|
||||
--> $DIR/pinned-drop-check.rs:88:21
|
||||
--> $DIR/pinned-drop-check.rs:139:21
|
||||
|
|
||||
LL | fn pin_drop(&mut self) {}
|
||||
| ^^^^^^^^^ expected `Pin<&mut pin_drop_wrong_type::Bar>`, found `&mut pin_drop_wrong_type::Bar`
|
||||
@@ -132,14 +257,14 @@ LL + fn pin_drop(self: Pin<&mut pin_drop_wrong_type::Bar>) {}
|
||||
|
|
||||
|
||||
error: `Bar` must implement `pin_drop`
|
||||
--> $DIR/pinned-drop-check.rs:103:9
|
||||
--> $DIR/pinned-drop-check.rs:154:9
|
||||
|
|
||||
LL | fn drop(&mut self) {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: structurally pinned types must keep `Pin`'s safety contract
|
||||
note: `Bar` is marked `#[pin_v2]` here
|
||||
--> $DIR/pinned-drop-check.rs:94:5
|
||||
--> $DIR/pinned-drop-check.rs:145:5
|
||||
|
|
||||
LL | #[pin_v2]
|
||||
| ^^^^^^^^^
|
||||
@@ -154,30 +279,42 @@ LL - #[pin_v2]
|
||||
|
|
||||
|
||||
error[E0040]: explicit use of destructor method
|
||||
--> $DIR/pinned-drop-check.rs:99:13
|
||||
--> $DIR/pinned-drop-check.rs:150:13
|
||||
|
|
||||
LL | Drop::pin_drop(todo!());
|
||||
| ^^^^^^^^^^^^^^ explicit destructor calls not allowed
|
||||
|
||||
error[E0040]: explicit use of destructor method
|
||||
--> $DIR/pinned-drop-check.rs:105:13
|
||||
--> $DIR/pinned-drop-check.rs:156:13
|
||||
|
|
||||
LL | Drop::pin_drop(todo!());
|
||||
| ^^^^^^^^^^^^^^ explicit destructor calls not allowed
|
||||
|
||||
error[E0040]: explicit use of destructor method
|
||||
--> $DIR/pinned-drop-check.rs:117:13
|
||||
--> $DIR/pinned-drop-check.rs:168:13
|
||||
|
|
||||
LL | Drop::drop(todo!());
|
||||
| ^^^^^^^^^^ explicit destructor calls not allowed
|
||||
|
||||
error[E0040]: explicit use of destructor method
|
||||
--> $DIR/pinned-drop-check.rs:122:13
|
||||
--> $DIR/pinned-drop-check.rs:173:13
|
||||
|
|
||||
LL | Drop::drop(todo!());
|
||||
| ^^^^^^^^^^ explicit destructor calls not allowed
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
error[E0040]: explicit use of destructor method
|
||||
--> $DIR/pinned-drop-check.rs:183:13
|
||||
|
|
||||
LL | Drop::drop(todo!());
|
||||
| ^^^^^^^^^^ explicit destructor calls not allowed
|
||||
|
||||
Some errors have detailed explanations: E0040, E0046, E0053.
|
||||
error[E0040]: explicit use of destructor method
|
||||
--> $DIR/pinned-drop-check.rs:184:13
|
||||
|
|
||||
LL | Drop::pin_drop(todo!());
|
||||
| ^^^^^^^^^^^^^^ explicit destructor calls not allowed
|
||||
|
||||
error: aborting due to 25 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0040, E0046, E0053, E0201.
|
||||
For more information about an error, try `rustc --explain E0040`.
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
//@ check-pass
|
||||
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
#![feature(no_core, pin_ergonomics, lang_items)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
#[lang = "pointee_sized"]
|
||||
trait PointeeSized {}
|
||||
|
||||
#[lang = "meta_sized"]
|
||||
trait MetaSized: PointeeSized {}
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized: MetaSized {}
|
||||
|
||||
#[lang = "copy"]
|
||||
trait Copy {}
|
||||
|
||||
#[lang = "legacy_receiver"]
|
||||
trait LegacyReceiver: PointeeSized {}
|
||||
|
||||
#[lang = "deref"]
|
||||
trait Deref: PointeeSized {
|
||||
#[lang = "deref_target"]
|
||||
type Target: PointeeSized;
|
||||
|
||||
fn deref(&self) -> &Self::Target;
|
||||
}
|
||||
|
||||
#[lang = "deref_mut"]
|
||||
trait DerefMut: Deref + PointeeSized {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target;
|
||||
}
|
||||
|
||||
#[lang = "pin"]
|
||||
struct Pin<T> {
|
||||
pointer: T,
|
||||
}
|
||||
|
||||
impl<T: PointeeSized> LegacyReceiver for &T {}
|
||||
impl<T: PointeeSized> LegacyReceiver for &mut T {}
|
||||
impl<Ptr: LegacyReceiver> LegacyReceiver for Pin<Ptr> {}
|
||||
|
||||
impl<Ptr: Deref> Deref for Pin<Ptr> {
|
||||
type Target = Ptr::Target;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&*self.pointer
|
||||
}
|
||||
}
|
||||
|
||||
impl<Ptr: DerefMut> DerefMut for Pin<Ptr> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut *self.pointer
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PointeeSized> Deref for &mut T {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
struct LocalDrop;
|
||||
|
||||
impl Drop for LocalDrop {
|
||||
fn drop(&pin mut self) {}
|
||||
}
|
||||
|
||||
#[lang = "drop"]
|
||||
trait Drop {
|
||||
fn drop(&mut self) {}
|
||||
fn pin_drop(self: Pin<&mut Self>) {}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
//@ edition:2024
|
||||
|
||||
#![feature(pin_ergonomics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::pin::Pin;
|
||||
|
||||
struct S;
|
||||
|
||||
trait NeedsPinDrop {
|
||||
fn pin_drop(self: Pin<&mut Self>);
|
||||
}
|
||||
|
||||
impl NeedsPinDrop for S {
|
||||
//~^ ERROR not all trait items implemented, missing: `pin_drop` [E0046]
|
||||
fn drop(&pin mut self) {}
|
||||
//~^ ERROR method `drop` with `&pin mut self` is only supported for the `Drop` trait
|
||||
}
|
||||
|
||||
trait HasDrop {
|
||||
fn drop(self: Pin<&mut Self>);
|
||||
}
|
||||
|
||||
impl HasDrop for S {
|
||||
//~^ ERROR not all trait items implemented, missing: `drop` [E0046]
|
||||
fn drop(&pin mut self) {}
|
||||
//~^ ERROR method `drop` is not a member of trait `HasDrop` [E0407]
|
||||
}
|
||||
|
||||
trait HasPinnedDropReceiver {
|
||||
fn drop(self: &pin mut Self);
|
||||
}
|
||||
|
||||
impl HasPinnedDropReceiver for S {
|
||||
//~^ ERROR not all trait items implemented, missing: `drop` [E0046]
|
||||
fn drop(&pin mut self) {}
|
||||
//~^ ERROR method `drop` is not a member of trait `HasPinnedDropReceiver` [E0407]
|
||||
}
|
||||
|
||||
struct Inherent;
|
||||
|
||||
impl Inherent {
|
||||
fn drop(&pin mut self) {}
|
||||
}
|
||||
|
||||
mod local_drop_trait {
|
||||
use std::pin::Pin;
|
||||
|
||||
struct S;
|
||||
|
||||
trait Drop {
|
||||
fn pin_drop(self: Pin<&mut Self>);
|
||||
}
|
||||
|
||||
impl Drop for S {
|
||||
//~^ ERROR not all trait items implemented, missing: `pin_drop` [E0046]
|
||||
fn drop(&pin mut self) {}
|
||||
//~^ ERROR method `drop` with `&pin mut self` is only supported for the `Drop` trait
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,70 @@
|
||||
error[E0407]: method `drop` is not a member of trait `HasDrop`
|
||||
--> $DIR/pinned-drop-sugar-not-other-traits.rs:26:5
|
||||
|
|
||||
LL | fn drop(&pin mut self) {}
|
||||
| ^^^----^^^^^^^^^^^^^^^^^^
|
||||
| | |
|
||||
| | help: there is an associated function with a similar name: `drop`
|
||||
| not a member of trait `HasDrop`
|
||||
|
||||
error[E0407]: method `drop` is not a member of trait `HasPinnedDropReceiver`
|
||||
--> $DIR/pinned-drop-sugar-not-other-traits.rs:36:5
|
||||
|
|
||||
LL | fn drop(&pin mut self) {}
|
||||
| ^^^----^^^^^^^^^^^^^^^^^^
|
||||
| | |
|
||||
| | help: there is an associated function with a similar name: `drop`
|
||||
| not a member of trait `HasPinnedDropReceiver`
|
||||
|
||||
error: method `drop` with `&pin mut self` is only supported for the `Drop` trait
|
||||
--> $DIR/pinned-drop-sugar-not-other-traits.rs:16:5
|
||||
|
|
||||
LL | fn drop(&pin mut self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not a `Drop::pin_drop` implementation
|
||||
|
||||
error: method `drop` with `&pin mut self` is only supported for the `Drop` trait
|
||||
--> $DIR/pinned-drop-sugar-not-other-traits.rs:57:9
|
||||
|
|
||||
LL | fn drop(&pin mut self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not a `Drop::pin_drop` implementation
|
||||
|
||||
error[E0046]: not all trait items implemented, missing: `pin_drop`
|
||||
--> $DIR/pinned-drop-sugar-not-other-traits.rs:14:1
|
||||
|
|
||||
LL | fn pin_drop(self: Pin<&mut Self>);
|
||||
| ---------------------------------- `pin_drop` from trait
|
||||
...
|
||||
LL | impl NeedsPinDrop for S {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ missing `pin_drop` in implementation
|
||||
|
||||
error[E0046]: not all trait items implemented, missing: `drop`
|
||||
--> $DIR/pinned-drop-sugar-not-other-traits.rs:24:1
|
||||
|
|
||||
LL | fn drop(self: Pin<&mut Self>);
|
||||
| ------------------------------ `drop` from trait
|
||||
...
|
||||
LL | impl HasDrop for S {
|
||||
| ^^^^^^^^^^^^^^^^^^ missing `drop` in implementation
|
||||
|
||||
error[E0046]: not all trait items implemented, missing: `drop`
|
||||
--> $DIR/pinned-drop-sugar-not-other-traits.rs:34:1
|
||||
|
|
||||
LL | fn drop(self: &pin mut Self);
|
||||
| ----------------------------- `drop` from trait
|
||||
...
|
||||
LL | impl HasPinnedDropReceiver for S {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `drop` in implementation
|
||||
|
||||
error[E0046]: not all trait items implemented, missing: `pin_drop`
|
||||
--> $DIR/pinned-drop-sugar-not-other-traits.rs:55:5
|
||||
|
|
||||
LL | fn pin_drop(self: Pin<&mut Self>);
|
||||
| ---------------------------------- `pin_drop` from trait
|
||||
...
|
||||
LL | impl Drop for S {
|
||||
| ^^^^^^^^^^^^^^^ missing `pin_drop` in implementation
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0046, E0407.
|
||||
For more information about an error, try `rustc --explain E0046`.
|
||||
@@ -0,0 +1,31 @@
|
||||
//@ check-pass
|
||||
//@ edition:2024
|
||||
|
||||
#![feature(pin_ergonomics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct Unpinned;
|
||||
|
||||
#[pin_v2]
|
||||
struct Pinned;
|
||||
|
||||
struct Qualified;
|
||||
struct CoreQualified;
|
||||
|
||||
impl Drop for Unpinned {
|
||||
fn drop(&pin mut self) {}
|
||||
}
|
||||
|
||||
impl Drop for Pinned {
|
||||
fn drop(&pin mut self) {}
|
||||
}
|
||||
|
||||
impl std::ops::Drop for Qualified {
|
||||
fn drop(&pin mut self) {}
|
||||
}
|
||||
|
||||
impl core::ops::Drop for CoreQualified {
|
||||
fn drop(&pin mut self) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#![feature(min_generic_const_args)]
|
||||
|
||||
trait Bar<const N: bool = false> {}
|
||||
trait Bar<const N: usize = const { 1 + 1 }> {}
|
||||
|
||||
trait Foo {
|
||||
type AssocB: Bar;
|
||||
|
||||
Reference in New Issue
Block a user