Skip to content

Rollup of 5 pull requests #65053

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

Closed
wants to merge 32 commits into from
Closed
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c845f3d
track the kind of async generator we are creating
nikomatsakis Sep 25, 2019
44e801a
thread down the body so we can check if this is an async fn body
nikomatsakis Sep 25, 2019
c8e5851
improved debug output
nikomatsakis Oct 2, 2019
f7ed53c
extract expected return type from `-> impl Future` obligation
nikomatsakis Oct 2, 2019
094f3a8
WIP tidy hir/lowering/expr.rs
nikomatsakis Oct 2, 2019
81cd596
WIP rebase for `shallow_resolve` call
nikomatsakis Oct 2, 2019
dce20bf
WIP fix tests
nikomatsakis Oct 2, 2019
3ae4abb
correct coercion comments
nikomatsakis Oct 2, 2019
a999132
improve comments on `GeneratorKind` and `AsyncGeneratorKind`
nikomatsakis Oct 2, 2019
5d64b3d
document `ret_coercion` and `ret_coercion_span`
nikomatsakis Oct 2, 2019
5fea1d2
document `shallow_resolve`
nikomatsakis Oct 2, 2019
3f277e1
s/`async` fn/`async fn`/
nikomatsakis Oct 2, 2019
a5cfc40
Avoid ICE on ReFree region from malformed code
estebank Oct 1, 2019
a96bce7
avoid using `skip_binder` and instead look for bound vars properly
nikomatsakis Oct 2, 2019
08a60ac
Calculate liveness for the same locals with and without -Zpolonius
matthewjasper Sep 21, 2019
2180c24
Make lifetimes in constants live at the point of use
matthewjasper Sep 24, 2019
4a49351
add unsize slice-str coercion
nikomatsakis Oct 2, 2019
19c07cc
fix example (le sigh)
nikomatsakis Oct 2, 2019
de81565
review comments
estebank Oct 2, 2019
a8b2fe0
[RFC 2091] Add #[track_caller] attribute.
ayosec Jul 20, 2019
e9deff0
track_caller run-pass test, lint cleanup, PR review.
anp Oct 3, 2019
1e78d99
track_caller feature gate starts in 1.40.0.
anp Oct 3, 2019
da86007
Mark #![feature(track_caller)] as incomplete.
anp Oct 3, 2019
8ac9104
track_caller error numbers and text.
anp Oct 3, 2019
9e301d1
track_caller tests account for incomplete feature warning.
anp Oct 3, 2019
a807032
./x.py test --bless --compare-mode=nll
nikomatsakis Oct 3, 2019
d1310dc
proc_macro: Add `Span::mixed_site` exposing `macro_rules` hygiene
petrochenkov Sep 22, 2019
49c8463
Rollup merge of #64690 - petrochenkov:mixed, r=dtolnay
Centril Oct 3, 2019
1172cd4
Rollup merge of #64749 - matthewjasper:liveness-opt, r=nikomatsakis
Centril Oct 3, 2019
f22cd77
Rollup merge of #64938 - estebank:ice-ice-baby, r=matthewjasper
Centril Oct 3, 2019
83adae8
Rollup merge of #64999 - nikomatsakis:issue-60424-async-return-infere…
Centril Oct 3, 2019
18ce550
Rollup merge of #65037 - anp:track-caller, r=oli-obk
Centril Oct 3, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/doc/unstable-book/src/language-features/track-caller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# `track_caller`

The tracking issue for this feature is: [#47809](https://github.com/rust-lang/rust/issues/47809).

------------------------
1 change: 1 addition & 0 deletions src/libproc_macro/bridge/mod.rs
Original file line number Diff line number Diff line change
@@ -148,6 +148,7 @@ macro_rules! with_api {
fn debug($self: $S::Span) -> String;
fn def_site() -> $S::Span;
fn call_site() -> $S::Span;
fn mixed_site() -> $S::Span;
fn source_file($self: $S::Span) -> $S::SourceFile;
fn parent($self: $S::Span) -> Option<$S::Span>;
fn source($self: $S::Span) -> $S::Span;
9 changes: 9 additions & 0 deletions src/libproc_macro/lib.rs
Original file line number Diff line number Diff line change
@@ -271,6 +271,15 @@ impl Span {
Span(bridge::client::Span::call_site())
}

/// A span that represents `macro_rules` hygiene, and sometimes resolves at the macro
/// definition site (local variables, labels, `$crate`) and sometimes at the macro
/// call site (everything else).
/// The span location is taken from the call-site.
#[unstable(feature = "proc_macro_mixed_site", issue = "65049")]
pub fn mixed_site() -> Span {
Span(bridge::client::Span::mixed_site())
}

/// The original source file into which this span points.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn source_file(&self) -> SourceFile {
10 changes: 10 additions & 0 deletions src/librustc/error_codes.rs
Original file line number Diff line number Diff line change
@@ -2234,6 +2234,15 @@ These attributes are meant to only be used by the standard library and are
rejected in your own crates.
"##,

E0736: r##"
#[track_caller] and #[naked] cannot be applied to the same function.

This is primarily due to ABI incompatibilities between the two attributes.
See [RFC 2091] for details on this and other limitations.

[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
"##,

;
// E0006, // merged with E0005
// E0101, // replaced with E0282
@@ -2296,4 +2305,5 @@ rejected in your own crates.
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
E0727, // `async` generators are not yet supported
E0728, // `await` must be in an `async` function or block
E0735, // invalid track_caller application/syntax
}
30 changes: 29 additions & 1 deletion src/librustc/hir/check_attr.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ use crate::ty::TyCtxt;
use crate::ty::query::Providers;

use std::fmt::{self, Display};
use syntax::symbol::sym;
use syntax::{attr, symbol::sym};
use syntax_pos::Span;

#[derive(Copy, Clone, PartialEq)]
@@ -103,6 +103,8 @@ impl CheckAttrVisitor<'tcx> {
self.check_marker(attr, item, target)
} else if attr.check_name(sym::target_feature) {
self.check_target_feature(attr, item, target)
} else if attr.check_name(sym::track_caller) {
self.check_track_caller(attr, &item, target)
} else {
true
};
@@ -135,6 +137,32 @@ impl CheckAttrVisitor<'tcx> {
}
}

/// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
fn check_track_caller(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) -> bool {
if target != Target::Fn {
struct_span_err!(
self.tcx.sess,
attr.span,
E0735,
"attribute should be applied to function"
)
.span_label(item.span, "not a function")
.emit();
false
} else if attr::contains_name(&item.attrs, sym::naked) {
struct_span_err!(
self.tcx.sess,
attr.span,
E0736,
"cannot use `#[track_caller]` with `#[naked]`",
)
.emit();
false
} else {
true
}
}

/// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid.
fn check_non_exhaustive(
&self,
30 changes: 19 additions & 11 deletions src/librustc/hir/lowering/expr.rs
Original file line number Diff line number Diff line change
@@ -89,9 +89,14 @@ impl LoweringContext<'_> {
hir::MatchSource::Normal,
),
ExprKind::Async(capture_clause, closure_node_id, ref block) => {
self.make_async_expr(capture_clause, closure_node_id, None, block.span, |this| {
this.with_new_scopes(|this| this.lower_block_expr(block))
})
self.make_async_expr(
capture_clause,
closure_node_id,
None,
block.span,
hir::AsyncGeneratorKind::Block,
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
)
}
ExprKind::Await(ref expr) => self.lower_expr_await(e.span, expr),
ExprKind::Closure(
@@ -457,6 +462,7 @@ impl LoweringContext<'_> {
closure_node_id: NodeId,
ret_ty: Option<AstP<Ty>>,
span: Span,
async_gen_kind: hir::AsyncGeneratorKind,
body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
) -> hir::ExprKind {
let capture_clause = self.lower_capture_clause(capture_clause);
@@ -470,7 +476,7 @@ impl LoweringContext<'_> {
};
let decl = self.lower_fn_decl(&ast_decl, None, /* impl trait allowed */ false, None);
let body_id = self.lower_fn_body(&ast_decl, |this| {
this.generator_kind = Some(hir::GeneratorKind::Async);
this.generator_kind = Some(hir::GeneratorKind::Async(async_gen_kind));
body(this)
});

