Skip to content

Commit

Permalink
Auto merge of #119053 - matthiaskrgr:rollup-hky3ld3, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 4 pull requests

Successful merges:

 - #118880 (More expressions correctly are marked to end with curly braces)
 - #118928 (fix: Overlapping spans in delimited meta-vars)
 - #119022 (Remove unnecessary constness from ProjectionCandidate)
 - #119052 (Avoid overflow in GVN constant indexing.)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Dec 17, 2023
2 parents 4283aea + 39fe059 commit 6a62871
Show file tree
Hide file tree
Showing 14 changed files with 739 additions and 27 deletions.
35 changes: 32 additions & 3 deletions compiler/rustc_ast/src/util/classify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,44 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
| Range(_, Some(e), _)
| Ret(Some(e))
| Unary(_, e)
| Yield(Some(e)) => {
| Yield(Some(e))
| Yeet(Some(e))
| Become(e) => {
expr = e;
}
Closure(closure) => {
expr = &closure.body;
}
Gen(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..)
| TryBlock(..) | While(..) => break Some(expr),
_ => break None,
| TryBlock(..) | While(..) | ConstBlock(_) => break Some(expr),

// FIXME: These can end in `}`, but changing these would break stable code.
InlineAsm(_) | OffsetOf(_, _) | MacCall(_) | IncludedBytes(_) | FormatArgs(_) => {
break None;
}

Break(_, None)
| Range(_, None, _)
| Ret(None)
| Yield(None)
| Array(_)
| Call(_, _)
| MethodCall(_)
| Tup(_)
| Lit(_)
| Cast(_, _)
| Type(_, _)
| Await(_, _)
| Field(_, _)
| Index(_, _, _)
| Underscore
| Path(_, _)
| Continue(_)
| Repeat(_, _)
| Paren(_)
| Try(_)
| Yeet(None)
| Err => break None,
}
}
}
7 changes: 7 additions & 0 deletions compiler/rustc_expand/src/mbe/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,13 @@ fn expand_macro<'cx>(
target_sp.open = source_sp.open.with_ctxt(ctxt);
target_sp.close = source_sp.close.with_ctxt(ctxt);
}
(
TokenTree::Delimited(target_sp, ..),
mbe::TokenTree::MetaVar(source_sp, ..),
) => {
target_sp.open = source_sp.with_ctxt(ctxt);
target_sp.close = source_sp.with_ctxt(ctxt).shrink_to_hi();
}
_ => {
let sp = rhs_tt.span().with_ctxt(ctxt);
tt.set_span(sp);
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_middle/src/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,8 @@ pub enum SelectionCandidate<'tcx> {

/// This is a trait matching with a projected type as `Self`, and we found
/// an applicable bound in the trait definition. The `usize` is an index
/// into the list returned by `tcx.item_bounds`. The constness is the
/// constness of the bound in the trait.
// FIXME(effects) do we need this constness
ProjectionCandidate(usize, ty::BoundConstness),
/// into the list returned by `tcx.item_bounds`.
ProjectionCandidate(usize),

/// Implementation of a `Fn`-family trait by one of the anonymous types
/// generated for an `||` expression.
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,12 +644,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
{
if let Some(offset) = self.evaluated[idx].as_ref()
&& let Ok(offset) = self.ecx.read_target_usize(offset)
&& let Some(min_length) = offset.checked_add(1)
{
projection.to_mut()[i] = ProjectionElem::ConstantIndex {
offset,
min_length: offset + 1,
from_end: false,
};
projection.to_mut()[i] =
ProjectionElem::ConstantIndex { offset, min_length, from_end: false };
} else if let Some(new_idx) = self.try_as_local(idx, location) {
projection.to_mut()[i] = ProjectionElem::Index(new_idx);
self.reused_locals.insert(new_idx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.infcx
.probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));

// FIXME(effects) proper constness needed?
candidates.vec.extend(
result.into_iter().map(|idx| ProjectionCandidate(idx, ty::BoundConstness::NotConst)),
);
candidates.vec.extend(result.into_iter().map(|idx| ProjectionCandidate(idx)));
}

/// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller
Expand Down Expand Up @@ -585,7 +582,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}

