Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #99001

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b22450f
created tcpstream quickack trait
Apr 22, 2022
907ea55
Adapt tests to be able to run in miri
Noratrieb Jun 3, 2022
4d67f5b
Remove needless FIXME
camelid Jun 29, 2022
8192288
Replace weird handling of edge case with panic
camelid Jun 29, 2022
2d2fd31
Remove FIXME that hasn't been an issue in practice
camelid Jun 29, 2022
1eb1d91
Make MIR basic blocks field public
tmiasko Jul 4, 2022
f14a887
Move `is_cfg_cyclic` from Body to BasicBlocks
tmiasko Jul 5, 2022
d32e13e
Move `predecessors` from Body to BasicBlocks
tmiasko Jul 5, 2022
a7bdce3
Move `switch_sources` from Body to BasicBlocks
tmiasko Jul 5, 2022
802cb1c
Move `dominators` from Body to BasicBlocks
tmiasko Jul 5, 2022
a2799b2
fix projectionelem validation
beepster4096 May 9, 2022
211fb66
Fix stacked borrows violation in rustc_arena
Noratrieb Jun 3, 2022
14d288f
socket `set_mark` addition.
devnexen Apr 23, 2022
48ef00e
doc additions
devnexen Apr 27, 2022
10f5a19
changes from feedback
devnexen Jul 6, 2022
6c6388c
Document, that some lint have to be expected on the crate level (RFC …
xFrednet Jun 16, 2022
c8b4873
Add function to manually fulfill lint expectations (RFC 2383)
xFrednet Jun 16, 2022
a2810cd
Fix `#[expect]` and `#[allow]` for `clippy::duplicate_mod`
xFrednet Jun 25, 2022
91a3ce8
Rollup merge of #96324 - berendjan:set_tcp_quickack, r=dtolnay
Dylan-DPC Jul 7, 2022
7eaf0c9
Rollup merge of #96334 - devnexen:socket_mark, r=dtolnay
Dylan-DPC Jul 7, 2022
7ede77f
Rollup merge of #96856 - DrMeepster:fix_projection_validation, r=Icnr
Dylan-DPC Jul 7, 2022
3ce668e
Rollup merge of #97711 - Nilstrieb:rustc-arena-ub, r=wesleywiser
Dylan-DPC Jul 7, 2022
7260f7e
Rollup merge of #98507 - xFrednet:rfc-2383-manual-expectation-magic, …
Dylan-DPC Jul 7, 2022
c78e7f5
Rollup merge of #98692 - camelid:more-fixmes, r=GuillaumeGomez
Dylan-DPC Jul 7, 2022
36f7f55
Rollup merge of #98930 - tmiasko:pub-basic-blocks, r=oli-obk
Dylan-DPC Jul 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions compiler/rustc_arena/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#![feature(rustc_attrs)]
#![cfg_attr(test, feature(test))]
#![feature(strict_provenance)]
#![feature(ptr_const_cast)]

use smallvec::SmallVec;

Expand All @@ -27,7 +28,7 @@ use std::cell::{Cell, RefCell};
use std::cmp;
use std::marker::{PhantomData, Send};
use std::mem::{self, MaybeUninit};
use std::ptr;
use std::ptr::{self, NonNull};
use std::slice;

#[inline(never)]
Expand Down Expand Up @@ -55,15 +56,24 @@ pub struct TypedArena<T> {

struct ArenaChunk<T = u8> {
/// The raw storage for the arena chunk.
storage: Box<[MaybeUninit<T>]>,
storage: NonNull<[MaybeUninit<T>]>,
/// The number of valid entries in the chunk.
entries: usize,
}

unsafe impl<#[may_dangle] T> Drop for ArenaChunk<T> {
fn drop(&mut self) {
unsafe { Box::from_raw(self.storage.as_mut()) };
}
}

impl<T> ArenaChunk<T> {
#[inline]
unsafe fn new(capacity: usize) -> ArenaChunk<T> {
ArenaChunk { storage: Box::new_uninit_slice(capacity), entries: 0 }
ArenaChunk {
storage: NonNull::new(Box::into_raw(Box::new_uninit_slice(capacity))).unwrap(),
entries: 0,
}
}

/// Destroys this arena chunk.
Expand All @@ -72,14 +82,15 @@ impl<T> ArenaChunk<T> {
// The branch on needs_drop() is an -O1 performance optimization.
// Without the branch, dropping TypedArena<u8> takes linear time.
if mem::needs_drop::<T>() {
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut self.storage[..len]));
let slice = &mut *(self.storage.as_mut());
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len]));
}
}

