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 4 pull requests #119053

Merged
merged 8 commits into from
Dec 17, 2023
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
Loading