mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Auto merge of #129873 - matthiaskrgr:rollup-bv849ud, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #127474 (doc: Make block of inline Deref methods foldable) - #129678 (Deny imports of `rustc_type_ir::inherent` outside of type ir + new trait solver) - #129738 (`rustc_mir_transform` cleanups) - #129793 (add extra linebreaks so rustdoc can identify the first sentence) - #129804 (Fixed some typos in the standard library documentation/comments) - #129837 (Actually parse stdout json, instead of using hacky contains logic.) - #129842 (Fix LLVM ABI NAME for riscv64imac-unknown-nuttx-elf) - #129843 (Mark myself as on vacation for triagebot) - #129858 (Replace walk with visit so we dont skip outermost expr kind in def collector) Failed merges: - #129777 (Add `unreachable_pub`, round 4) - #129868 (Remove kobzol vacation status) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
a4601859ae
@ -783,6 +783,9 @@ lint_tykind = usage of `ty::TyKind`
|
||||
lint_tykind_kind = usage of `ty::TyKind::<kind>`
|
||||
.suggestion = try using `ty::<kind>` directly
|
||||
|
||||
lint_type_ir_inherent_usage = do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
|
||||
.note = the method or struct you're looking for is likely defined somewhere else downstream in the compiler
|
||||
|
||||
lint_undropped_manually_drops = calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing
|
||||
.label = argument has type `{$arg_ty}`
|
||||
.suggestion = use `std::mem::ManuallyDrop::into_inner` to get the inner value
|
||||
|
@ -18,7 +18,7 @@ use tracing::debug;
|
||||
use crate::lints::{
|
||||
BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword,
|
||||
NonGlobImportTypeIrInherent, QueryInstability, SpanUseEqCtxtDiag, TyQualified, TykindDiag,
|
||||
TykindKind, UntranslatableDiag,
|
||||
TykindKind, TypeIrInherentUsage, UntranslatableDiag,
|
||||
};
|
||||
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
|
||||
@ -277,13 +277,39 @@ declare_tool_lint! {
|
||||
report_in_external_macro: true
|
||||
}
|
||||
|
||||
declare_lint_pass!(TypeIr => [NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT]);
|
||||
declare_tool_lint! {
|
||||
/// The `usage_of_type_ir_inherent` lint detects usage `rustc_type_ir::inherent`.
|
||||
///
|
||||
/// This module should only be used within the trait solver.
|
||||
pub rustc::USAGE_OF_TYPE_IR_INHERENT,
|
||||
Allow,
|
||||
"usage `rustc_type_ir::inherent` outside of trait system",
|
||||
report_in_external_macro: true
|
||||
}
|
||||
|
||||
declare_lint_pass!(TypeIr => [NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT, USAGE_OF_TYPE_IR_INHERENT]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for TypeIr {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
let rustc_hir::ItemKind::Use(path, kind) = item.kind else { return };
|
||||
|
||||
let is_mod_inherent = |def_id| cx.tcx.is_diagnostic_item(sym::type_ir_inherent, def_id);
|
||||
|
||||
// Path segments except for the final.
|
||||
if let Some(seg) =
|
||||
path.segments.iter().find(|seg| seg.res.opt_def_id().is_some_and(is_mod_inherent))
|
||||
{
|
||||
cx.emit_span_lint(USAGE_OF_TYPE_IR_INHERENT, seg.ident.span, TypeIrInherentUsage);
|
||||
}
|
||||
// Final path resolutions, like `use rustc_type_ir::inherent`
|
||||
else if path.res.iter().any(|res| res.opt_def_id().is_some_and(is_mod_inherent)) {
|
||||
cx.emit_span_lint(
|
||||
USAGE_OF_TYPE_IR_INHERENT,
|
||||
path.segments.last().unwrap().ident.span,
|
||||
TypeIrInherentUsage,
|
||||
);
|
||||
}
|
||||
|
||||
let (lo, hi, snippet) = match path.segments {
|
||||
[.., penultimate, segment]
|
||||
if penultimate.res.opt_def_id().is_some_and(is_mod_inherent) =>
|
||||
|
@ -918,6 +918,11 @@ pub(crate) struct TyQualified {
|
||||
pub suggestion: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_type_ir_inherent_usage)]
|
||||
#[note]
|
||||
pub(crate) struct TypeIrInherentUsage;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_non_glob_import_type_ir_inherent)]
|
||||
pub(crate) struct NonGlobImportTypeIrInherent {
|
||||
|
@ -86,7 +86,7 @@ fn add_move_for_packed_drop<'tcx>(
|
||||
|
||||
let source_info = terminator.source_info;
|
||||
let ty = place.ty(body, tcx).ty;
|
||||
let temp = patch.new_temp(ty, terminator.source_info.span);
|
||||
let temp = patch.new_temp(ty, source_info.span);
|
||||
|
||||
let storage_dead_block = patch.new_block(BasicBlockData {
|
||||
statements: vec![Statement { source_info, kind: StatementKind::StorageDead(temp) }],
|
||||
|
@ -37,24 +37,17 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
|
||||
if context.is_borrow() {
|
||||
if util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
|
||||
let def_id = self.body.source.instance.def_id();
|
||||
if let Some(impl_def_id) = self.tcx.impl_of_method(def_id)
|
||||
&& self.tcx.is_builtin_derived(impl_def_id)
|
||||
{
|
||||
// If we ever reach here it means that the generated derive
|
||||
// code is somehow doing an unaligned reference, which it
|
||||
// shouldn't do.
|
||||
span_bug!(
|
||||
self.source_info.span,
|
||||
"builtin derive created an unaligned reference"
|
||||
);
|
||||
} else {
|
||||
self.tcx
|
||||
.dcx()
|
||||
.emit_err(errors::UnalignedPackedRef { span: self.source_info.span });
|
||||
}
|
||||
if context.is_borrow() && util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
|
||||
let def_id = self.body.source.instance.def_id();
|
||||
if let Some(impl_def_id) = self.tcx.impl_of_method(def_id)
|
||||
&& self.tcx.is_builtin_derived(impl_def_id)
|
||||
{
|
||||
// If we ever reach here it means that the generated derive
|
||||
// code is somehow doing an unaligned reference, which it
|
||||
// shouldn't do.
|
||||
span_bug!(self.source_info.span, "builtin derive created an unaligned reference");
|
||||
} else {
|
||||
self.tcx.dcx().emit_err(errors::UnalignedPackedRef { span: self.source_info.span });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,9 @@ use rustc_index::bit_set::{BitMatrix, BitSet, GrowableBitSet};
|
||||
use rustc_index::{Idx, IndexVec};
|
||||
use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, CoroutineArgs, CoroutineArgsExt, InstanceKind, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{
|
||||
self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, Ty, TyCtxt,
|
||||
};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_mir_dataflow::impls::{
|
||||
MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive,
|
||||
@ -113,11 +115,18 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
struct DerefArgVisitor<'tcx> {
|
||||
struct SelfArgVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
new_base: Place<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> {
|
||||
impl<'tcx> SelfArgVisitor<'tcx> {
|
||||
fn new(tcx: TyCtxt<'tcx>, elem: ProjectionElem<Local, Ty<'tcx>>) -> Self {
|
||||
Self { tcx, new_base: Place { local: SELF_ARG, projection: tcx.mk_place_elems(&[elem]) } }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MutVisitor<'tcx> for SelfArgVisitor<'tcx> {
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
@ -128,53 +137,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> {
|
||||
|
||||
fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
|
||||
if place.local == SELF_ARG {
|
||||
replace_base(
|
||||
place,
|
||||
Place {
|
||||
local: SELF_ARG,
|
||||
projection: self.tcx().mk_place_elems(&[ProjectionElem::Deref]),
|
||||
},
|
||||
self.tcx,
|
||||
);
|
||||
} else {
|
||||
self.visit_local(&mut place.local, context, location);
|
||||
|
||||
for elem in place.projection.iter() {
|
||||
if let PlaceElem::Index(local) = elem {
|
||||
assert_ne!(local, SELF_ARG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PinArgVisitor<'tcx> {
|
||||
ref_coroutine_ty: Ty<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) {
|
||||
assert_ne!(*local, SELF_ARG);
|
||||
}
|
||||
|
||||
fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
|
||||
if place.local == SELF_ARG {
|
||||
replace_base(
|
||||
place,
|
||||
Place {
|
||||
local: SELF_ARG,
|
||||
projection: self.tcx().mk_place_elems(&[ProjectionElem::Field(
|
||||
FieldIdx::ZERO,
|
||||
self.ref_coroutine_ty,
|
||||
)]),
|
||||
},
|
||||
self.tcx,
|
||||
);
|
||||
replace_base(place, self.new_base, self.tcx);
|
||||
} else {
|
||||
self.visit_local(&mut place.local, context, location);
|
||||
|
||||
@ -198,15 +161,6 @@ fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtx
|
||||
|
||||
const SELF_ARG: Local = Local::from_u32(1);
|
||||
|
||||
/// Coroutine has not been resumed yet.
|
||||
const UNRESUMED: usize = CoroutineArgs::UNRESUMED;
|
||||
/// Coroutine has returned / is completed.
|
||||
const RETURNED: usize = CoroutineArgs::RETURNED;
|
||||
/// Coroutine has panicked and is poisoned.
|
||||
const POISONED: usize = CoroutineArgs::POISONED;
|
||||
/// Number of reserved variants of coroutine state.
|
||||
const RESERVED_VARIANTS: usize = CoroutineArgs::RESERVED_VARIANTS;
|
||||
|
||||
/// A `yield` point in the coroutine.
|
||||
struct SuspensionPoint<'tcx> {
|
||||
/// State discriminant used when suspending or resuming at this point.
|
||||
@ -261,14 +215,10 @@ impl<'tcx> TransformVisitor<'tcx> {
|
||||
// `gen` continues return `None`
|
||||
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
|
||||
let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
|
||||
Rvalue::Aggregate(
|
||||
Box::new(AggregateKind::Adt(
|
||||
option_def_id,
|
||||
VariantIdx::ZERO,
|
||||
self.tcx.mk_args(&[self.old_yield_ty.into()]),
|
||||
None,
|
||||
None,
|
||||
)),
|
||||
make_aggregate_adt(
|
||||
option_def_id,
|
||||
VariantIdx::ZERO,
|
||||
self.tcx.mk_args(&[self.old_yield_ty.into()]),
|
||||
IndexVec::new(),
|
||||
)
|
||||
}
|
||||
@ -317,64 +267,28 @@ impl<'tcx> TransformVisitor<'tcx> {
|
||||
is_return: bool,
|
||||
statements: &mut Vec<Statement<'tcx>>,
|
||||
) {
|
||||
const ZERO: VariantIdx = VariantIdx::ZERO;
|
||||
const ONE: VariantIdx = VariantIdx::from_usize(1);
|
||||
let rvalue = match self.coroutine_kind {
|
||||
CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => {
|
||||
let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, None);
|
||||
let args = self.tcx.mk_args(&[self.old_ret_ty.into()]);
|
||||
if is_return {
|
||||
// Poll::Ready(val)
|
||||
Rvalue::Aggregate(
|
||||
Box::new(AggregateKind::Adt(
|
||||
poll_def_id,
|
||||
VariantIdx::ZERO,
|
||||
args,
|
||||
None,
|
||||
None,
|
||||
)),
|
||||
IndexVec::from_raw(vec![val]),
|
||||
)
|
||||
let (variant_idx, operands) = if is_return {
|
||||
(ZERO, IndexVec::from_raw(vec![val])) // Poll::Ready(val)
|
||||
} else {
|
||||
// Poll::Pending
|
||||
Rvalue::Aggregate(
|
||||
Box::new(AggregateKind::Adt(
|
||||
poll_def_id,
|
||||
VariantIdx::from_usize(1),
|
||||
args,
|
||||
None,
|
||||
None,
|
||||
)),
|
||||
IndexVec::new(),
|
||||
)
|
||||
}
|
||||
(ONE, IndexVec::new()) // Poll::Pending
|
||||
};
|
||||
make_aggregate_adt(poll_def_id, variant_idx, args, operands)
|
||||
}
|
||||
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
|
||||
let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
|
||||
let args = self.tcx.mk_args(&[self.old_yield_ty.into()]);
|
||||
if is_return {
|
||||
// None
|
||||
Rvalue::Aggregate(
|
||||
Box::new(AggregateKind::Adt(
|
||||
option_def_id,
|
||||
VariantIdx::ZERO,
|
||||
args,
|
||||
None,
|
||||
None,
|
||||
)),
|
||||
IndexVec::new(),
|
||||
)
|
||||
let (variant_idx, operands) = if is_return {
|
||||
(ZERO, IndexVec::new()) // None
|
||||
} else {
|
||||
// Some(val)
|
||||
Rvalue::Aggregate(
|
||||
Box::new(AggregateKind::Adt(
|
||||
option_def_id,
|
||||
VariantIdx::from_usize(1),
|
||||
args,
|
||||
None,
|
||||
None,
|
||||
)),
|
||||
IndexVec::from_raw(vec![val]),
|
||||
)
|
||||
}
|
||||
(ONE, IndexVec::from_raw(vec![val])) // Some(val)
|
||||
};
|
||||
make_aggregate_adt(option_def_id, variant_idx, args, operands)
|
||||
}
|
||||
CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => {
|
||||
if is_return {
|
||||
@ -400,31 +314,17 @@ impl<'tcx> TransformVisitor<'tcx> {
|
||||
let coroutine_state_def_id =
|
||||
self.tcx.require_lang_item(LangItem::CoroutineState, None);
|
||||
let args = self.tcx.mk_args(&[self.old_yield_ty.into(), self.old_ret_ty.into()]);
|
||||
if is_return {
|
||||
// CoroutineState::Complete(val)
|
||||
Rvalue::Aggregate(
|
||||
Box::new(AggregateKind::Adt(
|
||||
coroutine_state_def_id,
|
||||
VariantIdx::from_usize(1),
|
||||
args,
|
||||
None,
|
||||
None,
|
||||
)),
|
||||
IndexVec::from_raw(vec![val]),
|
||||
)
|
||||
let variant_idx = if is_return {
|
||||
ONE // CoroutineState::Complete(val)
|
||||
} else {
|
||||
// CoroutineState::Yielded(val)
|
||||
Rvalue::Aggregate(
|
||||
Box::new(AggregateKind::Adt(
|
||||
coroutine_state_def_id,
|
||||
VariantIdx::ZERO,
|
||||
args,
|
||||
None,
|
||||
None,
|
||||
)),
|
||||
IndexVec::from_raw(vec![val]),
|
||||
)
|
||||
}
|
||||
ZERO // CoroutineState::Yielded(val)
|
||||
};
|
||||
make_aggregate_adt(
|
||||
coroutine_state_def_id,
|
||||
variant_idx,
|
||||
args,
|
||||
IndexVec::from_raw(vec![val]),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
@ -517,7 +417,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
|
||||
self.make_state(v, source_info, is_return, &mut data.statements);
|
||||
let state = if let Some((resume, mut resume_arg)) = resume {
|
||||
// Yield
|
||||
let state = RESERVED_VARIANTS + self.suspension_points.len();
|
||||
let state = CoroutineArgs::RESERVED_VARIANTS + self.suspension_points.len();
|
||||
|
||||
// The resume arg target location might itself be remapped if its base local is
|
||||
// live across a yield.
|
||||
@ -550,7 +450,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
|
||||
VariantIdx::new(state)
|
||||
} else {
|
||||
// Return
|
||||
VariantIdx::new(RETURNED) // state for returned
|
||||
VariantIdx::new(CoroutineArgs::RETURNED) // state for returned
|
||||
};
|
||||
data.statements.push(self.set_discr(state, source_info));
|
||||
data.terminator_mut().kind = TerminatorKind::Return;
|
||||
@ -560,6 +460,15 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_aggregate_adt<'tcx>(
|
||||
def_id: DefId,
|
||||
variant_idx: VariantIdx,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
operands: IndexVec<FieldIdx, Operand<'tcx>>,
|
||||
) -> Rvalue<'tcx> {
|
||||
Rvalue::Aggregate(Box::new(AggregateKind::Adt(def_id, variant_idx, args, None, None)), operands)
|
||||
}
|
||||
|
||||
fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let coroutine_ty = body.local_decls.raw[1].ty;
|
||||
|
||||
@ -569,7 +478,7 @@ fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Bo
|
||||
body.local_decls.raw[1].ty = ref_coroutine_ty;
|
||||
|
||||
// Add a deref to accesses of the coroutine state
|
||||
DerefArgVisitor { tcx }.visit_body(body);
|
||||
SelfArgVisitor::new(tcx, ProjectionElem::Deref).visit_body(body);
|
||||
}
|
||||
|
||||
fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
@ -584,7 +493,8 @@ fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body
|
||||
body.local_decls.raw[1].ty = pin_ref_coroutine_ty;
|
||||
|
||||
// Add the Pin field access to accesses of the coroutine state
|
||||
PinArgVisitor { ref_coroutine_ty, tcx }.visit_body(body);
|
||||
SelfArgVisitor::new(tcx, ProjectionElem::Field(FieldIdx::ZERO, ref_coroutine_ty))
|
||||
.visit_body(body);
|
||||
}
|
||||
|
||||
/// Allocates a new local and replaces all references of `local` with it. Returns the new local.
|
||||
@ -651,8 +561,6 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let local = eliminate_get_context_call(&mut body[bb]);
|
||||
replace_resume_ty_local(tcx, body, local, context_mut_ref);
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
TerminatorKind::Yield { resume_arg, .. } => {
|
||||
@ -665,24 +573,23 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
|
||||
fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local {
|
||||
let terminator = bb_data.terminator.take().unwrap();
|
||||
if let TerminatorKind::Call { args, destination, target, .. } = terminator.kind {
|
||||
let [arg] = *Box::try_from(args).unwrap();
|
||||
let local = arg.node.place().unwrap().local;
|
||||
|
||||
let arg = Rvalue::Use(arg.node);
|
||||
let assign = Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((destination, arg))),
|
||||
};
|
||||
bb_data.statements.push(assign);
|
||||
bb_data.terminator = Some(Terminator {
|
||||
source_info: terminator.source_info,
|
||||
kind: TerminatorKind::Goto { target: target.unwrap() },
|
||||
});
|
||||
local
|
||||
} else {
|
||||
let TerminatorKind::Call { args, destination, target, .. } = terminator.kind else {
|
||||
bug!();
|
||||
}
|
||||
};
|
||||
let [arg] = *Box::try_from(args).unwrap();
|
||||
let local = arg.node.place().unwrap().local;
|
||||
|
||||
let arg = Rvalue::Use(arg.node);
|
||||
let assign = Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((destination, arg))),
|
||||
};
|
||||
bb_data.statements.push(assign);
|
||||
bb_data.terminator = Some(Terminator {
|
||||
source_info: terminator.source_info,
|
||||
kind: TerminatorKind::Goto { target: target.unwrap() },
|
||||
});
|
||||
local
|
||||
}
|
||||
|
||||
#[cfg_attr(not(debug_assertions), allow(unused))]
|
||||
@ -1085,10 +992,11 @@ fn compute_layout<'tcx>(
|
||||
// Build the coroutine variant field list.
|
||||
// Create a map from local indices to coroutine struct indices.
|
||||
let mut variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>> =
|
||||
iter::repeat(IndexVec::new()).take(RESERVED_VARIANTS).collect();
|
||||
iter::repeat(IndexVec::new()).take(CoroutineArgs::RESERVED_VARIANTS).collect();
|
||||
let mut remap = IndexVec::from_elem_n(None, saved_locals.domain_size());
|
||||
for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() {
|
||||
let variant_index = VariantIdx::from(RESERVED_VARIANTS + suspension_point_idx);
|
||||
let variant_index =
|
||||
VariantIdx::from(CoroutineArgs::RESERVED_VARIANTS + suspension_point_idx);
|
||||
let mut fields = IndexVec::new();
|
||||
for (idx, saved_local) in live_locals.iter().enumerate() {
|
||||
fields.push(saved_local);
|
||||
@ -1183,12 +1091,10 @@ fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
source_info,
|
||||
kind: TerminatorKind::Drop { place, target, unwind, replace: _ },
|
||||
} => {
|
||||
if let Some(local) = place.as_local() {
|
||||
if local == SELF_ARG {
|
||||
(target, unwind, source_info)
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
if let Some(local) = place.as_local()
|
||||
&& local == SELF_ARG
|
||||
{
|
||||
(target, unwind, source_info)
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@ -1237,7 +1143,7 @@ fn create_coroutine_drop_shim<'tcx>(
|
||||
|
||||
let mut cases = create_cases(&mut body, transform, Operation::Drop);
|
||||
|
||||
cases.insert(0, (UNRESUMED, drop_clean));
|
||||
cases.insert(0, (CoroutineArgs::UNRESUMED, drop_clean));
|
||||
|
||||
// The returned state and the poisoned state fall through to the default
|
||||
// case which is just to return
|
||||
@ -1387,7 +1293,9 @@ fn create_coroutine_resume_function<'tcx>(
|
||||
if can_unwind {
|
||||
let source_info = SourceInfo::outermost(body.span);
|
||||
let poison_block = body.basic_blocks_mut().push(BasicBlockData {
|
||||
statements: vec![transform.set_discr(VariantIdx::new(POISONED), source_info)],
|
||||
statements: vec![
|
||||
transform.set_discr(VariantIdx::new(CoroutineArgs::POISONED), source_info),
|
||||
],
|
||||
terminator: Some(Terminator { source_info, kind: TerminatorKind::UnwindResume }),
|
||||
is_cleanup: true,
|
||||
});
|
||||
@ -1419,13 +1327,16 @@ fn create_coroutine_resume_function<'tcx>(
|
||||
use rustc_middle::mir::AssertKind::{ResumedAfterPanic, ResumedAfterReturn};
|
||||
|
||||
// Jump to the entry point on the unresumed
|
||||
cases.insert(0, (UNRESUMED, START_BLOCK));
|
||||
cases.insert(0, (CoroutineArgs::UNRESUMED, START_BLOCK));
|
||||
|
||||
// Panic when resumed on the returned or poisoned state
|
||||
if can_unwind {
|
||||
cases.insert(
|
||||
1,
|
||||
(POISONED, insert_panic_block(tcx, body, ResumedAfterPanic(transform.coroutine_kind))),
|
||||
(
|
||||
CoroutineArgs::POISONED,
|
||||
insert_panic_block(tcx, body, ResumedAfterPanic(transform.coroutine_kind)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -1440,7 +1351,7 @@ fn create_coroutine_resume_function<'tcx>(
|
||||
transform.insert_none_ret_block(body)
|
||||
}
|
||||
};
|
||||
cases.insert(1, (RETURNED, block));
|
||||
cases.insert(1, (CoroutineArgs::RETURNED, block));
|
||||
}
|
||||
|
||||
insert_switch(body, cases, &transform, TerminatorKind::Unreachable);
|
||||
|
@ -3,13 +3,11 @@
|
||||
#![feature(box_patterns)]
|
||||
#![feature(const_type_name)]
|
||||
#![feature(cow_is_borrowed)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(impl_trait_in_assoc_type)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(map_try_insert)]
|
||||
#![feature(never_type)]
|
||||
#![feature(option_get_or_insert_default)]
|
||||
#![feature(round_char_boundary)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(yeet_expr)]
|
||||
@ -17,6 +15,7 @@
|
||||
|
||||
use hir::ConstContext;
|
||||
use required_consts::RequiredConstsVisitor;
|
||||
use rustc_const_eval::check_consts::{self, ConstCx};
|
||||
use rustc_const_eval::util;
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_data_structures::steal::Steal;
|
||||
@ -33,6 +32,7 @@ use rustc_middle::mir::{
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::util::Providers;
|
||||
use rustc_middle::{bug, query, span_bug};
|
||||
use rustc_mir_dataflow::rustc_peek;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{sym, DUMMY_SP};
|
||||
use rustc_trait_selection::traits;
|
||||
@ -108,9 +108,6 @@ mod unreachable_enum_branching;
|
||||
mod unreachable_prop;
|
||||
mod validate;
|
||||
|
||||
use rustc_const_eval::check_consts::{self, ConstCx};
|
||||
use rustc_mir_dataflow::rustc_peek;
|
||||
|
||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
@ -128,7 +125,7 @@ pub fn provide(providers: &mut Providers) {
|
||||
mir_coroutine_witnesses: coroutine::mir_coroutine_witnesses,
|
||||
optimized_mir,
|
||||
is_mir_available,
|
||||
is_ctfe_mir_available: |tcx, did| is_mir_available(tcx, did),
|
||||
is_ctfe_mir_available: is_mir_available,
|
||||
mir_callgraph_reachable: inline::cycle::mir_callgraph_reachable,
|
||||
mir_inliner_callees: inline::cycle::mir_inliner_callees,
|
||||
promoted_mir,
|
||||
@ -221,10 +218,8 @@ fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|
||||
/// Finds the full set of `DefId`s within the current crate that have
|
||||
/// MIR associated with them.
|
||||
fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
|
||||
let mut set = FxIndexSet::default();
|
||||
|
||||
// All body-owners have MIR associated with them.
|
||||
set.extend(tcx.hir().body_owners());
|
||||
let mut set: FxIndexSet<_> = tcx.hir().body_owners().collect();
|
||||
|
||||
// Additionally, tuple struct/variant constructors have MIR, but
|
||||
// they don't have a BodyId, so we need to build them separately.
|
||||
@ -249,8 +244,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
|
||||
|
||||
// No need to const-check a non-const `fn`.
|
||||
match const_kind {
|
||||
Some(ConstContext::Const { .. } | ConstContext::Static(_))
|
||||
| Some(ConstContext::ConstFn) => {}
|
||||
Some(ConstContext::Const { .. } | ConstContext::Static(_) | ConstContext::ConstFn) => {}
|
||||
None => span_bug!(
|
||||
tcx.def_span(def),
|
||||
"`mir_const_qualif` should only be called on const fns and const items"
|
||||
|
@ -5,6 +5,7 @@
|
||||
//! So if you got to this crate from the old solver, it's totally normal.
|
||||
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_inherent))]
|
||||
#![warn(unreachable_pub)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
|
@ -223,7 +223,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
||||
// we must create two defs.
|
||||
let coroutine_def =
|
||||
self.create_def(coroutine_kind.closure_id(), kw::Empty, DefKind::Closure, span);
|
||||
self.with_parent(coroutine_def, |this| visit::walk_expr(this, body));
|
||||
self.with_parent(coroutine_def, |this| this.visit_expr(body));
|
||||
}
|
||||
_ => visit::walk_fn(self, fn_kind),
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ pub fn target() -> Target {
|
||||
os: "nuttx".into(),
|
||||
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
|
||||
linker: Some("rust-lld".into()),
|
||||
llvm_abiname: "lp64d".into(),
|
||||
cpu: "generic-rv64".into(),
|
||||
max_atomic_width: Some(64),
|
||||
features: "+m,+a,+c".into(),
|
||||
|
@ -5,6 +5,7 @@
|
||||
feature(associated_type_defaults, never_type, rustc_attrs, negative_impls)
|
||||
)]
|
||||
#![cfg_attr(feature = "nightly", allow(internal_features))]
|
||||
#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_inherent))]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
extern crate self as rustc_type_ir;
|
||||
|
@ -3302,7 +3302,7 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> {
|
||||
Some(kv)
|
||||
}
|
||||
|
||||
/// Removes the precending element from the `BTreeMap`.
|
||||
/// Removes the preceding element from the `BTreeMap`.
|
||||
///
|
||||
/// The element that was removed is returned. The cursor position is
|
||||
/// unchanged (after the removed element).
|
||||
@ -3408,7 +3408,7 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMut<'a, K, V, A> {
|
||||
self.inner.remove_next()
|
||||
}
|
||||
|
||||
/// Removes the precending element from the `BTreeMap`.
|
||||
/// Removes the preceding element from the `BTreeMap`.
|
||||
///
|
||||
/// The element that was removed is returned. The cursor position is
|
||||
/// unchanged (after the removed element).
|
||||
|
@ -2298,7 +2298,7 @@ impl<'a, T: Ord, A: Allocator + Clone> CursorMut<'a, T, A> {
|
||||
self.inner.remove_next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Removes the precending element from the `BTreeSet`.
|
||||
/// Removes the preceding element from the `BTreeSet`.
|
||||
///
|
||||
/// The element that was removed is returned. The cursor position is
|
||||
/// unchanged (after the removed element).
|
||||
@ -2384,7 +2384,7 @@ impl<'a, T: Ord, A: Allocator + Clone> CursorMutKey<'a, T, A> {
|
||||
self.inner.remove_next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Removes the precending element from the `BTreeSet`.
|
||||
/// Removes the preceding element from the `BTreeSet`.
|
||||
///
|
||||
/// The element that was removed is returned. The cursor position is
|
||||
/// unchanged (after the removed element).
|
||||
|
@ -37,7 +37,7 @@ pub use iter::IntoIter;
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Creating muliple copies of a `String`:
|
||||
/// Creating multiple copies of a `String`:
|
||||
/// ```rust
|
||||
/// #![feature(array_repeat)]
|
||||
///
|
||||
|
@ -157,7 +157,7 @@ async unsafe fn surface_drop_in_place<T: Drop + ?Sized>(ptr: *mut T) {
|
||||
unsafe { crate::ops::fallback_surface_drop(&mut *ptr) }
|
||||
}
|
||||
|
||||
/// Wraps a future to continue outputing `Poll::Ready(())` once after
|
||||
/// Wraps a future to continue outputting `Poll::Ready(())` once after
|
||||
/// wrapped future completes by returning `Poll::Ready(())` on poll. This
|
||||
/// is useful for constructing async destructors to guarantee this
|
||||
/// "fuse" property
|
||||
@ -223,7 +223,7 @@ where
|
||||
/// # Safety
|
||||
///
|
||||
/// Same as `async_drop_in_place` except is lazy to avoid creating
|
||||
/// multiple mutable refernces.
|
||||
/// multiple mutable references.
|
||||
#[lang = "async_drop_defer"]
|
||||
async unsafe fn defer<T: ?Sized>(to_drop: *mut T) {
|
||||
// SAFETY: same safety requirements as `async_drop_in_place`
|
||||
|
@ -1,6 +1,7 @@
|
||||
#![stable(feature = "core_hint", since = "1.27.0")]
|
||||
|
||||
//! Hints to compiler that affects how code should be emitted or optimized.
|
||||
//!
|
||||
//! Hints may be compile time or runtime.
|
||||
|
||||
use crate::{intrinsics, ub_checks};
|
||||
|
@ -310,7 +310,7 @@ define!(
|
||||
);
|
||||
define!(
|
||||
"mir_unwind_cleanup",
|
||||
/// An unwind action that continues execution in a given basic blok.
|
||||
/// An unwind action that continues execution in a given basic block.
|
||||
fn UnwindCleanup(goto: BasicBlock) -> UnwindActionArg
|
||||
);
|
||||
|
||||
|
@ -1072,7 +1072,7 @@ pub(crate) mod builtin {
|
||||
/// If the environment variable is not defined, then a compilation error
|
||||
/// will be emitted. To not emit a compile error, use the [`option_env!`]
|
||||
/// macro instead. A compilation error will also be emitted if the
|
||||
/// environment variable is not a vaild Unicode string.
|
||||
/// environment variable is not a valid Unicode string.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -832,8 +832,9 @@ mod prim_array {}
|
||||
#[doc(alias = "[")]
|
||||
#[doc(alias = "]")]
|
||||
#[doc(alias = "[]")]
|
||||
/// A dynamically-sized view into a contiguous sequence, `[T]`. Contiguous here
|
||||
/// means that elements are laid out so that every element is the same
|
||||
/// A dynamically-sized view into a contiguous sequence, `[T]`.
|
||||
///
|
||||
/// Contiguous here means that elements are laid out so that every element is the same
|
||||
/// distance from its neighbors.
|
||||
///
|
||||
/// *[See also the `std::slice` module](crate::slice).*
|
||||
|
@ -142,7 +142,7 @@ fn main() {
|
||||
|
||||
// Configure platforms that have reliable basics but may have unreliable math.
|
||||
|
||||
// LLVM is currenlty adding missing routines, <https://github.com/llvm/llvm-project/issues/93566>
|
||||
// LLVM is currently adding missing routines, <https://github.com/llvm/llvm-project/issues/93566>
|
||||
let has_reliable_f16_math = has_reliable_f16
|
||||
&& match (target_arch.as_str(), target_os.as_str()) {
|
||||
// FIXME: Disabled on Miri as the intrinsics are not implemented yet.
|
||||
|
@ -738,7 +738,7 @@ fn read_buf_full_read() {
|
||||
#[test]
|
||||
// Miri does not support signalling OOM
|
||||
#[cfg_attr(miri, ignore)]
|
||||
// 64-bit only to be sure the allocator will fail fast on an impossible to satsify size
|
||||
// 64-bit only to be sure the allocator will fail fast on an impossible to satisfy size
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
fn try_oom_error() {
|
||||
let mut v = Vec::<u8>::new();
|
||||
|
@ -146,7 +146,7 @@ fn lang_start_internal(
|
||||
rtabort!("drop of the panic payload panicked");
|
||||
});
|
||||
panic::catch_unwind(cleanup).map_err(rt_abort)?;
|
||||
// Guard against multple threads calling `libc::exit` concurrently.
|
||||
// Guard against multiple threads calling `libc::exit` concurrently.
|
||||
// See the documentation for `unique_thread_exit` for more information.
|
||||
panic::catch_unwind(|| crate::sys::exit_guard::unique_thread_exit()).map_err(rt_abort)?;
|
||||
ret_code
|
||||
|
@ -551,7 +551,7 @@ impl<T> Channel<T> {
|
||||
|
||||
let mut head = self.head.index.load(Ordering::Acquire);
|
||||
// The channel may be uninitialized, so we have to swap to avoid overwriting any sender's attempts
|
||||
// to initalize the first block before noticing that the receivers disconnected. Late allocations
|
||||
// to initialize the first block before noticing that the receivers disconnected. Late allocations
|
||||
// will be deallocated by the sender in Drop.
|
||||
let mut block = self.head.block.swap(ptr::null_mut(), Ordering::AcqRel);
|
||||
|
||||
|
@ -470,7 +470,7 @@ mod uefi_command_internal {
|
||||
let st_size = unsafe { (*self.st.as_ptr()).hdr.header_size as usize };
|
||||
let mut crc32: u32 = 0;
|
||||
|
||||
// Set crc to 0 before calcuation
|
||||
// Set crc to 0 before calculation
|
||||
unsafe {
|
||||
(*self.st.as_mut_ptr()).hdr.crc32 = 0;
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ impl Socket {
|
||||
_ => {
|
||||
if cfg!(target_os = "vxworks") {
|
||||
// VxWorks poll does not return POLLHUP or POLLERR in revents. Check if the
|
||||
// connnection actually succeeded and return ok only when the socket is
|
||||
// connection actually succeeded and return ok only when the socket is
|
||||
// ready and no errors were found.
|
||||
if let Some(e) = self.take_error()? {
|
||||
return Err(e);
|
||||
|
@ -1250,6 +1250,7 @@ fn render_assoc_items_inner(
|
||||
let Some(v) = cache.impls.get(&it) else { return };
|
||||
let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none());
|
||||
if !non_trait.is_empty() {
|
||||
let mut close_tags = <Vec<&str>>::with_capacity(1);
|
||||
let mut tmp_buf = Buffer::html();
|
||||
let (render_mode, id, class_html) = match what {
|
||||
AssocItemRender::All => {
|
||||
@ -1260,6 +1261,8 @@ fn render_assoc_items_inner(
|
||||
let id =
|
||||
cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
|
||||
let derived_id = cx.derive_id(&id);
|
||||
tmp_buf.write_str("<details class=\"toggle big-toggle\" open><summary>");
|
||||
close_tags.push("</details>");
|
||||
write_impl_section_heading(
|
||||
&mut tmp_buf,
|
||||
&format!(
|
||||
@ -1269,6 +1272,7 @@ fn render_assoc_items_inner(
|
||||
),
|
||||
&id,
|
||||
);
|
||||
tmp_buf.write_str("</summary>");
|
||||
if let Some(def_id) = type_.def_id(cx.cache()) {
|
||||
cx.deref_id_map.insert(def_id, id);
|
||||
}
|
||||
@ -1302,6 +1306,9 @@ fn render_assoc_items_inner(
|
||||
impls_buf.into_inner()
|
||||
)
|
||||
.unwrap();
|
||||
for tag in close_tags.into_iter().rev() {
|
||||
w.write_str(tag).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1558,7 +1565,7 @@ fn render_impl(
|
||||
let cache = &shared.cache;
|
||||
let traits = &cache.traits;
|
||||
let trait_ = i.trait_did().map(|did| &traits[&did]);
|
||||
let mut close_tags = String::new();
|
||||
let mut close_tags = <Vec<&str>>::with_capacity(2);
|
||||
|
||||
// For trait implementations, the `interesting` output contains all methods that have doc
|
||||
// comments, and the `boring` output contains all methods that do not. The distinction is
|
||||
@ -1870,7 +1877,7 @@ fn render_impl(
|
||||
if render_mode == RenderMode::Normal {
|
||||
let toggled = !(impl_items.is_empty() && default_impl_items.is_empty());
|
||||
if toggled {
|
||||
close_tags.insert_str(0, "</details>");
|
||||
close_tags.push("</details>");
|
||||
write!(
|
||||
w,
|
||||
"<details class=\"toggle implementors-toggle\"{}>\
|
||||
@ -1916,14 +1923,16 @@ fn render_impl(
|
||||
}
|
||||
if !default_impl_items.is_empty() || !impl_items.is_empty() {
|
||||
w.write_str("<div class=\"impl-items\">");
|
||||
close_tags.insert_str(0, "</div>");
|
||||
close_tags.push("</div>");
|
||||
}
|
||||
}
|
||||
if !default_impl_items.is_empty() || !impl_items.is_empty() {
|
||||
w.push_buffer(default_impl_items);
|
||||
w.push_buffer(impl_items);
|
||||
}
|
||||
w.write_str(&close_tags);
|
||||
for tag in close_tags.into_iter().rev() {
|
||||
w.write_str(tag);
|
||||
}
|
||||
}
|
||||
|
||||
// Render the items that appear on the right side of methods, impls, and
|
||||
|
@ -1852,6 +1852,11 @@ details.toggle {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
details.big-toggle {
|
||||
/* This makes [-] on the same line as <summary>. */
|
||||
contain: inline-size;
|
||||
}
|
||||
|
||||
/* The hideme class is used on summary tags that contain a span with
|
||||
placeholder text shown only when the toggle is closed. For instance,
|
||||
"Expand description" or "Show methods". */
|
||||
@ -1942,6 +1947,11 @@ details.toggle > summary:not(.hideme)::before {
|
||||
left: -24px;
|
||||
}
|
||||
|
||||
details.big-toggle > summary:not(.hideme)::before {
|
||||
left: -34px;
|
||||
top: 9px;
|
||||
}
|
||||
|
||||
/* When a "hideme" summary is open and the "Expand description" or "Show
|
||||
methods" text is hidden, we want the [-] toggle that remains to not
|
||||
affect the layout of the items to its right. To do that, we use
|
||||
|
@ -4,17 +4,28 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use run_make_support::path_helpers::{cwd, has_extension, read_dir_entries_recursive};
|
||||
use run_make_support::rustdoc;
|
||||
use run_make_support::{rustdoc, serde_json};
|
||||
|
||||
fn main() {
|
||||
// First we check that we generate the JSON in the stdout.
|
||||
rustdoc()
|
||||
let json_string = rustdoc()
|
||||
.input("foo.rs")
|
||||
.out_dir("-")
|
||||
.arg("-Zunstable-options")
|
||||
.output_format("json")
|
||||
.run()
|
||||
.assert_stdout_contains("{\"");
|
||||
.stdout_utf8();
|
||||
|
||||
// First we check that we generate the JSON in the stdout.
|
||||
let json_value: serde_json::Value =
|
||||
serde_json::from_str(&json_string).expect("stdout should be valid json");
|
||||
|
||||
// We don't care to test the specifics of the JSON, as that's done
|
||||
// elsewhere, just check that it has a format_version (as all JSON output
|
||||
// should).
|
||||
let format_version = json_value["format_version"]
|
||||
.as_i64()
|
||||
.expect("json output should contain format_version field");
|
||||
assert!(format_version > 30);
|
||||
|
||||
// Then we check it didn't generate any JSON file.
|
||||
read_dir_entries_recursive(cwd(), |path| {
|
||||
|
30
tests/rustdoc-gui/deref-block.goml
Normal file
30
tests/rustdoc-gui/deref-block.goml
Normal file
@ -0,0 +1,30 @@
|
||||
// This test ensures that several clickable items actually have the pointer cursor.
|
||||
go-to: "file://" + |DOC_PATH| + "/lib2/struct.Derefer.html"
|
||||
|
||||
assert-text: (".big-toggle summary", "Methods from Deref<Target = str>§")
|
||||
// We ensure it doesn't go over `§`.
|
||||
assert-css: (".big-toggle summary::before", {
|
||||
"left": "-34px",
|
||||
"top": "9px",
|
||||
})
|
||||
// It should NOT have the same X or Y position as the other toggles.
|
||||
compare-elements-position-false: (
|
||||
".big-toggle summary::before",
|
||||
".method-toggle summary::before",
|
||||
["x", "y"],
|
||||
)
|
||||
|
||||
// We now check that if we're in mobile mode, it gets back to its original X position.
|
||||
set-window-size: (600, 600)
|
||||
assert-css: (".big-toggle summary::before", {
|
||||
"left": "-11px",
|
||||
"top": "9px",
|
||||
})
|
||||
// It should have the same X position as the other toggles.
|
||||
compare-elements-position: (".big-toggle summary::before", ".method-toggle summary::before", ["x"])
|
||||
// But still shouldn't have the same Y position.
|
||||
compare-elements-position-false: (
|
||||
".big-toggle summary::before",
|
||||
".method-toggle summary::before",
|
||||
["y"],
|
||||
)
|
@ -356,3 +356,13 @@ pub mod scroll_traits {
|
||||
fn this_is_a_method_with_a_long_name_returning_something() -> String;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Derefer(String);
|
||||
|
||||
impl std::ops::Deref for Derefer {
|
||||
type Target = str;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
//@ compile-flags: -Z unstable-options
|
||||
|
||||
// #[cfg(bootstrap)]: We can stop ignoring next beta bump; afterward this ALWAYS should run.
|
||||
//@ ignore-stage1
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![deny(rustc::usage_of_type_ir_inherent)]
|
||||
|
||||
extern crate rustc_type_ir;
|
||||
|
||||
use rustc_type_ir::inherent::*;
|
||||
//~^ ERROR do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
|
||||
use rustc_type_ir::inherent;
|
||||
//~^ ERROR do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
|
||||
use rustc_type_ir::inherent::Predicate;
|
||||
//~^ ERROR do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,31 @@
|
||||
error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
|
||||
--> $DIR/import-of-type-ir-inherent.rs:11:20
|
||||
|
|
||||
LL | use rustc_type_ir::inherent::*;
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler
|
||||
note: the lint level is defined here
|
||||
--> $DIR/import-of-type-ir-inherent.rs:7:9
|
||||
|
|
||||
LL | #![deny(rustc::usage_of_type_ir_inherent)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
|
||||
--> $DIR/import-of-type-ir-inherent.rs:13:20
|
||||
|
|
||||
LL | use rustc_type_ir::inherent;
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler
|
||||
|
||||
error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
|
||||
--> $DIR/import-of-type-ir-inherent.rs:15:20
|
||||
|
|
||||
LL | use rustc_type_ir::inherent::Predicate;
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
12
tests/ui/async-await/async-closures/mac-body.rs
Normal file
12
tests/ui/async-await/async-closures/mac-body.rs
Normal file
@ -0,0 +1,12 @@
|
||||
//@ edition: 2021
|
||||
//@ check-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
// Make sure we don't ICE if an async closure has a macro body.
|
||||
// This happened because we were calling walk instead of visit
|
||||
// in the def collector, oops!
|
||||
|
||||
fn main() {
|
||||
let _ = async || println!();
|
||||
}
|
@ -913,7 +913,14 @@ cc = ["@kobzol"]
|
||||
[assign]
|
||||
warn_non_default_branch = true
|
||||
contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
|
||||
users_on_vacation = ["jyn514", "jhpratt", "oli-obk", "kobzol", "joboet"]
|
||||
users_on_vacation = [
|
||||
"jhpratt",
|
||||
"joboet",
|
||||
"jyn514",
|
||||
"kobzol",
|
||||
"oli-obk",
|
||||
"tgross35",
|
||||
]
|
||||
|
||||
[assign.adhoc_groups]
|
||||
compiler-team = [
|
||||
|
Loading…
Reference in New Issue
Block a user