ty::Alias(ty::Opaque, _) => {
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(..))) {
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(_))) {
// We do not generate an auto impl candidate for `impl Trait`s which already
// reference our auto trait.
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ImplSource::Builtin(BuiltinImplSource::Misc, data)
}

ProjectionCandidate(idx, _) => {
ProjectionCandidate(idx) => {
let obligations = self.confirm_projection_candidate(obligation, idx)?;
ImplSource::Param(obligations)
}
Expand Down Expand Up @@ -1313,7 +1313,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// If we have a projection type, make sure to normalize it so we replace it
// with a fresh infer variable
ty::Alias(ty::Projection | ty::Inherent, ..) => {
// FIXME(effects) this needs constness
let predicate = normalize_with_depth_to(
self,
obligation.param_env,
Expand Down Expand Up @@ -1344,7 +1343,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// since it's either not `const Drop` (and we raise an error during selection),
// or it's an ADT (and we need to check for a custom impl during selection)
_ => {
// FIXME(effects) this needs constness
let predicate = self_ty.rebind(ty::TraitPredicate {
trait_ref: ty::TraitRef::from_lang_item(
self.tcx(),
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1883,7 +1883,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
| BuiltinCandidate { .. }
| TraitAliasCandidate
| ObjectCandidate(_)
| ProjectionCandidate(..),
| ProjectionCandidate(_),
) => {
// We have a where clause so don't go around looking
// for impls. Arbitrarily give param candidates priority
Expand All @@ -1893,7 +1893,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
// here (see issue #50825).
DropVictim::drop_if(!is_global(other_cand))
}
(ObjectCandidate(_) | ProjectionCandidate(..), ParamCandidate(ref victim_cand)) => {
(ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(ref victim_cand)) => {
// Prefer these to a global where-clause bound
// (see issue #50825).
if is_global(victim_cand) { DropVictim::Yes } else { DropVictim::No }
Expand Down Expand Up @@ -1921,20 +1921,20 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
)
}

(ProjectionCandidate(i, _), ProjectionCandidate(j, _))
(ProjectionCandidate(i), ProjectionCandidate(j))
| (ObjectCandidate(i), ObjectCandidate(j)) => {
// Arbitrarily pick the lower numbered candidate for backwards
// compatibility reasons. Don't let this affect inference.
DropVictim::drop_if(i < j && !has_non_region_infer)
}
(ObjectCandidate(_), ProjectionCandidate(..))
| (ProjectionCandidate(..), ObjectCandidate(_)) => {
(ObjectCandidate(_), ProjectionCandidate(_))
| (ProjectionCandidate(_), ObjectCandidate(_)) => {
bug!("Have both object and projection candidate")
}

// Arbitrarily give projection and object candidates priority.
(
ObjectCandidate(_) | ProjectionCandidate(..),
ObjectCandidate(_) | ProjectionCandidate(_),
ImplCandidate(..)
| AutoImplCandidate
| ClosureCandidate { .. }
Expand Down Expand Up @@ -1964,7 +1964,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
| TraitUpcastingUnsizeCandidate(_)
| BuiltinCandidate { .. }
| TraitAliasCandidate,
ObjectCandidate(_) | ProjectionCandidate(..),
ObjectCandidate(_) | ProjectionCandidate(_),
) => DropVictim::No,

(&ImplCandidate(other_def), &ImplCandidate(victim_def)) => {
Expand Down
104 changes: 104 additions & 0 deletions tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
- // MIR for `constant_index_overflow` before GVN
+ // MIR for `constant_index_overflow` after GVN

fn constant_index_overflow(_1: &[T]) -> () {
debug x => _1;
let mut _0: ();
let _2: usize;
let mut _4: bool;
let mut _5: usize;
let mut _6: usize;
let mut _7: &[T];
let _8: usize;
let mut _9: usize;
let mut _10: bool;
let _11: usize;
let mut _12: usize;
let mut _13: bool;
let mut _14: T;
scope 1 {
debug a => _2;
let _3: T;
scope 2 {
debug b => _3;
}
}

bb0: {
- StorageLive(_2);
- _2 = const _ as usize (IntToInt);
+ nop;
+ _2 = const usize::MAX;
StorageLive(_3);
StorageLive(_4);
StorageLive(_5);
- _5 = _2;
+ _5 = const usize::MAX;
StorageLive(_6);
StorageLive(_7);
_7 = &(*_1);
_6 = core::slice::<impl [T]>::len(move _7) -> [return: bb1, unwind unreachable];
}

bb1: {
StorageDead(_7);
- _4 = Lt(move _5, move _6);
+ _4 = Lt(const usize::MAX, move _6);
switchInt(move _4) -> [0: bb4, otherwise: bb2];
}

bb2: {
StorageDead(_6);
StorageDead(_5);
StorageLive(_8);
- _8 = _2;
+ _8 = const usize::MAX;
_9 = Len((*_1));
- _10 = Lt(_8, _9);
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable];
+ _10 = Lt(const usize::MAX, _9);
+ assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, const usize::MAX) -> [success: bb3, unwind unreachable];
}

bb3: {
- _3 = (*_1)[_8];
+ _3 = (*_1)[_2];
StorageDead(_8);
goto -> bb6;
}

bb4: {
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
_11 = const 0_usize;
_12 = Len((*_1));
- _13 = Lt(_11, _12);
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind unreachable];
+ _13 = Lt(const 0_usize, _12);
+ assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 0_usize) -> [success: bb5, unwind unreachable];
}

bb5: {
- _3 = (*_1)[_11];
+ _3 = (*_1)[0 of 1];
StorageDead(_11);
goto -> bb6;
}

bb6: {
StorageDead(_4);
StorageLive(_14);
_14 = _3;
_0 = opaque::<T>(move _14) -> [return: bb7, unwind unreachable];
}

bb7: {
StorageDead(_14);
StorageDead(_3);
- StorageDead(_2);
+ nop;
return;
}
}

104 changes: 104 additions & 0 deletions tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
- // MIR for `constant_index_overflow` before GVN
+ // MIR for `constant_index_overflow` after GVN

fn constant_index_overflow(_1: &[T]) -> () {
debug x => _1;
let mut _0: ();
let _2: usize;
let mut _4: bool;
let mut _5: usize;
let mut _6: usize;
let mut _7: &[T];
let _8: usize;
let mut _9: usize;
let mut _10: bool;
let _11: usize;
let mut _12: usize;
let mut _13: bool;
let mut _14: T;
scope 1 {
debug a => _2;
let _3: T;
scope 2 {
debug b => _3;
}
}

bb0: {
- StorageLive(_2);
- _2 = const _ as usize (IntToInt);
+ nop;
+ _2 = const usize::MAX;
StorageLive(_3);
StorageLive(_4);
StorageLive(_5);
- _5 = _2;
+ _5 = const usize::MAX;
StorageLive(_6);
StorageLive(_7);
_7 = &(*_1);
_6 = core::slice::<impl [T]>::len(move _7) -> [return: bb1, unwind continue];
}

bb1: {
StorageDead(_7);
- _4 = Lt(move _5, move _6);
+ _4 = Lt(const usize::MAX, move _6);
switchInt(move _4) -> [0: bb4, otherwise: bb2];
}

bb2: {
StorageDead(_6);
StorageDead(_5);
StorageLive(_8);
- _8 = _2;
+ _8 = const usize::MAX;
_9 = Len((*_1));
- _10 = Lt(_8, _9);
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind continue];
+ _10 = Lt(const usize::MAX, _9);
+ assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, const usize::MAX) -> [success: bb3, unwind continue];
}

bb3: {
- _3 = (*_1)[_8];
+ _3 = (*_1)[_2];
StorageDead(_8);
goto -> bb6;
}

bb4: {
StorageDead(_6);
StorageDead(_5);
StorageLive(_11);
_11 = const 0_usize;
_12 = Len((*_1));
- _13 = Lt(_11, _12);
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind continue];
+ _13 = Lt(const 0_usize, _12);
+ assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 0_usize) -> [success: bb5, unwind continue];
}

bb5: {
- _3 = (*_1)[_11];
+ _3 = (*_1)[0 of 1];
StorageDead(_11);
goto -> bb6;
}

bb6: {
StorageDead(_4);
StorageLive(_14);
_14 = _3;
_0 = opaque::<T>(move _14) -> [return: bb7, unwind continue];
}

bb7: {
StorageDead(_14);
StorageDead(_3);
- StorageDead(_2);
+ nop;
return;
}
}

Loading

0 comments on commit 6a62871

Please sign in to comment.