Auto merge of #91627 - matthiaskrgr:rollup-z3e2peg, r=matthiaskrgr

Rollup of 10 pull requests

Successful merges:

 - #87614 (Recommend fix `count()` -> `len()` on slices)
 - #91065 (Add test for evaluate_obligation: Ok(EvaluatedToOkModuloRegions) ICE)
 - #91312 (Fix AnonConst ICE)
 - #91341 (Add `array::IntoIter::{empty, from_raw_parts}`)
 - #91493 (Remove a dead code path.)
 - #91503 (Tweak "call this function" suggestion to have smaller span)
 - #91547 (Suggest try_reserve in try_reserve_exact)
 - #91562 (Pretty print async block without redundant space)
 - #91620 (Update books)
 - #91622 (⬆️ rust-analyzer)

Failed merges:

 - #91571 (Remove unneeded access to pretty printer's `s` field in favor of deref)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-12-07 11:18:26 +00:00
commit c5c9494509
31 changed files with 606 additions and 52 deletions

View File

@ -2077,7 +2077,6 @@ impl<'a> State<'a> {
ast::ExprKind::Async(capture_clause, _, ref blk) => {
self.word_nbsp("async");
self.print_capture_clause(capture_clause);
self.s.space();
// cbox/ibox in analogy to the `ExprKind::Block` arm above
self.cbox(INDENT_UNIT);
self.ibox(0);

View File

@ -461,10 +461,6 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
if let Some(def_id) = def_id.as_local() {
let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
let parent_def_id = self.infcx.defining_use_anchor;
let def_scope_default = || {
let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id);
parent_def_id == tcx.hir().local_def_id(opaque_parent_hir_id)
};
let (in_definition_scope, origin) = match tcx.hir().expect_item(def_id).kind
{
// Anonymous `impl Trait`
@ -481,7 +477,14 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
}) => {
(may_define_opaque_type(tcx, parent_def_id, opaque_hir_id), origin)
}
_ => (def_scope_default(), hir::OpaqueTyOrigin::TyAlias),
ref itemkind => {
span_bug!(
self.value_span,
"weird opaque type: {:#?}, {:#?}",
ty.kind(),
itemkind
)
}
};
if in_definition_scope {
let opaque_type_key =

View File

@ -499,6 +499,7 @@ symbols! {
core_panic_macro,
cosf32,
cosf64,
count,
cr,
crate_id,
crate_in_paths,

View File

@ -67,6 +67,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
fn is_slice_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
self.autoderef(span, ty).any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
}
pub fn report_method_error(
&self,
mut span: Span,
@ -691,7 +695,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut restrict_type_params = false;
let mut unsatisfied_bounds = false;
if !unsatisfied_predicates.is_empty() {
if item_name.name == sym::count && self.is_slice_ty(actual, span) {
let msg = "consider using `len` instead";
if let SelfSource::MethodCall(_expr) = source {
err.span_suggestion_short(
span,
msg,
String::from("len"),
Applicability::MachineApplicable,
);
} else {
err.span_label(span, msg);
}
if let Some(iterator_trait) = self.tcx.get_diagnostic_item(sym::Iterator) {
let iterator_trait = self.tcx.def_path_str(iterator_trait);
err.note(&format!("`count` is defined on `{iterator_trait}`, which `{actual}` does not implement"));
}
} else if !unsatisfied_predicates.is_empty() {
let def_span = |def_id| {
self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id))
};
@ -990,9 +1010,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
let mut fallback_span = true;
let msg = "remove this method call";
if item_name.name == sym::as_str && actual.peel_refs().is_str() {
let msg = "remove this method call";
let mut fallback_span = true;
if let SelfSource::MethodCall(expr) = source {
let call_expr =
self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));

View File

@ -492,7 +492,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> bool /* did we suggest to call a function because of missing parentheses? */ {
err.span_label(span, ty.to_string());
if let FnDef(def_id, _) = *ty.kind() {
let source_map = self.tcx.sess.source_map();
if !self.tcx.has_typeck_results(def_id) {
return false;
}
@ -517,20 +516,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.lookup_op_method(fn_sig.output(), &[other_ty], Op::Binary(op, is_assign))
.is_ok()
{
if let Ok(snippet) = source_map.span_to_snippet(span) {
let (variable_snippet, applicability) = if !fn_sig.inputs().is_empty() {
(format!("{}( /* arguments */ )", snippet), Applicability::HasPlaceholders)
} else {
(format!("{}()", snippet), Applicability::MaybeIncorrect)
};
let (variable_snippet, applicability) = if !fn_sig.inputs().is_empty() {
("( /* arguments */ )".to_string(), Applicability::HasPlaceholders)
} else {
("()".to_string(), Applicability::MaybeIncorrect)
};
err.span_suggestion(
span,
"you might have forgotten to call this function",
variable_snippet,
applicability,
);
}
err.span_suggestion_verbose(
span.shrink_to_hi(),
"you might have forgotten to call this function",
variable_snippet,
applicability,
);
return true;
}
}

View File

@ -172,7 +172,7 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
// We've encountered an `AnonConst` in some path, so we need to
// figure out which generic parameter it corresponds to and return
// the relevant type.
let (arg_index, segment) = path
let filtered = path
.segments
.iter()
.filter_map(|seg| seg.args.map(|args| (args.args, seg)))
@ -181,10 +181,17 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
.filter(|arg| arg.is_const())
.position(|arg| arg.id() == hir_id)
.map(|index| (index, seg))
})
.unwrap_or_else(|| {
bug!("no arg matching AnonConst in path");
});
let (arg_index, segment) = match filtered {
None => {
tcx.sess.delay_span_bug(
tcx.def_span(def_id),
"no arg matching AnonConst in path",
);
return None;
}
Some(inner) => inner,
};
// Try to use the segment resolution if it is valid, otherwise we
// default to the path resolution.

View File

@ -720,9 +720,9 @@ impl<T, A: Allocator> VecDeque<T, A> {
///
/// Note that the allocator may give the collection more space than it
/// requests. Therefore, capacity can not be relied upon to be precisely
/// minimal. Prefer [`reserve`] if future insertions are expected.
/// minimal. Prefer [`try_reserve`] if future insertions are expected.
///
/// [`reserve`]: VecDeque::reserve
/// [`try_reserve`]: VecDeque::try_reserve
///
/// # Errors
///

View File

@ -1044,9 +1044,9 @@ impl String {
///
/// Note that the allocator may give the collection more space than it
/// requests. Therefore, capacity can not be relied upon to be precisely
/// minimal. Prefer [`reserve`] if future insertions are expected.
/// minimal. Prefer [`try_reserve`] if future insertions are expected.
///
/// [`reserve`]: String::reserve
/// [`try_reserve`]: String::try_reserve
///
/// # Errors
///

View File

@ -881,9 +881,9 @@ impl<T, A: Allocator> Vec<T, A> {
///
/// Note that the allocator may give the collection more space than it
/// requests. Therefore, capacity can not be relied upon to be precisely
/// minimal. Prefer [`reserve`] if future insertions are expected.
/// minimal. Prefer [`try_reserve`] if future insertions are expected.
///
/// [`reserve`]: Vec::reserve
/// [`try_reserve`]: Vec::try_reserve
///
/// # Errors
///

View File

@ -84,6 +84,135 @@ impl<T, const N: usize> IntoIter<T, N> {
IntoIterator::into_iter(array)
}
/// Creates an iterator over the elements in a partially-initialized buffer.
///
/// If you have a fully-initialized array, then use [`IntoIterator`].
/// But this is useful for returning partial results from unsafe code.
///
/// # Safety
///
/// - The `buffer[initialized]` elements must all be initialized.
/// - The range must be canonical, with `initialized.start <= initialized.end`.
/// - The range must in in-bounds for the buffer, with `initialized.end <= N`.
/// (Like how indexing `[0][100..100]` fails despite the range being empty.)
///
/// It's sound to have more elements initialized than mentioned, though that
/// will most likely result in them being leaked.
///
/// # Examples
///
/// ```
/// #![feature(array_into_iter_constructors)]
///
/// #![feature(maybe_uninit_array_assume_init)]
/// #![feature(maybe_uninit_uninit_array)]
/// use std::array::IntoIter;
/// use std::mem::MaybeUninit;
///
/// # // Hi! Thanks for reading the code. This is restricted to `Copy` because
/// # // otherwise it could leak. A fully-general version this would need a drop
/// # // guard to handle panics from the iterator, but this works for an example.
/// fn next_chunk<T: Copy, const N: usize>(
/// it: &mut impl Iterator<Item = T>,
/// ) -> Result<[T; N], IntoIter<T, N>> {
/// let mut buffer = MaybeUninit::uninit_array();
/// let mut i = 0;
/// while i < N {
/// match it.next() {
/// Some(x) => {
/// buffer[i].write(x);
/// i += 1;
/// }
/// None => {
/// // SAFETY: We've initialized the first `i` items
/// unsafe {
/// return Err(IntoIter::new_unchecked(buffer, 0..i));
/// }
/// }
/// }
/// }
///
/// // SAFETY: We've initialized all N items
/// unsafe { Ok(MaybeUninit::array_assume_init(buffer)) }
/// }
///
/// let r: [_; 4] = next_chunk(&mut (10..16)).unwrap();
/// assert_eq!(r, [10, 11, 12, 13]);
/// let r: IntoIter<_, 40> = next_chunk(&mut (10..16)).unwrap_err();
/// assert_eq!(r.collect::<Vec<_>>(), vec![10, 11, 12, 13, 14, 15]);
/// ```
#[unstable(feature = "array_into_iter_constructors", issue = "91583")]
#[rustc_const_unstable(feature = "const_array_into_iter_constructors", issue = "91583")]
pub const unsafe fn new_unchecked(
buffer: [MaybeUninit<T>; N],
initialized: Range<usize>,
) -> Self {
Self { data: buffer, alive: initialized }
}
/// Creates an iterator over `T` which returns no elements.
///
/// If you just need an empty iterator, then use
/// [`iter::empty()`](crate::iter::empty) instead.
/// And if you need an empty array, use `[]`.
///
/// But this is useful when you need an `array::IntoIter<T, N>` *specifically*.
///
/// # Examples
///
/// ```
/// #![feature(array_into_iter_constructors)]
/// use std::array::IntoIter;
///
/// let empty = IntoIter::<i32, 3>::empty();
/// assert_eq!(empty.len(), 0);
/// assert_eq!(empty.as_slice(), &[]);
///
/// let empty = IntoIter::<std::convert::Infallible, 200>::empty();
/// assert_eq!(empty.len(), 0);
/// ```
///
/// `[1, 2].into_iter()` and `[].into_iter()` have different types
/// ```should_fail,edition2021
/// #![feature(array_into_iter_constructors)]
/// use std::array::IntoIter;
///
/// pub fn get_bytes(b: bool) -> IntoIter<i8, 4> {
/// if b {
/// [1, 2, 3, 4].into_iter()
/// } else {
/// [].into_iter() // error[E0308]: mismatched types
/// }
/// }
/// ```
///
/// But using this method you can get an empty iterator of appropriate size:
/// ```edition2021
/// #![feature(array_into_iter_constructors)]
/// use std::array::IntoIter;
///
/// pub fn get_bytes(b: bool) -> IntoIter<i8, 4> {
/// if b {
/// [1, 2, 3, 4].into_iter()
/// } else {
/// IntoIter::empty()
/// }
/// }
///
/// assert_eq!(get_bytes(true).collect::<Vec<_>>(), vec![1, 2, 3, 4]);
/// assert_eq!(get_bytes(false).collect::<Vec<_>>(), vec![]);
/// ```
#[unstable(feature = "array_into_iter_constructors", issue = "91583")]
#[rustc_const_unstable(feature = "const_array_into_iter_constructors", issue = "91583")]
pub const fn empty() -> Self {
let buffer = MaybeUninit::uninit_array();
let initialized = 0..0;
// SAFETY: We're telling it that none of the elements are initialized,
// which is trivially true. And ∀N: usize, 0 <= N.
unsafe { Self::new_unchecked(buffer, initialized) }
}
/// Returns an immutable slice of all elements that have not been yielded
/// yet.
#[stable(feature = "array_value_iter", since = "1.51.0")]

View File

@ -101,6 +101,7 @@
#![feature(const_align_of_val)]
#![feature(const_alloc_layout)]
#![feature(const_arguments_as_str)]
#![feature(const_array_into_iter_constructors)]
#![feature(const_bigint_helper_methods)]
#![feature(const_caller_location)]
#![feature(const_cell_into_inner)]
@ -138,6 +139,7 @@
#![feature(const_type_name)]
#![feature(const_default_impls)]
#![feature(duration_consts_float)]
#![feature(maybe_uninit_uninit_array)]
#![feature(ptr_metadata)]
#![feature(slice_ptr_get)]
#![feature(str_internals)]

@ -1 +1 @@
Subproject commit a5e0c5b2c5f9054be3b961aea2c7edfeea591de8
Subproject commit 5f9358faeb1f46e19b8a23a21e79fd7fe150491e

@ -1 +1 @@
Subproject commit 8e0ec8c77d8b28b86159fdee9d33a758225ecf9c
Subproject commit beea0a3cdc3885375342fd010f9ad658e6a5e09a

@ -1 +1 @@
Subproject commit c6b4bf831e9a40aec34f53067d20634839a6778b
Subproject commit 49681ea4a9fa81173dbe9ffed74b4d4a35eae9e3

@ -1 +1 @@
Subproject commit c0f222da23568477155991d391c9ce918e381351
Subproject commit 954f3d441ad880737a13e241108f791a4d2a38cd

@ -1 +1 @@
Subproject commit 43f82530210b83cf888282b207ed13d5893da9b2
Subproject commit 1ca6a7bd1d73edc4a3e6c7d6a40f5d4b66c1e517

@ -1 +1 @@
Subproject commit a2fc9635029c04e692474965a6606f8e286d539a
Subproject commit a374e7d8bb6b79de45b92295d06b4ac0ef35bc09

View File

@ -0,0 +1,118 @@
// revisions:cfail1 cfail2
//[cfail1] compile-flags: --crate-type=lib --edition=2021 -Zassert-incr-state=not-loaded
//[cfail2] compile-flags: --crate-type=lib --edition=2021 -Zassert-incr-state=loaded
// build-pass
use core::any::Any;
use core::marker::PhantomData;
struct DerefWrap<T>(T);
impl<T> core::ops::Deref for DerefWrap<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
struct Storage<T, D> {
phantom: PhantomData<(T, D)>,
}
type ReadStorage<T> = Storage<T, DerefWrap<MaskedStorage<T>>>;
pub trait Component {
type Storage;
}
struct VecStorage;
struct Pos;
impl Component for Pos {
type Storage = VecStorage;
}
struct GenericComp<T> {
_t: T,
}
impl<T: 'static> Component for GenericComp<T> {
type Storage = VecStorage;
}
struct ReadData {
pos_interpdata: ReadStorage<GenericComp<Pos>>,
}
trait System {
type SystemData;
fn run(data: Self::SystemData, any: Box<dyn Any>);
}
struct Sys;
impl System for Sys {
type SystemData = (ReadData, ReadStorage<Pos>);
fn run((data, pos): Self::SystemData, any: Box<dyn Any>) {
<ReadStorage<GenericComp<Pos>> as SystemData>::setup(any);
ParJoin::par_join((&pos, &data.pos_interpdata));
}
}
trait ParJoin {
fn par_join(self)
where
Self: Sized,
{
}
}
impl<'a, T, D> ParJoin for &'a Storage<T, D>
where
T: Component,
D: core::ops::Deref<Target = MaskedStorage<T>>,
T::Storage: Sync,
{
}
impl<A, B> ParJoin for (A, B)
where
A: ParJoin,
B: ParJoin,
{
}
pub trait SystemData {
fn setup(any: Box<dyn Any>);
}
impl<T: 'static> SystemData for ReadStorage<T>
where
T: Component,
{
fn setup(any: Box<dyn Any>) {
let storage: &MaskedStorage<T> = any.downcast_ref().unwrap();
<dyn Any as CastFrom<MaskedStorage<T>>>::cast(&storage);
}
}
pub struct MaskedStorage<T: Component> {
_inner: T::Storage,
}
pub unsafe trait CastFrom<T> {
fn cast(t: &T) -> &Self;
}
unsafe impl<T> CastFrom<T> for dyn Any
where
T: Any + 'static,
{
fn cast(t: &T) -> &Self {
t
}
}

9
src/test/pretty/async.rs Normal file
View File

@ -0,0 +1,9 @@
// pp-exact
// pretty-compare-only
// edition:2021
async fn f() {
let first = async { 1 };
let second = async move { 2 };
join(first, second).await
}

View File

@ -3,5 +3,5 @@
// edition:2018
// pp-exact
fn main() { let _a = (async { }); }
fn main() { let _a = (async { }); }
//~^ WARNING unnecessary parentheses around assigned value

View File

@ -1,14 +1,14 @@
warning: unnecessary parentheses around assigned value
--> $DIR/issue-54752-async-block.rs:6:22
|
LL | fn main() { let _a = (async { }); }
| ^ ^
LL | fn main() { let _a = (async { }); }
| ^ ^
|
= note: `#[warn(unused_parens)]` on by default
help: remove these parentheses
|
LL - fn main() { let _a = (async { }); }
LL + fn main() { let _a = async { }; }
LL - fn main() { let _a = (async { }); }
LL + fn main() { let _a = async { }; }
|
warning: 1 warning emitted

View File

@ -9,11 +9,11 @@ LL | let x = f == g;
help: you might have forgotten to call this function
|
LL | let x = f() == g;
| ~~~
| ++
help: you might have forgotten to call this function
|
LL | let x = f == g();
| ~~~
| ++
error[E0308]: mismatched types
--> $DIR/fn-compare-mismatch.rs:4:18

View File

@ -5,7 +5,11 @@ LL | foo > 12;
| --- ^ -- {integer}
| |
| fn() -> i32 {foo}
| help: you might have forgotten to call this function: `foo()`
|
help: you might have forgotten to call this function
|
LL | foo() > 12;
| ++
error[E0308]: mismatched types
--> $DIR/issue-59488.rs:14:11
@ -23,7 +27,11 @@ LL | bar > 13;
| --- ^ -- {integer}
| |
| fn(i64) -> i64 {bar}
| help: you might have forgotten to call this function: `bar( /* arguments */ )`
|
help: you might have forgotten to call this function
|
LL | bar( /* arguments */ ) > 13;
| +++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/issue-59488.rs:18:11
@ -45,11 +53,11 @@ LL | foo > foo;
help: you might have forgotten to call this function
|
LL | foo() > foo;
| ~~~~~
| ++
help: you might have forgotten to call this function
|
LL | foo > foo();
| ~~~~~
| ++
error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}`
--> $DIR/issue-59488.rs:25:9

View File

@ -6,9 +6,12 @@ LL | assert_eq!(a, 0);
| |
| fn() -> i32 {a}
| {integer}
| help: you might have forgotten to call this function: `*left_val()`
|
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might have forgotten to call this function
|
LL | if !(*left_val() == *right_val) {
| ++
error[E0308]: mismatched types
--> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5

View File

@ -0,0 +1,8 @@
fn main() {
let slice = [1,2,3,4];
let vec = vec![1,2,3,4];
slice.count(); //~ERROR: E0599
vec.count(); //~ERROR: E0599
vec.as_slice().count(); //~ERROR: E0599
}

View File

@ -0,0 +1,36 @@
error[E0599]: no method named `count` found for array `[{integer}; 4]` in the current scope
--> $DIR/count2len.rs:5:11
|
LL | slice.count();
| ^^^^^
| |
| method cannot be called on `[{integer}; 4]` due to unsatisfied trait bounds
| help: consider using `len` instead
|
= note: `count` is defined on `Iterator`, which `[{integer}; 4]` does not implement
error[E0599]: no method named `count` found for struct `Vec<{integer}>` in the current scope
--> $DIR/count2len.rs:6:9
|
LL | vec.count();
| ^^^^^
| |
| method cannot be called on `Vec<{integer}>` due to unsatisfied trait bounds
| help: consider using `len` instead
|
= note: `count` is defined on `Iterator`, which `Vec<{integer}>` does not implement
error[E0599]: no method named `count` found for reference `&[{integer}]` in the current scope
--> $DIR/count2len.rs:7:20
|
LL | vec.as_slice().count();
| ^^^^^
| |
| method cannot be called on `&[{integer}]` due to unsatisfied trait bounds
| help: consider using `len` instead
|
= note: `count` is defined on `Iterator`, which `&[{integer}]` does not implement
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0599`.

View File

@ -0,0 +1,143 @@
// compile-flags: --edition=2021
#![feature(rustc_attrs)]
use core::any::Any;
use core::marker::PhantomData;
fn main() {
test::<MaskedStorage<GenericComp<Pos>>>(make());
//~^ ERROR evaluate(Binder(TraitPredicate(<MaskedStorage<GenericComp<Pos>> as std::marker::Sized>, polarity:Positive), [])) = Ok(EvaluatedToOk)
//~| ERROR evaluate(Binder(TraitPredicate(<MaskedStorage<GenericComp<Pos>> as std::marker::Sized>, polarity:Positive), [])) = Ok(EvaluatedToOk)
test::<MaskedStorage<GenericComp2<Pos>>>(make());
//~^ ERROR evaluate(Binder(TraitPredicate(<MaskedStorage<GenericComp2<Pos>> as std::marker::Sized>, polarity:Positive), [])) = Ok(EvaluatedToOkModuloRegions)
//~| ERROR evaluate(Binder(TraitPredicate(<MaskedStorage<GenericComp2<Pos>> as std::marker::Sized>, polarity:Positive), [])) = Ok(EvaluatedToOkModuloRegions)
}
#[rustc_evaluate_where_clauses]
fn test<T: Sized>(_: T) {}
fn make<T>() -> T {
todo!()
}
struct DerefWrap<T>(T);
impl<T> core::ops::Deref for DerefWrap<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
struct Storage<T, D> {
phantom: PhantomData<(T, D)>,
}
type ReadStorage<T> = Storage<T, DerefWrap<MaskedStorage<T>>>;
pub trait Component {
type Storage;
}
struct VecStorage;
struct Pos;
impl Component for Pos {
type Storage = VecStorage;
}
struct GenericComp<T> {
_t: T,
}
impl<T: 'static> Component for GenericComp<T> {
type Storage = VecStorage;
}
struct GenericComp2<T> {
_t: T,
}
impl<T: 'static> Component for GenericComp2<T> where for<'a> &'a bool: 'a {
type Storage = VecStorage;
}
struct ReadData {
pos_interpdata: ReadStorage<GenericComp<Pos>>,
}
trait System {
type SystemData;
fn run(data: Self::SystemData, any: Box<dyn Any>);
}
struct Sys;
impl System for Sys {
type SystemData = (ReadData, ReadStorage<Pos>);
fn run((data, pos): Self::SystemData, any: Box<dyn Any>) {
<ReadStorage<GenericComp<Pos>> as SystemData>::setup(any);
ParJoin::par_join((&pos, &data.pos_interpdata));
}
}
trait ParJoin {
fn par_join(self)
where
Self: Sized,
{
}
}
impl<'a, T, D> ParJoin for &'a Storage<T, D>
where
T: Component,
D: core::ops::Deref<Target = MaskedStorage<T>>,
T::Storage: Sync,
{
}
impl<A, B> ParJoin for (A, B)
where
A: ParJoin,
B: ParJoin,
{
}
pub trait SystemData {
fn setup(any: Box<dyn Any>);
}
impl<T: 'static> SystemData for ReadStorage<T>
where
T: Component,
{
fn setup(any: Box<dyn Any>) {
let storage: &MaskedStorage<T> = any.downcast_ref().unwrap();
<dyn Any as CastFrom<MaskedStorage<T>>>::cast(&storage);
}
}
pub struct MaskedStorage<T: Component> {
_inner: T::Storage,
}
pub unsafe trait CastFrom<T> {
fn cast(t: &T) -> &Self;
}
unsafe impl<T> CastFrom<T> for dyn Any
where
T: Any + 'static,
{
fn cast(t: &T) -> &Self {
t
}
}

View File

@ -0,0 +1,38 @@
error: evaluate(Binder(TraitPredicate(<MaskedStorage<GenericComp<Pos>> as std::marker::Sized>, polarity:Positive), [])) = Ok(EvaluatedToOk)
--> $DIR/issue-85360-eval-obligation-ice.rs:9:5
|
LL | test::<MaskedStorage<GenericComp<Pos>>>(make());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | fn test<T: Sized>(_: T) {}
| - predicate
error: evaluate(Binder(TraitPredicate(<MaskedStorage<GenericComp<Pos>> as std::marker::Sized>, polarity:Positive), [])) = Ok(EvaluatedToOk)
--> $DIR/issue-85360-eval-obligation-ice.rs:9:5
|
LL | test::<MaskedStorage<GenericComp<Pos>>>(make());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | fn test<T: Sized>(_: T) {}
| ----- predicate
error: evaluate(Binder(TraitPredicate(<MaskedStorage<GenericComp2<Pos>> as std::marker::Sized>, polarity:Positive), [])) = Ok(EvaluatedToOkModuloRegions)
--> $DIR/issue-85360-eval-obligation-ice.rs:13:5
|
LL | test::<MaskedStorage<GenericComp2<Pos>>>(make());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | fn test<T: Sized>(_: T) {}
| - predicate
error: evaluate(Binder(TraitPredicate(<MaskedStorage<GenericComp2<Pos>> as std::marker::Sized>, polarity:Positive), [])) = Ok(EvaluatedToOkModuloRegions)
--> $DIR/issue-85360-eval-obligation-ice.rs:13:5
|
LL | test::<MaskedStorage<GenericComp2<Pos>>>(make());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | fn test<T: Sized>(_: T) {}
| ----- predicate
error: aborting due to 4 previous errors

View File

@ -0,0 +1,6 @@
fn main() {
0: u8<e<5>=e>
//~^ ERROR: cannot find type `e` in this scope [E0412]
//~| ERROR: associated type bindings are not allowed here [E0229]
//~| ERROR: mismatched types [E0308]
}

View File

@ -0,0 +1,27 @@
error[E0412]: cannot find type `e` in this scope
--> $DIR/issue-91267.rs:2:16
|
LL | 0: u8<e<5>=e>
| ^
| |
| not found in this scope
| help: maybe you meant to write an assignment here: `let e`
error[E0229]: associated type bindings are not allowed here
--> $DIR/issue-91267.rs:2:11
|
LL | 0: u8<e<5>=e>
| ^^^^^^ associated type not allowed here
error[E0308]: mismatched types
--> $DIR/issue-91267.rs:2:5
|
LL | fn main() {
| - expected `()` because of default return type
LL | 0: u8<e<5>=e>
| ^^^^^^^^^^^^^ expected `()`, found `u8`
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0229, E0308, E0412.
For more information about an error, try `rustc --explain E0229`.

@ -1 +1 @@
Subproject commit d9b2291f546abc77d24499339a72a89127464b95
Subproject commit 7d6fcbc0be2151bfa85ec146545b42d8be2fb28c