Skip to content

Commit

Permalink
Auto merge of #72504 - Dylan-DPC:rollup-6wi1ifz, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

 - #72292 (Replace obligation construction with deref_steps())
 - #72431 (add warning sign to UB examples)
 - #72446 (Impl Ord for proc_macro::LineColumn)
 - #72492 (Add some regression tests)
 - #72496 (Correct small typo: 'not' -> 'note')

Failed merges:

r? @ghost
  • Loading branch information
bors committed May 23, 2020
2 parents 75b0a68 + a03bf3f commit 8970e8b
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 78 deletions.
26 changes: 13 additions & 13 deletions src/libcore/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ use crate::mem::ManuallyDrop;
/// # #![allow(invalid_value)]
/// use std::mem::{self, MaybeUninit};
///
/// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior!
/// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior! ⚠️
/// // The equivalent code with `MaybeUninit<&i32>`:
/// let x: &i32 = unsafe { MaybeUninit::zeroed().assume_init() }; // undefined behavior!
/// let x: &i32 = unsafe { MaybeUninit::zeroed().assume_init() }; // undefined behavior! ⚠️
/// ```
///
/// This is exploited by the compiler for various optimizations, such as eliding
Expand All @@ -35,9 +35,9 @@ use crate::mem::ManuallyDrop;
/// # #![allow(invalid_value)]
/// use std::mem::{self, MaybeUninit};
///
/// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior!
/// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior! ⚠️
/// // The equivalent code with `MaybeUninit<bool>`:
/// let b: bool = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior!
/// let b: bool = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! ⚠️
/// ```
///
/// Moreover, uninitialized memory is special in that the compiler knows that
Expand All @@ -49,9 +49,9 @@ use crate::mem::ManuallyDrop;
/// # #![allow(invalid_value)]
/// use std::mem::{self, MaybeUninit};
///
/// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior!
/// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior! ⚠️
/// // The equivalent code with `MaybeUninit<i32>`:
/// let x: i32 = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior!
/// let x: i32 = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! ⚠️
/// ```
/// (Notice that the rules around uninitialized integers are not finalized yet, but
/// until they are, it is advisable to avoid them.)
Expand Down Expand Up @@ -348,7 +348,7 @@ impl<T> MaybeUninit<T> {
/// let x = MaybeUninit::<(u8, NotZero)>::zeroed();
/// let x = unsafe { x.assume_init() };
/// // Inside a pair, we create a `NotZero` that does not have a valid discriminant.
/// // This is undefined behavior.
/// // This is undefined behavior. ⚠️
/// ```
#[stable(feature = "maybe_uninit", since = "1.36.0")]
#[inline]
Expand Down Expand Up @@ -400,7 +400,7 @@ impl<T> MaybeUninit<T> {
///
/// let x = MaybeUninit::<Vec<u32>>::uninit();
/// let x_vec = unsafe { &*x.as_ptr() };
/// // We have created a reference to an uninitialized vector! This is undefined behavior.
/// // We have created a reference to an uninitialized vector! This is undefined behavior. ⚠️
/// ```
///
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
Expand Down Expand Up @@ -437,7 +437,7 @@ impl<T> MaybeUninit<T> {
///
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
/// let x_vec = unsafe { &mut *x.as_mut_ptr() };
/// // We have created a reference to an uninitialized vector! This is undefined behavior.
/// // We have created a reference to an uninitialized vector! This is undefined behavior. ⚠️
/// ```
///
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
Expand Down Expand Up @@ -489,7 +489,7 @@ impl<T> MaybeUninit<T> {
///
/// let x = MaybeUninit::<Vec<u32>>::uninit();
/// let x_init = unsafe { x.assume_init() };
/// // `x` had not been initialized yet, so this last line caused undefined behavior.
/// // `x` had not been initialized yet, so this last line caused undefined behavior. ⚠️
/// ```
#[stable(feature = "maybe_uninit", since = "1.36.0")]
#[inline(always)]
Expand Down Expand Up @@ -553,7 +553,7 @@ impl<T> MaybeUninit<T> {
/// x.write(Some(vec![0,1,2]));
/// let x1 = unsafe { x.read() };
/// let x2 = unsafe { x.read() };
/// // We now created two copies of the same vector, leading to a double-free when
/// // We now created two copies of the same vector, leading to a double-free ⚠️ when
/// // they both get dropped!
/// ```
#[unstable(feature = "maybe_uninit_extra", issue = "63567")]
Expand Down Expand Up @@ -603,7 +603,7 @@ impl<T> MaybeUninit<T> {
///
/// let x = MaybeUninit::<Vec<u32>>::uninit();
/// let x_vec: &Vec<u32> = unsafe { x.get_ref() };
/// // We have created a reference to an uninitialized vector! This is undefined behavior.
/// // We have created a reference to an uninitialized vector! This is undefined behavior. ⚠️
/// ```
///
/// ```rust,no_run
Expand Down Expand Up @@ -686,7 +686,7 @@ impl<T> MaybeUninit<T> {
/// unsafe {
/// *b.get_mut() = true;
/// // We have created a (mutable) reference to an uninitialized `bool`!
/// // This is undefined behavior.
/// // This is undefined behavior. ⚠️
/// }
/// ```
///
Expand Down
15 changes: 15 additions & 0 deletions src/libproc_macro/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ mod diagnostic;
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
pub use diagnostic::{Diagnostic, Level, MultiSpan};

use std::cmp::Ordering;
use std::ops::{Bound, RangeBounds};
use std::path::PathBuf;
use std::str::FromStr;
Expand Down Expand Up @@ -420,6 +421,20 @@ impl !Send for LineColumn {}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl !Sync for LineColumn {}

#[unstable(feature = "proc_macro_span", issue = "54725")]
impl Ord for LineColumn {
fn cmp(&self, other: &Self) -> Ordering {
self.line.cmp(&other.line).then(self.column.cmp(&other.column))
}
}

#[unstable(feature = "proc_macro_span", issue = "54725")]
impl PartialOrd for LineColumn {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

/// The source file of a given `Span`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
#[derive(Clone)]
Expand Down
12 changes: 12 additions & 0 deletions src/libproc_macro/tests/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![feature(proc_macro_span)]

use proc_macro::LineColumn;

#[test]
fn test_line_column_ord() {
let line0_column0 = LineColumn { line: 0, column: 0 };
let line0_column1 = LineColumn { line: 0, column: 1 };
let line1_column0 = LineColumn { line: 1, column: 0 };
assert!(line0_column0 < line0_column1);
assert!(line0_column1 < line1_column0);
}
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let coerce = Coerce::new(self, cause, AllowTwoPhase::No);
coerce
.autoderef(rustc_span::DUMMY_SP, expr_ty)
.find_map(|(ty, steps)| coerce.unify(ty, target).ok().map(|_| steps))
.find_map(|(ty, steps)| self.probe(|_| coerce.unify(ty, target)).ok().map(|_| steps))
}

/// Given some expressions, their known unified type and another expression,
Expand Down
72 changes: 26 additions & 46 deletions src/librustc_typeck/check/demand.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
use crate::check::FnCtxt;
use rustc_infer::infer::InferOk;
use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_trait_selection::traits::{self, ObligationCause};
use rustc_trait_selection::traits::ObligationCause;

use rustc_ast::util::parser::PREC_POSTFIX;
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::lang_items::{CloneTraitLangItem, DerefTraitLangItem};
use rustc_hir::lang_items::CloneTraitLangItem;
use rustc_hir::{is_range_literal, Node};
use rustc_middle::ty::adjustment::AllowTwoPhase;
use rustc_middle::ty::{self, AssocItem, ToPredicate, Ty, TypeAndMut};
use rustc_middle::ty::{self, AssocItem, Ty, TypeAndMut};
use rustc_span::symbol::sym;
use rustc_span::Span;

Expand Down Expand Up @@ -633,48 +632,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
_ if sp == expr.span && !is_macro => {
// Check for `Deref` implementations by constructing a predicate to
// prove: `<T as Deref>::Output == U`
let deref_trait = self.tcx.require_lang_item(DerefTraitLangItem, Some(sp));
let item_def_id = self
.tcx
.associated_items(deref_trait)
.in_definition_order()
.find(|item| item.kind == ty::AssocKind::Type)
.unwrap()
.def_id;
let predicate =
ty::PredicateKind::Projection(ty::Binder::bind(ty::ProjectionPredicate {
// `<T as Deref>::Output`
projection_ty: ty::ProjectionTy {
// `T`
substs: self.tcx.intern_substs(&[checked_ty.into()]),
// `Deref::Output`
item_def_id,
},
// `U`
ty: expected,
}))
.to_predicate(self.tcx);
let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
let impls_deref = self.infcx.predicate_may_hold(&obligation);

// For a suggestion to make sense, the type would need to be `Copy`.
let is_copy = self.infcx.type_is_copy_modulo_regions(self.param_env, expected, sp);

if is_copy && impls_deref {
if let Ok(code) = sm.span_to_snippet(sp) {
let message = if checked_ty.is_region_ptr() {
"consider dereferencing the borrow"
} else {
"consider dereferencing the type"
};
let suggestion = if is_struct_pat_shorthand_field {
format!("{}: *{}", code, code)
} else {
format!("*{}", code)
};
return Some((sp, message, suggestion, Applicability::MachineApplicable));
if let Some(steps) = self.deref_steps(checked_ty, expected) {
if steps == 1 {
// For a suggestion to make sense, the type would need to be `Copy`.
if self.infcx.type_is_copy_modulo_regions(self.param_env, expected, sp) {
if let Ok(code) = sm.span_to_snippet(sp) {
let message = if checked_ty.is_region_ptr() {
"consider dereferencing the borrow"
} else {
"consider dereferencing the type"
};
let suggestion = if is_struct_pat_shorthand_field {
format!("{}: *{}", code, code)
} else {
format!("*{}", code)
};
return Some((
sp,
message,
suggestion,
Applicability::MachineApplicable,
));
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ impl f32 {
/// Returns `max` if `self` is greater than `max`, and `min` if `self` is
/// less than `min`. Otherwise this returns `self`.
///
/// Not that this function returns NaN if the initial value was NaN as
/// Note that this function returns NaN if the initial value was NaN as
/// well.
///
/// # Panics
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,7 @@ impl f64 {
/// Returns `max` if `self` is greater than `max`, and `min` if `self` is
/// less than `min`. Otherwise this returns `self`.
///
/// Not that this function returns NaN if the initial value was NaN as
/// Note that this function returns NaN if the initial value was NaN as
/// well.
///
/// # Panics
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// compile-flags: -Zsave-analysis
// This is also a regression test for #69415 and the above flag is needed.

#![feature(untagged_unions)]

trait Tr1 { type As1: Copy; }
Expand Down
Loading

0 comments on commit 8970e8b

Please sign in to comment.