@@ -522,7 +528,7 @@ impl LoweringContext<'_> {
/// ```
fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind {
match self.generator_kind {
Some(hir::GeneratorKind::Async) => {},
Some(hir::GeneratorKind::Async(_)) => {},
Some(hir::GeneratorKind::Gen) |
None => {
let mut err = struct_span_err!(
@@ -727,7 +733,7 @@ impl LoweringContext<'_> {
Movability::Static => hir::GeneratorMovability::Static,
})
},
Some(hir::GeneratorKind::Async) => {
Some(hir::GeneratorKind::Async(_)) => {
bug!("non-`async` closure body turned `async` during lowering");
},
None => {
@@ -786,10 +792,12 @@ impl LoweringContext<'_> {
None
};
let async_body = this.make_async_expr(
capture_clause, closure_id, async_ret_ty, body.span,
|this| {
this.with_new_scopes(|this| this.lower_expr(body))
}
capture_clause,
closure_id,
async_ret_ty,
body.span,
hir::AsyncGeneratorKind::Closure,
|this| this.with_new_scopes(|this| this.lower_expr(body)),
);
this.expr(fn_decl_span, async_body, ThinVec::new())
});
@@ -1005,7 +1013,7 @@ impl LoweringContext<'_> {
fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind {
match self.generator_kind {
Some(hir::GeneratorKind::Gen) => {},
Some(hir::GeneratorKind::Async) => {
Some(hir::GeneratorKind::Async(_)) => {
span_err!(
self.sess,
span,
6 changes: 5 additions & 1 deletion src/librustc/hir/lowering/item.rs
Original file line number Diff line number Diff line change
@@ -1222,7 +1222,11 @@ impl LoweringContext<'_> {
}

let async_expr = this.make_async_expr(
CaptureBy::Value, closure_id, None, body.span,
CaptureBy::Value,
closure_id,
None,
body.span,
hir::AsyncGeneratorKind::Fn,
|this| {
// Create a block from the user's function body:
let user_body = this.lower_block_expr(body);
43 changes: 37 additions & 6 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
@@ -1362,21 +1362,49 @@ impl Body {
}

/// The type of source expression that caused this generator to be created.
// Not `IsAsync` because we want to eventually add support for `AsyncGen`
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum GeneratorKind {
/// An `async` block or function.
Async,
/// An explicit `async` block or the body of an async function.
Async(AsyncGeneratorKind),

/// A generator literal created via a `yield` inside a closure.
Gen,
}

impl fmt::Display for GeneratorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
GeneratorKind::Async(k) => fmt::Display::fmt(k, f),
GeneratorKind::Gen => f.write_str("generator"),
}
}
}

/// In the case of a generator created as part of an async construct,
/// which kind of async construct caused it to be created?
///
/// This helps error messages but is also used to drive coercions in
/// type-checking (see #60424).
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum AsyncGeneratorKind {
/// An explicit `async` block written by the user.
Block,

/// An explicit `async` block written by the user.
Closure,

/// The `async` block generated as the body of an async function.
Fn,
}

impl fmt::Display for AsyncGeneratorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
GeneratorKind::Async => "`async` object",
GeneratorKind::Gen => "generator",
AsyncGeneratorKind::Block => "`async` block",
AsyncGeneratorKind::Closure => "`async` closure body",
AsyncGeneratorKind::Fn => "`async fn` body",
})
}
}
@@ -1758,6 +1786,7 @@ pub struct Destination {
pub enum GeneratorMovability {
/// May contain self-references, `!Unpin`.
Static,

/// Must not contain self-references, `Unpin`.
Movable,
}
@@ -2687,7 +2716,9 @@ bitflags! {
const USED = 1 << 9;
/// #[ffi_returns_twice], indicates that an extern function can return
/// multiple times
const FFI_RETURNS_TWICE = 1 << 10;
const FFI_RETURNS_TWICE = 1 << 10;
/// #[track_caller]: allow access to the caller location
const TRACK_CALLER = 1 << 11;
}
}

11 changes: 11 additions & 0 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
@@ -1319,6 +1319,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}

/// Resolve any type variables found in `value` -- but only one
/// level. So, if the variable `?X` is bound to some type
/// `Foo<?Y>`, then this would return `Foo<?Y>` (but `?Y` may
/// itself be bound to a type).
///
/// Useful when you only need to inspect the outermost level of
/// the type and don't care about nested types (or perhaps you
/// will be resolving them as well, e.g. in a loop).
pub fn shallow_resolve<T>(&self, value: T) -> T
where
T: TypeFoldable<'tcx>,
@@ -1579,6 +1587,9 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
ShallowResolver { infcx }
}

