Skip to content

Commit

Permalink
Auto merge of rust-lang#125285 - spastorino:unchk-region-opaque-deadc…
Browse files Browse the repository at this point in the history
…ode, r=<try>

 Error for RPIT if they are not defined during MIR borrowck

r? `@lcnr`

Fixes rust-lang#112417

There are some changes in tests that we would need to properly review. I've left some comments on each of them.
  • Loading branch information
bors committed May 20, 2024
2 parents 474bee7 + c130bfb commit 5ff4501
Show file tree
Hide file tree
Showing 43 changed files with 392 additions and 190 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,8 @@ hir_analysis_typeof_reserved_keyword_used =
hir_analysis_unconstrained_opaque_type = unconstrained opaque type
.note = `{$name}` must be used in combination with a concrete type within the same {$what}
hir_analysis_undefined_opaque_type = undefined opaque type
hir_analysis_unnamed_fields_repr_field_defined = unnamed field defined here
hir_analysis_unnamed_fields_repr_field_missing_repr_c =
Expand Down
17 changes: 4 additions & 13 deletions compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP};

use crate::errors::{TaitForwardCompat, TypeOf, UnconstrainedOpaqueType};
use crate::errors::{TaitForwardCompat, TypeOf, UnconstrainedOpaqueType, UndefinedOpaqueType};

