Auto merge of #107064 - GuillaumeGomez:rollup-pbgu6r3, r=GuillaumeGomez

Rollup of 5 pull requests

Successful merges:

 - #105977 (Transform async `ResumeTy` in generator transform)
 - #106927 (make `CastError::NeedsDeref` create a `MachineApplicable` suggestion)
 - #106931 (document + UI test `E0208` and make its output more user-friendly)
 - #107027 (Remove extra removal from test path)
 - #107037 (Fix Dominators::rank_partial_cmp to match documentation)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-01-19 11:12:31 +00:00
commit 79335f1ac4
33 changed files with 716 additions and 100 deletions

View File

@ -299,7 +299,7 @@ impl<Node: Idx> Dominators<Node> {
/// of two unrelated nodes will also be consistent, but otherwise the order has no
/// meaning.) This method cannot be used to determine if either Node dominates the other.
pub fn rank_partial_cmp(&self, lhs: Node, rhs: Node) -> Option<Ordering> {
self.post_order_rank[lhs].partial_cmp(&self.post_order_rank[rhs])
self.post_order_rank[rhs].partial_cmp(&self.post_order_rank[lhs])
}
}

View File

@ -1 +1,46 @@
#### This error code is internal to the compiler and will not be emitted with normal Rust code.
#### Note: this error code is no longer emitted by the compiler.
This error code shows the variance of a type's generic parameters.
Erroneous code example:
```compile_fail
// NOTE: this feature is perma-unstable and should *only* be used for
// testing purposes.
#![feature(rustc_attrs)]
#[rustc_variance]
struct Foo<'a, T> { // error: deliberate error to display type's variance
t: &'a mut T,
}
```
which produces the following error:
```text
error: [-, o]
--> <anon>:4:1
|
4 | struct Foo<'a, T> {
| ^^^^^^^^^^^^^^^^^
```
*Note that while `#[rustc_variance]` still exists and is used within the*
*compiler, it no longer is marked as `E0208` and instead has no error code.*
This error is deliberately triggered with the `#[rustc_variance]` attribute
(`#![feature(rustc_attrs)]` must be enabled) and helps to show you the variance
of the type's generic parameters. You can read more about variance and
subtyping in [this section of the Rustnomicon]. For a more in depth look at
variance (including a more complete list of common variances) see
[this section of the Reference]. For information on how variance is implemented
in the compiler, see [this section of `rustc-dev-guide`].
This error can be easily fixed by removing the `#[rustc_variance]` attribute,
the compiler's suggestion to comment it out can be applied automatically with
`rustfix`.
[this section of the Rustnomicon]: https://doc.rust-lang.org/nomicon/subtyping.html
[this section of the Reference]: https://doc.rust-lang.org/reference/subtyping.html#variance
[this section of `rustc-dev-guide`]: https://rustc-dev-guide.rust-lang.org/variance.html

View File