// Returns a pointer to the first allocated object.
#[inline]
fn start(&mut self) -> *mut T {
MaybeUninit::slice_as_mut_ptr(&mut self.storage)
self.storage.as_ptr() as *mut T
}

// Returns a pointer to the end of the allocated space.
Expand All @@ -90,7 +101,7 @@ impl<T> ArenaChunk<T> {
// A pointer as large as possible for zero-sized elements.
ptr::invalid_mut(!0)
} else {
self.start().add(self.storage.len())
self.start().add((*self.storage.as_ptr()).len())
}
}
}
Expand Down Expand Up @@ -274,7 +285,7 @@ impl<T> TypedArena<T> {
// If the previous chunk's len is less than HUGE_PAGE
// bytes, then this chunk will be least double the previous
// chunk's size.
new_cap = last_chunk.storage.len().min(HUGE_PAGE / elem_size / 2);
new_cap = (*last_chunk.storage.as_ptr()).len().min(HUGE_PAGE / elem_size / 2);
new_cap *= 2;
} else {
new_cap = PAGE / elem_size;
Expand Down Expand Up @@ -382,7 +393,7 @@ impl DroplessArena {
// If the previous chunk's len is less than HUGE_PAGE
// bytes, then this chunk will be least double the previous
// chunk's size.
new_cap = last_chunk.storage.len().min(HUGE_PAGE / 2);
new_cap = (*last_chunk.storage.as_ptr()).len().min(HUGE_PAGE / 2);
new_cap *= 2;
} else {
new_cap = PAGE;
Expand Down
24 changes: 20 additions & 4 deletions compiler/rustc_arena/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ fn test_arena_alloc_nested() {
#[test]
pub fn test_copy() {
let arena = TypedArena::default();
for _ in 0..100000 {
#[cfg(not(miri))]
const N: usize = 100000;
#[cfg(miri)]
const N: usize = 1000;
for _ in 0..N {
arena.alloc(Point { x: 1, y: 2, z: 3 });
}
}
Expand All @@ -106,15 +110,23 @@ struct Noncopy {
#[test]
pub fn test_noncopy() {
let arena = TypedArena::default();
for _ in 0..100000 {
#[cfg(not(miri))]
const N: usize = 100000;
#[cfg(miri)]
const N: usize = 1000;
for _ in 0..N {
arena.alloc(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] });
}
}

#[test]
pub fn test_typed_arena_zero_sized() {
let arena = TypedArena::default();
for _ in 0..100000 {
#[cfg(not(miri))]
const N: usize = 100000;
#[cfg(miri)]
const N: usize = 1000;
for _ in 0..N {
arena.alloc(());
}
}
Expand All @@ -124,7 +136,11 @@ pub fn test_typed_arena_clear() {
let mut arena = TypedArena::default();
for _ in 0..10 {
arena.clear();
for _ in 0..10000 {
#[cfg(not(miri))]
const N: usize = 10000;
#[cfg(miri)]
const N: usize = 100;
for _ in 0..N {
arena.alloc(Point { x: 1, y: 2, z: 3 });
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1628,7 +1628,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
location: Location,
) -> impl Iterator<Item = Location> + Captures<'tcx> + 'a {
if location.statement_index == 0 {
let predecessors = body.predecessors()[location.block].to_vec();
let predecessors = body.basic_blocks.predecessors()[location.block].to_vec();
Either::Left(predecessors.into_iter().map(move |bb| body.terminator_loc(bb)))
} else {
Either::Right(std::iter::once(Location {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/invalidation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub(super) fn generate_invalidates<'tcx>(

if let Some(all_facts) = all_facts {
let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation");
let dominators = body.dominators();
let dominators = body.basic_blocks.dominators();
let mut ig = InvalidationGenerator {
all_facts,
borrow_set,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ fn do_mir_borrowck<'a, 'tcx>(
};
}

let dominators = body.dominators();
let dominators = body.basic_blocks.dominators();

let mut mbcx = MirBorrowckCtxt {
infcx,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/type_check/liveness/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {

let block = self.cx.elements.to_location(block_start).block;
self.stack.extend(
self.cx.body.predecessors()[block]
self.cx.body.basic_blocks.predecessors()[block]
.iter()
.map(|&pred_bb| self.cx.body.terminator_loc(pred_bb))
.map(|pred_loc| self.cx.elements.point_from_location(pred_loc)),
Expand Down Expand Up @@ -354,7 +354,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
}

let body = self.cx.body;
for &pred_block in body.predecessors()[block].iter() {
for &pred_block in body.basic_blocks.predecessors()[block].iter() {
debug!("compute_drop_live_points_for_block: pred_block = {:?}", pred_block,);

// Check whether the variable is (at least partially)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
fx: &FunctionCx<'a, 'tcx, Bx>,
) -> BitSet<mir::Local> {
let mir = fx.mir;
let dominators = mir.dominators();
let dominators = mir.basic_blocks.dominators();
let locals = mir
.local_decls
.iter()
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_const_eval/src/transform/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
literal: ConstantKind::from_const(_const, tcx),
}))
};
let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut();
let blocks = self.source.basic_blocks.as_mut();
let local_decls = &mut self.source.local_decls;
let loc = candidate.location;
let statement = &mut blocks[loc.block].statements[loc.statement_index];
match statement.kind {
Expand All @@ -865,7 +866,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
Rvalue::Ref(ref mut region, borrow_kind, ref mut place),
)) => {
// Use the underlying local for this (necessarily interior) borrow.
let ty = local_decls.local_decls()[place.local].ty;
let ty = local_decls[place.local].ty;
let span = statement.source_info.span;

let ref_ty = tcx.mk_ref(
Expand Down
49 changes: 43 additions & 6 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use rustc_middle::mir::{
Statement, StatementKind, Terminator, TerminatorKind, UnOp, START_BLOCK,
};
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable, TypeVisitable};
use rustc_mir_dataflow::impls::MaybeStorageLive;
use rustc_mir_dataflow::storage::always_live_locals;
Expand Down Expand Up @@ -275,7 +276,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
};

match parent_ty.ty.kind() {
let kind = match parent_ty.ty.kind() {
&ty::Opaque(def_id, substs) => {
self.tcx.bound_type_of(def_id).subst(self.tcx, substs).kind()
}
kind => kind,
};

match kind {
ty::Tuple(fields) => {
let Some(f_ty) = fields.get(f.as_usize()) else {
fail_out_of_bounds(self, location);
Expand All @@ -299,12 +307,39 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
};
check_equal(self, location, f_ty);
}
ty::Generator(_, substs, _) => {
let substs = substs.as_generator();
let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else {
fail_out_of_bounds(self, location);
return;
&ty::Generator(def_id, substs, _) => {
let f_ty = if let Some(var) = parent_ty.variant_index {
let gen_body = if def_id == self.body.source.def_id() {
self.body
} else {
self.tcx.optimized_mir(def_id)
};

let Some(layout) = gen_body.generator_layout() else {
self.fail(location, format!("No generator layout for {:?}", parent_ty));
return;
};

let Some(&local) = layout.variant_fields[var].get(f) else {
fail_out_of_bounds(self, location);
return;
};

let Some(&f_ty) = layout.field_tys.get(local) else {
self.fail(location, format!("Out of bounds local {:?} for {:?}", local, parent_ty));
return;
};

f_ty
} else {
let Some(f_ty) = substs.as_generator().prefix_tys().nth(f.index()) else {
fail_out_of_bounds(self, location);
return;
};

f_ty
};

check_equal(self, location, f_ty);
}
_ => {
Expand All @@ -328,6 +363,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
{
self.fail(location, format!("{:?}, has deref at the wrong place", place));
}

self.super_place(place, cntxt, location);
}

fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
Expand Down
33 changes: 32 additions & 1 deletion compiler/rustc_lint/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use rustc_middle::middle::stability;
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, print::Printer, subst::GenericArg, RegisteredTools, Ty, TyCtxt};
use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_session::lint::{BuiltinLintDiagnostics, LintExpectationId};
use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
use rustc_session::Session;
use rustc_span::lev_distance::find_best_match_for_name;
Expand Down Expand Up @@ -906,6 +906,29 @@ pub trait LintContext: Sized {
) {
self.lookup(lint, None as Option<Span>, decorate);
}

/// This returns the lint level for the given lint at the current location.
fn get_lint_level(&self, lint: &'static Lint) -> Level;

/// This function can be used to manually fulfill an expectation. This can
/// be used for lints which contain several spans, and should be suppressed,
/// if either location was marked with an expectation.
///
/// Note that this function should only be called for [`LintExpectationId`]s
/// retrieved from the current lint pass. Buffered or manually created ids can
/// cause ICEs.
fn fulfill_expectation(&self, expectation: LintExpectationId) {
// We need to make sure that submitted expectation ids are correctly fulfilled suppressed
// and stored between compilation sessions. To not manually do these steps, we simply create
// a dummy diagnostic and emit is as usual, which will be suppressed and stored like a normal
// expected lint diagnostic.
self.sess()
.struct_expect(
"this is a dummy diagnostic, to submit and store an expectation",
expectation,
)
.emit();
}
}

impl<'a> EarlyContext<'a> {
Expand Down Expand Up @@ -953,6 +976,10 @@ impl LintContext for LateContext<'_> {
None => self.tcx.struct_lint_node(lint, hir_id, decorate),
}
}

fn get_lint_level(&self, lint: &'static Lint) -> Level {
self.tcx.lint_level_at_node(lint, self.last_node_with_lint_attrs).0
}
}

impl LintContext for EarlyContext<'_> {
Expand All @@ -975,6 +1002,10 @@ impl LintContext for EarlyContext<'_> {
) {
self.builder.struct_lint(lint, span.map(|s| s.into()), decorate)
}

fn get_lint_level(&self, lint: &'static Lint) -> Level {
self.builder.lint_level(lint).0
}
}

impl<'tcx> LateContext<'tcx> {
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,11 @@ declare_lint! {
/// The `expect` attribute can be removed if this is intended behavior otherwise
/// it should be investigated why the expected lint is no longer issued.
///
/// In rare cases, the expectation might be emitted at a different location than
/// shown in the shown code snippet. In most cases, the `#[expect]` attribute
/// works when added to the outer scope. A few lints can only be expected
/// on a crate level.
///
/// Part of RFC 2383. The progress is being tracked in [#54503]
///
/// [#54503]: https://github.com/rust-lang/rust/issues/54503
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_lint_defs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,13 @@ impl Level {
Level::Deny | Level::Forbid => true,
}
}

pub fn get_expectation_id(&self) -> Option<LintExpectationId> {
match self {
Level::Expect(id) | Level::ForceWarn(Some(id)) => Some(*id),
_ => None,
}
}
}

/// Specification of a single lint.
Expand Down
Loading