Skip to content

Commit ccf817b

Browse files
committed
Auto merge of rust-lang#115848 - matthiaskrgr:rollup-lsul9dz, r=matthiaskrgr
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
2 parents e437e57 + 9362604 commit ccf817b

File tree

13 files changed

+133
-41
lines changed

13 files changed

+133
-41
lines changed

compiler/rustc_feature/src/removed.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ declare_features! (
137137
/// Allows use of unary negate on unsigned integers, e.g., -e for e: u8
138138
(removed, negate_unsigned, "1.0.0", Some(29645), None, None),
139139
/// Allows `#[no_coverage]` on functions.
140-
/// The feature was renamed to `coverage` and the attribute to `#[coverage(on|off)]`
141-
(removed, no_coverage, "CURRENT_RUSTC_VERSION", Some(84605), None, Some("renamed to `coverage`")),
140+
/// The feature was renamed to `coverage_attribute` and the attribute to `#[coverage(on|off)]`
141+
(removed, no_coverage, "CURRENT_RUSTC_VERSION", Some(84605), None, Some("renamed to `coverage_attribute`")),
142142
/// Allows `#[no_debug]`.
143143
(removed, no_debug, "1.43.0", Some(29721), None, Some("removed due to lack of demand")),
144144
/// Allows using `#[on_unimplemented(..)]` on traits.

compiler/rustc_hir_analysis/src/check/check.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,15 @@ fn check_opaque_meets_bounds<'tcx>(
461461
}
462462
match origin {
463463
// Checked when type checking the function containing them.
464-
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {}
464+
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {
465+
// HACK: this should also fall through to the hidden type check below, but the original
466+
// implementation had a bug where equivalent lifetimes are not identical. This caused us
467+
// to reject existing stable code that is otherwise completely fine. The real fix is to
468+
// compare the hidden types via our type equivalence/relation infra instead of doing an
469+
// identity check.
470+
let _ = infcx.take_opaque_types();
471+
return Ok(());
472+
}
465473
// Nested opaque types occur only in associated types:
466474
// ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
467475
// They can only be referenced as `<Opaque<T> as Trait<&'static T>>::AssocTy`.

compiler/rustc_middle/src/ty/flags.rs

+21-15
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,26 @@ impl FlagComputation {
3434
result.flags
3535
}
3636

37+
pub fn bound_var_flags(vars: &ty::List<ty::BoundVariableKind>) -> FlagComputation {
38+
let mut computation = FlagComputation::new();
39+
40+
for bv in vars {
41+
match bv {
42+
ty::BoundVariableKind::Ty(_) => {
43+
computation.flags |= TypeFlags::HAS_TY_LATE_BOUND;
44+
}
45+
ty::BoundVariableKind::Region(_) => {
46+
computation.flags |= TypeFlags::HAS_RE_LATE_BOUND;
47+
}
48+
ty::BoundVariableKind::Const => {
49+
computation.flags |= TypeFlags::HAS_CT_LATE_BOUND;
50+
}
51+
}
52+
}
53+
54+
computation
55+
}
56+
3757
fn add_flags(&mut self, flags: TypeFlags) {
3858
self.flags = self.flags | flags;
3959
}
@@ -57,21 +77,7 @@ impl FlagComputation {
5777
where
5878
F: FnOnce(&mut Self, T),
5979
{
60-
let mut computation = FlagComputation::new();
61-
62-
for bv in value.bound_vars() {
63-
match bv {
64-
ty::BoundVariableKind::Ty(_) => {
65-
computation.flags |= TypeFlags::HAS_TY_LATE_BOUND;
66-
}
67-
ty::BoundVariableKind::Region(_) => {
68-
computation.flags |= TypeFlags::HAS_RE_LATE_BOUND;
69-
}
70-
ty::BoundVariableKind::Const => {
71-
computation.flags |= TypeFlags::HAS_CT_LATE_BOUND;
72-
}
73-
}
74-
}
80+
let mut computation = FlagComputation::bound_var_flags(value.bound_vars());
7581

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

compiler/rustc_middle/src/ty/visit.rs

+24
Original file line numberDiff line numberDiff line change
@@ -481,9 +481,33 @@ impl std::fmt::Debug for HasTypeFlagsVisitor {
481481
// `Ty`/`Const`/`Predicate`, but not within those types. This is because the
482482
// type flags at the outer layer are enough. So it's faster than it first
483483
// looks, particular for `Ty`/`Predicate` where it's just a field access.
484+
//
485+
// N.B. The only case where this isn't totally true is binders, which also
486+
// add `HAS_{RE,TY,CT}_LATE_BOUND` flag depending on the *bound variables* that
487+
// are present, regardless of whether those bound variables are used. This
488+
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
489+
// specifically detect this case in `visit_binder`.
484490
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
485491
type BreakTy = FoundFlags;
486492

493+
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
494+
&mut self,
495+
t: &Binder<'tcx, T>,
496+
) -> ControlFlow<Self::BreakTy> {
497+
// If we're looking for any of the HAS_*_LATE_BOUND flags, we need to
498+
// additionally consider the bound vars on the binder itself, even if
499+
// the contents of a the binder (e.g. a `TraitRef`) doesn't reference
500+
// the bound vars.
501+
if self.flags.intersects(TypeFlags::HAS_LATE_BOUND) {
502+
let bound_var_flags = FlagComputation::bound_var_flags(t.bound_vars());
503+
if bound_var_flags.flags.intersects(self.flags) {
504+
return ControlFlow::Break(FoundFlags);
505+
}
506+
}
507+
508+
t.super_visit_with(self)
509+
}
510+
487511
#[inline]
488512
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
489513
// Note: no `super_visit_with` call.

compiler/rustc_smir/src/rustc_internal/mod.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc_interface::{interface, Queries};
1717
use rustc_middle::mir::interpret::AllocId;
1818
use rustc_middle::ty::TyCtxt;
1919
pub use rustc_span::def_id::{CrateNum, DefId};
20+
use rustc_span::Span;
2021

2122
fn with_tables<R>(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R {
2223
let mut ret = None;
@@ -159,14 +160,28 @@ impl<'tcx> Tables<'tcx> {
159160
self.alloc_ids.push(aid);
160161
stable_mir::AllocId(id)
161162
}
163+
164+
pub(crate) fn create_span(&mut self, span: Span) -> stable_mir::ty::Span {
165+
for (i, &sp) in self.spans.iter().enumerate() {
166+
if sp == span {
167+
return stable_mir::ty::Span(i);
168+
}
169+
}
170+
let id = self.spans.len();
171+
self.spans.push(span);
172+
stable_mir::ty::Span(id)
173+
}
162174
}
163175

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

168180
pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
169-
crate::stable_mir::run(Tables { tcx, def_ids: vec![], alloc_ids: vec![], types: vec![] }, f);
181+
crate::stable_mir::run(
182+
Tables { tcx, def_ids: vec![], alloc_ids: vec![], spans: vec![], types: vec![] },
183+
f,
184+
);
170185
}
171186

172187
/// A type that provides internal information but that can still be used for debug purpose.

compiler/rustc_smir/src/rustc_smir/mod.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
1010
use crate::rustc_internal::{self, opaque};
1111
use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
12-
use crate::stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, TyKind, UintTy};
12+
use crate::stable_mir::ty::{
13+
FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy,
14+
};
1315
use crate::stable_mir::{self, CompilerError, Context};
1416
use rustc_hir as hir;
1517
use rustc_middle::mir::interpret::{alloc_range, AllocId};
@@ -42,7 +44,7 @@ impl<'tcx> Context for Tables<'tcx> {
4244
self.tcx.def_path_str(self[def_id])
4345
}
4446

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

@@ -185,6 +187,7 @@ pub struct Tables<'tcx> {
185187
pub tcx: TyCtxt<'tcx>,
186188
pub def_ids: Vec<DefId>,
187189
pub alloc_ids: Vec<AllocId>,
190+
pub spans: Vec<rustc_span::Span>,
188191
pub types: Vec<MaybeStable<stable_mir::ty::TyKind, Ty<'tcx>>>,
189192
}
190193

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

1517-
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
1518-
// FIXME: add a real implementation of stable spans
1519-
opaque(self)
1520+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1521+
tables.create_span(*self)
15201522
}
15211523
}
15221524