/// If `typ` is a type variable of some kind, resolve it one level
/// (but do not resolve types found in the result). If `typ` is
/// not a type variable, just return it unmodified.
pub fn shallow_resolve(&mut self, typ: Ty<'tcx>) -> Ty<'tcx> {
match typ.kind {
ty::Infer(ty::TyVar(v)) => {
Original file line number Diff line number Diff line change
@@ -70,6 +70,10 @@ impl LocalUseMap {
appearances: IndexVec::new(),
};

if live_locals.is_empty() {
return local_use_map;
}

let mut locals_with_use_data: IndexVec<Local, bool> =
IndexVec::from_elem_n(false, body.local_decls.len());
live_locals.iter().for_each(|&local| locals_with_use_data[local] = true);
52 changes: 30 additions & 22 deletions src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
Original file line number Diff line number Diff line change
@@ -36,31 +36,39 @@ pub(super) fn generate<'tcx>(
) {
debug!("liveness::generate");

let live_locals: Vec<Local> = if AllFacts::enabled(typeck.tcx()) {
// If "dump facts from NLL analysis" was requested perform
// the liveness analysis for all `Local`s. This case opens
// the possibility of the variables being analyzed in `trace`
// to be *any* `Local`, not just the "live" ones, so we can't
// make any assumptions past this point as to the characteristics
// of the `live_locals`.
// FIXME: Review "live" terminology past this point, we should
// not be naming the `Local`s as live.
body.local_decls.indices().collect()
let free_regions = regions_that_outlive_free_regions(
typeck.infcx.num_region_vars(),
&typeck.borrowck_context.universal_regions,
&typeck.borrowck_context.constraints.outlives_constraints,
);
let live_locals = compute_live_locals(typeck.tcx(), &free_regions, body);
let facts_enabled = AllFacts::enabled(typeck.tcx());


let polonius_drop_used = if facts_enabled {
let mut drop_used = Vec::new();
polonius::populate_access_facts(
typeck,
body,
location_table,
move_data,
&mut drop_used,
);
Some(drop_used)
} else {
let free_regions = {
regions_that_outlive_free_regions(
typeck.infcx.num_region_vars(),
&typeck.borrowck_context.universal_regions,
&typeck.borrowck_context.constraints.outlives_constraints,
)
};
compute_live_locals(typeck.tcx(), &free_regions, body)
None
};

if !live_locals.is_empty() {
trace::trace(typeck, body, elements, flow_inits, move_data, live_locals);

polonius::populate_access_facts(typeck, body, location_table, move_data);
if !live_locals.is_empty() || facts_enabled {
trace::trace(
typeck,
body,
elements,
flow_inits,
move_data,
live_locals,
polonius_drop_used,
);
}
}

Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ struct UseFactsExtractor<'me> {
var_defined: &'me mut VarPointRelations,
var_used: &'me mut VarPointRelations,
location_table: &'me LocationTable,
var_drop_used: &'me mut VarPointRelations,
var_drop_used: &'me mut Vec<(Local, Location)>,
move_data: &'me MoveData<'me>,
path_accessed_at: &'me mut MovePathPointRelations,
}
@@ -39,7 +39,7 @@ impl UseFactsExtractor<'_> {

fn insert_drop_use(&mut self, local: Local, location: Location) {
debug!("LivenessFactsExtractor::insert_drop_use()");
self.var_drop_used.push((local, self.location_to_index(location)));
self.var_drop_used.push((local, location));
}

fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
@@ -100,19 +100,24 @@ pub(super) fn populate_access_facts(
body: &Body<'tcx>,
location_table: &LocationTable,
move_data: &MoveData<'_>,
drop_used: &mut Vec<(Local, Location)>,
) {
debug!("populate_var_liveness_facts()");

if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
UseFactsExtractor {
var_defined: &mut facts.var_defined,
var_used: &mut facts.var_used,
var_drop_used: &mut facts.var_drop_used,
var_drop_used: drop_used,
path_accessed_at: &mut facts.path_accessed_at,
location_table,
move_data,
}
.visit_body(body);

facts.var_drop_used.extend(drop_used.iter().map(|&(local, location)| {
(local, location_table.mid_index(location))
}));
}

for (local, local_decl) in body.local_decls.iter_enumerated() {
37 changes: 35 additions & 2 deletions src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ use rustc::traits::query::type_op::outlives::DropckOutlives;
use rustc::traits::query::type_op::TypeOp;
use rustc::ty::{Ty, TypeFoldable};
use rustc_index::bit_set::HybridBitSet;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use std::rc::Rc;

/// This is the heart of the liveness computation. For each variable X
@@ -37,6 +37,7 @@ pub(super) fn trace(
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
move_data: &MoveData<'tcx>,
live_locals: Vec<Local>,
polonius_drop_used: Option<Vec<(Local, Location)>>,
) {
debug!("trace()");

@@ -52,7 +53,13 @@ pub(super) fn trace(
drop_data: FxHashMap::default(),
};

LivenessResults::new(cx).compute_for_all_locals(live_locals);
let mut results = LivenessResults::new(cx);

if let Some(drop_used) = polonius_drop_used {
results.add_extra_drop_facts(drop_used, live_locals.iter().copied().collect())
}

results.compute_for_all_locals(live_locals);
}

/// Contextual state for the type-liveness generator.
@@ -145,6 +152,32 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
}
}

/// Add extra drop facts needed for Polonius.
///
/// Add facts for all locals with free regions, since regions may outlive
/// the function body only at certain nodes in the CFG.
fn add_extra_drop_facts(
&mut self,
drop_used: Vec<(Local, Location)>,
live_locals: FxHashSet<Local>,
) {
let locations = HybridBitSet::new_empty(self.cx.elements.num_points());

for (local, location) in drop_used {
if !live_locals.contains(&local) {
let local_ty = self.cx.body.local_decls[local].ty;
if local_ty.has_free_regions() {
self.cx.add_drop_live_facts_for(
local,
local_ty,
&[location],
&locations,
);
}
}
}
}

/// Clear the value of fields that are "per local variable".
fn reset_local_state(&mut self) {
self.defs.clear();
64 changes: 41 additions & 23 deletions src/librustc_mir/borrow_check/nll/type_check/mod.rs
Original file line number Diff line number Diff line change
@@ -276,7 +276,17 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {

fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
self.super_constant(constant, location);
self.sanitize_type(constant, constant.literal.ty);
let ty = self.sanitize_type(constant, constant.literal.ty);

self.cx.infcx.tcx.for_each_free_region(&ty, |live_region| {
let live_region_vid =
self.cx.borrowck_context.universal_regions.to_region_vid(live_region);
self.cx
.borrowck_context
.constraints
.liveness_constraints
.add_element(live_region_vid, location);
});

if let Some(annotation_index) = constant.user_ty {
if let Err(terr) = self.cx.relate_type_and_user_type(
@@ -528,56 +538,64 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {

let parent_body = mem::replace(&mut self.body, promoted_body);

// Use new sets of constraints and closure bounds so that we can
// modify their locations.
let all_facts = &mut None;
let mut constraints = Default::default();
let mut closure_bounds = Default::default();
let mut liveness_constraints = LivenessValues::new(
Rc::new(RegionValueElements::new(promoted_body)),
);
// Don't try to add borrow_region facts for the promoted MIR
mem::swap(self.cx.borrowck_context.all_facts, all_facts);

// Use a new sets of constraints and closure bounds so that we can
// modify their locations.
mem::swap(
&mut self.cx.borrowck_context.constraints.outlives_constraints,
&mut constraints
);
mem::swap(
&mut self.cx.borrowck_context.constraints.closure_bounds_mapping,
&mut closure_bounds
);
let mut swap_constraints = |this: &mut Self| {
mem::swap(this.cx.borrowck_context.all_facts, all_facts);
mem::swap(
&mut this.cx.borrowck_context.constraints.outlives_constraints,
&mut constraints
);
mem::swap(
&mut this.cx.borrowck_context.constraints.closure_bounds_mapping,
&mut closure_bounds
);
mem::swap(
&mut this.cx.borrowck_context.constraints.liveness_constraints,
&mut liveness_constraints
);
};

swap_constraints(self);

self.visit_body(promoted_body);


if !self.errors_reported {
// if verifier failed, don't do further checks to avoid ICEs
self.cx.typeck_mir(promoted_body);
}

self.body = parent_body;
// Merge the outlives constraints back in, at the given location.
mem::swap(self.cx.borrowck_context.all_facts, all_facts);
mem::swap(
&mut self.cx.borrowck_context.constraints.outlives_constraints,
&mut constraints
);
mem::swap(
&mut self.cx.borrowck_context.constraints.closure_bounds_mapping,
&mut closure_bounds
);
swap_constraints(self);

let locations = location.to_locations();
for constraint in constraints.outlives().iter() {
let mut constraint = *constraint;
constraint.locations = locations;
if let ConstraintCategory::Return
| ConstraintCategory::UseAsConst
| ConstraintCategory::UseAsStatic = constraint.category
| ConstraintCategory::UseAsConst
| ConstraintCategory::UseAsStatic = constraint.category
{
// "Returning" from a promoted is an assigment to a
// temporary from the user's point of view.
constraint.category = ConstraintCategory::Boring;
}
self.cx.borrowck_context.constraints.outlives_constraints.push(constraint)
}
for live_region in liveness_constraints.rows() {
self.cx.borrowck_context.constraints.liveness_constraints
.add_element(live_region, location);
}

if !closure_bounds.is_empty() {
let combined_bounds_mapping = closure_bounds
134 changes: 131 additions & 3 deletions src/librustc_typeck/check/closure.rs
Original file line number Diff line number Diff line change
@@ -337,7 +337,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> ClosureSignatures<'tcx> {
debug!("sig_of_closure_no_expectation()");

let bound_sig = self.supplied_sig_of_closure(expr_def_id, decl);
let bound_sig = self.supplied_sig_of_closure(expr_def_id, decl, body);

self.closure_sigs(expr_def_id, body, bound_sig)
}
@@ -490,7 +490,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
//
// (See comment on `sig_of_closure_with_expectation` for the
// meaning of these letters.)
let supplied_sig = self.supplied_sig_of_closure(expr_def_id, decl);
let supplied_sig = self.supplied_sig_of_closure(expr_def_id, decl, body);

debug!(
"check_supplied_sig_against_expectation: supplied_sig={:?}",
@@ -591,14 +591,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
expr_def_id: DefId,
decl: &hir::FnDecl,
body: &hir::Body,
) -> ty::PolyFnSig<'tcx> {
let astconv: &dyn AstConv<'_> = self;

debug!(
"supplied_sig_of_closure(decl={:?}, body.generator_kind={:?})",
decl,
body.generator_kind,
);

// First, convert the types that the user supplied (if any).
let supplied_arguments = decl.inputs.iter().map(|a| astconv.ast_ty_to_ty(a));
let supplied_return = match decl.output {
hir::Return(ref output) => astconv.ast_ty_to_ty(&output),
hir::DefaultReturn(_) => astconv.ty_infer(None, decl.output.span()),
hir::DefaultReturn(_) => match body.generator_kind {
// In the case of the async block that we create for a function body,
// we expect the return type of the block to match that of the enclosing
// function.
Some(hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn)) => {
debug!("supplied_sig_of_closure: closure is async fn body");
self.deduce_future_output_from_obligations(expr_def_id)
}

_ => astconv.ty_infer(None, decl.output.span()),
}
};

let result = ty::Binder::bind(self.tcx.mk_fn_sig(
@@ -620,6 +637,117 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
result
}

/// Invoked when we are translating the generator that results
/// from desugaring an `async fn`. Returns the "sugared" return
/// type of the `async fn` -- that is, the return type that the
/// user specified. The "desugared" return type is a `impl
/// Future<Output = T>`, so we do this by searching through the
/// obligations to extract the `T`.
fn deduce_future_output_from_obligations(
&self,
expr_def_id: DefId,
) -> Ty<'tcx> {
debug!("deduce_future_output_from_obligations(expr_def_id={:?})", expr_def_id);

let ret_coercion =
self.ret_coercion
.as_ref()
.unwrap_or_else(|| span_bug!(
self.tcx.def_span(expr_def_id),
"async fn generator outside of a fn"
));

// In practice, the return type of the surrounding function is
// always a (not yet resolved) inference variable, because it
// is the hidden type for an `impl Trait` that we are going to
// be inferring.
let ret_ty = ret_coercion.borrow().expected_ty();
let ret_ty = self.inh.infcx.shallow_resolve(ret_ty);
let ret_vid = match ret_ty.kind {
ty::Infer(ty::TyVar(ret_vid)) => ret_vid,
_ => {
span_bug!(
self.tcx.def_span(expr_def_id),
"async fn generator return type not an inference variable"
)
}
};

// Search for a pending obligation like
//
// `<R as Future>::Output = T`
//
// where R is the return type we are expecting. This type `T`
// will be our output.
let output_ty = self.obligations_for_self_ty(ret_vid)
.find_map(|(_, obligation)| {
if let ty::Predicate::Projection(ref proj_predicate) = obligation.predicate {
self.deduce_future_output_from_projection(
obligation.cause.span,
proj_predicate
)
} else {
None
}
})
.unwrap();

debug!("deduce_future_output_from_obligations: output_ty={:?}", output_ty);
output_ty
}

/// Given a projection like
///
/// `<X as Future>::Output = T`
///
/// where `X` is some type that has no late-bound regions, returns
/// `Some(T)`. If the projection is for some other trait, returns
/// `None`.
fn deduce_future_output_from_projection(
&self,
cause_span: Span,
predicate: &ty::PolyProjectionPredicate<'tcx>,
) -> Option<Ty<'tcx>> {
debug!("deduce_future_output_from_projection(predicate={:?})", predicate);

// We do not expect any bound regions in our predicate, so
// skip past the bound vars.
let predicate = match predicate.no_bound_vars() {
Some(p) => p,
None => {
debug!("deduce_future_output_from_projection: has late-bound regions");
return None;
}
};

// Check that this is a projection from the `Future` trait.
let trait_ref = predicate.projection_ty.trait_ref(self.tcx);
let future_trait = self.tcx.lang_items().future_trait().unwrap();
if trait_ref.def_id != future_trait {
debug!("deduce_future_output_from_projection: not a future");
return None;
}

// The `Future` trait has only one associted item, `Output`,
// so check that this is what we see.
let output_assoc_item = self.tcx.associated_items(future_trait).nth(0).unwrap().def_id;
if output_assoc_item != predicate.projection_ty.item_def_id {
span_bug!(
cause_span,
"projecting associated item `{:?}` from future, which is not Output `{:?}`",
predicate.projection_ty.item_def_id,
output_assoc_item,
);
}

// Extract the type from the projection. Note that there can
// be no bound variables in this type because the "self type"
// does not have any regions in it.
let output_ty = self.resolve_vars_if_possible(&predicate.ty);
debug!("deduce_future_output_from_projection: output_ty={:?}", output_ty);
Some(output_ty)
}

/// Converts the types that the user supplied, in case that doing
/// so should yield an error, but returns back a signature where
/// all parameters are of type `TyErr`.
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/generator_interior.rs
Original file line number Diff line number Diff line change
@@ -55,7 +55,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
expr_and_pat_count: 0,
source: match self.kind { // Guess based on the kind of the current generator.
hir::GeneratorKind::Gen => hir::YieldSource::Yield,
hir::GeneratorKind::Async => hir::YieldSource::Await,
hir::GeneratorKind::Async(_) => hir::YieldSource::Await,
},
}));

14 changes: 13 additions & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
@@ -562,7 +562,19 @@ pub struct FnCtxt<'a, 'tcx> {
// if type checking is run in parallel.
err_count_on_creation: usize,

/// If `Some`, this stores coercion information for returned
/// expressions. If `None`, this is in a context where return is
/// inappropriate, such as a const expression.
///
/// This is a `RefCell<DynamicCoerceMany>`, which means that we
/// can track all the return expressions and then use them to
/// compute a useful coercion from the set, similar to a match
/// expression or other branching context. You can use methods
/// like `expected_ty` to access the declared return type (if
/// any).
ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,

/// First span of a return site that we find. Used in error messages.
ret_coercion_span: RefCell<Option<Span>>,

yield_ty: Option<Ty<'tcx>>,
@@ -4534,7 +4546,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let item_id = self.tcx().hir().get_parent_node(self.body_id);
if let Some(body_id) = self.tcx().hir().maybe_body_owned_by(item_id) {
let body = self.tcx().hir().body(body_id);
if let Some(hir::GeneratorKind::Async) = body.generator_kind {
if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
let sp = expr.span;
// Check for `Future` implementations by constructing a predicate to
// prove: `<T as Future>::Output == U`
12 changes: 12 additions & 0 deletions src/librustc_typeck/check/wfcheck.rs
Original file line number Diff line number Diff line change
@@ -172,6 +172,18 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: DefId) {
_ => None
};
check_associated_item(tcx, trait_item.hir_id, trait_item.span, method_sig);

// Prohibits applying `#[track_caller]` to trait methods
for attr in &trait_item.attrs {
if attr.check_name(sym::track_caller) {
struct_span_err!(
tcx.sess,
attr.span,
E0738,
"`#[track_caller]` is not supported for trait items yet."
).emit();
}
}
}

pub fn check_impl_item(tcx: TyCtxt<'_>, def_id: DefId) {
10 changes: 10 additions & 0 deletions src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
@@ -2596,6 +2596,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
} else if attr.check_name(sym::thread_local) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
} else if attr.check_name(sym::track_caller) {
if tcx.fn_sig(id).abi() != abi::Abi::Rust {
struct_span_err!(
tcx.sess,
attr.span,
E0737,
"rust ABI is required to use `#[track_caller]`"
).emit();
}
codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
} else if attr.check_name(sym::export_name) {
if let Some(s) = attr.value_str() {
if s.as_str().contains("\0") {
15 changes: 15 additions & 0 deletions src/librustc_typeck/error_codes.rs
Original file line number Diff line number Diff line change
@@ -4907,6 +4907,21 @@ fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> {
The `Box<...>` ensures that the result is of known size,
and the pin is required to keep it in the same place in memory.
"##,

E0737: r##"
#[track_caller] requires functions to have the "Rust" ABI for passing caller
location. See [RFC 2091] for details on this and other restrictions.
[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
"##,

E0738: r##"
#[track_caller] cannot be applied to trait methods. See [RFC 2091]
for details on this and other restrictions.
[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
"##,

;
// E0035, merged into E0087/E0089
// E0036, merged into E0087/E0089
9 changes: 7 additions & 2 deletions src/librustc_typeck/outlives/utils.rs
Original file line number Diff line number Diff line change
@@ -161,9 +161,14 @@ fn is_free_region(tcx: TyCtxt<'_>, region: Region<'_>) -> bool {
// ignore it. We can't put it on the struct header anyway.
RegionKind::ReLateBound(..) => false,

// This can appear in `where Self: ` bounds (#64855):
//
// struct Bar<T>(<Self as Foo>::Type) where Self: ;
// struct Baz<'a>(&'a Self) where Self: ;
RegionKind::ReEmpty => false,

// These regions don't appear in types from type declarations:
RegionKind::ReEmpty
| RegionKind::ReErased
RegionKind::ReErased
| RegionKind::ReClosureBound(..)
| RegionKind::ReScope(..)
| RegionKind::ReVar(..)
6 changes: 6 additions & 0 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
@@ -953,6 +953,12 @@ impl<'a> ExtCtxt<'a> {
span.with_call_site_ctxt(self.current_expansion.id)
}

/// Equivalent of `Span::mixed_site` from the proc macro API,
/// except that the location is taken from the span passed as an argument.
pub fn with_mixed_site_ctxt(&self, span: Span) -> Span {
span.with_mixed_site_ctxt(self.current_expansion.id)
}

/// Returns span for the macro which originally caused the current expansion to happen.
///
/// Stops backtracing at include! boundary.
5 changes: 5 additions & 0 deletions src/libsyntax/ext/proc_macro_server.rs
Original file line number Diff line number Diff line change
@@ -355,6 +355,7 @@ pub(crate) struct Rustc<'a> {
sess: &'a ParseSess,
def_site: Span,
call_site: Span,
mixed_site: Span,
}

impl<'a> Rustc<'a> {
@@ -364,6 +365,7 @@ impl<'a> Rustc<'a> {
sess: cx.parse_sess,
def_site: cx.with_def_site_ctxt(expn_data.def_site),
call_site: cx.with_call_site_ctxt(expn_data.call_site),
mixed_site: cx.with_mixed_site_ctxt(expn_data.call_site),
}
}

@@ -664,6 +666,9 @@ impl server::Span for Rustc<'_> {
fn call_site(&mut self) -> Self::Span {
self.call_site
}
fn mixed_site(&mut self) -> Self::Span {
self.mixed_site
}
fn source_file(&mut self, span: Self::Span) -> Self::SourceFile {
self.sess.source_map().lookup_char_pos(span.lo()).file
}
4 changes: 4 additions & 0 deletions src/libsyntax/feature_gate/active.rs
Original file line number Diff line number Diff line change
@@ -519,6 +519,9 @@ declare_features! (
/// Allows the use of or-patterns (e.g., `0 | 1`).
(active, or_patterns, "1.38.0", Some(54883), None),

/// Enable accurate caller location reporting during panic (RFC 2091).
(active, track_caller, "1.40.0", Some(47809), None),

// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
@@ -533,4 +536,5 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
sym::const_generics,
sym::or_patterns,
sym::let_chains,
sym::track_caller,
];
1 change: 1 addition & 0 deletions src/libsyntax/feature_gate/builtin_attrs.rs
Original file line number Diff line number Diff line change
@@ -307,6 +307,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
),

gated!(ffi_returns_twice, Whitelisted, template!(Word), experimental!(ffi_returns_twice)),
gated!(track_caller, Whitelisted, template!(Word), experimental!(track_caller)),

// ==========================================================================
// Internal attributes: Stability, deprecation, and unsafe:
6 changes: 6 additions & 0 deletions src/libsyntax_pos/lib.rs
Original file line number Diff line number Diff line change
@@ -526,6 +526,12 @@ impl Span {
self.with_ctxt_from_mark(expn_id, Transparency::Transparent)
}

/// Equivalent of `Span::mixed_site` from the proc macro API,
/// except that the location is taken from the `self` span.
pub fn with_mixed_site_ctxt(&self, expn_id: ExpnId) -> Span {
self.with_ctxt_from_mark(expn_id, Transparency::SemiTransparent)
}

/// Produces a span with the same location as `self` and context produced by a macro with the
/// given ID and transparency, assuming that macro was defined directly and not produced by
/// some other macro (which is the case for built-in and procedural macros).
1 change: 1 addition & 0 deletions src/libsyntax_pos/symbol.rs
Original file line number Diff line number Diff line change
@@ -671,6 +671,7 @@ symbols! {
tool_attributes,
tool_lints,
trace_macros,
track_caller,
trait_alias,
transmute,
transparent,
5 changes: 5 additions & 0 deletions src/test/ui/associated-types/issue-64855-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// check-pass

pub struct Bar<'a>(&'a Self) where Self: ;

fn main() {}
8 changes: 8 additions & 0 deletions src/test/ui/associated-types/issue-64855.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pub trait Foo {
type Type;
}

pub struct Bar<T>(<Self as Foo>::Type) where Self: ;
//~^ ERROR the trait bound `Bar<T>: Foo` is not satisfied

fn main() {}
9 changes: 9 additions & 0 deletions src/test/ui/associated-types/issue-64855.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0277]: the trait bound `Bar<T>: Foo` is not satisfied
--> $DIR/issue-64855.rs:5:19
|
LL | pub struct Bar<T>(<Self as Foo>::Type) where Self: ;
| ^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bar<T>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ fn return_targets_async_block_not_fn() -> u8 {
}

async fn return_targets_async_block_not_async_fn() -> u8 {
//~^ ERROR type mismatch resolving
//~^ ERROR mismatched types
let block = async {
return 0u8;
};
Original file line number Diff line number Diff line change
@@ -39,6 +39,22 @@ LL | let _: &dyn Future<Output = ()> = &block;
found type `()`
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`

error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:22:58
|
LL | async fn return_targets_async_block_not_async_fn() -> u8 {
| __________________________________________________________^
LL | |
LL | | let block = async {
LL | | return 0u8;
... |
LL | |
LL | | }
| |_^ expected u8, found ()
|
= note: expected type `u8`
found type `()`

error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
--> $DIR/async-block-control-flow-static-semantics.rs:27:39
|
@@ -49,16 +65,6 @@ LL | let _: &dyn Future<Output = ()> = &block;
found type `()`
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`

error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == u8`
--> $DIR/async-block-control-flow-static-semantics.rs:22:55
|
LL | async fn return_targets_async_block_not_async_fn() -> u8 {
| ^^ expected (), found u8
|
= note: expected type `()`
found type `u8`
= note: the return type of a function must have a statically known size

error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:48:44
|

This file was deleted.

2 changes: 1 addition & 1 deletion src/test/ui/async-await/async-error-span.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ fn get_future() -> impl Future<Output = ()> {
}

async fn foo() {
let a; //~ ERROR type inside `async` object must be known in this context
let a; //~ ERROR type inside `async fn` body must be known in this context
get_future().await;
}

4 changes: 2 additions & 2 deletions src/test/ui/async-await/async-error-span.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error[E0698]: type inside `async` object must be known in this context
error[E0698]: type inside `async fn` body must be known in this context
--> $DIR/async-error-span.rs:12:9
|
LL | let a;
| ^ cannot infer type
|
note: the type is part of the `async` object because of this `await`
note: the type is part of the `async fn` body because of this `await`
--> $DIR/async-error-span.rs:13:5
|
LL | get_future().await;
4 changes: 2 additions & 2 deletions src/test/ui/async-await/issues/issue-63388-1.rs
Original file line number Diff line number Diff line change
@@ -9,9 +9,9 @@ trait Foo {}
impl Xyz {
async fn do_sth<'a>(
&'a self, foo: &dyn Foo
) -> &dyn Foo //~ ERROR lifetime mismatch
) -> &dyn Foo
{
foo
foo //~ ERROR lifetime mismatch
}
}

9 changes: 5 additions & 4 deletions src/test/ui/async-await/issues/issue-63388-1.stderr
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
error[E0623]: lifetime mismatch
--> $DIR/issue-63388-1.rs:12:10
--> $DIR/issue-63388-1.rs:14:9
|
LL | &'a self, foo: &dyn Foo
| -------- this parameter and the return type are declared with different lifetimes...
LL | ) -> &dyn Foo
| ^^^^^^^^
| |
| ...but data from `foo` is returned here
| --------
LL | {
LL | foo
| ^^^ ...but data from `foo` is returned here

error: aborting due to previous error

9 changes: 5 additions & 4 deletions src/test/ui/async-await/issues/issue-63388-2.stderr
Original file line number Diff line number Diff line change
@@ -11,8 +11,9 @@ error: cannot infer an appropriate lifetime
|
LL | foo: &dyn Foo, bar: &'a dyn Foo
| ^^^ ...but this borrow...
LL | ) -> &dyn Foo
| -------- this return type evaluates to the `'static` lifetime...
...
LL | foo
| --- this return type evaluates to the `'static` lifetime...
|
note: ...can't outlive the lifetime '_ as defined on the method body at 11:14
--> $DIR/issue-63388-2.rs:11:14
@@ -21,8 +22,8 @@ LL | foo: &dyn Foo, bar: &'a dyn Foo
| ^
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 11:14
|
LL | ) -> &dyn Foo + '_
| ^^^^^^^^^^^^^
LL | foo + '_
|

error: aborting due to 2 previous errors

25 changes: 25 additions & 0 deletions src/test/ui/async-await/return-ty-raw-ptr-coercion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Check that we apply unsizing coercions based on the return type.
//
// Also serves as a regression test for #60424.
//
// edition:2018
// check-pass

#![allow(warnings)]

use std::fmt::Debug;

const TMP: u32 = 22;

// Coerce from `&u32` to `*const u32`
fn raw_pointer_coercion() {
fn sync_example() -> *const u32 {
&TMP
}

async fn async_example() -> *const u32 {
&TMP
}
}

fn main() {}
45 changes: 45 additions & 0 deletions src/test/ui/async-await/return-ty-unsize-coercion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Check that we apply unsizing coercions based on the return type.
//
// Also serves as a regression test for #60424.
//
// edition:2018
// check-pass

#![allow(warnings)]

use std::fmt::Debug;

// Unsizing coercion from `Box<&'static str>` to `Box<dyn Debug>`.
fn unsize_trait_coercion() {
fn sync_example() -> Box<dyn Debug> {
Box::new("asdf")
}

async fn async_example() -> Box<dyn Debug> {
Box::new("asdf")
}
}

// Unsizing coercion from `Box<[u32; N]>` to `Box<[32]>`.
fn unsize_slice_coercion() {
fn sync_example() -> Box<[u32]> {
Box::new([0])
}

async fn async_example() -> Box<[u32]> {
Box::new([0])
}
}

// Unsizing coercion from `&[&str; 1]` to `&[&str]`
fn unsize_slice_str_coercion() {
fn sync_example() -> &'static [&'static str] {
&["hi"]
}

async fn async_example() -> &'static [&'static str] {
&["hi"]
}
}

fn main() {}
4 changes: 2 additions & 2 deletions src/test/ui/async-await/unresolved_type_param.rs
Original file line number Diff line number Diff line change
@@ -7,9 +7,9 @@ async fn bar<T>() -> () {}

async fn foo() {
bar().await;
//~^ ERROR type inside `async` object must be known in this context
//~^ ERROR type inside `async fn` body must be known in this context
//~| NOTE cannot infer type for `T`
//~| NOTE the type is part of the `async` object because of this `await`
//~| NOTE the type is part of the `async fn` body because of this `await`
//~| NOTE in this expansion of desugaring of `await`
}
fn main() {}
4 changes: 2 additions & 2 deletions src/test/ui/async-await/unresolved_type_param.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error[E0698]: type inside `async` object must be known in this context
error[E0698]: type inside `async fn` body must be known in this context
--> $DIR/unresolved_type_param.rs:9:5
|
LL | bar().await;
| ^^^ cannot infer type for `T`
|
note: the type is part of the `async` object because of this `await`
note: the type is part of the `async fn` body because of this `await`
--> $DIR/unresolved_type_param.rs:9:5
|
LL | bar().await;

This file was deleted.

This file was deleted.

This file was deleted.

148 changes: 0 additions & 148 deletions src/test/ui/borrowck/two-phase-surprise-no-conflict.polonius.stderr

This file was deleted.

29 changes: 0 additions & 29 deletions src/test/ui/consts/promote_const_let.polonius.stderr

This file was deleted.

78 changes: 0 additions & 78 deletions src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr

This file was deleted.

5 changes: 5 additions & 0 deletions src/test/ui/feature-gates/feature-gate-track_caller.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#[track_caller]
fn f() {}
//~^^ ERROR the `#[track_caller]` attribute is an experimental feature

fn main() {}
12 changes: 12 additions & 0 deletions src/test/ui/feature-gates/feature-gate-track_caller.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0658]: the `#[track_caller]` attribute is an experimental feature
--> $DIR/feature-gate-track_caller.rs:1:1
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/47809
= help: add `#![feature(track_caller)]` to the crate attributes to enable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0658`.

This file was deleted.

8 changes: 8 additions & 0 deletions src/test/ui/hrtb/due-to-where-clause.nll.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: higher-ranked subtype error
--> $DIR/due-to-where-clause.rs:2:5
|
LL | test::<FooS>(&mut 42);
| ^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

3 changes: 0 additions & 3 deletions src/test/ui/hrtb/due-to-where-clause.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// ignore-compare-mode-nll
// ^ This code works in nll mode.

fn main() {
test::<FooS>(&mut 42); //~ ERROR implementation of `Foo` is not general enough
}
2 changes: 1 addition & 1 deletion src/test/ui/hrtb/due-to-where-clause.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: implementation of `Foo` is not general enough
--> $DIR/due-to-where-clause.rs:5:5
--> $DIR/due-to-where-clause.rs:2:5
|
LL | test::<FooS>(&mut 42);
| ^^^^^^^^^^^^ implementation of `Foo` is not general enough
5 changes: 4 additions & 1 deletion src/test/ui/nll/get_default.polonius.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
--> $DIR/get_default.rs:32:17
|
LL | fn err(map: &mut Map) -> &String {
| - let's call the lifetime of this reference `'1`
LL | loop {
LL | match map.get() {
| --- immutable borrow occurs here
LL | Some(v) => {
LL | map.set(String::new()); // Both AST and MIR error here
| ^^^ mutable borrow occurs here
LL |
LL | return v;
| - immutable borrow later used here
| - returning this value requires that `*map` is borrowed for `'1`

error: aborting due to previous error

15 changes: 0 additions & 15 deletions src/test/ui/nll/loan_ends_mid_block_pair.polonius.stderr

This file was deleted.

4 changes: 3 additions & 1 deletion src/test/ui/nll/polonius/polonius-smoke-test.stderr
Original file line number Diff line number Diff line change
@@ -17,12 +17,14 @@ LL | let w = y;
error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/polonius-smoke-test.rs:19:13
|
LL | pub fn use_while_mut_fr(x: &mut i32) -> &mut i32 {
| - let's call the lifetime of this reference `'1`
LL | let y = &mut *x;
| ------- borrow of `*x` occurs here
LL | let z = x;
| ^ move out of `x` occurs here
LL | y
| - borrow later used here
| - returning this value requires that `*x` is borrowed for `'1`

error[E0505]: cannot move out of `s` because it is borrowed
--> $DIR/polonius-smoke-test.rs:43:5
8 changes: 8 additions & 0 deletions src/test/ui/nll/promoted-liveness.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Test that promoted that have larger mir bodies than their containing function
// don't cause an ICE.

// check-pass

fn main() {
&["0", "1", "2", "3", "4", "5", "6", "7"];
}
15 changes: 0 additions & 15 deletions src/test/ui/nll/return-ref-mut-issue-46557.polonius.stderr

This file was deleted.

42 changes: 42 additions & 0 deletions src/test/ui/proc-macro/auxiliary/mixed-site-span.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// force-host
// no-prefer-dynamic

#![feature(proc_macro_hygiene)]
#![feature(proc_macro_mixed_site)]
#![feature(proc_macro_quote)]

#![crate_type = "proc-macro"]

extern crate proc_macro;
use proc_macro::*;

#[proc_macro]
pub fn proc_macro_rules(input: TokenStream) -> TokenStream {
if input.is_empty() {
let id = |s| TokenTree::from(Ident::new(s, Span::mixed_site()));
let item_def = id("ItemDef");
let local_def = id("local_def");
let item_use = id("ItemUse");
let local_use = id("local_use");
let mut single_quote = Punct::new('\'', Spacing::Joint);
single_quote.set_span(Span::mixed_site());
let label_use: TokenStream = [
TokenTree::from(single_quote),
id("label_use"),
].iter().cloned().collect();
quote!(
struct $item_def;
let $local_def = 0;

$item_use; // OK
$local_use; // ERROR
break $label_use; // ERROR
)
} else {
let mut dollar_crate = input.into_iter().next().unwrap();
dollar_crate.set_span(Span::mixed_site());
quote!(
type A = $dollar_crate::ItemUse;
)
}
}
22 changes: 11 additions & 11 deletions src/test/ui/proc-macro/dollar-crate-issue-62325.stdout
Original file line number Diff line number Diff line change
@@ -59,54 +59,54 @@ PRINT-ATTR RE-COLLECTED (DISPLAY): struct B (identity ! ($crate :: S)) ;
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
span: #8 bytes(LO..HI),
span: #10 bytes(LO..HI),
},
Ident {
ident: "B",
span: #8 bytes(LO..HI),
span: #10 bytes(LO..HI),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "identity",
span: #8 bytes(LO..HI),
span: #10 bytes(LO..HI),
},
Punct {
ch: '!',
spacing: Alone,
span: #8 bytes(LO..HI),
span: #10 bytes(LO..HI),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "$crate",
span: #8 bytes(LO..HI),
span: #10 bytes(LO..HI),
},
Punct {
ch: ':',
spacing: Joint,
span: #8 bytes(LO..HI),
span: #10 bytes(LO..HI),
},
Punct {
ch: ':',
spacing: Alone,
span: #8 bytes(LO..HI),
span: #10 bytes(LO..HI),
},
Ident {
ident: "S",
span: #8 bytes(LO..HI),
span: #10 bytes(LO..HI),
},
],
span: #8 bytes(LO..HI),
span: #10 bytes(LO..HI),
},
],
span: #8 bytes(LO..HI),
span: #10 bytes(LO..HI),
},
Punct {
ch: ';',
spacing: Alone,
span: #8 bytes(LO..HI),
span: #10 bytes(LO..HI),
},
]
48 changes: 24 additions & 24 deletions src/test/ui/proc-macro/dollar-crate.stdout
Original file line number Diff line number Diff line change
@@ -124,121 +124,121 @@ PRINT-BANG INPUT (DISPLAY): struct M ($crate :: S) ;
PRINT-BANG INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Ident {
ident: "M",
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "$crate",
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Punct {
ch: ':',
spacing: Joint,
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Punct {
ch: ':',
spacing: Alone,
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Ident {
ident: "S",
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
],
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Punct {
ch: ';',
spacing: Alone,
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
]
PRINT-ATTR INPUT (DISPLAY): struct A(::dollar_crate_external::S);
PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ($crate :: S) ;
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Ident {
ident: "A",
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "$crate",
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Punct {
ch: ':',
spacing: Joint,
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Punct {
ch: ':',
spacing: Alone,
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Ident {
ident: "S",
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
],
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Punct {
ch: ';',
spacing: Alone,
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
]
PRINT-DERIVE INPUT (DISPLAY): struct D(::dollar_crate_external::S);
PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ($crate :: S) ;
PRINT-DERIVE INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Ident {
ident: "D",
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "$crate",
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Punct {
ch: ':',
spacing: Joint,
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Punct {
ch: ':',
spacing: Alone,
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Ident {
ident: "S",
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
],
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
Punct {
ch: ';',
spacing: Alone,
span: #10 bytes(LO..HI),
span: #13 bytes(LO..HI),
},
]
26 changes: 26 additions & 0 deletions src/test/ui/proc-macro/mixed-site-span.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Proc macros using `mixed_site` spans exhibit usual properties of `macro_rules` hygiene.

// aux-build:mixed-site-span.rs

#![feature(proc_macro_hygiene)]

#[macro_use]
extern crate mixed_site_span;

struct ItemUse;

fn main() {
'label_use: loop {
let local_use = 1;
proc_macro_rules!();
//~^ ERROR use of undeclared label `'label_use`
//~| ERROR cannot find value `local_use` in this scope
ItemDef; // OK
local_def; //~ ERROR cannot find value `local_def` in this scope
}
}

macro_rules! pass_dollar_crate {
() => (proc_macro_rules!($crate);) //~ ERROR cannot find type `ItemUse` in crate `$crate`
}
pass_dollar_crate!();
49 changes: 49 additions & 0 deletions src/test/ui/proc-macro/mixed-site-span.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
error[E0426]: use of undeclared label `'label_use`
--> $DIR/mixed-site-span.rs:15:9
|
LL | proc_macro_rules!();
| ^^^^^^^^^^^^^^^^^^^^
| |
| undeclared label `'label_use`
| in this macro invocation

error[E0425]: cannot find value `local_use` in this scope
--> $DIR/mixed-site-span.rs:15:9
|
LL | proc_macro_rules!();
| ^^^^^^^^^^^^^^^^^^^^
| |
| not found in this scope
| in this macro invocation

error[E0425]: cannot find value `local_def` in this scope
--> $DIR/mixed-site-span.rs:19:9
|
LL | local_def;
| ^^^^^^^^^ not found in this scope

error[E0412]: cannot find type `ItemUse` in crate `$crate`
--> $DIR/auxiliary/mixed-site-span.rs:14:1
|
LL | / pub fn proc_macro_rules(input: TokenStream) -> TokenStream {
LL | | if input.is_empty() {
LL | | let id = |s| TokenTree::from(Ident::new(s, Span::mixed_site()));
LL | | let item_def = id("ItemDef");
... |
LL | | }
LL | | }
| |_^ not found in `$crate`
|
::: $DIR/mixed-site-span.rs:26:1
|
LL | pass_dollar_crate!();
| --------------------- in this macro invocation
help: possible candidate is found in another module, you can import it into scope
|
LL | use ItemUse;
|

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0412, E0425, E0426.
For more information about an error, try `rustc --explain E0412`.
7 changes: 7 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-odd-syntax.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete

#[track_caller(1)]
fn f() {}
//~^^ ERROR malformed `track_caller` attribute input

fn main() {}
16 changes: 16 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-odd-syntax.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error: malformed `track_caller` attribute input
--> $DIR/error-odd-syntax.rs:3:1
|
LL | #[track_caller(1)]
| ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[track_caller]`

warning: the feature `track_caller` is incomplete and may cause the compiler to crash
--> $DIR/error-odd-syntax.rs:1:12
|
LL | #![feature(track_caller)]
| ^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error: aborting due to previous error

7 changes: 7 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete

#[track_caller]
extern "C" fn f() {}
//~^^ ERROR rust ABI is required to use `#[track_caller]`

fn main() {}
17 changes: 17 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
--> $DIR/error-with-invalid-abi.rs:1:12
|
LL | #![feature(track_caller)]
| ^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error[E0737]: rust ABI is required to use `#[track_caller]`
--> $DIR/error-with-invalid-abi.rs:3:1
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0737`.
8 changes: 8 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-with-naked.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#![feature(naked_functions, track_caller)] //~ WARN the feature `track_caller` is incomplete

#[track_caller]
#[naked]
fn f() {}
//~^^^ ERROR cannot use `#[track_caller]` with `#[naked]`

fn main() {}
17 changes: 17 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-with-naked.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
--> $DIR/error-with-naked.rs:1:29
|
LL | #![feature(naked_functions, track_caller)]
| ^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error[E0736]: cannot use `#[track_caller]` with `#[naked]`
--> $DIR/error-with-naked.rs:3:1
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0736`.
13 changes: 13 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-with-trait-fns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete

trait Trait {
#[track_caller]
fn unwrap(&self);
//~^^ ERROR: `#[track_caller]` is not supported for trait items yet.
}

impl Trait for u64 {
fn unwrap(&self) {}
}

fn main() {}
17 changes: 17 additions & 0 deletions src/test/ui/rfc-2091-track-caller/error-with-trait-fns.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
--> $DIR/error-with-trait-fns.rs:1:12
|
LL | #![feature(track_caller)]
| ^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error[E0738]: `#[track_caller]` is not supported for trait items yet.
--> $DIR/error-with-trait-fns.rs:4:5
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0738`.
7 changes: 7 additions & 0 deletions src/test/ui/rfc-2091-track-caller/only-for-fns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete

#[track_caller]
struct S;
//~^^ ERROR attribute should be applied to function

fn main() {}
18 changes: 18 additions & 0 deletions src/test/ui/rfc-2091-track-caller/only-for-fns.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
--> $DIR/only-for-fns.rs:1:12
|
LL | #![feature(track_caller)]
| ^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error[E0735]: attribute should be applied to function
--> $DIR/only-for-fns.rs:3:1
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^
LL | struct S;
| --------- not a function

error: aborting due to previous error

9 changes: 9 additions & 0 deletions src/test/ui/rfc-2091-track-caller/pass.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// run-pass
#![feature(track_caller)] //~ WARN the feature `track_caller` is incomplete

#[track_caller]
fn f() {}

fn main() {
f();
}
8 changes: 8 additions & 0 deletions src/test/ui/rfc-2091-track-caller/pass.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
warning: the feature `track_caller` is incomplete and may cause the compiler to crash
--> $DIR/pass.rs:2:12
|
LL | #![feature(track_caller)]
| ^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

Original file line number Diff line number Diff line change
@@ -7,19 +7,19 @@ LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
= note: hidden type `impl std::future::Future` captures lifetime '_#15r

error: lifetime may not live long enough
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:50
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52
|
LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
| - ^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
| - ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here

error: lifetime may not live long enough
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:73
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:75
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| - ^^^^^^^^^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
| - ^^^^^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
@@ -33,12 +33,11 @@ LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
= note: hidden type `impl std::future::Future` captures lifetime '_#15r

error: lifetime may not live long enough
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:62
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
|
LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
| -- - ^^^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'a`
| | |
| | lifetime `'_` defined here
| -- - lifetime `'_` defined here ^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'a`
| |
| lifetime `'a` defined here

error: aborting due to 5 previous errors
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
error[E0623]: lifetime mismatch
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:45
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52
|
LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
| ---- ^^^^
| | |
| | ...but data from `f` is returned here
| ---- ---- ^ ...but data from `f` is returned here
| |
| this parameter and the return type are declared with different lifetimes...

error[E0623]: lifetime mismatch
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:55
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:82
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| ----- ^^^^^^^^^^^^^^^^^
| | |
| | ...but data from `f` is returned here
| ----- ----------------- ^ ...but data from `f` is returned here
| |
| this parameter and the return type are declared with different lifetimes...

error[E0623]: lifetime mismatch
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:58
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
|
LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
| ----- ^^^
| | |
| | ...but data from `arg` is returned here
| ----- --- ^^^ ...but data from `arg` is returned here
| |
| this parameter and the return type are declared with different lifetimes...

error: aborting due to 3 previous errors
114 changes: 54 additions & 60 deletions src/test/ui/self/elision/lt-ref-self-async.nll.stderr
Original file line number Diff line number Diff line change
@@ -7,16 +7,15 @@ LL | async fn ref_self(&self, f: &u32) -> &u32 {
= note: hidden type `impl std::future::Future` captures lifetime '_#23r

error: lifetime may not live long enough
--> $DIR/lt-ref-self-async.rs:13:47
|
LL | async fn ref_self(&self, f: &u32) -> &u32 {
| _______________________-_______________________^
| | |
| | lifetime `'_` defined here
| | lifetime `'_` defined here
LL | | f
LL | | }
| |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
--> $DIR/lt-ref-self-async.rs:14:9
|
LL | async fn ref_self(&self, f: &u32) -> &u32 {
| -
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
LL | f
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`

error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> $DIR/lt-ref-self-async.rs:19:48
@@ -27,16 +26,15 @@ LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
= note: hidden type `impl std::future::Future` captures lifetime '_#23r

error: lifetime may not live long enough
--> $DIR/lt-ref-self-async.rs:19:53
|
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
| _____________________________-_______________________^
| | |
| | lifetime `'_` defined here
| | lifetime `'_` defined here
LL | | f
LL | | }
| |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
--> $DIR/lt-ref-self-async.rs:20:9
|
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
| -
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
LL | f
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`

error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> $DIR/lt-ref-self-async.rs:23:57
@@ -47,16 +45,15 @@ LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
= note: hidden type `impl std::future::Future` captures lifetime '_#23r

error: lifetime may not live long enough
--> $DIR/lt-ref-self-async.rs:23:62
|
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| _____________________________________-________________________^
| | |
| | lifetime `'_` defined here
| | lifetime `'_` defined here
LL | | f
LL | | }
| |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
--> $DIR/lt-ref-self-async.rs:24:9
|
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| -
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
LL | f
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`

error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> $DIR/lt-ref-self-async.rs:27:57
@@ -67,16 +64,15 @@ LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
= note: hidden type `impl std::future::Future` captures lifetime '_#23r

error: lifetime may not live long enough
--> $DIR/lt-ref-self-async.rs:27:62
|
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| _____________________________________-________________________^
| | |
| | lifetime `'_` defined here
| | lifetime `'_` defined here
LL | | f
LL | | }
| |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
--> $DIR/lt-ref-self-async.rs:28:9
|
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| -
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
LL | f
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`

error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> $DIR/lt-ref-self-async.rs:31:66
@@ -87,16 +83,15 @@ LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
= note: hidden type `impl std::future::Future` captures lifetime '_#23r

error: lifetime may not live long enough
--> $DIR/lt-ref-self-async.rs:31:71
|
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| _____________________________________________-_________________________^
| | |
| | lifetime `'_` defined here
| | lifetime `'_` defined here
LL | | f
LL | | }
| |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
--> $DIR/lt-ref-self-async.rs:32:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| -
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
LL | f
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`

error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> $DIR/lt-ref-self-async.rs:35:62
@@ -107,16 +102,15 @@ LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
= note: hidden type `impl std::future::Future` captures lifetime '_#23r

error: lifetime may not live long enough
--> $DIR/lt-ref-self-async.rs:35:67
|
LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| _________________________________________-_________________________^
| | |
| | lifetime `'_` defined here
| | lifetime `'_` defined here
LL | | f
LL | | }
| |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
--> $DIR/lt-ref-self-async.rs:36:9
|
LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| -
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
LL | f
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`

error: aborting due to 12 previous errors

12 changes: 6 additions & 6 deletions src/test/ui/self/elision/lt-ref-self-async.rs
Original file line number Diff line number Diff line change
@@ -11,29 +11,29 @@ impl<'a> Struct<'a> {
// Test using `&self` sugar:

async fn ref_self(&self, f: &u32) -> &u32 {
f //~^ ERROR lifetime mismatch
f //~ ERROR lifetime mismatch
}

// Test using `&Self` explicitly:

async fn ref_Self(self: &Self, f: &u32) -> &u32 {
f //~^ ERROR lifetime mismatch
f //~ ERROR lifetime mismatch
}

async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
f //~^ ERROR lifetime mismatch
f //~ ERROR lifetime mismatch
}

async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
f //~^ ERROR lifetime mismatch
f //~ ERROR lifetime mismatch
}

async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
f //~^ ERROR lifetime mismatch
f //~ ERROR lifetime mismatch
}

async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
f //~^ ERROR lifetime mismatch
f //~ ERROR lifetime mismatch
}
}

54 changes: 30 additions & 24 deletions src/test/ui/self/elision/lt-ref-self-async.stderr
Original file line number Diff line number Diff line change
@@ -1,56 +1,62 @@
error[E0623]: lifetime mismatch
--> $DIR/lt-ref-self-async.rs:13:42
--> $DIR/lt-ref-self-async.rs:14:9
|
LL | async fn ref_self(&self, f: &u32) -> &u32 {
| ----- ^^^^
| | |
| | ...but data from `f` is returned here
| ----- ----
| |
| this parameter and the return type are declared with different lifetimes...
LL | f
| ^ ...but data from `f` is returned here

error[E0623]: lifetime mismatch
--> $DIR/lt-ref-self-async.rs:19:48
--> $DIR/lt-ref-self-async.rs:20:9
|
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
| ----- ^^^^
| | |
| | ...but data from `f` is returned here
| ----- ----
| |
| this parameter and the return type are declared with different lifetimes...
LL | f
| ^ ...but data from `f` is returned here

error[E0623]: lifetime mismatch
--> $DIR/lt-ref-self-async.rs:23:57
--> $DIR/lt-ref-self-async.rs:24:9
|
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| ----- ^^^^
| | |
| | ...but data from `f` is returned here
| ----- ----
| |
| this parameter and the return type are declared with different lifetimes...
LL | f
| ^ ...but data from `f` is returned here

error[E0623]: lifetime mismatch
--> $DIR/lt-ref-self-async.rs:27:57
--> $DIR/lt-ref-self-async.rs:28:9
|
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| ----- ^^^^
| | |
| | ...but data from `f` is returned here
| ----- ----
| |
| this parameter and the return type are declared with different lifetimes...
LL | f
| ^ ...but data from `f` is returned here

error[E0623]: lifetime mismatch
--> $DIR/lt-ref-self-async.rs:31:66
--> $DIR/lt-ref-self-async.rs:32:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| ----- ^^^^
| | |
| | ...but data from `f` is returned here
| ----- ----
| |
| this parameter and the return type are declared with different lifetimes...
LL | f
| ^ ...but data from `f` is returned here

error[E0623]: lifetime mismatch
--> $DIR/lt-ref-self-async.rs:35:62
--> $DIR/lt-ref-self-async.rs:36:9
|
LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| ----- ^^^^
| | |
| | ...but data from `f` is returned here
| ----- ----
| |
| this parameter and the return type are declared with different lifetimes...
LL | f
| ^ ...but data from `f` is returned here

error: aborting due to 6 previous errors

114 changes: 54 additions & 60 deletions src/test/ui/self/elision/ref-mut-self-async.nll.stderr
Original file line number Diff line number Diff line change
@@ -7,16 +7,15 @@ LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
= note: hidden type `impl std::future::Future` captures lifetime '_#15r

error: lifetime may not live long enough
--> $DIR/ref-mut-self-async.rs:13:51
|
LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
| _______________________-___________________________^
| | |
| | lifetime `'_` defined here
| | lifetime `'_` defined here
LL | | f
LL | | }
| |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
--> $DIR/ref-mut-self-async.rs:14:9
|
LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
| -
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
LL | f
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`

error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> $DIR/ref-mut-self-async.rs:19:52
@@ -27,16 +26,15 @@ LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
= note: hidden type `impl std::future::Future` captures lifetime '_#15r

error: lifetime may not live long enough
--> $DIR/ref-mut-self-async.rs:19:57
|
LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
| _____________________________-___________________________^
| | |
| | lifetime `'_` defined here
| | lifetime `'_` defined here
LL | | f
LL | | }
| |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
--> $DIR/ref-mut-self-async.rs:20:9
|
LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
| -
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
LL | f
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`

error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> $DIR/ref-mut-self-async.rs:23:61
@@ -47,16 +45,15 @@ LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
= note: hidden type `impl std::future::Future` captures lifetime '_#15r

error: lifetime may not live long enough
--> $DIR/ref-mut-self-async.rs:23:66
|
LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
| _____________________________________-____________________________^
| | |
| | lifetime `'_` defined here
| | lifetime `'_` defined here
LL | | f
LL | | }
| |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
--> $DIR/ref-mut-self-async.rs:24:9
|
LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
| -
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
LL | f
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`

error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> $DIR/ref-mut-self-async.rs:27:61
@@ -67,16 +64,15 @@ LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
= note: hidden type `impl std::future::Future` captures lifetime '_#15r

error: lifetime may not live long enough
--> $DIR/ref-mut-self-async.rs:27:66
|
LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
| _____________________________________-____________________________^
| | |
| | lifetime `'_` defined here
| | lifetime `'_` defined here
LL | | f
LL | | }
| |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
--> $DIR/ref-mut-self-async.rs:28:9
|
LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
| -
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
LL | f
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`

error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> $DIR/ref-mut-self-async.rs:31:70
@@ -87,16 +83,15 @@ LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
= note: hidden type `impl std::future::Future` captures lifetime '_#15r

error: lifetime may not live long enough
--> $DIR/ref-mut-self-async.rs:31:75
|
LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
| _____________________________________________-_____________________________^
| | |
| | lifetime `'_` defined here
| | lifetime `'_` defined here
LL | | f
LL | | }
| |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
--> $DIR/ref-mut-self-async.rs:32:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
| -
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
LL | f
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`

error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> $DIR/ref-mut-self-async.rs:35:70
@@ -107,16 +102,15 @@ LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
= note: hidden type `impl std::future::Future` captures lifetime '_#15r

error: lifetime may not live long enough
--> $DIR/ref-mut-self-async.rs:35:75
|
LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
| _____________________________________________-_____________________________^
| | |
| | lifetime `'_` defined here
| | lifetime `'_` defined here
LL | | f
LL | | }
| |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
--> $DIR/ref-mut-self-async.rs:36:9
|
LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
| -
| |
| lifetime `'_` defined here
| lifetime `'_` defined here
LL | f
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`

error: aborting due to 12 previous errors

14 changes: 7 additions & 7 deletions src/test/ui/self/elision/ref-mut-self-async.rs
Original file line number Diff line number Diff line change
@@ -10,30 +10,30 @@ struct Struct { }
impl Struct {
// Test using `&mut self` sugar:

async fn ref_self(&mut self, f: &u32) -> &u32 { //~ ERROR lifetime mismatch
f
async fn ref_self(&mut self, f: &u32) -> &u32 {
f //~ ERROR lifetime mismatch
}

// Test using `&mut Self` explicitly:

async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
f //~^ ERROR lifetime mismatch
f //~ ERROR lifetime mismatch
}

async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
f //~^ ERROR lifetime mismatch
f //~ ERROR lifetime mismatch
}

async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
f //~^ ERROR lifetime mismatch
f //~ ERROR lifetime mismatch
}

async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
f //~^ ERROR lifetime mismatch
f //~ ERROR lifetime mismatch
}

async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
f //~^ ERROR lifetime mismatch
f //~ ERROR lifetime mismatch
}
}

54 changes: 30 additions & 24 deletions src/test/ui/self/elision/ref-mut-self-async.stderr
Original file line number Diff line number Diff line change
@@ -1,56 +1,62 @@
error[E0623]: lifetime mismatch
--> $DIR/ref-mut-self-async.rs:13:46
--> $DIR/ref-mut-self-async.rs:14:9
|
LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
| --------- ^^^^
| | |
| | ...but data from `f` is returned here
| --------- ----
| |
| this parameter and the return type are declared with different lifetimes...
LL | f
| ^ ...but data from `f` is returned here

error[E0623]: lifetime mismatch
--> $DIR/ref-mut-self-async.rs:19:52
--> $DIR/ref-mut-self-async.rs:20:9
|
LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
| --------- ^^^^
| | |
| | ...but data from `f` is returned here
| --------- ----
| |
| this parameter and the return type are declared with different lifetimes...
LL | f
| ^ ...but data from `f` is returned here

error[E0623]: lifetime mismatch
--> $DIR/ref-mut-self-async.rs:23:61
--> $DIR/ref-mut-self-async.rs:24:9
|
LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
| --------- ^^^^
| | |
| | ...but data from `f` is returned here
| --------- ----
| |
| this parameter and the return type are declared with different lifetimes...
LL | f
| ^ ...but data from `f` is returned here

error[E0623]: lifetime mismatch
--> $DIR/ref-mut-self-async.rs:27:61
--> $DIR/ref-mut-self-async.rs:28:9
|
LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
| --------- ^^^^
| | |
| | ...but data from `f` is returned here
| --------- ----
| |
| this parameter and the return type are declared with different lifetimes...
LL | f
| ^ ...but data from `f` is returned here

error[E0623]: lifetime mismatch
--> $DIR/ref-mut-self-async.rs:31:70
--> $DIR/ref-mut-self-async.rs:32:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
| --------- ^^^^
| | |
| | ...but data from `f` is returned here
| --------- ----
| |
| this parameter and the return type are declared with different lifetimes...
LL | f
| ^ ...but data from `f` is returned here

error[E0623]: lifetime mismatch
--> $DIR/ref-mut-self-async.rs:35:70
--> $DIR/ref-mut-self-async.rs:36:9
|
LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
| --------- ^^^^
| | |
| | ...but data from `f` is returned here
| --------- ----
| |
| this parameter and the return type are declared with different lifetimes...
LL | f
| ^ ...but data from `f` is returned here

error: aborting due to 6 previous errors

Loading