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 8 pull requests #67560

Merged
merged 29 commits into from
Dec 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
9ee16e1
Require const stability attributes on intrinsics to be able to use th…
oli-obk Dec 20, 2019
032d810
Add a big notice about const intrinsics
oli-obk Dec 20, 2019
89986a3
add partialeq and eq to cursor
Luro02 Dec 11, 2019
4ce2384
Improve JS code a bit by avoid erasing all event handlers
GuillaumeGomez Dec 22, 2019
b677013
Improve code readability
GuillaumeGomez Dec 22, 2019
71ff18f
Fix invalid results showing back
GuillaumeGomez Dec 22, 2019
056dff5
Fix ICE in mir interpretation
oli-obk Dec 23, 2019
c205f6a
Remove mem::uninitalized from tests
Mark-Simulacrum Dec 22, 2019
5b8df34
Update src/librustc_mir/interpret/place.rs
oli-obk Dec 23, 2019
45acee3
Move `{hir::lowering -> hir}::is_range_literal`.
Centril Dec 22, 2019
a5991c5
Add the full issue reference to equality constraints in `where` clauses
varkor Dec 22, 2019
b7bfdbe
Improve invalid assignment error
varkor Dec 22, 2019
5fa02ec
Add note about destructuring assignments
varkor Dec 22, 2019
5ab4735
Recognise nested tuples/arrays/structs
varkor Dec 22, 2019
35979a9
Add span information to `ExprKind::Assign`
varkor Dec 22, 2019
9a60224
Add new folder for destructuring assignment tests
varkor Dec 22, 2019
dd7f493
is_range_literal: fix fallout
Centril Dec 22, 2019
4bb8346
is_range_literal: leave FIXME
Centril Dec 22, 2019
9e50813
Fix reformatting rebase issues
varkor Dec 23, 2019
a08df28
Document that calling Drop, even after it panics, is UB
Mark-Simulacrum Dec 23, 2019
63d2822
Fix typo
oli-obk Dec 23, 2019
260514d
Rollup merge of #67233 - Luro02:cursor_traits, r=sfackler
Centril Dec 23, 2019
1de2705
Rollup merge of #67466 - oli-obk:const_intrinsic, r=Centril
Centril Dec 23, 2019
67c0f4e
Rollup merge of #67507 - Mark-Simulacrum:purge-uninit, r=Centril
Centril Dec 23, 2019
6f38a15
Rollup merge of #67527 - GuillaumeGomez:results-show-too-much, r=kinn…
Centril Dec 23, 2019
3a07f3b
Rollup merge of #67536 - Centril:move-is_range_literal, r=Mark-Simula…
Centril Dec 23, 2019
4164761
Rollup merge of #67538 - varkor:lhs-assign-diagnostics, r=Centril
Centril Dec 23, 2019
7eb025f
Rollup merge of #67546 - oli-obk:slice_pattern_ice, r=varkor
Centril Dec 23, 2019
68a9a2d
Rollup merge of #67559 - Mark-Simulacrum:drop-doc, r=RalfJung
Centril Dec 23, 2019
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
43 changes: 43 additions & 0 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
//! Compiler intrinsics.
//!
//! The corresponding definitions are in `librustc_codegen_llvm/intrinsic.rs`.
//! The corresponding const implementations are in `librustc_mir/interpret/intrinsics.rs`
//!
//! # Const intrinsics
//!
//! Note: any changes to the constness of intrinsics should be discussed with the language team.
//! This includes changes in the stability of the constness.
//!
//! In order to make an intrinsic usable at compile-time, one needs to copy the implementation
//! from https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics.rs to
//! `librustc_mir/interpret/intrinsics.rs` and add a
//! `#[rustc_const_unstable(feature = "foo", issue = "01234")]` to the intrinsic.
//!
//! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute,
//! the intrinsic's attribute must be `rustc_const_stable`, too. Such a change should not be done
//! without T-lang consulation, because it bakes a feature into the language that cannot be
//! replicated in user code without compiler support.
//!
//! # Volatiles
//!
Expand Down Expand Up @@ -671,14 +687,17 @@ extern "rust-intrinsic" {
///
/// The stabilized version of this intrinsic is
/// [`std::mem::size_of`](../../std/mem/fn.size_of.html).
#[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
pub fn size_of<T>() -> usize;

/// Moves a value to an uninitialized memory location.
///
/// Drop glue is not run on the destination.
pub fn move_val_init<T>(dst: *mut T, src: T);

#[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")]
pub fn min_align_of<T>() -> usize;
#[rustc_const_unstable(feature = "const_pref_align_of", issue = "0")]
pub fn pref_align_of<T>() -> usize;

/// The size of the referenced value in bytes.
Expand All @@ -689,18 +708,21 @@ extern "rust-intrinsic" {
pub fn min_align_of_val<T: ?Sized>(_: &T) -> usize;

/// Gets a static string slice containing the name of a type.
#[rustc_const_unstable(feature = "const_type_name", issue = "0")]
pub fn type_name<T: ?Sized>() -> &'static str;

/// Gets an identifier which is globally unique to the specified type. This
/// function will return the same value for a type regardless of whichever
/// crate it is invoked in.
#[rustc_const_unstable(feature = "const_type_id", issue = "0")]
pub fn type_id<T: ?Sized + 'static>() -> u64;

/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
/// This will statically either panic, or do nothing.
pub fn panic_if_uninhabited<T>();

/// Gets a reference to a static `Location` indicating where it was called.
#[rustc_const_unstable(feature = "const_caller_location", issue = "47809")]
pub fn caller_location() -> &'static crate::panic::Location<'static>;

/// Creates a value initialized to zero.
Expand Down Expand Up @@ -957,6 +979,7 @@ extern "rust-intrinsic" {
///
/// The stabilized version of this intrinsic is
/// [`std::mem::needs_drop`](../../std/mem/fn.needs_drop.html).
#[rustc_const_stable(feature = "const_needs_drop", since = "1.40.0")]
pub fn needs_drop<T>() -> bool;

/// Calculates the offset from a pointer.
Expand Down Expand Up @@ -1154,6 +1177,7 @@ extern "rust-intrinsic" {
pub fn float_to_int_approx_unchecked<Float, Int>(value: Float) -> Int;

/// Returns the number of bits set in an integer type `T`
#[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")]
pub fn ctpop<T>(x: T) -> T;

/// Returns the number of leading unset bits (zeroes) in an integer type `T`.
Expand Down Expand Up @@ -1181,6 +1205,7 @@ extern "rust-intrinsic" {
/// let num_leading = ctlz(x);
/// assert_eq!(num_leading, 16);
/// ```
#[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")]
pub fn ctlz<T>(x: T) -> T;

/// Like `ctlz`, but extra-unsafe as it returns `undef` when
Expand All @@ -1197,6 +1222,7 @@ extern "rust-intrinsic" {
/// let num_leading = unsafe { ctlz_nonzero(x) };
/// assert_eq!(num_leading, 3);
/// ```
#[rustc_const_unstable(feature = "constctlz", issue = "0")]
pub fn ctlz_nonzero<T>(x: T) -> T;

/// Returns the number of trailing unset bits (zeroes) in an integer type `T`.
Expand Down Expand Up @@ -1224,6 +1250,7 @@ extern "rust-intrinsic" {
/// let num_trailing = cttz(x);
/// assert_eq!(num_trailing, 16);
/// ```
#[rustc_const_stable(feature = "const_cttz", since = "1.40.0")]
pub fn cttz<T>(x: T) -> T;

/// Like `cttz`, but extra-unsafe as it returns `undef` when
Expand All @@ -1240,30 +1267,36 @@ extern "rust-intrinsic" {
/// let num_trailing = unsafe { cttz_nonzero(x) };
/// assert_eq!(num_trailing, 3);
/// ```
#[rustc_const_unstable(feature = "const_cttz", issue = "0")]
pub fn cttz_nonzero<T>(x: T) -> T;

/// Reverses the bytes in an integer type `T`.
#[rustc_const_stable(feature = "const_bswap", since = "1.40.0")]
pub fn bswap<T>(x: T) -> T;

/// Reverses the bits in an integer type `T`.
#[rustc_const_stable(feature = "const_bitreverse", since = "1.40.0")]
pub fn bitreverse<T>(x: T) -> T;

/// Performs checked integer addition.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `overflowing_add` method. For example,
/// [`std::u32::overflowing_add`](../../std/primitive.u32.html#method.overflowing_add)
#[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
pub fn add_with_overflow<T>(x: T, y: T) -> (T, bool);

/// Performs checked integer subtraction
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `overflowing_sub` method. For example,
/// [`std::u32::overflowing_sub`](../../std/primitive.u32.html#method.overflowing_sub)
#[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
pub fn sub_with_overflow<T>(x: T, y: T) -> (T, bool);

/// Performs checked integer multiplication
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `overflowing_mul` method. For example,
/// [`std::u32::overflowing_mul`](../../std/primitive.u32.html#method.overflowing_mul)
#[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
pub fn mul_with_overflow<T>(x: T, y: T) -> (T, bool);

/// Performs an exact division, resulting in undefined behavior where
Expand All @@ -1279,9 +1312,11 @@ extern "rust-intrinsic" {

/// Performs an unchecked left shift, resulting in undefined behavior when
/// y < 0 or y >= N, where N is the width of T in bits.
#[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
pub fn unchecked_shl<T>(x: T, y: T) -> T;
/// Performs an unchecked right shift, resulting in undefined behavior when
/// y < 0 or y >= N, where N is the width of T in bits.
#[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
pub fn unchecked_shr<T>(x: T, y: T) -> T;

/// Returns the result of an unchecked addition, resulting in
Expand All @@ -1300,39 +1335,46 @@ extern "rust-intrinsic" {
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `rotate_left` method. For example,
/// [`std::u32::rotate_left`](../../std/primitive.u32.html#method.rotate_left)
#[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
pub fn rotate_left<T>(x: T, y: T) -> T;

/// Performs rotate right.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `rotate_right` method. For example,
/// [`std::u32::rotate_right`](../../std/primitive.u32.html#method.rotate_right)
#[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
pub fn rotate_right<T>(x: T, y: T) -> T;

/// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `wrapping_add` method. For example,
/// [`std::u32::wrapping_add`](../../std/primitive.u32.html#method.wrapping_add)
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
pub fn wrapping_add<T>(a: T, b: T) -> T;
/// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `wrapping_sub` method. For example,
/// [`std::u32::wrapping_sub`](../../std/primitive.u32.html#method.wrapping_sub)
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
pub fn wrapping_sub<T>(a: T, b: T) -> T;
/// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `wrapping_mul` method. For example,
/// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul)
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
pub fn wrapping_mul<T>(a: T, b: T) -> T;

/// Computes `a + b`, while saturating at numeric bounds.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `saturating_add` method. For example,
/// [`std::u32::saturating_add`](../../std/primitive.u32.html#method.saturating_add)
#[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
pub fn saturating_add<T>(a: T, b: T) -> T;
/// Computes `a - b`, while saturating at numeric bounds.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `saturating_sub` method. For example,
/// [`std::u32::saturating_sub`](../../std/primitive.u32.html#method.saturating_sub)
#[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
pub fn saturating_sub<T>(a: T, b: T) -> T;

/// Returns the value of the discriminant for the variant in 'v',
Expand All @@ -1354,6 +1396,7 @@ extern "rust-intrinsic" {
pub fn nontemporal_store<T>(ptr: *mut T, val: T);

/// See documentation of `<*const T>::offset_from` for details.
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "0")]
pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;

/// Internal hook used by Miri to implement unwinding.
Expand Down
2 changes: 2 additions & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@
#![feature(maybe_uninit_slice)]
#![feature(external_doc)]
#![feature(associated_type_bounds)]
#![feature(const_type_id)]
#![feature(const_caller_location)]

#[prelude_import]
#[allow(unused)]
Expand Down
1 change: 1 addition & 0 deletions src/libcore/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// the `caller_location` intrinsic, but once `#[track_caller]` is implemented,
// `panicking::{panic, panic_fmt}` can use that instead of a `Location` argument.
core_intrinsics,
const_caller_location,
)]
#[stable(feature = "core", since = "1.6.0")]
macro_rules! panic {
Expand Down
6 changes: 6 additions & 0 deletions src/libcore/ops/drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,15 @@ pub trait Drop {
/// Given that a [`panic!`] will call `drop` as it unwinds, any [`panic!`]
/// in a `drop` implementation will likely abort.
///
/// Note that even if this panics, the value is considered to be dropped;
/// you must not cause `drop` to be called again. This is normally automatically
/// handled by the compiler, but when using unsafe code, can sometimes occur
/// unintentionally, particularly when using [`std::ptr::drop_in_place`].
///
/// [E0040]: ../../error-index.html#E0040
/// [`panic!`]: ../macro.panic.html
/// [`std::mem::drop`]: ../../std/mem/fn.drop.html
/// [`std::ptr::drop_in_place`]: ../../std/ptr/fn.drop_in_place.html
#[stable(feature = "rust1", since = "1.0.0")]
fn drop(&mut self);
}
6 changes: 3 additions & 3 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1043,9 +1043,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
walk_list!(visitor, visit_label, opt_label);
visitor.visit_block(block);
}
ExprKind::Assign(ref left_hand_expression, ref right_hand_expression) => {
visitor.visit_expr(right_hand_expression);
visitor.visit_expr(left_hand_expression)
ExprKind::Assign(ref lhs, ref rhs, _) => {
visitor.visit_expr(rhs);
visitor.visit_expr(lhs)
}
ExprKind::AssignOp(_, ref left_expression, ref right_expression) => {
visitor.visit_expr(right_expression);
Expand Down
62 changes: 0 additions & 62 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3437,65 +3437,3 @@ fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body<'hir>>) -> Vec<hir::BodyId>
body_ids.sort_by_key(|b| bodies[b].value.span);
body_ids
}

/// Checks if the specified expression is a built-in range literal.
/// (See: `LoweringContext::lower_expr()`).
pub fn is_range_literal(sess: &Session, expr: &hir::Expr) -> bool {
use hir::{Path, QPath, ExprKind, TyKind};

// Returns whether the given path represents a (desugared) range,
// either in std or core, i.e. has either a `::std::ops::Range` or
// `::core::ops::Range` prefix.
fn is_range_path(path: &Path) -> bool {
let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.to_string()).collect();
let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect();

// "{{root}}" is the equivalent of `::` prefix in `Path`.
if let ["{{root}}", std_core, "ops", range] = segs.as_slice() {
(*std_core == "std" || *std_core == "core") && range.starts_with("Range")
} else {
false
}
};

// Check whether a span corresponding to a range expression is a
// range literal, rather than an explicit struct or `new()` call.
fn is_lit(sess: &Session, span: &Span) -> bool {
let source_map = sess.source_map();
let end_point = source_map.end_point(*span);

if let Ok(end_string) = source_map.span_to_snippet(end_point) {
!(end_string.ends_with("}") || end_string.ends_with(")"))
} else {
false
}
};

match expr.kind {
// All built-in range literals but `..=` and `..` desugar to `Struct`s.
ExprKind::Struct(ref qpath, _, _) => {
if let QPath::Resolved(None, ref path) = **qpath {
return is_range_path(&path) && is_lit(sess, &expr.span);
}
}

// `..` desugars to its struct path.
ExprKind::Path(QPath::Resolved(None, ref path)) => {
return is_range_path(&path) && is_lit(sess, &expr.span);
}

// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
ExprKind::Call(ref func, _) => {
if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.kind {
if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.kind {
let new_call = segment.ident.name == sym::new;
return is_range_path(&path) && is_lit(sess, &expr.span) && new_call;
}
}
}

_ => {}
}

false
}
11 changes: 7 additions & 4 deletions src/librustc/hir/lowering/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ impl LoweringContext<'_, '_> {
self.lower_block(blk, opt_label.is_some()),
self.lower_label(opt_label),
),
ExprKind::Assign(ref el, ref er) => {
hir::ExprKind::Assign(P(self.lower_expr(el)), P(self.lower_expr(er)))
ExprKind::Assign(ref el, ref er, span) => {
hir::ExprKind::Assign(P(self.lower_expr(el)), P(self.lower_expr(er)), span)
}
ExprKind::AssignOp(op, ref el, ref er) => hir::ExprKind::AssignOp(
self.lower_binop(op),
Expand Down Expand Up @@ -994,8 +994,11 @@ impl LoweringContext<'_, '_> {
let (val_pat, val_pat_hid) = self.pat_ident(pat.span, val_ident);
let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat_hid));
let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat_hid));
let assign =
P(self.expr(pat.span, hir::ExprKind::Assign(next_expr, val_expr), ThinVec::new()));
let assign = P(self.expr(
pat.span,
hir::ExprKind::Assign(next_expr, val_expr, pat.span),
ThinVec::new(),
));
let some_pat = self.pat_some(pat.span, val_pat);
self.arm(some_pat, assign)
};
Expand Down
Loading