Skip to content

Rollup of 5 pull requests #106945

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

Merged
merged 10 commits into from
Jan 16, 2023
20 changes: 9 additions & 11 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::ObligationCtxt;

use crate::session_diagnostics::NonGenericOpaqueTypeParam;

use super::RegionInferenceContext;

impl<'tcx> RegionInferenceContext<'tcx> {
Expand Down Expand Up @@ -389,17 +391,13 @@ fn check_opaque_type_parameter_valid(
} else {
// Prevent `fn foo() -> Foo<u32>` from being defining.
let opaque_param = opaque_generics.param_at(i, tcx);
tcx.sess
.struct_span_err(span, "non-defining opaque type use in defining scope")
.span_note(
tcx.def_span(opaque_param.def_id),
&format!(
"used non-generic {} `{}` for generic parameter",
opaque_param.kind.descr(),
arg,
),
)
.emit();
let kind = opaque_param.kind.descr();
tcx.sess.emit_err(NonGenericOpaqueTypeParam {
ty: arg,
kind,
span,
param_span: tcx.def_span(opaque_param.def_id),
});
return false;
}
}
Expand Down
13 changes: 12 additions & 1 deletion compiler/rustc_borrowck/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use rustc_errors::{IntoDiagnosticArg, MultiSpan};
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::Ty;
use rustc_middle::ty::{GenericArg, Ty};
use rustc_span::Span;

use crate::diagnostics::RegionName;
Expand Down Expand Up @@ -240,3 +240,14 @@ pub(crate) struct MoveBorrow<'a> {
#[label]
pub borrow_span: Span,
}

#[derive(Diagnostic)]
#[diag(borrowck_opaque_type_non_generic_param, code = "E0792")]
pub(crate) struct NonGenericOpaqueTypeParam<'a, 'tcx> {
pub ty: GenericArg<'tcx>,
pub kind: &'a str,
#[primary_span]
pub span: Span,
#[label]
pub param_span: Span,
}
1 change: 1 addition & 0 deletions compiler/rustc_error_codes/src/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ E0787: include_str!("./error_codes/E0787.md"),
E0788: include_str!("./error_codes/E0788.md"),
E0790: include_str!("./error_codes/E0790.md"),
E0791: include_str!("./error_codes/E0791.md"),
E0792: include_str!("./error_codes/E0792.md"),
;
// E0006, // merged with E0005
// E0008, // cannot bind by-move into a pattern guard
Expand Down
60 changes: 60 additions & 0 deletions compiler/rustc_error_codes/src/error_codes/E0792.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
A type alias impl trait can only have its hidden type assigned
when used fully generically (and within their defining scope).
This means

```compile_fail,E0792
#![feature(type_alias_impl_trait)]

type Foo<T> = impl std::fmt::Debug;

fn foo() -> Foo<u32> {
5u32
}
```

is not accepted. If it were accepted, one could create unsound situations like

```compile_fail,E0792
#![feature(type_alias_impl_trait)]

type Foo<T> = impl Default;

fn foo() -> Foo<u32> {
5u32
}

fn main() {
let x = Foo::<&'static mut String>::default();
}
```


Instead you need to make the function generic:

```
#![feature(type_alias_impl_trait)]

type Foo<T> = impl std::fmt::Debug;

fn foo<U>() -> Foo<U> {
5u32
}
```

This means that no matter the generic parameter to `foo`,
the hidden type will always be `u32`.
If you want to link the generic parameter to the hidden type,
you can do that, too:


```
#![feature(type_alias_impl_trait)]

use std::fmt::Debug;

type Foo<T: Debug> = impl Debug;

fn foo<U: Debug>() -> Foo<U> {
Vec::<U>::new()
}
```
4 changes: 4 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/borrowck.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,7 @@ borrowck_cannot_move_when_borrowed =
[value] value
*[other] {$value_place}
} occurs here

borrowck_opaque_type_non_generic_param =
expected generic {$kind} parameter, found `{$ty}`
.label = this generic parameter must be used with a generic {$kind} parameter
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_type_ir::sty::TyKind::*;

