about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-09-14 17:22:20 +0000
committerbors <bors@rust-lang.org>2023-09-14 17:22:20 +0000
commitccf817b9bbe449204a227430d0a84a4f1d1798cc (patch)
treebf8b58fa8fd33484312a6ad6880283dc52eeb4c6
parente437e57954ee1d1cd4630d222e42ad0277cd4bf2 (diff)
parent9362604518a495ad7369d4adbd082e7fc4c3c338 (diff)
downloadrust-ccf817b9bbe449204a227430d0a84a4f1d1798cc.tar.gz
rust-ccf817b9bbe449204a227430d0a84a4f1d1798cc.zip
Auto merge of #115848 - matthiaskrgr:rollup-lsul9dz, r=matthiaskrgr
Rollup of 4 pull requests

Successful merges:

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

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_feature/src/removed.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs10
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs36
-rw-r--r--compiler/rustc_middle/src/ty/visit.rs24
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs17
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs12
-rw-r--r--compiler/rustc_smir/src/stable_mir/mod.rs2
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs11
-rw-r--r--tests/ui/feature-gates/feature-gate-coverage-attribute.stderr2
-rw-r--r--tests/ui/impl-trait/lifetime-ambiguity-regression.rs13
-rw-r--r--tests/ui/lifetimes/anonymize-unnamed-bound-vars-in-binders.rs27
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr14
13 files changed, 133 insertions, 41 deletions
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index c70e8e3e6b1..da18cb2a239 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -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.
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index c0cf1ea34cf..9a57cc6dbab 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -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`.
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 3cafd9a8da9..231635c086e 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -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;
     }
@@ -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());
 
diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs
index fb760654ea7..5deb5bfb19e 100644
--- a/compiler/rustc_middle/src/ty/visit.rs
+++ b/compiler/rustc_middle/src/ty/visit.rs
@@ -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.
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 4203990ab05..10ee5af86c6 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -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;
@@ -159,6 +160,17 @@ 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 {
@@ -166,7 +178,10 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
 }
 
 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.
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 141a3efe964..93b5b9654d3 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -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};
@@ -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)
     }
 
@@ -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>>>,
 }
 
@@ -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)
     }
 }
 
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
index ef5901482d8..3c86cb4038a 100644
--- a/compiler/rustc_smir/src/stable_mir/mod.rs
+++ b/compiler/rustc_smir/src/stable_mir/mod.rs
@@ -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))
     }
 }
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index 76e7beac571..3a8fc1a502e 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -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 {
diff --git a/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr b/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr
index 3912b9834fe..0131a19a39d 100644
--- a/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr
+++ b/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr
@@ -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
diff --git a/tests/ui/impl-trait/lifetime-ambiguity-regression.rs b/tests/ui/impl-trait/lifetime-ambiguity-regression.rs
new file mode 100644
index 00000000000..ce6ae3786e1
--- /dev/null
+++ b/tests/ui/impl-trait/lifetime-ambiguity-regression.rs
@@ -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() {}
diff --git a/tests/ui/lifetimes/anonymize-unnamed-bound-vars-in-binders.rs b/tests/ui/lifetimes/anonymize-unnamed-bound-vars-in-binders.rs
new file mode 100644
index 00000000000..05e3763e9d1
--- /dev/null
+++ b/tests/ui/lifetimes/anonymize-unnamed-bound-vars-in-binders.rs
@@ -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();
+}
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs
index 4a9631a7208..ba705d6f85a 100644
--- a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs
+++ b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.rs
@@ -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`
 
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr
index 9a783a6d92a..f208730552d 100644
--- a/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr
+++ b/tests/ui/type-alias-impl-trait/nested-tait-hrtb.stderr
@@ -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`.