@ -1787,6 +1787,14 @@ impl Expr<'_> {
expr
}
pub fn peel_borrows(&self) -> &Self {
let mut expr = self;
while let ExprKind::AddrOf(.., inner) = &expr.kind {
expr = inner;
}
expr
}
pub fn can_have_side_effects(&self) -> bool {
match self.peel_drop_temps().kind {
ExprKind::Path(_) | ExprKind::Lit(_) => false,

View File

@ -291,6 +291,7 @@ language_item_table! {
IdentityFuture, sym::identity_future, identity_future_fn, Target::Fn, GenericRequirement::None;
GetContext, sym::get_context, get_context_fn, Target::Fn, GenericRequirement::None;
Context, sym::Context, context, Target::Struct, GenericRequirement::None;
FuturePoll, sym::poll, future_poll_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
FromFrom, sym::from, from_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;

View File

@ -1,4 +1,3 @@
use rustc_errors::struct_span_err;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::sym;
@ -8,8 +7,8 @@ pub fn test_variance(tcx: TyCtxt<'_>) {
for id in tcx.hir().items() {
if tcx.has_attr(id.owner_id.to_def_id(), sym::rustc_variance) {
let variances_of = tcx.variances_of(id.owner_id);
struct_span_err!(tcx.sess, tcx.def_span(id.owner_id), E0208, "{:?}", variances_of)
.emit();
tcx.sess.struct_span_err(tcx.def_span(id.owner_id), format!("{variances_of:?}")).emit();
}
}
}

View File

@ -31,6 +31,7 @@
use super::FnCtxt;
use crate::type_error_struct;
use hir::ExprKind;
use rustc_errors::{
struct_span_err, Applicability, DelayDm, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
};
@ -151,7 +152,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[derive(Copy, Clone)]
pub enum CastError {
ErrorGuaranteed,
ErrorGuaranteed(ErrorGuaranteed),
CastToBool,
CastToChar,
@ -176,8 +177,8 @@ pub enum CastError {
}
impl From<ErrorGuaranteed> for CastError {
fn from(_: ErrorGuaranteed) -> Self {
CastError::ErrorGuaranteed
fn from(err: ErrorGuaranteed) -> Self {
CastError::ErrorGuaranteed(err)
}
}
@ -225,11 +226,10 @@ impl<'a, 'tcx> CastCheck<'tcx> {
fn report_cast_error(&self, fcx: &FnCtxt<'a, 'tcx>, e: CastError) {
match e {
CastError::ErrorGuaranteed => {
CastError::ErrorGuaranteed(_) => {
// an error has already been reported
}
CastError::NeedDeref => {
let error_span = self.span;
let mut err = make_invalid_casting_error(
fcx.tcx.sess,
self.span,
@ -237,21 +237,25 @@ impl<'a, 'tcx> CastCheck<'tcx> {
self.cast_ty,
fcx,
);
let cast_ty = fcx.ty_to_string(self.cast_ty);
err.span_label(
error_span,
format!("cannot cast `{}` as `{}`", fcx.ty_to_string(self.expr_ty), cast_ty),
);
if let Ok(snippet) = fcx.sess().source_map().span_to_snippet(self.expr_span) {
err.span_suggestion(
self.expr_span,
"dereference the expression",
format!("*{}", snippet),
Applicability::MaybeIncorrect,
if matches!(self.expr.kind, ExprKind::AddrOf(..)) {
// get just the borrow part of the expression
let span = self.expr_span.with_hi(self.expr.peel_borrows().span.lo());
err.span_suggestion_verbose(
span,
"remove the unneeded borrow",
"",
Applicability::MachineApplicable,
);
} else {
err.span_help(self.expr_span, "dereference the expression with `*`");
err.span_suggestion_verbose(
self.expr_span.shrink_to_lo(),
"dereference the expression",
"*",
Applicability::MachineApplicable,
);
}
err.emit();
}
CastError::NeedViaThinPtr | CastError::NeedViaPtr => {

View File

@ -1952,6 +1952,15 @@ impl<'tcx> TyCtxt<'tcx> {
self.mk_ty(GeneratorWitness(types))
}
/// Creates a `&mut Context<'_>` [`Ty`] with erased lifetimes.
pub fn mk_task_context(self) -> Ty<'tcx> {
let context_did = self.require_lang_item(LangItem::Context, None);
let context_adt_ref = self.adt_def(context_did);
let context_substs = self.intern_substs(&[self.lifetimes.re_erased.into()]);
let context_ty = self.mk_adt(context_adt_ref, context_substs);
self.mk_mut_ref(self.lifetimes.re_erased, context_ty)
}
#[inline]
pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> {
self.mk_ty_infer(TyVar(v))

View File

@ -341,11 +341,11 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
if a.is_in_same_bcb(b) {
Some(Ordering::Equal)
} else {
// Sort equal spans by dominator relationship, in reverse order (so
// dominators always come after the dominated equal spans). When later
// comparing two spans in order, the first will either dominate the second,
// or they will have no dominator relationship.
self.basic_coverage_blocks.dominators().rank_partial_cmp(b.bcb, a.bcb)
// Sort equal spans by dominator relationship (so dominators always come
// before the dominated equal spans). When later comparing two spans in
// order, the first will either dominate the second, or they will have no
// dominator relationship.
self.basic_coverage_blocks.dominators().rank_partial_cmp(a.bcb, b.bcb)
}
} else {
// Sort hi() in reverse order so shorter spans are attempted after longer spans.

View File

@ -460,6 +460,104 @@ fn replace_local<'tcx>(
new_local
}
/// Transforms the `body` of the generator applying the following transforms:
///
/// - Eliminates all the `get_context` calls that async lowering created.
/// - Replace all `Local` `ResumeTy` types with `&mut Context<'_>` (`context_mut_ref`).
///
/// The `Local`s that have their types replaced are:
/// - The `resume` argument itself.
/// - The argument to `get_context`.
/// - The yielded value of a `yield`.
///
/// The `ResumeTy` hides a `&mut Context<'_>` behind an unsafe raw pointer, and the
/// `get_context` function is being used to convert that back to a `&mut Context<'_>`.
///
/// Ideally the async lowering would not use the `ResumeTy`/`get_context` indirection,
/// but rather directly use `&mut Context<'_>`, however that would currently
/// lead to higher-kinded lifetime errors.
/// See <https://github.com/rust-lang/rust/issues/105501>.
///
/// The async lowering step and the type / lifetime inference / checking are
/// still using the `ResumeTy` indirection for the time being, and that indirection
/// is removed here. After this transform, the generator body only knows about `&mut Context<'_>`.
fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let context_mut_ref = tcx.mk_task_context();
// replace the type of the `resume` argument
replace_resume_ty_local(tcx, body, Local::new(2), context_mut_ref);
let get_context_def_id = tcx.require_lang_item(LangItem::GetContext, None);
for bb in BasicBlock::new(0)..body.basic_blocks.next_index() {
let bb_data = &body[bb];
if bb_data.is_cleanup {
continue;
}
match &bb_data.terminator().kind {
TerminatorKind::Call { func, .. } => {
let func_ty = func.ty(body, tcx);
if let ty::FnDef(def_id, _) = *func_ty.kind() {
if def_id == get_context_def_id {
let local = eliminate_get_context_call(&mut body[bb]);
replace_resume_ty_local(tcx, body, local, context_mut_ref);
}
} else {
continue;
}
}
TerminatorKind::Yield { resume_arg, .. } => {
replace_resume_ty_local(tcx, body, resume_arg.local, context_mut_ref);
}
_ => {}
}
}
}
fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local {
let terminator = bb_data.terminator.take().unwrap();
if let TerminatorKind::Call { mut args, destination, target, .. } = terminator.kind {
let arg = args.pop().unwrap();
let local = arg.place().unwrap().local;
let arg = Rvalue::Use(arg);
let assign = Statement {
source_info: terminator.source_info,
kind: StatementKind::Assign(Box::new((destination, arg))),
};
bb_data.statements.push(assign);
bb_data.terminator = Some(Terminator {
source_info: terminator.source_info,
kind: TerminatorKind::Goto { target: target.unwrap() },
});
local
} else {
bug!();
}
}
#[cfg_attr(not(debug_assertions), allow(unused))]
fn replace_resume_ty_local<'tcx>(
tcx: TyCtxt<'tcx>,
body: &mut Body<'tcx>,
local: Local,
context_mut_ref: Ty<'tcx>,
) {
let local_ty = std::mem::replace(&mut body.local_decls[local].ty, context_mut_ref);
// We have to replace the `ResumeTy` that is used for type and borrow checking
// with `&mut Context<'_>` in MIR.
#[cfg(debug_assertions)]
{
if let ty::Adt(resume_ty_adt, _) = local_ty.kind() {
let expected_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None));
assert_eq!(*resume_ty_adt, expected_adt);
} else {
panic!("expected `ResumeTy`, found `{:?}`", local_ty);
};
}
}
struct LivenessInfo {
/// Which locals are live across any suspension point.
saved_locals: GeneratorSavedLocals,
@ -1283,13 +1381,13 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
}
};
let is_async_kind = body.generator_kind().unwrap() != GeneratorKind::Gen;
let is_async_kind = matches!(body.generator_kind(), Some(GeneratorKind::Async(_)));
let (state_adt_ref, state_substs) = if is_async_kind {
// Compute Poll<return_ty>
let state_did = tcx.require_lang_item(LangItem::Poll, None);
let state_adt_ref = tcx.adt_def(state_did);
let state_substs = tcx.intern_substs(&[body.return_ty().into()]);
(state_adt_ref, state_substs)
let poll_did = tcx.require_lang_item(LangItem::Poll, None);
let poll_adt_ref = tcx.adt_def(poll_did);
let poll_substs = tcx.intern_substs(&[body.return_ty().into()]);
(poll_adt_ref, poll_substs)
} else {
// Compute GeneratorState<yield_ty, return_ty>
let state_did = tcx.require_lang_item(LangItem::GeneratorState, None);
@ -1303,13 +1401,19 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
// RETURN_PLACE then is a fresh unused local with type ret_ty.
let new_ret_local = replace_local(RETURN_PLACE, ret_ty, body, tcx);
// Replace all occurrences of `ResumeTy` with `&mut Context<'_>` within async bodies.
if is_async_kind {
transform_async_context(tcx, body);
}
// We also replace the resume argument and insert an `Assign`.
// This is needed because the resume argument `_2` might be live across a `yield`, in which
// case there is no `Assign` to it that the transform can turn into a store to the generator
// state. After the yield the slot in the generator state would then be uninitialized.
let resume_local = Local::new(2);
let new_resume_local =
replace_local(resume_local, body.local_decls[resume_local].ty, body, tcx);
let resume_ty =
if is_async_kind { tcx.mk_task_context() } else { body.local_decls[resume_local].ty };
let new_resume_local = replace_local(resume_local, resume_ty, body, tcx);
// When first entering the generator, move the resume argument into its new local.
let source_info = SourceInfo::outermost(body.span);

View File

@ -164,6 +164,7 @@ symbols! {
Capture,
Center,
Clone,
Context,
Continue,
Copy,
Count,

View File

@ -108,21 +108,41 @@ fn fn_sig_for_fn_abi<'tcx>(
// `Generator::resume(...) -> GeneratorState` function in case we
// have an ordinary generator, or the `Future::poll(...) -> Poll`
// function in case this is a special generator backing an async construct.
let ret_ty = if tcx.generator_is_async(did) {
let state_did = tcx.require_lang_item(LangItem::Poll, None);
let state_adt_ref = tcx.adt_def(state_did);
let state_substs = tcx.intern_substs(&[sig.return_ty.into()]);
tcx.mk_adt(state_adt_ref, state_substs)
let (resume_ty, ret_ty) = if tcx.generator_is_async(did) {
// The signature should be `Future::poll(_, &mut Context<'_>) -> Poll<Output>`
let poll_did = tcx.require_lang_item(LangItem::Poll, None);
let poll_adt_ref = tcx.adt_def(poll_did);
let poll_substs = tcx.intern_substs(&[sig.return_ty.into()]);
let ret_ty = tcx.mk_adt(poll_adt_ref, poll_substs);
// We have to replace the `ResumeTy` that is used for type and borrow checking
// with `&mut Context<'_>` which is used in codegen.
#[cfg(debug_assertions)]
{
if let ty::Adt(resume_ty_adt, _) = sig.resume_ty.kind() {
let expected_adt =
tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, None));
assert_eq!(*resume_ty_adt, expected_adt);
} else {
panic!("expected `ResumeTy`, found `{:?}`", sig.resume_ty);
};
}
let context_mut_ref = tcx.mk_task_context();
(context_mut_ref, ret_ty)
} else {
// The signature should be `Generator::resume(_, Resume) -> GeneratorState<Yield, Return>`
let state_did = tcx.require_lang_item(LangItem::GeneratorState, None);
let state_adt_ref = tcx.adt_def(state_did);
let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]);
tcx.mk_adt(state_adt_ref, state_substs)
let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
(sig.resume_ty, ret_ty)
};
ty::Binder::bind_with_vars(
tcx.mk_fn_sig(
[env_ty, sig.resume_ty].iter(),
[env_ty, resume_ty].iter(),
&ret_ty,
false,
hir::Unsafety::Normal,

View File

@ -112,6 +112,10 @@ pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> {
unsafe { &mut *cx.0.as_ptr().cast() }
}
// FIXME(swatinem): This fn is currently needed to work around shortcomings
// in type and lifetime inference.
// See the comment at the bottom of `LoweringContext::make_async_expr` and
// <https://github.com/rust-lang/rust/issues/104826>.
#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
#[inline]

View File

@ -174,6 +174,7 @@ impl RawWakerVTable {
/// Currently, `Context` only serves to provide access to a [`&Waker`](Waker)
/// which can be used to wake the current task.
#[stable(feature = "futures_api", since = "1.36.0")]
#[cfg_attr(not(bootstrap), lang = "Context")]
pub struct Context<'a> {
waker: &'a Waker,
// Ensure we future-proof against variance changes by forcing

View File

@ -775,7 +775,7 @@ fn make_test_name(
) -> test::TestName {
// Print the name of the file, relative to the repository root.
// `src_base` looks like `/path/to/rust/tests/ui`
let root_directory = config.src_base.parent().unwrap().parent().unwrap().parent().unwrap();
let root_directory = config.src_base.parent().unwrap().parent().unwrap();
let path = testpaths.file.strip_prefix(root_directory).unwrap();
let debugger = match config.debugger {
Some(d) => format!("-{}", d),

View File

@ -27,8 +27,7 @@ const ERROR_DOCS_PATH: &str = "compiler/rustc_error_codes/src/error_codes/";
const ERROR_TESTS_PATH: &str = "tests/ui/error-codes/";
// Error codes that (for some reason) can't have a doctest in their explanation. Error codes are still expected to provide a code example, even if untested.
const IGNORE_DOCTEST_CHECK: &[&str] =
&["E0208", "E0464", "E0570", "E0601", "E0602", "E0640", "E0717"];
const IGNORE_DOCTEST_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602", "E0640", "E0717"];
// Error codes that don't yet have a UI test. This list will eventually be removed.
const IGNORE_UI_TEST_CHECK: &[&str] =

View File

@ -0,0 +1,41 @@
// MIR for `a::{closure#0}` 0 generator_resume
/* generator_layout = GeneratorLayout {
field_tys: {},
variant_fields: {
Unresumed(0): [],
Returned (1): [],
Panicked (2): [],
},
storage_conflicts: BitMatrix(0x0) {},
} */
fn a::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:11:14: 11:16]>, _2: &mut Context<'_>) -> Poll<()> {
debug _task_context => _4; // in scope 0 at $DIR/async_await.rs:+0:14: +0:16
let mut _0: std::task::Poll<()>; // return place in scope 0 at $DIR/async_await.rs:+0:14: +0:16
let mut _3: (); // in scope 0 at $DIR/async_await.rs:+0:14: +0:16
let mut _4: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+0:14: +0:16
let mut _5: u32; // in scope 0 at $DIR/async_await.rs:+0:14: +0:16
bb0: {
_5 = discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:11:14: 11:16]))); // scope 0 at $DIR/async_await.rs:+0:14: +0:16
switchInt(move _5) -> [0: bb1, 1: bb2, otherwise: bb3]; // scope 0 at $DIR/async_await.rs:+0:14: +0:16
}
bb1: {
_4 = move _2; // scope 0 at $DIR/async_await.rs:+0:14: +0:16
_3 = const (); // scope 0 at $DIR/async_await.rs:+0:14: +0:16
Deinit(_0); // scope 0 at $DIR/async_await.rs:+0:16: +0:16
((_0 as Ready).0: ()) = move _3; // scope 0 at $DIR/async_await.rs:+0:16: +0:16
discriminant(_0) = 0; // scope 0 at $DIR/async_await.rs:+0:16: +0:16
discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:11:14: 11:16]))) = 1; // scope 0 at $DIR/async_await.rs:+0:16: +0:16
return; // scope 0 at $DIR/async_await.rs:+0:16: +0:16
}
bb2: {
assert(const false, "`async fn` resumed after completion") -> bb2; // scope 0 at $DIR/async_await.rs:+0:14: +0:16
}
bb3: {
unreachable; // scope 0 at $DIR/async_await.rs:+0:14: +0:16
}
}