impl<'tcx> IntoDiagnosticArg for Ty<'tcx> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
format!("{}", self).into_diagnostic_arg()
self.to_string().into_diagnostic_arg()
}
}

Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_middle/src/ty/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::ty::visit::{TypeVisitable, TypeVisitor};
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};

use rustc_data_structures::intern::Interned;
use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
use rustc_serialize::{self, Decodable, Encodable};
Expand Down Expand Up @@ -36,6 +37,12 @@ pub struct GenericArg<'tcx> {
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>,
}

impl<'tcx> IntoDiagnosticArg for GenericArg<'tcx> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
self.to_string().into_diagnostic_arg()
}
}

const TAG_MASK: usize = 0b11;
const TYPE_TAG: usize = 0b00;
const REGION_TAG: usize = 0b01;
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2459,6 +2459,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {

let pretty = parse_pretty(&unstable_opts, error_format);

// query-dep-graph is required if dump-dep-graph is given #106736
if unstable_opts.dump_dep_graph && !unstable_opts.query_dep_graph {
early_error(error_format, "can't dump dependency graph without `-Z query-dep-graph`");
}

// Try to find a directory containing the Rust `src`, for more details see
// the doc comment on the `real_rust_source_base_dir` field.
let tmp_buf;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/solve/project_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
let impl_substs_with_gat = goal.predicate.projection_ty.substs.rebase_onto(
tcx,
goal_trait_ref.def_id,
impl_trait_ref.substs,
impl_substs,
);
let substs = translate_substs(
acx.infcx,
Expand Down
2 changes: 1 addition & 1 deletion src/doc/book
2 changes: 1 addition & 1 deletion src/doc/nomicon
2 changes: 1 addition & 1 deletion src/doc/rust-by-example
2 changes: 2 additions & 0 deletions src/doc/rustc/src/instrument-coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ $ RUSTFLAGS="-C instrument-coverage" \
cargo test --tests
```

> **Note**: The default for `LLVM_PROFILE_FILE` is `default_%m_%p.profraw`. Versions prior to 1.65 had a default of `default.profraw`, so if using those earlier versions, it is recommended to explicitly set `LLVM_PROFILE_FILE="default_%m_%p.profraw"` to avoid having multiple tests overwrite the `.profraw` files.

Make note of the test binary file paths, displayed after the word "`Running`" in the test output:

```text
Expand Down
6 changes: 6 additions & 0 deletions tests/ui/dep-graph/dep-graph-dump.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Test dump-dep-graph requires query-dep-graph enabled

// incremental
// compile-flags: -Z dump-dep-graph

fn main() {}
2 changes: 2 additions & 0 deletions tests/ui/dep-graph/dep-graph-dump.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: can't dump dependency graph without `-Z query-dep-graph`

2 changes: 1 addition & 1 deletion tests/ui/type-alias-impl-trait/bound_reduction2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ impl<W> Trait<W> for () {}

fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
()
//~^ ERROR non-defining opaque type use
//~^ ERROR expected generic type parameter, found `<T as TraitWithAssoc>::Assoc`
}
12 changes: 5 additions & 7 deletions tests/ui/type-alias-impl-trait/bound_reduction2.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
error: non-defining opaque type use in defining scope
error[E0792]: expected generic type parameter, found `<T as TraitWithAssoc>::Assoc`
--> $DIR/bound_reduction2.rs:16:5
|
LL | type Foo<V> = impl Trait<V>;
| - this generic parameter must be used with a generic type parameter
...
LL | ()
| ^^
|
note: used non-generic type `<T as TraitWithAssoc>::Assoc` for generic parameter
--> $DIR/bound_reduction2.rs:9:10
|
LL | type Foo<V> = impl Trait<V>;
| ^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0792`.
5 changes: 2 additions & 3 deletions tests/ui/type-alias-impl-trait/generic_nondefining_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ type OneLifetime<'a> = impl Debug;

type OneConst<const X: usize> = impl Debug;


// Not defining uses, because they doesn't define *all* possible generics.

fn concrete_ty() -> OneTy<u32> {
5u32
//~^ ERROR non-defining opaque type use in defining scope
//~^ ERROR expected generic type parameter, found `u32`
}

fn concrete_lifetime() -> OneLifetime<'static> {
Expand All @@ -25,5 +24,5 @@ fn concrete_lifetime() -> OneLifetime<'static> {

fn concrete_const() -> OneConst<{ 123 }> {
7u32
//~^ ERROR non-defining opaque type use in defining scope
//~^ ERROR expected generic constant parameter, found `123`
}
29 changes: 12 additions & 17 deletions tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
error: non-defining opaque type use in defining scope
--> $DIR/generic_nondefining_use.rs:17:5
error[E0792]: expected generic type parameter, found `u32`
--> $DIR/generic_nondefining_use.rs:16:5
|
LL | type OneTy<T> = impl Debug;
| - this generic parameter must be used with a generic type parameter
...
LL | 5u32
| ^^^^
|
note: used non-generic type `u32` for generic parameter
--> $DIR/generic_nondefining_use.rs:7:12
|
LL | type OneTy<T> = impl Debug;
| ^

error: non-defining opaque type use in defining scope
--> $DIR/generic_nondefining_use.rs:22:5
--> $DIR/generic_nondefining_use.rs:21:5
|
LL | type OneLifetime<'a> = impl Debug;
| -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
...
LL | 6u32
| ^^^^

error: non-defining opaque type use in defining scope
--> $DIR/generic_nondefining_use.rs:27:5
error[E0792]: expected generic constant parameter, found `123`
--> $DIR/generic_nondefining_use.rs:26:5
|
LL | type OneConst<const X: usize> = impl Debug;
| -------------- this generic parameter must be used with a generic constant parameter
...
LL | 7u32
| ^^^^
|
note: used non-generic constant `123` for generic parameter
--> $DIR/generic_nondefining_use.rs:11:15
|
LL | type OneConst<const X: usize> = impl Debug;
| ^^^^^^^^^^^^^^

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0792`.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ fn main() {
let y = 42;
let x = wrong_generic(&y);
let z: i32 = x;
//~^ ERROR non-defining opaque type use
//~^ ERROR expected generic type parameter, found `&'static i32
}

type WrongGeneric<T> = impl 'static;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@ error: at least one trait must be specified
LL | type WrongGeneric<T> = impl 'static;
| ^^^^^^^^^^^^

error: non-defining opaque type use in defining scope
error[E0792]: expected generic type parameter, found `&'static i32`
--> $DIR/generic_type_does_not_live_long_enough.rs:6:18
|
LL | let z: i32 = x;
| ^
|
note: used non-generic type `&'static i32` for generic parameter
--> $DIR/generic_type_does_not_live_long_enough.rs:10:19
|
...
LL | type WrongGeneric<T> = impl 'static;
| ^
| - this generic parameter must be used with a generic type parameter

error[E0310]: the parameter type `T` may not live long enough
--> $DIR/generic_type_does_not_live_long_enough.rs:14:5
Expand All @@ -29,4 +26,5 @@ LL | fn wrong_generic<T: 'static>(t: T) -> WrongGeneric<T> {

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0310`.
Some errors have detailed explanations: E0310, E0792.
For more information about an error, try `rustc --explain E0310`.
2 changes: 1 addition & 1 deletion tests/ui/type-alias-impl-trait/issue-60564.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ where
type BitsIter = IterBitsIter<T, E, u8>;
fn iter_bits(self, n: u8) -> Self::BitsIter {
(0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
//~^ ERROR non-defining opaque type use in defining scope
//~^ ERROR expected generic type parameter, found `u8`
}
}

Expand Down
12 changes: 5 additions & 7 deletions tests/ui/type-alias-impl-trait/issue-60564.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
error: non-defining opaque type use in defining scope
error[E0792]: expected generic type parameter, found `u8`
--> $DIR/issue-60564.rs:20:9
|
LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
| - this generic parameter must be used with a generic type parameter
...
LL | (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: used non-generic type `u8` for generic parameter
--> $DIR/issue-60564.rs:8:25
|
LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
| ^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0792`.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ trait Trait<T> {}
type Alias<'a, U> = impl Trait<U>;

fn f<'a>() -> Alias<'a, ()> {}
//~^ ERROR non-defining opaque type use in defining scope
//~^ ERROR expected generic type parameter, found `()`

fn main() {}

Expand Down
Loading