Auto merge of #105775 - matthiaskrgr:rollup-2o8qn7e, r=matthiaskrgr

Rollup of 8 pull requests

Successful merges:

 - #105725 (Allow `impl ~const Trait` opaque types)
 - #105744 (Rewrite `E0158` error-code docs for clarity)
 - #105747 (Fix ICE calling method on auto trait)
 - #105748 (doc: Fix a few small issues)
 - #105756 (rustdoc: simplify CSS for codeblock tooltips)
 - #105757 (rustdoc: remove unused CSS `.sub-settings`)
 - #105764 (rustdoc: name the source page sidebar-toggle `#src-sidebar-toggle`)
 - #105774 (Remove unused stderr files)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-12-16 15:12:00 +00:00
commit 63b3bac77c
22 changed files with 195 additions and 157 deletions

View File

@ -42,7 +42,6 @@ enum SelfSemantic {
/// What is the context that prevents using `~const`?
enum DisallowTildeConstContext<'a> {
TraitObject,
ImplTrait,
Fn(FnKind<'a>),
}
@ -187,11 +186,7 @@ impl<'a> AstValidator<'a> {
fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) {
let old = mem::replace(&mut self.outer_impl_trait, outer);
if outer.is_some() {
self.with_banned_tilde_const(DisallowTildeConstContext::ImplTrait, f);
} else {
f(self);
}
f(self);
self.outer_impl_trait = old;
}
@ -1384,7 +1379,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
let mut err = self.err_handler().struct_span_err(bound.span(), "`~const` is not allowed here");
match reason {
DisallowTildeConstContext::TraitObject => err.note("trait objects cannot have `~const` trait bounds"),
DisallowTildeConstContext::ImplTrait => err.note("`impl Trait`s cannot have `~const` trait bounds"),
DisallowTildeConstContext::Fn(FnKind::Closure(..)) => err.note("closures cannot have `~const` trait bounds"),
DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => err.span_note(ident.span, "this function is not `const`, so it cannot have `~const` trait bounds"),
};

View File

@ -1,38 +1,53 @@
An associated const has been referenced in a pattern.
An associated `const`, `const` parameter or `static` has been referenced
in a pattern.
Erroneous code example:
```compile_fail,E0158
enum EFoo { A, B, C, D }
trait Foo {
const X: EFoo;
enum Foo {
One,
Two
}
fn test<A: Foo>(arg: EFoo) {
trait Bar {
const X: Foo;
}
fn test<A: Bar>(arg: Foo) {
match arg {
A::X => { // error!
println!("A::X");
}
A::X => println!("A::X"), // error: E0158: associated consts cannot be
// referenced in patterns
Foo::Two => println!("Two")
}
}
```
`const` and `static` mean different things. A `const` is a compile-time
constant, an alias for a literal value. This property means you can match it
directly within a pattern.
Associated `const`s cannot be referenced in patterns because it is impossible
for the compiler to prove exhaustiveness (that some pattern will always match).
Take the above example, because Rust does type checking in the *generic*
method, not the *monomorphized* specific instance. So because `Bar` could have
theoretically infinite implementations, there's no way to always be sure that
`A::X` is `Foo::One`. So this code must be rejected. Even if code can be
proven exhaustive by a programmer, the compiler cannot currently prove this.
The `static` keyword, on the other hand, guarantees a fixed location in memory.
This does not always mean that the value is constant. For example, a global
mutex can be declared `static` as well.
The same holds true of `const` parameters and `static`s.
If you want to match against a `static`, consider using a guard instead:
If you want to match against an associated `const`, `const` parameter or
`static` consider using a guard instead:
```
static FORTY_TWO: i32 = 42;
trait Trait {
const X: char;
}
match Some(42) {
Some(x) if x == FORTY_TWO => {}
_ => {}
static FOO: char = 'j';
fn test<A: Trait, const Y: char>(arg: char) {
match arg {
c if c == A::X => println!("A::X"),
c if c == Y => println!("Y"),
c if c == FOO => println!("FOO"),
_ => ()
}
}
```

View File

@ -689,6 +689,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let entry = spanned_predicates.entry(spans);
entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p);
}
Some(Node::Item(hir::Item {
kind: hir::ItemKind::Trait(rustc_ast::ast::IsAuto::Yes, ..),
span: item_span,
..
})) => {
tcx.sess.delay_span_bug(
*item_span,
"auto trait is invoked with no method error, but no error reported?",
);
}
Some(_) => unreachable!(),
None => (),
}