pub fn test_opaque_hidden_types(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
let mut res = Ok(());
Expand Down Expand Up @@ -389,18 +389,9 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
// the `concrete_opaque_types` table.
Ty::new_error(tcx, guar)
} else {
// Fall back to the RPIT we inferred during HIR typeck
if let Some(hir_opaque_ty) = hir_opaque_ty {
hir_opaque_ty.ty
} else {
// We failed to resolve the opaque type or it
// resolves to itself. We interpret this as the
// no values of the hidden type ever being constructed,
// so we can just make the hidden type be `!`.
// For backwards compatibility reasons, we fall back to
// `()` until we the diverging default is changed.
Ty::new_diverging_default(tcx)
}
// Error if we couldn't define the RPIT during MIR borrowck
let err = tcx.dcx().emit_err(UndefinedOpaqueType { span: tcx.def_span(def_id) });
Ty::new_error(tcx, err)
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,13 @@ pub struct UnconstrainedOpaqueType {
pub what: &'static str,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_undefined_opaque_type)]
pub struct UndefinedOpaqueType {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_tait_forward_compat)]
#[note]
Expand Down
33 changes: 33 additions & 0 deletions tests/ui/borrowck/opaque-types-deadcode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//@ compile-flags:-Zverbose-internals

#![feature(rustc_attrs)]
#![rustc_hidden_type_of_opaques]

trait CallMeMaybe<'a, 'b> {
fn mk() -> Self;
fn subtype<T>(self, x: &'b T) -> &'a T;
}

struct Foo<'a, 'b: 'a>(&'a (), &'b ());
impl<'a, 'b> CallMeMaybe<'a, 'b> for Foo<'a, 'b> {
fn mk() -> Self {
Foo(&(), &())
}

fn subtype<T>(self, x: &'b T) -> &'a T {
x
}
}

fn good_bye() -> ! {
panic!();
}

fn foo<'a, 'b: 'a>() -> impl CallMeMaybe<'a, 'b> {
//~^ ERROR: {type error}
//~| ERROR: undefined opaque type
good_bye();
Foo(&(), &())
}

fn main() {}
14 changes: 14 additions & 0 deletions tests/ui/borrowck/opaque-types-deadcode.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: undefined opaque type
--> $DIR/opaque-types-deadcode.rs:26:25
|
LL | fn foo<'a, 'b: 'a>() -> impl CallMeMaybe<'a, 'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^

error: {type error}
--> $DIR/opaque-types-deadcode.rs:26:25
|
LL | fn foo<'a, 'b: 'a>() -> impl CallMeMaybe<'a, 'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

2 changes: 2 additions & 0 deletions tests/ui/delegation/not-supported.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,14 @@ mod opaque {

pub fn opaque_arg(_: impl Trait) -> i32 { 0 }
pub fn opaque_ret() -> impl Trait { unimplemented!() }
//~^ ERROR undefined opaque type
}
reuse to_reuse::opaque_arg;
//~^ ERROR delegation with early bound generics is not supported yet

trait ToReuse {
fn opaque_ret() -> impl Trait { unimplemented!() }
//~^ ERROR undefined opaque type
}

// FIXME: Inherited `impl Trait`s create query cycles when used inside trait impls.
Expand Down
42 changes: 27 additions & 15 deletions tests/ui/delegation/not-supported.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -107,62 +107,74 @@ LL | reuse Trait::foo2 { &self.0 }
| ^^^^

error: delegation with early bound generics is not supported yet
--> $DIR/not-supported.rs:74:21
--> $DIR/not-supported.rs:75:21
|
LL | pub fn opaque_arg(_: impl Trait) -> i32 { 0 }
| --------------------------------------- callee defined here
...
LL | reuse to_reuse::opaque_arg;
| ^^^^^^^^^^

error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:82:5: 82:24>::{synthetic#0}`
--> $DIR/not-supported.rs:83:25
error: undefined opaque type
--> $DIR/not-supported.rs:79:28
|
LL | fn opaque_ret() -> impl Trait { unimplemented!() }
| ^^^^^^^^^^

error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:84:5: 84:24>::{synthetic#0}`
--> $DIR/not-supported.rs:85:25
|
LL | reuse to_reuse::opaque_ret;
| ^^^^^^^^^^
|
note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
--> $DIR/not-supported.rs:83:25
--> $DIR/not-supported.rs:85:25
|
LL | reuse to_reuse::opaque_ret;
| ^^^^^^^^^^
= note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:82:5: 82:24>::{synthetic#0}`, completing the cycle
note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:82:5: 82:24>` is well-formed
--> $DIR/not-supported.rs:82:5
= note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:84:5: 84:24>::{synthetic#0}`, completing the cycle
note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:84:5: 84:24>` is well-formed
--> $DIR/not-supported.rs:84:5
|
LL | impl ToReuse for u8 {
| ^^^^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:85:5: 85:25>::{synthetic#0}`
--> $DIR/not-supported.rs:86:24
error: undefined opaque type
--> $DIR/not-supported.rs:72:32
|
LL | pub fn opaque_ret() -> impl Trait { unimplemented!() }
| ^^^^^^^^^^

error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:87:5: 87:25>::{synthetic#0}`
--> $DIR/not-supported.rs:88:24
|
LL | reuse ToReuse::opaque_ret;
| ^^^^^^^^^^
|
note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
--> $DIR/not-supported.rs:86:24
--> $DIR/not-supported.rs:88:24
|
LL | reuse ToReuse::opaque_ret;
| ^^^^^^^^^^
= note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:85:5: 85:25>::{synthetic#0}`, completing the cycle
note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:85:5: 85:25>` is well-formed
--> $DIR/not-supported.rs:85:5
= note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:87:5: 87:25>::{synthetic#0}`, completing the cycle
note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:87:5: 87:25>` is well-formed
--> $DIR/not-supported.rs:87:5
|
LL | impl ToReuse for u16 {
| ^^^^^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: recursive delegation is not supported yet
--> $DIR/not-supported.rs:99:22
--> $DIR/not-supported.rs:101:22
|
LL | pub reuse to_reuse2::foo;
| --- callee defined here
...
LL | reuse to_reuse1::foo;
| ^^^

error: aborting due to 16 previous errors
error: aborting due to 18 previous errors

Some errors have detailed explanations: E0049, E0195, E0391.
For more information about an error, try `rustc --explain E0049`.
3 changes: 1 addition & 2 deletions tests/ui/impl-trait/divergence.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//@ check-pass

fn foo() -> impl MyTrait {
//~^ ERROR undefined opaque type
panic!();
MyStruct
}
Expand Down
8 changes: 8 additions & 0 deletions tests/ui/impl-trait/divergence.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: undefined opaque type
--> $DIR/divergence.rs:1:13
|
LL | fn foo() -> impl MyTrait {
| ^^^^^^^^^^^^

error: aborting due to 1 previous error

1 change: 1 addition & 0 deletions tests/ui/impl-trait/impl-fn-hrtb-bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {

fn d() -> impl Fn() -> (impl Debug + '_) {
//~^ ERROR missing lifetime specifier
//~| ERROR undefined opaque type
|| ()
}

Expand Down
8 changes: 7 additions & 1 deletion tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@ note: lifetime declared here
LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
| ^^

error: aborting due to 4 previous errors
error: undefined opaque type
--> $DIR/impl-fn-hrtb-bounds.rs:19:25
|
LL | fn d() -> impl Fn() -> (impl Debug + '_) {
| ^^^^^^^^^^^^^^^

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0106, E0657.
For more information about an error, try `rustc --explain E0106`.
1 change: 1 addition & 0 deletions tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ fn a() -> impl Fn(&u8) -> impl Debug + '_ {

fn b() -> impl Fn() -> impl Debug + Send {
//~^ ERROR ambiguous `+` in a type
//~| ERROR undefined opaque type
|| ()
}

Expand Down
8 changes: 7 additions & 1 deletion tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ note: lifetime declared here
LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
| ^

error: aborting due to 3 previous errors
error: undefined opaque type
--> $DIR/impl-fn-parsing-ambiguities.rs:10:24
|
LL | fn b() -> impl Fn() -> impl Debug + Send {
| ^^^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0657`.
5 changes: 4 additions & 1 deletion tests/ui/impl-trait/impl_fn_associativity.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
//@ run-pass
#![feature(impl_trait_in_fn_trait_return)]
use std::fmt::Debug;

fn f_debug() -> impl Fn() -> impl Debug {
//~^ ERROR undefined opaque type
|| ()
}

fn ff_debug() -> impl Fn() -> impl Fn() -> impl Debug {
//~^ ERROR undefined opaque type
//~| ERROR undefined opaque type
|| f_debug()
}

fn multi() -> impl Fn() -> (impl Debug + Send) {
//~^ ERROR undefined opaque type
|| ()
}

Expand Down
26 changes: 26 additions & 0 deletions tests/ui/impl-trait/impl_fn_associativity.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error: undefined opaque type
--> $DIR/impl_fn_associativity.rs:4:30
|
LL | fn f_debug() -> impl Fn() -> impl Debug {
| ^^^^^^^^^^

error: undefined opaque type
--> $DIR/impl_fn_associativity.rs:9:31
|
LL | fn ff_debug() -> impl Fn() -> impl Fn() -> impl Debug {
| ^^^^^^^^^^^^^^^^^^^^^^^

error: undefined opaque type
--> $DIR/impl_fn_associativity.rs:9:44
|
LL | fn ff_debug() -> impl Fn() -> impl Fn() -> impl Debug {
| ^^^^^^^^^^

error: undefined opaque type
--> $DIR/impl_fn_associativity.rs:15:29
|
LL | fn multi() -> impl Fn() -> (impl Debug + Send) {
| ^^^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors

14 changes: 8 additions & 6 deletions tests/ui/impl-trait/impl_trait_projections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@ fn path_parametrized_type_is_allowed() -> option::Option<impl Debug> {
}

fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
//~^ ERROR `impl Trait` is not allowed in path parameters
//~| ERROR `impl Trait` is not allowed in path parameters
//~^ ERROR `impl Trait` is not allowed in path parameters
//~| ERROR `impl Trait` is not allowed in path parameters
x.next().unwrap()
}

fn projection_with_named_trait_is_disallowed(mut x: impl Iterator)
-> <impl Iterator as Iterator>::Item
fn projection_with_named_trait_is_disallowed(
mut x: impl Iterator,
) -> <impl Iterator as Iterator>::Item
//~^ ERROR `impl Trait` is not allowed in path parameters
{
x.next().unwrap()
}

fn projection_with_named_trait_inside_path_is_disallowed()
-> <::std::ops::Range<impl Debug> as Iterator>::Item
-> <::std::ops::Range<impl Debug> as Iterator>::Item
//~^ ERROR `impl Trait` is not allowed in path parameters
//~| ERROR `impl Debug: Step` is not satisfied
{
Expand All @@ -32,8 +33,9 @@ fn projection_with_named_trait_inside_path_is_disallowed()
}

fn projection_from_impl_trait_inside_dyn_trait_is_disallowed()
-> <dyn Iterator<Item = impl Debug> as Iterator>::Item
-> <dyn Iterator<Item = impl Debug> as Iterator>::Item
//~^ ERROR `impl Trait` is not allowed in path parameters
//~| ERROR undefined opaque type
{
panic!()
}
Expand Down
Loading

0 comments on commit 5ff4501

Please sign in to comment.