compiler/rustc_smir/src/stable_mir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl CrateItem {
9090
with(|cx| cx.mir_body(self.0))
9191
}
9292

93-
pub fn span(&self) -> ty::Span {
93+
pub fn span(&self) -> Span {
9494
with(|cx| cx.span_of_an_item(self.0))
9595
}
9696
}

compiler/rustc_smir/src/stable_mir/ty.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,16 @@ pub struct Const {
3535

3636
type Ident = Opaque;
3737
pub(crate) type Region = Opaque;
38-
pub(crate) type Span = Opaque;
38+
#[derive(Clone, Copy, PartialEq, Eq)]
39+
pub struct Span(pub(crate) usize);
40+
41+
impl Debug for Span {
42+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
43+
let mut span = None;
44+
with(|context| context.rustc_tables(&mut |tables| span = Some(tables.spans[self.0])));
45+
f.write_fmt(format_args!("{:?}", &span.unwrap()))
46+
}
47+
}
3948

4049
#[derive(Clone, Debug)]
4150
pub enum TyKind {

tests/ui/feature-gates/feature-gate-coverage-attribute.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0557]: feature has been removed
44
LL | #![feature(no_coverage)]
55
| ^^^^^^^^^^^ feature has been removed
66
|
7-
= note: renamed to `coverage`
7+
= note: renamed to `coverage_attribute`
88