View File

@ -2541,7 +2541,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
/// The deque is assumed to be partitioned according to the given predicate.
/// This means that all elements for which the predicate returns true are at the start of the deque
/// and all elements for which the predicate returns false are at the end.
/// For example, [7, 15, 3, 5, 4, 12, 6] is a partitioned under the predicate x % 2 != 0
/// For example, `[7, 15, 3, 5, 4, 12, 6]` is partitioned under the predicate `x % 2 != 0`
/// (all odd numbers are at the start, all even at the end).
///
/// If the deque is not partitioned, the returned result is unspecified and meaningless,

View File

@ -69,7 +69,7 @@ where
/// if any element creation was unsuccessful.
///
/// The return type of this function depends on the return type of the closure.
/// If you return `Result<T, E>` from the closure, you'll get a `Result<[T; N]; E>`.
/// If you return `Result<T, E>` from the closure, you'll get a `Result<[T; N], E>`.
/// If you return `Option<T>` from the closure, you'll get an `Option<[T; N]>`.
///
/// # Arguments
@ -522,7 +522,7 @@ impl<T, const N: usize> [T; N] {
/// return an array the same size as `self` or the first error encountered.
///
/// The return type of this function depends on the return type of the closure.
/// If you return `Result<T, E>` from the closure, you'll get a `Result<[T; N]; E>`.
/// If you return `Result<T, E>` from the closure, you'll get a `Result<[T; N], E>`.
/// If you return `Option<T>` from the closure, you'll get an `Option<[T; N]>`.
///
/// # Examples

View File

@ -2734,7 +2734,7 @@ pub trait Iterator {
/// the first true result or the first error.
///
/// The return type of this method depends on the return type of the closure.
/// If you return `Result<bool, E>` from the closure, you'll get a `Result<Option<Self::Item>; E>`.
/// If you return `Result<bool, E>` from the closure, you'll get a `Result<Option<Self::Item>, E>`.
/// If you return `Option<bool>` from the closure, you'll get an `Option<Option<Self::Item>>`.
///
/// # Examples

View File

@ -3795,7 +3795,7 @@ impl<T> [T] {
/// The slice is assumed to be partitioned according to the given predicate.
/// This means that all elements for which the predicate returns true are at the start of the slice
/// and all elements for which the predicate returns false are at the end.
/// For example, [7, 15, 3, 5, 4, 12, 6] is a partitioned under the predicate x % 2 != 0
/// For example, `[7, 15, 3, 5, 4, 12, 6]` is partitioned under the predicate `x % 2 != 0`
/// (all odd numbers are at the start, all even at the end).
///
/// If this slice is not partitioned, the returned result is unspecified and meaningless,

View File

@ -396,15 +396,15 @@ img {
overflow-y: hidden;
}
.source .sidebar, #sidebar-toggle, #source-sidebar {
.source .sidebar, #src-sidebar-toggle, #source-sidebar {
background-color: var(--sidebar-background-color);
}
#sidebar-toggle > button:hover, #sidebar-toggle > button:focus {
#src-sidebar-toggle > button:hover, #src-sidebar-toggle > button:focus {
background-color: var(--sidebar-background-color-hover);
}
.source .sidebar > *:not(#sidebar-toggle) {
.source .sidebar > *:not(#src-sidebar-toggle) {
visibility: hidden;
}
@ -413,7 +413,7 @@ img {
flex-basis: 300px;
}
.source-sidebar-expanded .source .sidebar > *:not(#sidebar-toggle) {
.source-sidebar-expanded .source .sidebar > *:not(#src-sidebar-toggle) {
visibility: visible;
}
@ -1118,8 +1118,7 @@ pre.rust .doccomment {
top: 5px;
}
.example-wrap .tooltip::after {
display: none;
.example-wrap .tooltip:hover::after {
text-align: center;
padding: 5px 3px 3px 3px;
border-radius: 6px;
@ -1134,35 +1133,30 @@ pre.rust .doccomment {
color: var(--tooltip-color);
}
.example-wrap .tooltip::before {
.example-wrap .tooltip:hover::before {
content: " ";
position: absolute;
top: 50%;
left: 16px;
margin-top: -5px;
display: none;
z-index: 1;
border: 5px solid transparent;
border-right-color: var(--tooltip-background-color);
}
.example-wrap.ignore .tooltip::after {
.example-wrap.ignore .tooltip:hover::after {
content: "This example is not tested";
}
.example-wrap.compile_fail .tooltip::after {
.example-wrap.compile_fail .tooltip:hover::after {
content: "This example deliberately fails to compile";
}
.example-wrap.should_panic .tooltip::after {
.example-wrap.should_panic .tooltip:hover::after {
content: "This example panics";
}
.example-wrap.edition .tooltip::after {
.example-wrap.edition .tooltip:hover::after {
content: "This code runs with edition " attr(data-edition);
}
.example-wrap .tooltip:hover::before, .example-wrap .tooltip:hover::after {
display: inline;
}
.example-wrap.compile_fail .tooltip,
.example-wrap.should_panic .tooltip,
.example-wrap.ignore .tooltip {
@ -1295,7 +1289,7 @@ a.test-arrow:hover {
font-size: 1rem;
}
#sidebar-toggle {
#src-sidebar-toggle {
position: sticky;
top: 0;
left: 0;
@ -1324,7 +1318,7 @@ a.test-arrow:hover {
#source-sidebar div.files > a.selected {
background-color: var(--source-sidebar-background-selected);
}
#sidebar-toggle > button {
#src-sidebar-toggle > button {
font-size: inherit;
font-weight: bold;
background: none;
@ -1726,7 +1720,7 @@ in storage.js
left: -11px;
}
#sidebar-toggle {
#src-sidebar-toggle {
position: fixed;
left: 1px;
top: 100px;
@ -1740,7 +1734,7 @@ in storage.js
border-left: 0;
}
.source-sidebar-expanded #sidebar-toggle {
.source-sidebar-expanded #src-sidebar-toggle {
left: unset;
top: unset;
width: unset;
@ -1851,10 +1845,10 @@ in storage.js
width: 35px;
}
#sidebar-toggle {
#src-sidebar-toggle {
top: 10px;
}
.source-sidebar-expanded #sidebar-toggle {
.source-sidebar-expanded #src-sidebar-toggle {
top: unset;
}
}

View File

@ -59,12 +59,6 @@
cursor: pointer;
}
.setting-line > .sub-settings {
padding-left: 42px;
width: 100%;
display: block;
}
#settings .setting-line {
margin: 1.2em 0.6em;
}

View File

@ -83,7 +83,7 @@ function toggleSidebar() {
function createSidebarToggle() {
const sidebarToggle = document.createElement("div");
sidebarToggle.id = "sidebar-toggle";
sidebarToggle.id = "src-sidebar-toggle";
const inner = document.createElement("button");

View File

@ -1,7 +1,7 @@
// This test checks that the source code pages sidebar toggle is working as expected.
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
click: ".srclink"
wait-for: "#sidebar-toggle"
click: "#sidebar-toggle"
wait-for: "#src-sidebar-toggle"
click: "#src-sidebar-toggle"
fail: true
assert-css: ("#source-sidebar", { "left": "-300px" })

View File

@ -20,7 +20,7 @@ define-function: (
{"border-left": "2px solid rgba(255, 0, 0, 0.5)"},
)),
("move-cursor-to", ".docblock .example-wrap.compile_fail"),
("move-cursor-to", ".docblock .example-wrap.compile_fail .tooltip"),
("assert-css", (
".docblock .example-wrap.compile_fail .tooltip",
@ -60,7 +60,7 @@ define-function: (
{"border-left": "2px solid rgba(255, 0, 0, 0.5)"},
)),
("move-cursor-to", ".docblock .example-wrap.should_panic"),
("move-cursor-to", ".docblock .example-wrap.should_panic .tooltip"),
("assert-css", (
".docblock .example-wrap.should_panic .tooltip",
@ -100,7 +100,7 @@ define-function: (
{"border-left": "2px solid rgba(255, 142, 0, 0.6)"},
)),
("move-cursor-to", ".docblock .example-wrap.ignore"),
("move-cursor-to", ".docblock .example-wrap.ignore .tooltip"),
("assert-css", (
".docblock .example-wrap.ignore .tooltip",

View File

@ -21,4 +21,4 @@ assert-css: (".sidebar-menu-toggle", {"cursor": "pointer"})
// the sidebar toggle button on the source code pages
goto: "file://" + |DOC_PATH| + "/src/lib2/lib.rs.html"
assert-css: ("#sidebar-toggle > button", {"cursor": "pointer"})
assert-css: ("#src-sidebar-toggle > button", {"cursor": "pointer"})

View File

@ -2,18 +2,18 @@
javascript: false
goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
// Since the javascript is disabled, there shouldn't be a toggle.
assert-false: "#sidebar-toggle"
assert-false: "#src-sidebar-toggle"
wait-for-css: (".sidebar", {"display": "none"})
// Let's retry with javascript enabled.
javascript: true
reload:
wait-for: "#sidebar-toggle"
assert-css: ("#sidebar-toggle", {"visibility": "visible"})
assert-css: (".sidebar > *:not(#sidebar-toggle)", {"visibility": "hidden"})
wait-for: "#src-sidebar-toggle"
assert-css: ("#src-sidebar-toggle", {"visibility": "visible"})
assert-css: (".sidebar > *:not(#src-sidebar-toggle)", {"visibility": "hidden"})
// Let's expand the sidebar now.
click: "#sidebar-toggle"
wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
click: "#src-sidebar-toggle"
wait-for-css: ("#src-sidebar-toggle", {"visibility": "visible"})
// We now check that opening the sidebar and clicking a link will leave it open.
// The behavior here on desktop is different than the behavior on mobile,
@ -38,25 +38,25 @@ define-function: (
[
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
("reload"),
("wait-for-css", ("#sidebar-toggle", {"visibility": "visible"})),
("wait-for-css", ("#src-sidebar-toggle", {"visibility": "visible"})),
("assert-css", (
"#source-sidebar details[open] > .files a.selected",
{"color": |color_hover|, "background-color": |background|},
)),
// Without hover or focus.
("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle|})),
("assert-css", ("#src-sidebar-toggle > button", {"background-color": |background_toggle|})),
// With focus.
("focus", "#sidebar-toggle > button"),
("focus", "#src-sidebar-toggle > button"),
("assert-css", (
"#sidebar-toggle > button:focus",
"#src-sidebar-toggle > button:focus",
{"background-color": |background_toggle_hover|},
)),
("focus", ".search-input"),
// With hover.
("move-cursor-to", "#sidebar-toggle > button"),
("move-cursor-to", "#src-sidebar-toggle > button"),
("assert-css", (
"#sidebar-toggle > button:hover",
"#src-sidebar-toggle > button:hover",
{"background-color": |background_toggle_hover|},
)),
@ -151,16 +151,16 @@ call-function: ("check-colors", {
size: (500, 700)
reload:
// Waiting for the sidebar to be displayed...
wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
wait-for-css: ("#src-sidebar-toggle", {"visibility": "visible"})
// We now check it takes the full size of the display.
assert-property: ("body", {"clientWidth": "500", "clientHeight": "700"})
assert-property: (".sidebar", {"clientWidth": "500", "clientHeight": "700"})
// We now check the display of the toggle once the sidebar is expanded.
assert-property: ("#sidebar-toggle", {"clientWidth": "500", "clientHeight": "39"})
assert-property: ("#src-sidebar-toggle", {"clientWidth": "500", "clientHeight": "39"})
assert-css: (
"#sidebar-toggle",
"#src-sidebar-toggle",
{
"border-top-width": "0px",
"border-right-width": "0px",
@ -170,28 +170,28 @@ assert-css: (
)
// We now check that the scroll position is kept when opening the sidebar.
click: "#sidebar-toggle"
click: "#src-sidebar-toggle"
wait-for-css: (".sidebar", {"width": "0px"})
// We scroll to line 117 to change the scroll position.
scroll-to: '//*[@id="117"]'
assert-window-property: {"pageYOffset": "2542"}
// Expanding the sidebar...
click: "#sidebar-toggle"
click: "#src-sidebar-toggle"
wait-for-css: (".sidebar", {"width": "500px"})
click: "#sidebar-toggle"
click: "#src-sidebar-toggle"
wait-for-css: (".sidebar", {"width": "0px"})
// The "scrollTop" property should be the same.
assert-window-property: {"pageYOffset": "2542"}
// We now check that the scroll position is restored if the window is resized.
size: (500, 700)
click: "#sidebar-toggle"
click: "#src-sidebar-toggle"
wait-for-css: ("#source-sidebar", {"visibility": "visible"})
assert-window-property: {"pageYOffset": "0"}
size: (900, 900)
assert-window-property: {"pageYOffset": "2542"}
size: (500, 700)
click: "#sidebar-toggle"
click: "#src-sidebar-toggle"
wait-for-css: ("#source-sidebar", {"visibility": "hidden"})
// We now check that opening the sidebar and clicking a link will close it.
@ -199,7 +199,7 @@ wait-for-css: ("#source-sidebar", {"visibility": "hidden"})
// but common sense dictates that if you have a list of files that fills the entire screen, and
// you click one of them, you probably want to actually see the file's contents, and not just
// make it the current selection.
click: "#sidebar-toggle"
click: "#src-sidebar-toggle"
wait-for-css: ("#source-sidebar", {"visibility": "visible"})
assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
click: ".sidebar a.selected"
@ -210,6 +210,6 @@ assert-local-storage: {"rustdoc-source-sidebar-show": "false"}
size: (1000, 1000)
wait-for-css: ("#source-sidebar", {"visibility": "hidden"})
assert-local-storage: {"rustdoc-source-sidebar-show": "false"}
click: "#sidebar-toggle"
click: "#src-sidebar-toggle"
wait-for-css: ("#source-sidebar", {"visibility": "visible"})
assert-local-storage: {"rustdoc-source-sidebar-show": "true"}

View File

@ -97,7 +97,7 @@ assert-document-property: ({"URL": "/lib.rs.html"}, ENDS_WITH)
// Checking the source code sidebar.
// First we "open" it.
click: "#sidebar-toggle"
click: "#src-sidebar-toggle"
assert: ".source-sidebar-expanded"
// We check that the first entry of the sidebar is collapsed

View File

@ -1,8 +0,0 @@
error: type parameters must be declared prior to const parameters
--> $DIR/complex-unord-param.rs:8:41
|
LL | struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> {
| ---------------------^----------------------^--------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, A: 'a, T: 'a = u32, const N: usize, const M: usize>`
error: aborting due to previous error

View File

@ -1,8 +0,0 @@
error: type parameters must be declared prior to const parameters
--> $DIR/type-after-const-ok.rs:8:26
|
LL | struct A<const N: usize, T>(T);
| -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`
error: aborting due to previous error

View File

@ -0,0 +1,13 @@
#![feature(auto_traits)]
auto trait Foo {
fn g(&self); //~ ERROR auto traits cannot have associated items
}
trait Bar {
fn f(&self) {
self.g(); //~ ERROR the method `g` exists for reference `&Self`, but its trait bounds were not satisfied
}
}
fn main() {}

View File

@ -0,0 +1,28 @@
error[E0380]: auto traits cannot have associated items
--> $DIR/issue-105732.rs:4:8
|
LL | auto trait Foo {
| --- auto trait cannot have associated items
LL | fn g(&self);
| ---^-------- help: remove these associated items
error[E0599]: the method `g` exists for reference `&Self`, but its trait bounds were not satisfied
--> $DIR/issue-105732.rs:9:14
|
LL | self.g();
| ^
|
= note: the following trait bounds were not satisfied:
`Self: Foo`
which is required by `&Self: Foo`
`&Self: Foo`
= help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `g`, perhaps you need to add a supertrait for it:
|
LL | trait Bar: Foo {
| +++++
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0380, E0599.
For more information about an error, try `rustc --explain E0380`.

View File

@ -0,0 +1,55 @@
// check-pass
#![allow(incomplete_features)]
#![feature(
associated_type_bounds,
const_trait_impl,
const_cmp,
return_position_impl_trait_in_trait,
)]
use std::marker::Destruct;
const fn cmp(a: &impl ~const PartialEq) -> bool {
a == a
}
const fn wrap(x: impl ~const PartialEq + ~const Destruct)
-> impl ~const PartialEq + ~const Destruct
{
x
}
#[const_trait]
trait Foo {
fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
}
impl const Foo for () {
fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
123
}
}
const _: () = {
assert!(cmp(&0xDEADBEEFu32));
assert!(cmp(&()));
assert!(wrap(123) == wrap(123));
assert!(wrap(123) != wrap(456));
let x = <() as Foo>::huh();
assert!(x == x);
};
#[const_trait]
trait T {}
struct S;
impl const T for S {}
const fn rpit() -> impl ~const T { S }
const fn apit(_: impl ~const T + ~const Destruct) {}
const fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
const fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T> + ~const Destruct) {}
fn main() {}

View File

@ -1,23 +1,6 @@
#![feature(const_trait_impl)]
#![feature(associated_type_bounds)]
#[const_trait]
trait T {}
struct S;
impl T for S {}
fn rpit() -> impl ~const T { S }
//~^ ERROR `~const` is not allowed
fn apit(_: impl ~const T) {}
//~^ ERROR `~const` is not allowed
fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
//~^ ERROR `~const` is not allowed
fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
//~^ ERROR `~const` is not allowed
struct TildeQuestion<T: ~const ?Sized>(std::marker::PhantomData<T>);
//~^ ERROR `~const` and `?` are mutually exclusive

View File

@ -1,40 +1,8 @@
error: `~const` is not allowed here
--> $DIR/tilde-const-invalid-places.rs:9:19
|
LL | fn rpit() -> impl ~const T { S }
| ^^^^^^^^
|
= note: `impl Trait`s cannot have `~const` trait bounds
error: `~const` is not allowed here
--> $DIR/tilde-const-invalid-places.rs:12:17
|
LL | fn apit(_: impl ~const T) {}
| ^^^^^^^^
|
= note: `impl Trait`s cannot have `~const` trait bounds
error: `~const` is not allowed here
--> $DIR/tilde-const-invalid-places.rs:15:50
|
LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
| ^^^^^^^^
|
= note: `impl Trait`s cannot have `~const` trait bounds
error: `~const` is not allowed here
--> $DIR/tilde-const-invalid-places.rs:18:48
|
LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
| ^^^^^^^^
|
= note: `impl Trait`s cannot have `~const` trait bounds
error: `~const` and `?` are mutually exclusive
--> $DIR/tilde-const-invalid-places.rs:21:25
--> $DIR/tilde-const-invalid-places.rs:4:25
|
LL | struct TildeQuestion<T: ~const ?Sized>(std::marker::PhantomData<T>);
| ^^^^^^^^^^^^^
error: aborting due to 5 previous errors
error: aborting due to previous error