View File

@ -0,0 +1,337 @@
// MIR for `b::{closure#0}` 0 generator_resume
/* generator_layout = GeneratorLayout {
field_tys: {
_0: impl std::future::Future<Output = ()>,
_1: impl std::future::Future<Output = ()>,
},
variant_fields: {
Unresumed(0): [],
Returned (1): [],
Panicked (2): [],
Suspend0 (3): [_0],
Suspend1 (4): [_1],
},
storage_conflicts: BitMatrix(2x2) {
(_0, _0),
(_1, _1),
},
} */
fn b::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:14:18: 17:2]>, _2: &mut Context<'_>) -> Poll<()> {
debug _task_context => _38; // in scope 0 at $DIR/async_await.rs:+0:18: +3:2
let mut _0: std::task::Poll<()>; // return place in scope 0 at $DIR/async_await.rs:+0:18: +3:2
let _3: (); // in scope 0 at $DIR/async_await.rs:+1:5: +1:14
let mut _4: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
let mut _5: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:5: +1:8
let mut _6: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
let mut _7: (); // in scope 0 at $DIR/async_await.rs:+0:18: +3:2
let _8: (); // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
let mut _9: std::task::Poll<()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
let mut _10: std::pin::Pin<&mut impl std::future::Future<Output = ()>>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
let mut _11: &mut impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
let mut _12: &mut impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
let mut _13: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+1:5: +1:14
let mut _14: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+1:5: +1:14
let mut _15: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
let mut _16: isize; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
let mut _18: !; // in scope 0 at $DIR/async_await.rs:+1:5: +1:14
let mut _19: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
let mut _20: (); // in scope 0 at $DIR/async_await.rs:+1:8: +1:14
let mut _21: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
let mut _22: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:5: +2:8
let mut _23: impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
let _24: (); // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
let mut _25: std::task::Poll<()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
let mut _26: std::pin::Pin<&mut impl std::future::Future<Output = ()>>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
let mut _27: &mut impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
let mut _28: &mut impl std::future::Future<Output = ()>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
let mut _29: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+2:5: +2:14
let mut _30: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+2:5: +2:14
let mut _31: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
let mut _32: isize; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
let mut _34: !; // in scope 0 at $DIR/async_await.rs:+2:5: +2:14
let mut _35: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
let mut _36: (); // in scope 0 at $DIR/async_await.rs:+2:8: +2:14
let mut _37: (); // in scope 0 at $DIR/async_await.rs:+0:18: +3:2
let mut _38: &mut std::task::Context<'_>; // in scope 0 at $DIR/async_await.rs:+0:18: +3:2
let mut _39: u32; // in scope 0 at $DIR/async_await.rs:+0:18: +3:2
scope 1 {
debug __awaitee => (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#3).0: impl std::future::Future<Output = ()>); // in scope 1 at $DIR/async_await.rs:+1:8: +1:14
let _17: (); // in scope 1 at $DIR/async_await.rs:+1:5: +1:14
scope 2 {
}
scope 3 {
debug result => _17; // in scope 3 at $DIR/async_await.rs:+1:5: +1:14
}
}
scope 4 {
debug __awaitee => (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#4).0: impl std::future::Future<Output = ()>); // in scope 4 at $DIR/async_await.rs:+2:8: +2:14
let _33: (); // in scope 4 at $DIR/async_await.rs:+2:5: +2:14
scope 5 {
}
scope 6 {
debug result => _33; // in scope 6 at $DIR/async_await.rs:+2:5: +2:14
}
}
bb0: {
_39 = discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb30]; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
}
bb1: {
_38 = move _2; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
StorageLive(_3); // scope 0 at $DIR/async_await.rs:+1:5: +1:14
StorageLive(_4); // scope 0 at $DIR/async_await.rs:+1:8: +1:14
StorageLive(_5); // scope 0 at $DIR/async_await.rs:+1:5: +1:8
_5 = a() -> bb2; // scope 0 at $DIR/async_await.rs:+1:5: +1:8
// mir::Constant
// + span: $DIR/async_await.rs:15:5: 15:6
// + literal: Const { ty: fn() -> impl Future<Output = ()> {a}, val: Value(<ZST>) }
}
bb2: {
_4 = <impl Future<Output = ()> as IntoFuture>::into_future(move _5) -> bb3; // scope 0 at $DIR/async_await.rs:+1:8: +1:14
// mir::Constant
// + span: $DIR/async_await.rs:15:8: 15:14
// + literal: Const { ty: fn(impl Future<Output = ()>) -> <impl Future<Output = ()> as IntoFuture>::IntoFuture {<impl Future<Output = ()> as IntoFuture>::into_future}, val: Value(<ZST>) }
}
bb3: {
StorageDead(_5); // scope 0 at $DIR/async_await.rs:+1:13: +1:14
nop; // scope 0 at $DIR/async_await.rs:+1:8: +1:14
(((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#3).0: impl std::future::Future<Output = ()>) = move _4; // scope 0 at $DIR/async_await.rs:+1:8: +1:14
goto -> bb4; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
}
bb4: {
StorageLive(_8); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
StorageLive(_9); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
StorageLive(_10); // scope 2 at $DIR/async_await.rs:+1:8: +1:14
StorageLive(_11); // scope 2 at $DIR/async_await.rs:+1:8: +1:14
StorageLive(_12); // scope 2 at $DIR/async_await.rs:+1:8: +1:14
_12 = &mut (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#3).0: impl std::future::Future<Output = ()>); // scope 2 at $DIR/async_await.rs:+1:8: +1:14
_11 = &mut (*_12); // scope 2 at $DIR/async_await.rs:+1:8: +1:14
_10 = Pin::<&mut impl Future<Output = ()>>::new_unchecked(move _11) -> bb5; // scope 2 at $DIR/async_await.rs:+1:8: +1:14
// mir::Constant
// + span: $DIR/async_await.rs:15:8: 15:14
// + literal: Const { ty: unsafe fn(&mut impl Future<Output = ()>) -> Pin<&mut impl Future<Output = ()>> {Pin::<&mut impl Future<Output = ()>>::new_unchecked}, val: Value(<ZST>) }
}
bb5: {
StorageDead(_11); // scope 2 at $DIR/async_await.rs:+1:13: +1:14
StorageLive(_13); // scope 2 at $DIR/async_await.rs:+1:5: +1:14
StorageLive(_14); // scope 2 at $DIR/async_await.rs:+1:5: +1:14
StorageLive(_15); // scope 2 at $DIR/async_await.rs:+1:8: +1:14
_15 = _38; // scope 2 at $DIR/async_await.rs:+1:8: +1:14
_14 = move _15; // scope 2 at $DIR/async_await.rs:+1:5: +1:14
goto -> bb6; // scope 2 at $DIR/async_await.rs:+1:5: +1:14
}
bb6: {
_13 = &mut (*_14); // scope 2 at $DIR/async_await.rs:+1:5: +1:14
StorageDead(_15); // scope 2 at $DIR/async_await.rs:+1:13: +1:14
_9 = <impl Future<Output = ()> as Future>::poll(move _10, move _13) -> bb7; // scope 2 at $DIR/async_await.rs:+1:8: +1:14
// mir::Constant
// + span: $DIR/async_await.rs:15:8: 15:14
// + literal: Const { ty: for<'a, 'b, 'c> fn(Pin<&'a mut impl Future<Output = ()>>, &'b mut Context<'c>) -> Poll<<impl Future<Output = ()> as Future>::Output> {<impl Future<Output = ()> as Future>::poll}, val: Value(<ZST>) }
}
bb7: {
StorageDead(_13); // scope 2 at $DIR/async_await.rs:+1:13: +1:14
StorageDead(_10); // scope 2 at $DIR/async_await.rs:+1:13: +1:14
_16 = discriminant(_9); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
switchInt(move _16) -> [0: bb10, 1: bb8, otherwise: bb9]; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
}
bb8: {
_8 = const (); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
StorageDead(_14); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
StorageDead(_12); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
StorageDead(_9); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
StorageDead(_8); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
StorageLive(_19); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
StorageLive(_20); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
_20 = (); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
Deinit(_0); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
discriminant(_0) = 1; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))) = 3; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
return; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
}
bb9: {
unreachable; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
}
bb10: {
StorageLive(_17); // scope 1 at $DIR/async_await.rs:+1:5: +1:14
_17 = ((_9 as Ready).0: ()); // scope 1 at $DIR/async_await.rs:+1:5: +1:14
_3 = _17; // scope 3 at $DIR/async_await.rs:+1:5: +1:14
StorageDead(_17); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
StorageDead(_14); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
StorageDead(_12); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
StorageDead(_9); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
StorageDead(_8); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
goto -> bb12; // scope 0 at $DIR/async_await.rs:+1:13: +1:14
}
bb11: {
StorageDead(_20); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
_38 = move _19; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
StorageDead(_19); // scope 1 at $DIR/async_await.rs:+1:13: +1:14
_7 = const (); // scope 1 at $DIR/async_await.rs:+1:8: +1:14
goto -> bb4; // scope 1 at $DIR/async_await.rs:+1:8: +1:14
}
bb12: {
nop; // scope 0 at $DIR/async_await.rs:+1:13: +1:14
goto -> bb13; // scope 0 at $DIR/async_await.rs:+1:14: +1:15
}
bb13: {
StorageDead(_4); // scope 0 at $DIR/async_await.rs:+1:14: +1:15
StorageDead(_3); // scope 0 at $DIR/async_await.rs:+1:14: +1:15
StorageLive(_21); // scope 0 at $DIR/async_await.rs:+2:8: +2:14
StorageLive(_22); // scope 0 at $DIR/async_await.rs:+2:5: +2:8
_22 = a() -> bb14; // scope 0 at $DIR/async_await.rs:+2:5: +2:8
// mir::Constant
// + span: $DIR/async_await.rs:16:5: 16:6
// + literal: Const { ty: fn() -> impl Future<Output = ()> {a}, val: Value(<ZST>) }
}
bb14: {
_21 = <impl Future<Output = ()> as IntoFuture>::into_future(move _22) -> bb15; // scope 0 at $DIR/async_await.rs:+2:8: +2:14
// mir::Constant
// + span: $DIR/async_await.rs:16:8: 16:14
// + literal: Const { ty: fn(impl Future<Output = ()>) -> <impl Future<Output = ()> as IntoFuture>::IntoFuture {<impl Future<Output = ()> as IntoFuture>::into_future}, val: Value(<ZST>) }
}
bb15: {
StorageDead(_22); // scope 0 at $DIR/async_await.rs:+2:13: +2:14
nop; // scope 0 at $DIR/async_await.rs:+2:8: +2:14
(((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#4).0: impl std::future::Future<Output = ()>) = move _21; // scope 0 at $DIR/async_await.rs:+2:8: +2:14
goto -> bb16; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
}
bb16: {
StorageLive(_24); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
StorageLive(_25); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
StorageLive(_26); // scope 5 at $DIR/async_await.rs:+2:8: +2:14
StorageLive(_27); // scope 5 at $DIR/async_await.rs:+2:8: +2:14
StorageLive(_28); // scope 5 at $DIR/async_await.rs:+2:8: +2:14
_28 = &mut (((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2])) as variant#4).0: impl std::future::Future<Output = ()>); // scope 5 at $DIR/async_await.rs:+2:8: +2:14
_27 = &mut (*_28); // scope 5 at $DIR/async_await.rs:+2:8: +2:14
_26 = Pin::<&mut impl Future<Output = ()>>::new_unchecked(move _27) -> bb17; // scope 5 at $DIR/async_await.rs:+2:8: +2:14
// mir::Constant
// + span: $DIR/async_await.rs:16:8: 16:14
// + literal: Const { ty: unsafe fn(&mut impl Future<Output = ()>) -> Pin<&mut impl Future<Output = ()>> {Pin::<&mut impl Future<Output = ()>>::new_unchecked}, val: Value(<ZST>) }
}
bb17: {
StorageDead(_27); // scope 5 at $DIR/async_await.rs:+2:13: +2:14
StorageLive(_29); // scope 5 at $DIR/async_await.rs:+2:5: +2:14
StorageLive(_30); // scope 5 at $DIR/async_await.rs:+2:5: +2:14
StorageLive(_31); // scope 5 at $DIR/async_await.rs:+2:8: +2:14
_31 = _38; // scope 5 at $DIR/async_await.rs:+2:8: +2:14
_30 = move _31; // scope 5 at $DIR/async_await.rs:+2:5: +2:14
goto -> bb18; // scope 5 at $DIR/async_await.rs:+2:5: +2:14
}
bb18: {
_29 = &mut (*_30); // scope 5 at $DIR/async_await.rs:+2:5: +2:14
StorageDead(_31); // scope 5 at $DIR/async_await.rs:+2:13: +2:14
_25 = <impl Future<Output = ()> as Future>::poll(move _26, move _29) -> bb19; // scope 5 at $DIR/async_await.rs:+2:8: +2:14
// mir::Constant
// + span: $DIR/async_await.rs:16:8: 16:14
// + literal: Const { ty: for<'a, 'b, 'c> fn(Pin<&'a mut impl Future<Output = ()>>, &'b mut Context<'c>) -> Poll<<impl Future<Output = ()> as Future>::Output> {<impl Future<Output = ()> as Future>::poll}, val: Value(<ZST>) }
}
bb19: {
StorageDead(_29); // scope 5 at $DIR/async_await.rs:+2:13: +2:14
StorageDead(_26); // scope 5 at $DIR/async_await.rs:+2:13: +2:14
_32 = discriminant(_25); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
switchInt(move _32) -> [0: bb22, 1: bb20, otherwise: bb21]; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
}
bb20: {
_24 = const (); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
StorageDead(_30); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
StorageDead(_28); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
StorageDead(_25); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
StorageDead(_24); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
StorageLive(_35); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
StorageLive(_36); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
_36 = (); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
Deinit(_0); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
discriminant(_0) = 1; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))) = 4; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
return; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
}
bb21: {
unreachable; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
}
bb22: {
StorageLive(_33); // scope 4 at $DIR/async_await.rs:+2:5: +2:14
_33 = ((_25 as Ready).0: ()); // scope 4 at $DIR/async_await.rs:+2:5: +2:14
_37 = _33; // scope 6 at $DIR/async_await.rs:+2:5: +2:14
StorageDead(_33); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
StorageDead(_30); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
StorageDead(_28); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
StorageDead(_25); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
StorageDead(_24); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
goto -> bb24; // scope 0 at $DIR/async_await.rs:+2:13: +2:14
}
bb23: {
StorageDead(_36); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
_38 = move _35; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
StorageDead(_35); // scope 4 at $DIR/async_await.rs:+2:13: +2:14
_7 = const (); // scope 4 at $DIR/async_await.rs:+2:8: +2:14
goto -> bb16; // scope 4 at $DIR/async_await.rs:+2:8: +2:14
}
bb24: {
nop; // scope 0 at $DIR/async_await.rs:+2:13: +2:14
goto -> bb25; // scope 0 at $DIR/async_await.rs:+3:1: +3:2
}
bb25: {
StorageDead(_21); // scope 0 at $DIR/async_await.rs:+3:1: +3:2
goto -> bb26; // scope 0 at $DIR/async_await.rs:+3:1: +3:2
}
bb26: {
Deinit(_0); // scope 0 at $DIR/async_await.rs:+3:2: +3:2
((_0 as Ready).0: ()) = move _37; // scope 0 at $DIR/async_await.rs:+3:2: +3:2
discriminant(_0) = 0; // scope 0 at $DIR/async_await.rs:+3:2: +3:2
discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))) = 1; // scope 0 at $DIR/async_await.rs:+3:2: +3:2
return; // scope 0 at $DIR/async_await.rs:+3:2: +3:2
}
bb27: {
StorageLive(_3); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
StorageLive(_4); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
StorageLive(_19); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
StorageLive(_20); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
_19 = move _2; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
goto -> bb11; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
}
bb28: {
StorageLive(_21); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
StorageLive(_35); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
StorageLive(_36); // scope 0 at $DIR/async_await.rs:+0:18: +3:2
_35 = move _2; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
goto -> bb23; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
}
bb29: {
assert(const false, "`async fn` resumed after completion") -> bb29; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
}
bb30: {
unreachable; // scope 0 at $DIR/async_await.rs:+0:18: +3:2
}
}