99
error[E0658]: the `#[coverage]` attribute is an experimental feature
1010
--> $DIR/feature-gate-coverage-attribute.rs:10:1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! This test shows a situation where through subtle compiler changes we can
2+
//! suddenly infer a different lifetime in the hidden type, and thus not meet
3+
//! the opaque type bounds anymore. In this case `'a` and `'b` are equal, so
4+
//! picking either is fine, but then we'll fail an identity check of the hidden
5+
//! type and the expected hidden type.
6+
7+
// check-pass
8+
9+
fn test<'a: 'b, 'b: 'a>() -> impl IntoIterator<Item = (&'a u8, impl Into<(&'b u8, &'a u8)>)> {
10+
None::<(_, (_, _))>
11+
}
12+
13+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// build-pass
2+
// issue: #115807
3+
4+
trait Chip: for<'a> TraitWithLifetime<'a> + SomeMarker {
5+
fn compute(&self);
6+
}
7+
8+
trait SomeMarker {}
9+
10+
trait TraitWithLifetime<'a>: SomeMarker {}
11+
12+
trait Machine {
13+
fn run();
14+
}
15+
16+
struct BasicMachine;
17+
18+
impl Machine for BasicMachine {
19+
fn run() {
20+
let chips: [&dyn Chip; 0] = [];
21+
let _ = chips.map(|chip| chip.compute());
22+
}
23+
}
24+
25+
fn main() {
26+
BasicMachine::run();
27+
}

tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn without_lt() -> impl for<'a> Trait<'a, Assoc = WithoutLt> {}
88
//~^ ERROR captures lifetime that does not appear in bounds
99

1010
type WithLt<'a> = impl Sized + 'a;
11-
//~^ ERROR concrete type differs from previous defining opaque type use
11+
1212
fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
1313
//~^ ERROR expected generic lifetime parameter, found `'a`
1414

tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr

+1-13
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,7 @@ LL |
1717
LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
1818
| ^^
1919

20-
error: concrete type differs from previous defining opaque type use
21-
--> $DIR/nested-tait-hrtb.rs:10:19
22-
|
23-
LL | type WithLt<'a> = impl Sized + 'a;
24-
| ^^^^^^^^^^^^^^^ expected `&'a str`, got `{type error}`
25-
|
26-
note: previous use here
27-
--> $DIR/nested-tait-hrtb.rs:12:17
28-
|
29-
LL | fn with_lt() -> impl for<'a> Trait<'a, Assoc = WithLt<'a>> {}
30-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31-
32-
error: aborting due to 3 previous errors
20+
error: aborting due to 2 previous errors
3321

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

0 commit comments

Comments
 (0)