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:
bors
2026-05-15 16:17:07 +00:00
50 changed files with 1252 additions and 393 deletions
+13
View File
@@ -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,
+56 -17
View File
@@ -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, _) => {
+4 -1
View File
@@ -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 {
+103 -165
View File
@@ -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,
+2 -2
View File
@@ -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
+14 -3
View File
@@ -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();
+4 -1
View File
@@ -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,
} {
+1 -1
View File
@@ -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()))
}
}
+5 -3
View File
@@ -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))
}
}
+1 -1
View File
@@ -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() {
+1
View File
@@ -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)
+20
View File
@@ -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
+3
View File
@@ -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,
+15 -2
View File
@@ -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);
}
}
}
+80
View File
@@ -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() {}
+14
View File
@@ -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
+3
View File
@@ -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
}
+17 -8
View File
@@ -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`.
+21 -13
View File
@@ -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`.
+21 -13
View File
@@ -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`.
+2
View File
@@ -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() {}
+7
View File
@@ -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);
+10
View File
@@ -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`.
+83 -5
View File
@@ -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() {}
+165 -28
View File
@@ -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;