View File

@ -0,0 +1,17 @@
// This test makes sure that the generator MIR pass eliminates all calls to
// `get_context`, and that the MIR argument type for an async fn and all locals
// related to `yield` are `&mut Context`, and its return type is `Poll`.
// edition:2018
// compile-flags: -C panic=abort
#![crate_type = "lib"]
// EMIT_MIR async_await.a-{closure#0}.generator_resume.0.mir
async fn a() {}
// EMIT_MIR async_await.b-{closure#0}.generator_resume.0.mir
pub async fn b() {
a().await;
a().await
}

View File

@ -0,0 +1,8 @@
#![feature(rustc_attrs)]
#[rustc_variance]
struct Foo<'a, T> { //~ ERROR [-, o]
t: &'a mut T,
}
fn main() {}

View File

@ -0,0 +1,8 @@
error: [-, o]
--> $DIR/E0208.rs:4:1
|
LL | struct Foo<'a, T> {
| ^^^^^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -1,3 +1,4 @@
fn main() {
&0u8 as u8; //~ ERROR E0606
let x = &(&0u8 as u8); //~ ERROR E0606
x as u8; //~ casting `&u8` as `u8` is invalid [E0606]
}

View File

@ -1,12 +1,26 @@
error[E0606]: casting `&u8` as `u8` is invalid
--> $DIR/E0606.rs:2:5
--> $DIR/E0606.rs:2:14
|
LL | let x = &(&0u8 as u8);
| ^^^^^^^^^^^^
|
help: remove the unneeded borrow
|
LL - let x = &(&0u8 as u8);
LL + let x = &(0u8 as u8);
|
LL | &0u8 as u8;
| ----^^^^^^
| |
| cannot cast `&u8` as `u8`
| help: dereference the expression: `*&0u8`
error: aborting due to previous error
error[E0606]: casting `&u8` as `u8` is invalid
--> $DIR/E0606.rs:3:5
|
LL | x as u8;
| ^^^^^^^
|
help: dereference the expression
|
LL | *x as u8;
| +
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0606`.

View File

@ -69,10 +69,12 @@ error[E0606]: casting `&u8` as `u32` is invalid
--> $DIR/error-festival.rs:37:18
|
LL | let y: u32 = x as u32;
| -^^^^^^^
| |
| cannot cast `&u8` as `u32`
| help: dereference the expression: `*x`
| ^^^^^^^^
|
help: dereference the expression
|
LL | let y: u32 = *x as u32;
| +
error[E0607]: cannot cast thin pointer `*const u8` to fat pointer `*const [u8]`
--> $DIR/error-festival.rs:41:5

View File

@ -243,10 +243,12 @@ error[E0606]: casting `&{float}` as `f32` is invalid
--> $DIR/cast-rfc0401.rs:71:30
|
LL | vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>();
| -^^^^^^^
| |
| cannot cast `&{float}` as `f32`
| help: dereference the expression: `*s`
| ^^^^^^^^
|
help: dereference the expression
|
LL | vec![0.0].iter().map(|s| *s as f32).collect::<Vec<f32>>();
| +
error: aborting due to 34 previous errors

View File

@ -1,4 +1,4 @@
error[E0208]: [o]
error: [o]
--> $DIR/variance-associated-consts.rs:13:1
|
LL | struct Foo<T: Trait> {
@ -6,4 +6,3 @@ LL | struct Foo<T: Trait> {
error: aborting due to previous error
For more information about this error, try `rustc --explain E0208`.

View File

@ -1,10 +1,10 @@
error[E0208]: [-, +]
error: [-, +]
--> $DIR/variance-associated-types.rs:13:1
|
LL | struct Foo<'a, T : Trait<'a>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [o, o]
error: [o, o]
--> $DIR/variance-associated-types.rs:18:1
|
LL | struct Bar<'a, T : Trait<'a>> {
@ -12,4 +12,3 @@ LL | struct Bar<'a, T : Trait<'a>> {
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0208`.

