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 5 pull requests #72504

Merged
merged 12 commits into from
May 23, 2020
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