Skip to content

Commit

Permalink
Auto merge of rust-lang#97835 - Dylan-DPC:rollup-0ae3pwp, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

 - rust-lang#95948 (Improve the safety docs for `CStr`)
 - rust-lang#97325 (Fix precise field capture of univariant enums)
 - rust-lang#97817 (:arrow_up: rust-analyzer)
 - rust-lang#97821 (Remove confusing sentence from `Mutex` docs)
 - rust-lang#97826 (Add more information for rustdoc-gui tests)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jun 7, 2022
2 parents 7fe2c4b + 4851ec7 commit 5435ed6
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 42 deletions.
4 changes: 3 additions & 1 deletion compiler/rustc_middle/src/thir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,9 +317,11 @@ pub enum ExprKind<'tcx> {
lhs: ExprId,
rhs: ExprId,
},
/// Access to a struct or tuple field.
/// Access to a field of a struct, a tuple, an union, or an enum.
Field {
lhs: ExprId,
/// Variant containing the field.
variant_index: VariantIdx,
/// This can be a named (`.foo`) or unnamed (`.0`) field.
name: Field,
},
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/thir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
visitor.visit_expr(&visitor.thir()[lhs]);
visitor.visit_expr(&visitor.thir()[rhs]);
}
Field { lhs, name: _ } => visitor.visit_expr(&visitor.thir()[lhs]),
Field { lhs, variant_index: _, name: _ } => visitor.visit_expr(&visitor.thir()[lhs]),
Index { lhs, index } => {
visitor.visit_expr(&visitor.thir()[lhs]);
visitor.visit_expr(&visitor.thir()[index]);
Expand Down
59 changes: 48 additions & 11 deletions compiler/rustc_mir_build/src/build/expr/as_place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
use crate::build::{BlockAnd, BlockAndExtension, Builder};
use rustc_hir::def_id::DefId;
use rustc_hir::HirId;
use rustc_middle::hir::place::Projection as HirProjection;
use rustc_middle::hir::place::ProjectionKind as HirProjectionKind;
use rustc_middle::middle::region;
use rustc_middle::mir::AssertKind::BoundsCheck;
Expand Down Expand Up @@ -268,20 +269,52 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>(
ty::UpvarCapture::ByValue => upvar_resolved_place_builder,
};

let next_projection = capture.place.projections.len();
let mut curr_projections = from_builder.projection;

// We used some of the projections to build the capture itself,
// now we apply the remaining to the upvar resolved place.
upvar_resolved_place_builder
.projection
.extend(curr_projections.drain(next_projection..));
let remaining_projections = strip_prefix(
capture.place.base_ty,
from_builder.projection,
&capture.place.projections,
);
upvar_resolved_place_builder.projection.extend(remaining_projections);

Ok(upvar_resolved_place_builder)
}
}
}

/// Returns projections remaining after stripping an initial prefix of HIR
/// projections.
///
/// Supports only HIR projection kinds that represent a path that might be
/// captured by a closure or a generator, i.e., an `Index` or a `Subslice`
/// projection kinds are unsupported.
fn strip_prefix<'tcx>(
mut base_ty: Ty<'tcx>,
projections: Vec<PlaceElem<'tcx>>,
prefix_projections: &[HirProjection<'tcx>],
) -> impl Iterator<Item = PlaceElem<'tcx>> {
let mut iter = projections.into_iter();
for projection in prefix_projections {
match projection.kind {
HirProjectionKind::Deref => {
assert!(matches!(iter.next(), Some(ProjectionElem::Deref)));
}
HirProjectionKind::Field(..) => {
if base_ty.is_enum() {
assert!(matches!(iter.next(), Some(ProjectionElem::Downcast(..))));
}
assert!(matches!(iter.next(), Some(ProjectionElem::Field(..))));
}
HirProjectionKind::Index | HirProjectionKind::Subslice => {
bug!("unexpected projection kind: {:?}", projection);
}
}
base_ty = projection.ty;
}
iter
}

