Skip to content

Commit

Permalink
Auto merge of rust-lang#115848 - matthiaskrgr:rollup-lsul9dz, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 4 pull requests

Successful merges:

 - rust-lang#115772 (Improve Span in smir)
 - rust-lang#115832 (Fix the error message for `#![feature(no_coverage)]`)
 - rust-lang#115834 (Properly consider binder vars in `HasTypeFlagsVisitor`)
 - rust-lang#115844 (Paper over an accidental regression)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Sep 14, 2023
2 parents e437e57 + 9362604 commit ccf817b
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 41 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_feature/src/removed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ declare_features! (
/// Allows use of unary negate on unsigned integers, e.g., -e for e: u8
(removed, negate_unsigned, "1.0.0", Some(29645), None, None),
/// Allows `#[no_coverage]` on functions.
/// The feature was renamed to `coverage` and the attribute to `#[coverage(on|off)]`
(removed, no_coverage, "CURRENT_RUSTC_VERSION", Some(84605), None, Some("renamed to `coverage`")),
/// The feature was renamed to `coverage_attribute` and the attribute to `#[coverage(on|off)]`
(removed, no_coverage, "CURRENT_RUSTC_VERSION", Some(84605), None, Some("renamed to `coverage_attribute`")),
/// Allows `#[no_debug]`.
(removed, no_debug, "1.43.0", Some(29721), None, Some("removed due to lack of demand")),
/// Allows using `#[on_unimplemented(..)]` on traits.
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,15 @@ fn check_opaque_meets_bounds<'tcx>(
}
match origin {
// Checked when type checking the function containing them.
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {}
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {
// HACK: this should also fall through to the hidden type check below, but the original
// implementation had a bug where equivalent lifetimes are not identical. This caused us
// to reject existing stable code that is otherwise completely fine. The real fix is to
// compare the hidden types via our type equivalence/relation infra instead of doing an
// identity check.
let _ = infcx.take_opaque_types();
return Ok(());
}
// Nested opaque types occur only in associated types:
// ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
// They can only be referenced as `<Opaque<T> as Trait<&'static T>>::AssocTy`.
Expand Down
36 changes: 21 additions & 15 deletions compiler/rustc_middle/src/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,26 @@ impl FlagComputation {
result.flags
}

pub fn bound_var_flags(vars: &ty::List<ty::BoundVariableKind>) -> FlagComputation {
let mut computation = FlagComputation::new();

for bv in vars {
match bv {
ty::BoundVariableKind::Ty(_) => {
computation.flags |= TypeFlags::HAS_TY_LATE_BOUND;
}
ty::BoundVariableKind::Region(_) => {
computation.flags |= TypeFlags::HAS_RE_LATE_BOUND;
}
ty::BoundVariableKind::Const => {
computation.flags |= TypeFlags::HAS_CT_LATE_BOUND;
}
}
}

computation
}

fn add_flags(&mut self, flags: TypeFlags) {
self.flags = self.flags | flags;
}
Expand All @@ -57,21 +77,7 @@ impl FlagComputation {
where
F: FnOnce(&mut Self, T),
{
let mut computation = FlagComputation::new();

for bv in value.bound_vars() {
match bv {
ty::BoundVariableKind::Ty(_) => {
computation.flags |= TypeFlags::HAS_TY_LATE_BOUND;
}
ty::BoundVariableKind::Region(_) => {
computation.flags |= TypeFlags::HAS_RE_LATE_BOUND;
}
ty::BoundVariableKind::Const => {
computation.flags |= TypeFlags::HAS_CT_LATE_BOUND;
}
}
}
let mut computation = FlagComputation::bound_var_flags(value.bound_vars());

f(&mut computation, value.skip_binder());

Expand Down
24 changes: 24 additions & 0 deletions compiler/rustc_middle/src/ty/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,9 +481,33 @@ impl std::fmt::Debug for HasTypeFlagsVisitor {
// `Ty`/`Const`/`Predicate`, but not within those types. This is because the
// type flags at the outer layer are enough. So it's faster than it first
// looks, particular for `Ty`/`Predicate` where it's just a field access.
//
// N.B. The only case where this isn't totally true is binders, which also
// add `HAS_{RE,TY,CT}_LATE_BOUND` flag depending on the *bound variables* that
// are present, regardless of whether those bound variables are used. This
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
// specifically detect this case in `visit_binder`.
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
type BreakTy = FoundFlags;

fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
&mut self,
t: &Binder<'tcx, T>,
) -> ControlFlow<Self::BreakTy> {
// If we're looking for any of the HAS_*_LATE_BOUND flags, we need to
// additionally consider the bound vars on the binder itself, even if
// the contents of a the binder (e.g. a `TraitRef`) doesn't reference
// the bound vars.
if self.flags.intersects(TypeFlags::HAS_LATE_BOUND) {
let bound_var_flags = FlagComputation::bound_var_flags(t.bound_vars());
if bound_var_flags.flags.intersects(self.flags) {
return ControlFlow::Break(FoundFlags);
}
}

t.super_visit_with(self)
}

#[inline]
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
// Note: no `super_visit_with` call.
Expand Down
17 changes: 16 additions & 1 deletion compiler/rustc_smir/src/rustc_internal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use rustc_interface::{interface, Queries};
use rustc_middle::mir::interpret::AllocId;
use rustc_middle::ty::TyCtxt;
pub use rustc_span::def_id::{CrateNum, DefId};
use rustc_span::Span;

fn with_tables<R>(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R {
let mut ret = None;
Expand Down Expand Up @@ -159,14 +160,28 @@ impl<'tcx> Tables<'tcx> {
self.alloc_ids.push(aid);
stable_mir::AllocId(id)
}

pub(crate) fn create_span(&mut self, span: Span) -> stable_mir::ty::Span {
for (i, &sp) in self.spans.iter().enumerate() {
if sp == span {
return stable_mir::ty::Span(i);
}
}
let id = self.spans.len();
self.spans.push(span);
stable_mir::ty::Span(id)
}
}

pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
item.id.into()
}

pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
crate::stable_mir::run(Tables { tcx, def_ids: vec![], alloc_ids: vec![], types: vec![] }, f);
crate::stable_mir::run(
Tables { tcx, def_ids: vec![], alloc_ids: vec![], spans: vec![], types: vec![] },
f,
);
}

/// A type that provides internal information but that can still be used for debug purpose.
Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_smir/src/rustc_smir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
use crate::rustc_internal::{self, opaque};
use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
use crate::stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, TyKind, UintTy};
use crate::stable_mir::ty::{
FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy,
};
use crate::stable_mir::{self, CompilerError, Context};
use rustc_hir as hir;
use rustc_middle::mir::interpret::{alloc_range, AllocId};
Expand Down Expand Up @@ -42,7 +44,7 @@ impl<'tcx> Context for Tables<'tcx> {
self.tcx.def_path_str(self[def_id])
}

fn span_of_an_item(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::Span {
fn span_of_an_item(&mut self, def_id: stable_mir::DefId) -> Span {
self.tcx.def_span(self[def_id]).stable(self)
}

Expand Down Expand Up @@ -185,6 +187,7 @@ pub struct Tables<'tcx> {
pub tcx: TyCtxt<'tcx>,
pub def_ids: Vec<DefId>,
pub alloc_ids: Vec<AllocId>,
pub spans: Vec<rustc_span::Span>,
pub types: Vec<MaybeStable<stable_mir::ty::TyKind, Ty<'tcx>>>,
}

Expand Down Expand Up @@ -1514,9 +1517,8 @@ impl<'tcx> Stable<'tcx> for ty::Region<'tcx> {
impl<'tcx> Stable<'tcx> for rustc_span::Span {
type T = stable_mir::ty::Span;

fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
// FIXME: add a real implementation of stable spans
opaque(self)
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
tables.create_span(*self)
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_smir/src/stable_mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl CrateItem {
with(|cx| cx.mir_body(self.0))
}

pub fn span(&self) -> ty::Span {
pub fn span(&self) -> Span {
with(|cx| cx.span_of_an_item(self.0))
}
}
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_smir/src/stable_mir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,16 @@ pub struct Const {

type Ident = Opaque;
pub(crate) type Region = Opaque;
pub(crate) type Span = Opaque;
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct Span(pub(crate) usize);

impl Debug for Span {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let mut span = None;
with(|context| context.rustc_tables(&mut |tables| span = Some(tables.spans[self.0])));
f.write_fmt(format_args!("{:?}", &span.unwrap()))
}
}

#[derive(Clone, Debug)]
pub enum TyKind {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error[E0557]: feature has been removed
LL | #![feature(no_coverage)]
| ^^^^^^^^^^^ feature has been removed
|
= note: renamed to `coverage`
= note: renamed to `coverage_attribute`

error[E0658]: the `#[coverage]` attribute is an experimental feature
--> $DIR/feature-gate-coverage-attribute.rs:10:1
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/impl-trait/lifetime-ambiguity-regression.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//! This test shows a situation where through subtle compiler changes we can
//! suddenly infer a different lifetime in the hidden type, and thus not meet
//! the opaque type bounds anymore. In this case `'a` and `'b` are equal, so
//! picking either is fine, but then we'll fail an identity check of the hidden
//! type and the expected hidden type.
// check-pass

fn test<'a: 'b, 'b: 'a>() -> impl IntoIterator<Item = (&'a u8, impl Into<(&'b u8, &'a u8)>)> {
None::<(_, (_, _))>
}

fn main() {}
27 changes: 27 additions & 0 deletions tests/ui/lifetimes/anonymize-unnamed-bound-vars-in-binders.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// build-pass
// issue: #115807

trait Chip: for<'a> TraitWithLifetime<'a> + SomeMarker {
fn compute(&self);
}

trait SomeMarker {}

trait TraitWithLifetime<'a>: SomeMarker {}

trait Machine {
fn run();
}

struct BasicMachine;

impl Machine for BasicMachine {
fn run() {
let chips: [&dyn Chip; 0] = [];
let _ = chips.map(|chip| chip.compute());
}
}

fn main() {
BasicMachine::run();
}
2 changes: 1 addition & 1 deletion tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ fn without_lt() -> impl for<'a> Trait<'a, Assoc = WithoutLt> {}
//~^ ERROR captures lifetime that does not appear in bounds

type WithLt<'a> = impl Sized + 'a;
//~^ ERROR concrete type differs from previous defining opaque type use

fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
//~^ ERROR expected generic lifetime parameter, found `'a`

Expand Down
14 changes: 1 addition & 13 deletions tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,7 @@ LL |
LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
| ^^

error: concrete type differs from previous defining opaque type use
--> $DIR/nested-tait-hrtb.rs:10:19
|
LL | type WithLt<'a> = impl Sized + 'a;
| ^^^^^^^^^^^^^^^ expected `&'a str`, got `{type error}`
|
note: previous use here
--> $DIR/nested-tait-hrtb.rs:12:17
|
LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0700, E0792.
For more information about an error, try `rustc --explain E0700`.

0 comments on commit ccf817b

Please sign in to comment.