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 #91388

Merged
merged 17 commits into from
Nov 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
debug!("build: input_or_output={:?}", ty);
// We add implied bounds from both the unnormalized and normalized ty
// See issue #87748
let constraints_implied_1 = self.add_implied_bounds(ty);
let TypeOpOutput { output: norm_ty, constraints: constraints1, .. } = self
.param_env
.and(type_op::normalize::Normalize::new(ty))
Expand Down Expand Up @@ -284,10 +283,9 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
// }
// ```
// Both &Self::Bar and &() are WF
let constraints_implied_2 =
if ty != norm_ty { self.add_implied_bounds(norm_ty) } else { None };
let constraints_implied = self.add_implied_bounds(norm_ty);
normalized_inputs_and_output.push(norm_ty);
constraints1.into_iter().chain(constraints_implied_1).chain(constraints_implied_2)
constraints1.into_iter().chain(constraints_implied)
})
.collect();

Expand Down
26 changes: 25 additions & 1 deletion compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,10 +394,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
sym::transmute => {
self.copy_op_transmute(&args[0], dest)?;
}
sym::assert_inhabited => {
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => {
let ty = instance.substs.type_at(0);
let layout = self.layout_of(ty)?;

// For *all* intrinsics we first check `is_uninhabited` to give a more specific
// error message.
if layout.abi.is_uninhabited() {
// The run-time intrinsic panics just to get a good backtrace; here we abort
// since there is no problem showing a backtrace even for aborts.
Expand All @@ -409,6 +411,28 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
),
)?;
}
if intrinsic_name == sym::assert_zero_valid
&& !layout.might_permit_raw_init(self, /*zero:*/ true)
{
M::abort(
self,
format!(
"aborted execution: attempted to zero-initialize type `{}`, which is invalid",
ty
),
)?;
}
if intrinsic_name == sym::assert_uninit_valid
&& !layout.might_permit_raw_init(self, /*zero:*/ false)
{
M::abort(
self,
format!(
"aborted execution: attempted to leave type `{}` uninitialized, which is invalid",
ty
),
)?;
}
}
sym::simd_insert => {
let index = u64::from(self.read_scalar(&args[1])?.to_u32()?);
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_const_eval/src/transform/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
pub mod check_consts;
pub mod promote_consts;
pub mod validate;

pub use rustc_middle::mir::MirPass;
1 change: 0 additions & 1 deletion compiler/rustc_const_eval/src/transform/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ use std::cell::Cell;
use std::{cmp, iter, mem};

use crate::transform::check_consts::{qualifs, ConstCx};
use crate::transform::MirPass;

/// A `MirPass` for promotion.
///
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
//! Validates the MIR to ensure that invariants are upheld.

use super::MirPass;
use rustc_index::bit_set::BitSet;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::traversal;
use rustc_middle::mir::visit::{PlaceContext, Visitor};
use rustc_middle::mir::{
AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, PlaceElem,
PlaceRef, ProjectionElem, Rvalue, SourceScope, Statement, StatementKind, Terminator,
AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPass, MirPhase, Operand,
PlaceElem, PlaceRef, ProjectionElem, Rvalue, SourceScope, Statement, StatementKind, Terminator,
TerminatorKind, START_BLOCK,
};
use rustc_middle::ty::fold::BottomUpFolder;
Expand Down
41 changes: 26 additions & 15 deletions compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ pub trait Emitter {

/// Formats the substitutions of the primary_span
///
/// The are a lot of conditions to this method, but in short:
/// There are a lot of conditions to this method, but in short:
///
/// * If the current `Diagnostic` has only one visible `CodeSuggestion`,
/// we format the `help` suggestion depending on the content of the
Expand Down Expand Up @@ -736,7 +736,9 @@ impl EmitterWriter {

let line_offset = buffer.num_lines();

let left = margin.left(source_string.len()); // Left trim
// Left trim
let left = margin.left(source_string.len());

// Account for unicode characters of width !=0 that were removed.
let left = source_string
.chars()
Expand Down Expand Up @@ -1623,18 +1625,27 @@ impl EmitterWriter {
suggestions.iter().take(MAX_SUGGESTIONS)
{
notice_capitalization |= only_capitalization;
// Only show underline if the suggestion spans a single line and doesn't cover the
// entirety of the code output. If you have multiple replacements in the same line
// of code, show the underline.
let show_underline = !(parts.len() == 1 && parts[0].snippet.trim() == complete.trim())
&& complete.lines().count() == 1;

let has_deletion = parts.iter().any(|p| p.is_deletion());
let is_multiline = complete.lines().count() > 1;

let show_diff = has_deletion && !is_multiline;
enum DisplaySuggestion {
Underline,
Diff,
None,
}

let show_code_change = if has_deletion && !is_multiline {
DisplaySuggestion::Diff
} else if (parts.len() != 1 || parts[0].snippet.trim() != complete.trim())
&& !is_multiline
{
DisplaySuggestion::Underline
} else {
DisplaySuggestion::None
};

if show_diff {
if let DisplaySuggestion::Diff = show_code_change {
row_num += 1;
}

Expand All @@ -1657,7 +1668,7 @@ impl EmitterWriter {
&self.maybe_anonymized(line_start + line_pos),
Style::LineNumber,
);
if show_diff {
if let DisplaySuggestion::Diff = show_code_change {
// Add the line number for both addition and removal to drive the point home.
//
// N - fn foo<A: T>(bar: A) {
Expand Down Expand Up @@ -1727,7 +1738,7 @@ impl EmitterWriter {
let mut offsets: Vec<(usize, isize)> = Vec::new();
// Only show an underline in the suggestions if the suggestion is not the
// entirety of the code being shown and the displayed code is not multiline.
if show_underline {
if let DisplaySuggestion::Diff | DisplaySuggestion::Underline = show_code_change {
draw_col_separator(&mut buffer, row_num, max_line_num_len + 1);
for part in parts {
let span_start_pos = sm.lookup_char_pos(part.span.lo()).col_display;
Expand Down Expand Up @@ -1755,7 +1766,7 @@ impl EmitterWriter {
assert!(underline_start >= 0 && underline_end >= 0);
let padding: usize = max_line_num_len + 3;
for p in underline_start..underline_end {
if !show_diff {
if let DisplaySuggestion::Underline = show_code_change {
// If this is a replacement, underline with `^`, if this is an addition
// underline with `+`.
buffer.putc(
Expand All @@ -1766,7 +1777,7 @@ impl EmitterWriter {
);
}
}
if show_diff {
if let DisplaySuggestion::Diff = show_code_change {
// Colorize removal with red in diff format.
buffer.set_style_range(
row_num - 2,
Expand Down Expand Up @@ -1797,7 +1808,7 @@ impl EmitterWriter {
// if we elided some lines, add an ellipsis
if lines.next().is_some() {
buffer.puts(row_num, max_line_num_len - 1, "...", Style::LineNumber);
} else if !show_underline {
} else if let DisplaySuggestion::None = show_code_change {
draw_col_separator_no_space(&mut buffer, row_num, max_line_num_len + 1);
row_num += 1;
}
Expand Down Expand Up @@ -2083,7 +2094,7 @@ const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[
('\t', " "), // We do our own tab replacement
('\u{200D}', ""), // Replace ZWJ with nothing for consistent terminal output of grapheme clusters.
('\u{202A}', ""), // The following unicode text flow control characters are inconsistently
('\u{202B}', ""), // supported accross CLIs and can cause confusion due to the bytes on disk
('\u{202B}', ""), // supported across CLIs and can cause confusion due to the bytes on disk
('\u{202D}', ""), // not corresponding to the visible source code, so we replace them always.
('\u{202E}', ""),
('\u{2066}', ""),
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_index::vec::IndexVec;
use rustc_middle::mir::visit::Visitor as _;
use rustc_middle::mir::{dump_mir, traversal, Body, ConstQualifs, MirPhase, Promoted};
use rustc_middle::mir::{dump_mir, traversal, Body, ConstQualifs, MirPass, MirPhase, Promoted};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
use rustc_span::{Span, Symbol};
Expand Down Expand Up @@ -78,7 +78,6 @@ mod unreachable_prop;
use rustc_const_eval::transform::check_consts;
use rustc_const_eval::transform::promote_consts;
use rustc_const_eval::transform::validate;
pub use rustc_const_eval::transform::MirPass;
use rustc_mir_dataflow::rustc_peek;

pub fn provide(providers: &mut Providers) {
Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_typeck/src/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,14 +264,9 @@ fn compare_predicate_entailment<'tcx>(
// First liberate late bound regions and subst placeholders
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, tcx.fn_sig(trait_m.def_id));
let trait_sig = trait_sig.subst(tcx, trait_to_placeholder_substs);
// Next, add all inputs and output as well-formed tys. Importantly,
// we have to do this before normalization, since the normalized ty may
// not contain the input parameters. See issue #87748.
wf_tys.extend(trait_sig.inputs_and_output.iter());
let trait_sig =
inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, trait_sig);
// Also add the resulting inputs and output as well-formed.
// This probably isn't strictly necessary.
// Add the resulting inputs and output as well-formed.
wf_tys.extend(trait_sig.inputs_and_output.iter());
let trait_fty = tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig));

Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_typeck/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,6 @@ fn typeck_with_fallback<'tcx>(
let mut wf_tys = FxHashSet::default();
// Compute the fty from point of view of inside the fn.
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
wf_tys.extend(fn_sig.inputs_and_output.iter());
let fn_sig = inh.normalize_associated_types_in(
body.value.span,
body_id.hir_id,
Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1334,11 +1334,6 @@ fn check_fn_or_method<'fcx, 'tcx>(
) {
let sig = fcx.tcx.liberate_late_bound_regions(def_id, sig);

// Unnormalized types in signature are WF too
implied_bounds.extend(sig.inputs());
// FIXME(#27579) return types should not be implied bounds
implied_bounds.insert(sig.output());

// Normalize the input and output types one at a time, using a different
// `WellFormedLoc` for each. We cannot call `normalize_associated_types`
// on the entire `FnSig`, since this would use the same `WellFormedLoc`
Expand Down
2 changes: 2 additions & 0 deletions library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -860,12 +860,14 @@ extern "rust-intrinsic" {
/// zero-initialization: This will statically either panic, or do nothing.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_const_unstable(feature = "const_assert_type2", issue = "none")]
pub fn assert_zero_valid<T>();

/// A guard for unsafe functions that cannot ever be executed if `T` has invalid
/// bit patterns: This will statically either panic, or do nothing.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_const_unstable(feature = "const_assert_type2", issue = "none")]
pub fn assert_uninit_valid<T>();

/// Gets a reference to a static `Location` indicating where it was called.
Expand Down
1 change: 1 addition & 0 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,7 @@ pub trait Iterator {
/// assert_eq!(iter.next(), None);
/// ```
#[inline]
#[doc(alias = "drop_while")]
#[stable(feature = "rust1", since = "1.0.0")]
fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where
Expand Down
2 changes: 1 addition & 1 deletion src/test/debuginfo/rc_arc.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// pretty-printers are not loaded
// ignore-windows-gnu: pretty-printers are not loaded
// compile-flags:-g

// min-gdb-version: 8.1
Expand Down
22 changes: 22 additions & 0 deletions src/test/ui/consts/assert-type-intrinsics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// error-pattern: any use of this value will cause an error

#![feature(never_type)]
#![feature(const_maybe_uninit_assume_init, const_assert_type2)]
#![feature(core_intrinsics)]

use std::intrinsics;

#[allow(invalid_value)]
fn main() {
use std::mem::MaybeUninit;

const _BAD1: () = unsafe {
MaybeUninit::<!>::uninit().assume_init();
};
const _BAD2: () = unsafe {
intrinsics::assert_uninit_valid::<bool>();
};
const _BAD3: () = unsafe {
intrinsics::assert_zero_valid::<&'static i32>();
};
}
39 changes: 39 additions & 0 deletions src/test/ui/consts/assert-type-intrinsics.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
error: any use of this value will cause an error
--> $DIR/assert-type-intrinsics.rs:14:9
|
LL | / const _BAD1: () = unsafe {
LL | | MaybeUninit::<!>::uninit().assume_init();
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
LL | | };
| |______-
|
= note: `#[deny(const_err)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>

error: any use of this value will cause an error
--> $DIR/assert-type-intrinsics.rs:17:9
|
LL | / const _BAD2: () = unsafe {
LL | | intrinsics::assert_uninit_valid::<bool>();
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid
LL | | };
| |______-
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>

error: any use of this value will cause an error
--> $DIR/assert-type-intrinsics.rs:20:9
|
LL | / const _BAD3: () = unsafe {
LL | | intrinsics::assert_zero_valid::<&'static i32>();
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `&i32`, which is invalid
LL | | };
| |______-
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>

error: aborting due to 3 previous errors

13 changes: 0 additions & 13 deletions src/test/ui/consts/assume-type-intrinsics.rs

This file was deleted.

15 changes: 0 additions & 15 deletions src/test/ui/consts/assume-type-intrinsics.stderr

This file was deleted.

14 changes: 14 additions & 0 deletions src/test/ui/fn/implied-bounds-unnorm-associated-type.nll.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: lifetime may not live long enough
--> $DIR/implied-bounds-unnorm-associated-type.rs:14:5
|
LL | fn f<'a, 'b>(s: &'b str, _: <&'a &'b () as Trait>::Type) -> &'a str {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | s
| ^ returning this value requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`

error: aborting due to previous error

Loading