impl<'tcx> PlaceBuilder<'tcx> {
pub(crate) fn into_place<'a>(
self,
Expand Down Expand Up @@ -438,11 +471,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
this.expr_as_place(block, &this.thir[value], mutability, fake_borrow_temps)
})
}
ExprKind::Field { lhs, name } => {
let place_builder = unpack!(
block =
this.expr_as_place(block, &this.thir[lhs], mutability, fake_borrow_temps,)
);
ExprKind::Field { lhs, variant_index, name } => {
let lhs = &this.thir[lhs];
let mut place_builder =
unpack!(block = this.expr_as_place(block, lhs, mutability, fake_borrow_temps,));
if let ty::Adt(adt_def, _) = lhs.ty.kind() {
if adt_def.is_enum() {
place_builder = place_builder.downcast(*adt_def, variant_index);
}
}
block.and(place_builder.field(name, expr.ty))
}
ExprKind::Deref { arg } => {
Expand Down
14 changes: 6 additions & 8 deletions compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,7 @@ impl<'tcx> Cx<'tcx> {
}
hir::ExprKind::Field(ref source, ..) => ExprKind::Field {
lhs: self.mirror_expr(source),
variant_index: VariantIdx::new(0),
name: Field::new(tcx.field_index(expr.hir_id, self.typeck_results)),
},
hir::ExprKind::Cast(ref source, ref cast_ty) => {
Expand Down Expand Up @@ -994,14 +995,11 @@ impl<'tcx> Cx<'tcx> {
HirProjectionKind::Deref => {
ExprKind::Deref { arg: self.thir.exprs.push(captured_place_expr) }
}
HirProjectionKind::Field(field, ..) => {
// Variant index will always be 0, because for multi-variant
// enums, we capture the enum entirely.
ExprKind::Field {
lhs: self.thir.exprs.push(captured_place_expr),
name: Field::new(field as usize),
}
}
HirProjectionKind::Field(field, variant_index) => ExprKind::Field {
lhs: self.thir.exprs.push(captured_place_expr),
variant_index,
name: Field::new(field as usize),
},
HirProjectionKind::Index | HirProjectionKind::Subslice => {
// We don't capture these projections, so we can ignore them here
continue;
Expand Down
37 changes: 27 additions & 10 deletions library/core/src/ffi/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,20 +196,32 @@ impl CStr {
/// allows inspection and interoperation of non-owned C strings. The total
/// size of the raw C string must be smaller than `isize::MAX` **bytes**
/// in memory due to calling the `slice::from_raw_parts` function.
/// This method is unsafe for a number of reasons:
///
/// * There is no guarantee to the validity of `ptr`.
/// * The returned lifetime is not guaranteed to be the actual lifetime of
/// `ptr`.
/// * There is no guarantee that the memory pointed to by `ptr` contains a
/// valid nul terminator byte at the end of the string.
/// * It is not guaranteed that the memory pointed by `ptr` won't change
/// before the `CStr` has been destroyed.
/// # Safety
///
/// * The memory pointed to by `ptr` must contain a valid nul terminator at the
/// end of the string.
///
/// * `ptr` must be [valid] for reads of bytes up to and including the null terminator.
/// This means in particular:
///
/// * The entire memory range of this `CStr` must be contained within a single allocated object!
/// * `ptr` must be non-null even for a zero-length cstr.
///
/// * The memory referenced by the returned `CStr` must not be mutated for
/// the duration of lifetime `'a`.
///
/// > **Note**: This operation is intended to be a 0-cost cast but it is
/// > currently implemented with an up-front calculation of the length of
/// > the string. This is not guaranteed to always be the case.
///
/// # Caveat
///
/// The lifetime for the returned slice is inferred from its usage. To prevent accidental misuse,
/// it's suggested to tie the lifetime to whichever source lifetime is safe in the context,
/// such as by providing a helper function taking the lifetime of a host value for the slice,
/// or by explicit annotation.
///
/// # Examples
///
/// ```ignore (extern-declaration)
Expand All @@ -227,6 +239,8 @@ impl CStr {
/// }
/// # }
/// ```
///
/// [valid]: core::ptr#safety
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -349,8 +363,11 @@ impl CStr {
/// Unsafely creates a C string wrapper from a byte slice.
///
/// This function will cast the provided `bytes` to a `CStr` wrapper without
/// performing any sanity checks. The provided slice **must** be nul-terminated
/// and not contain any interior nul bytes.
/// performing any sanity checks.
///
/// # Safety
/// The provided slice **must** be nul-terminated and not contain any interior
/// nul bytes.
///
/// # Examples
///
Expand Down
9 changes: 4 additions & 5 deletions library/std/src/sync/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ use crate::sys_common::mutex as sys;
/// A mutual exclusion primitive useful for protecting shared data
///
/// This mutex will block threads waiting for the lock to become available. The
/// mutex can also be statically initialized or created via a [`new`]
/// constructor. Each mutex has a type parameter which represents the data that
/// it is protecting. The data can only be accessed through the RAII guards
/// returned from [`lock`] and [`try_lock`], which guarantees that the data is only
/// ever accessed when the mutex is locked.
/// mutex can be created via a [`new`] constructor. Each mutex has a type parameter
/// which represents the data that it is protecting. The data can only be accessed
/// through the RAII guards returned from [`lock`] and [`try_lock`], which
/// guarantees that the data is only ever accessed when the mutex is locked.
///
/// # Poisoning
///
Expand Down
20 changes: 15 additions & 5 deletions src/test/rustdoc-gui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,24 @@ You can find more information and its documentation in its [repository][browser-
If you need to have more information on the tests run, you can use `--test-args`:

```bash
$ ./x.py test src/test/rustdoc-gui --stage 1 --jobs 8 --test-args --debug
$ ./x.py test src/test/rustdoc-gui --stage 1 --test-args --debug
```

There are three options supported:
If you don't want to run in headless mode (helpful to debug sometimes), you can use
`--no-headless`:

* `--debug`: allows to see puppeteer commands.
* `--no-headless`: disable headless mode so you can see what's going on.
* `--show-text`: by default, text isn't rendered because of issues with fonts, it enables it back.
```bash
$ ./x.py test src/test/rustdoc-gui --stage 1 --test-args --no-headless
```

To see the supported options, use `--help`.

Important to be noted: if the chromium instance crashes when you run it, you might need to
use `--no-sandbox` to make it work:

```bash
$ ./x.py test src/test/rustdoc-gui --stage 1 --test-args --no-sandbox
```

[browser-ui-test]: https://github.com/GuillaumeGomez/browser-UI-test/
[puppeteer]: https://pptr.dev/
27 changes: 27 additions & 0 deletions src/test/ui/closures/2229_closure_analysis/capture-enum-field.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// edition:2021
// run-pass

#[derive(Debug, PartialEq, Eq)]
pub enum Color {
RGB(u8, u8, u8),
}

fn main() {
let mut color = Color::RGB(0, 0, 0);
let mut red = |v| {
let Color::RGB(ref mut r, _, _) = color;
*r = v;
};
let mut green = |v| {
let Color::RGB(_, ref mut g, _) = color;
*g = v;
};
let mut blue = |v| {
let Color::RGB(_, _, ref mut b) = color;
*b = v;
};
red(1);
green(2);
blue(3);
assert_eq!(Color::RGB(1, 2, 3), color);
}
2 changes: 1 addition & 1 deletion src/tools/rust-analyzer
1 change: 1 addition & 0 deletions src/tools/rustdoc-gui/tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ function showHelp() {
console.log(" --debug : show extra information about script run");
console.log(" --show-text : render font in pages");
console.log(" --no-headless : disable headless mode");
console.log(" --no-sandbox : disable sandbox mode");
console.log(" --help : show this message then quit");
console.log(" --tests-folder [PATH] : location of the .GOML tests folder");
console.log(" --jobs [NUMBER] : number of threads to run tests on");
Expand Down

0 comments on commit 5435ed6

Please sign in to comment.