Skip to content

Commit 8970e8b

Browse files
committed
Auto merge of #72504 - Dylan-DPC:rollup-6wi1ifz, r=Dylan-DPC
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
2 parents 75b0a68 + a03bf3f commit 8970e8b

File tree

10 files changed

+115
-78
lines changed

10 files changed

+115
-78
lines changed

src/libcore/mem/maybe_uninit.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ use crate::mem::ManuallyDrop;
2020
/// # #![allow(invalid_value)]
2121
/// use std::mem::{self, MaybeUninit};
2222
///
23-
/// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior!
23+
/// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior! ⚠️
2424
/// // The equivalent code with `MaybeUninit<&i32>`:
25-
/// let x: &i32 = unsafe { MaybeUninit::zeroed().assume_init() }; // undefined behavior!
25+
/// let x: &i32 = unsafe { MaybeUninit::zeroed().assume_init() }; // undefined behavior! ⚠️
2626
/// ```
2727
///
2828
/// This is exploited by the compiler for various optimizations, such as eliding
@@ -35,9 +35,9 @@ use crate::mem::ManuallyDrop;
3535
/// # #![allow(invalid_value)]
3636
/// use std::mem::{self, MaybeUninit};
3737
///
38-
/// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior!
38+
/// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior! ⚠️
3939
/// // The equivalent code with `MaybeUninit<bool>`:
40-
/// let b: bool = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior!
40+
/// let b: bool = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! ⚠️
4141
/// ```
4242
///
4343
/// Moreover, uninitialized memory is special in that the compiler knows that
@@ -49,9 +49,9 @@ use crate::mem::ManuallyDrop;
4949
/// # #![allow(invalid_value)]
5050
/// use std::mem::{self, MaybeUninit};
5151
///
52-
/// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior!
52+
/// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior! ⚠️
5353
/// // The equivalent code with `MaybeUninit<i32>`:
54-
/// let x: i32 = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior!
54+
/// let x: i32 = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! ⚠️
5555
/// ```
5656
/// (Notice that the rules around uninitialized integers are not finalized yet, but
5757
/// until they are, it is advisable to avoid them.)
@@ -348,7 +348,7 @@ impl<T> MaybeUninit<T> {
348348
/// let x = MaybeUninit::<(u8, NotZero)>::zeroed();
349349
/// let x = unsafe { x.assume_init() };
350350
/// // Inside a pair, we create a `NotZero` that does not have a valid discriminant.
351-
/// // This is undefined behavior.
351+
/// // This is undefined behavior. ⚠️
352352
/// ```
353353
#[stable(feature = "maybe_uninit", since = "1.36.0")]
354354
#[inline]
@@ -400,7 +400,7 @@ impl<T> MaybeUninit<T> {
400400
///
401401
/// let x = MaybeUninit::<Vec<u32>>::uninit();
402402
/// let x_vec = unsafe { &*x.as_ptr() };
403-
/// // We have created a reference to an uninitialized vector! This is undefined behavior.
403+
/// // We have created a reference to an uninitialized vector! This is undefined behavior. ⚠️
404404
/// ```
405405
///
406406
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
@@ -437,7 +437,7 @@ impl<T> MaybeUninit<T> {
437437
///
438438
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
439439
/// let x_vec = unsafe { &mut *x.as_mut_ptr() };
440-
/// // We have created a reference to an uninitialized vector! This is undefined behavior.
440+
/// // We have created a reference to an uninitialized vector! This is undefined behavior. ⚠️
441441
/// ```
442442
///
443443
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
@@ -489,7 +489,7 @@ impl<T> MaybeUninit<T> {
489489
///
490490
/// let x = MaybeUninit::<Vec<u32>>::uninit();
491491
/// let x_init = unsafe { x.assume_init() };
492-
/// // `x` had not been initialized yet, so this last line caused undefined behavior.
492+
/// // `x` had not been initialized yet, so this last line caused undefined behavior. ⚠️
493493
/// ```
494494
#[stable(feature = "maybe_uninit", since = "1.36.0")]
495495
#[inline(always)]
@@ -553,7 +553,7 @@ impl<T> MaybeUninit<T> {
553553
/// x.write(Some(vec![0,1,2]));
554554
/// let x1 = unsafe { x.read() };
555555
/// let x2 = unsafe { x.read() };
556-
/// // We now created two copies of the same vector, leading to a double-free when
556+
/// // We now created two copies of the same vector, leading to a double-free ⚠️ when
557557
/// // they both get dropped!
558558
/// ```
559559
#[unstable(feature = "maybe_uninit_extra", issue = "63567")]
@@ -603,7 +603,7 @@ impl<T> MaybeUninit<T> {
603603
///
604604
/// let x = MaybeUninit::<Vec<u32>>::uninit();
605605
/// let x_vec: &Vec<u32> = unsafe { x.get_ref() };
606-
/// // We have created a reference to an uninitialized vector! This is undefined behavior.
606+
/// // We have created a reference to an uninitialized vector! This is undefined behavior. ⚠️
607607
/// ```
608608
///
609609
/// ```rust,no_run
@@ -686,7 +686,7 @@ impl<T> MaybeUninit<T> {
686686
/// unsafe {
687687
/// *b.get_mut() = true;
688688
/// // We have created a (mutable) reference to an uninitialized `bool`!
689-
/// // This is undefined behavior.
689+
/// // This is undefined behavior. ⚠️
690690
/// }
691691
/// ```
692692
///

src/libproc_macro/lib.rs

+15
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ mod diagnostic;
3939
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
4040
pub use diagnostic::{Diagnostic, Level, MultiSpan};
4141

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

424+
#[unstable(feature = "proc_macro_span", issue = "54725")]
425+
impl Ord for LineColumn {
426+
fn cmp(&self, other: &Self) -> Ordering {
427+
self.line.cmp(&other.line).then(self.column.cmp(&other.column))
428+
}
429+
}
430+
431+
#[unstable(feature = "proc_macro_span", issue = "54725")]
432+
impl PartialOrd for LineColumn {
433+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
434+
Some(self.cmp(other))
435+
}
436+
}
437+
423438
/// The source file of a given `Span`.
424439
#[unstable(feature = "proc_macro_span", issue = "54725")]
425440
#[derive(Clone)]

src/libproc_macro/tests/test.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(proc_macro_span)]
2+
3+
use proc_macro::LineColumn;
4+
5+
#[test]
6+
fn test_line_column_ord() {
7+
let line0_column0 = LineColumn { line: 0, column: 0 };
8+
let line0_column1 = LineColumn { line: 0, column: 1 };
9+
let line1_column0 = LineColumn { line: 1, column: 0 };
10+
assert!(line0_column0 < line0_column1);
11+
assert!(line0_column1 < line1_column0);
12+
}

src/librustc_typeck/check/coercion.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
887887
let coerce = Coerce::new(self, cause, AllowTwoPhase::No);
888888
coerce
889889
.autoderef(rustc_span::DUMMY_SP, expr_ty)
890-
.find_map(|(ty, steps)| coerce.unify(ty, target).ok().map(|_| steps))
890+
.find_map(|(ty, steps)| self.probe(|_| coerce.unify(ty, target)).ok().map(|_| steps))
891891
}
892892

893893
/// Given some expressions, their known unified type and another expression,

src/librustc_typeck/check/demand.rs

+26-46
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
use crate::check::FnCtxt;
22
use rustc_infer::infer::InferOk;
33
use rustc_trait_selection::infer::InferCtxtExt as _;
4-
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
5-
use rustc_trait_selection::traits::{self, ObligationCause};
4+
use rustc_trait_selection::traits::ObligationCause;
65

76
use rustc_ast::util::parser::PREC_POSTFIX;
87
use rustc_errors::{Applicability, DiagnosticBuilder};
98
use rustc_hir as hir;
10-
use rustc_hir::lang_items::{CloneTraitLangItem, DerefTraitLangItem};
9+
use rustc_hir::lang_items::CloneTraitLangItem;
1110
use rustc_hir::{is_range_literal, Node};
1211
use rustc_middle::ty::adjustment::AllowTwoPhase;
13-
use rustc_middle::ty::{self, AssocItem, ToPredicate, Ty, TypeAndMut};
12+
use rustc_middle::ty::{self, AssocItem, Ty, TypeAndMut};
1413
use rustc_span::symbol::sym;
1514
use rustc_span::Span;
1615

@@ -633,48 +632,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
633632
}
634633
}
635634
_ if sp == expr.span && !is_macro => {
636-
// Check for `Deref` implementations by constructing a predicate to
637-
// prove: `<T as Deref>::Output == U`
638-
let deref_trait = self.tcx.require_lang_item(DerefTraitLangItem, Some(sp));
639-
let item_def_id = self
640-
.tcx
641-
.associated_items(deref_trait)
642-
.in_definition_order()
643-
.find(|item| item.kind == ty::AssocKind::Type)
644-
.unwrap()
645-
.def_id;
646-
let predicate =
647-
ty::PredicateKind::Projection(ty::Binder::bind(ty::ProjectionPredicate {
648-
// `<T as Deref>::Output`
649-
projection_ty: ty::ProjectionTy {
650-
// `T`
651-
substs: self.tcx.intern_substs(&[checked_ty.into()]),
652-
// `Deref::Output`
653-
item_def_id,
654-
},
655-
// `U`
656-
ty: expected,
657-
}))
658-
.to_predicate(self.tcx);
659-
let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
660-
let impls_deref = self.infcx.predicate_may_hold(&obligation);
661-
662-
// For a suggestion to make sense, the type would need to be `Copy`.
663-
let is_copy = self.infcx.type_is_copy_modulo_regions(self.param_env, expected, sp);
664-
665-
if is_copy && impls_deref {
666-
if let Ok(code) = sm.span_to_snippet(sp) {
667-
let message = if checked_ty.is_region_ptr() {
668-
"consider dereferencing the borrow"
669-
} else {
670-
"consider dereferencing the type"
671-
};
672-
let suggestion = if is_struct_pat_shorthand_field {
673-
format!("{}: *{}", code, code)
674-
} else {
675-
format!("*{}", code)
676-
};
677-
return Some((sp, message, suggestion, Applicability::MachineApplicable));
635+
if let Some(steps) = self.deref_steps(checked_ty, expected) {
636+
if steps == 1 {
637+
// For a suggestion to make sense, the type would need to be `Copy`.
638+
if self.infcx.type_is_copy_modulo_regions(self.param_env, expected, sp) {
639+
if let Ok(code) = sm.span_to_snippet(sp) {
640+
let message = if checked_ty.is_region_ptr() {
641+
"consider dereferencing the borrow"
642+
} else {
643+
"consider dereferencing the type"
644+
};
645+
let suggestion = if is_struct_pat_shorthand_field {
646+
format!("{}: *{}", code, code)
647+
} else {
648+
format!("*{}", code)
649+
};
650+
return Some((
651+
sp,
652+
message,
653+
suggestion,
654+
Applicability::MachineApplicable,
655+
));
656+
}
657+
}
678658
}
679659
}
680660
}

src/libstd/f32.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ impl f32 {
882882
/// Returns `max` if `self` is greater than `max`, and `min` if `self` is
883883
/// less than `min`. Otherwise this returns `self`.
884884
///
885-
/// Not that this function returns NaN if the initial value was NaN as
885+
/// Note that this function returns NaN if the initial value was NaN as
886886
/// well.
887887
///
888888
/// # Panics

src/libstd/f64.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ impl f64 {
884884
/// Returns `max` if `self` is greater than `max`, and `min` if `self` is
885885
/// less than `min`. Otherwise this returns `self`.
886886
///
887-
/// Not that this function returns NaN if the initial value was NaN as
887+
/// Note that this function returns NaN if the initial value was NaN as
888888
/// well.
889889
///
890890
/// # Panics

src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// compile-flags: -Zsave-analysis
2+
// This is also a regression test for #69415 and the above flag is needed.
3+
14
#![feature(untagged_unions)]
25

36
trait Tr1 { type As1: Copy; }

0 commit comments

Comments
 (0)