View File

@ -1,4 +1,4 @@
error[E0208]: [o]
error: [o]
--> $DIR/variance-object-types.rs:7:1
|
LL | struct Foo<'a> {
@ -6,4 +6,3 @@ LL | struct Foo<'a> {
error: aborting due to previous error
For more information about this error, try `rustc --explain E0208`.

View File

@ -1,40 +1,40 @@
error[E0208]: [-, -, -]
error: [-, -, -]
--> $DIR/variance-regions-direct.rs:9:1
|
LL | struct Test2<'a, 'b, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [+, +, +]
error: [+, +, +]
--> $DIR/variance-regions-direct.rs:18:1
|
LL | struct Test3<'a, 'b, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [-, o]
error: [-, o]
--> $DIR/variance-regions-direct.rs:27:1
|
LL | struct Test4<'a, 'b:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [+, o]
error: [+, o]
--> $DIR/variance-regions-direct.rs:35:1
|
LL | struct Test5<'a, 'b:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [-, o]
error: [-, o]
--> $DIR/variance-regions-direct.rs:45:1
|
LL | struct Test6<'a, 'b:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [*]
error: [*]
--> $DIR/variance-regions-direct.rs:52:1
|
LL | struct Test7<'a> {
| ^^^^^^^^^^^^^^^^
error[E0208]: [+, -, o]
error: [+, -, o]
--> $DIR/variance-regions-direct.rs:59:1
|
LL | enum Test8<'a, 'b, 'c:'b> {
@ -42,4 +42,3 @@ LL | enum Test8<'a, 'b, 'c:'b> {
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0208`.

View File

@ -1,28 +1,28 @@
error[E0208]: [+, -, o, *]
error: [+, -, o, *]
--> $DIR/variance-regions-indirect.rs:8:1
|
LL | enum Base<'a, 'b, 'c:'b, 'd> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [*, o, -, +]
error: [*, o, -, +]
--> $DIR/variance-regions-indirect.rs:15:1
|
LL | struct Derived1<'w, 'x:'y, 'y, 'z> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [o, o, *]
error: [o, o, *]
--> $DIR/variance-regions-indirect.rs:20:1
|
LL | struct Derived2<'a, 'b:'a, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [o, -, *]
error: [o, -, *]
--> $DIR/variance-regions-indirect.rs:25:1
|
LL | struct Derived3<'a:'b, 'b, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [+, -, o]
error: [+, -, o]
--> $DIR/variance-regions-indirect.rs:30:1
|
LL | struct Derived4<'a, 'b, 'c:'b> {
@ -30,4 +30,3 @@ LL | struct Derived4<'a, 'b, 'c:'b> {
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0208`.

View File

@ -1,22 +1,22 @@
error[E0208]: [+, +]
error: [+, +]
--> $DIR/variance-trait-bounds.rs:16:1
|
LL | struct TestStruct<U,T:Setter<U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [*, +]
error: [*, +]
--> $DIR/variance-trait-bounds.rs:21:1
|
LL | enum TestEnum<U,T:Setter<U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [*, +]
error: [*, +]
--> $DIR/variance-trait-bounds.rs:26:1
|
LL | struct TestContraStruct<U,T:Setter<U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [*, +]
error: [*, +]
--> $DIR/variance-trait-bounds.rs:31:1
|
LL | struct TestBox<U,T:Getter<U>+Setter<U>> {
@ -24,4 +24,3 @@ LL | struct TestBox<U,T:Getter<U>+Setter<U>> {
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0208`.

View File

@ -1,4 +1,4 @@
error[E0208]: [-]
error: [-]
--> $DIR/variance-trait-object-bound.rs:14:1
|
LL | struct TOption<'a> {
@ -6,4 +6,3 @@ LL | struct TOption<'a> {
error: aborting due to previous error
For more information about this error, try `rustc --explain E0208`.

View File

@ -1,28 +1,28 @@
error[E0208]: [+, +]
error: [+, +]
--> $DIR/variance-types-bounds.rs:7:1
|
LL | struct TestImm<A, B> {
| ^^^^^^^^^^^^^^^^^^^^
error[E0208]: [+, o]
error: [+, o]
--> $DIR/variance-types-bounds.rs:13:1
|
LL | struct TestMut<A, B:'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [+, o]
error: [+, o]
--> $DIR/variance-types-bounds.rs:19:1
|
LL | struct TestIndirect<A:'static, B:'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [o, o]
error: [o, o]
--> $DIR/variance-types-bounds.rs:24:1
|
LL | struct TestIndirect2<A:'static, B:'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [o, o]
error: [o, o]
--> $DIR/variance-types-bounds.rs:38:1
|
LL | struct TestObject<A, R> {
@ -30,4 +30,3 @@ LL | struct TestObject<A, R> {
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0208`.

View File

@ -1,34 +1,34 @@
error[E0208]: [-, o, o]
error: [-, o, o]
--> $DIR/variance-types.rs:10:1
|
LL | struct InvariantMut<'a,A:'a,B:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [o]
error: [o]
--> $DIR/variance-types.rs:15:1
|
LL | struct InvariantCell<A> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [o]
error: [o]
--> $DIR/variance-types.rs:20:1
|
LL | struct InvariantIndirect<A> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [+]
error: [+]
--> $DIR/variance-types.rs:25:1
|
LL | struct Covariant<A> {
| ^^^^^^^^^^^^^^^^^^^
error[E0208]: [-]
error: [-]
--> $DIR/variance-types.rs:30:1
|
LL | struct Contravariant<A> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0208]: [+, -, o]
error: [+, -, o]
--> $DIR/variance-types.rs:35:1
|
LL | enum Enum<A,B,C> {
@ -36,4 +36,3 @@ LL | enum Enum<A,B,C> {
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0208`.