mirror of https://github.com/rust-lang/rust.git
Auto merge of #68907 - Dylan-DPC:rollup-osm5e8o, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #67359 (Rename -Zexternal-macro-backtrace to -Zmacro-backtrace and clean up implementation.) - #68524 (Generator Resume Arguments) - #68791 (implement proper linkchecker hardening) - #68886 (Mark fn map_or() as eagerly evaluated.) - #68888 (error code examples: replace some more ignore with compile_fail) - #68894 (Update E0565 examples) Failed merges: r? @ghost
This commit is contained in:
commit
f8fd462447
|
@ -3067,6 +3067,7 @@ name = "rustbook"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"codespan",
|
||||
"codespan-reporting",
|
||||
"failure",
|
||||
"mdbook",
|
||||
|
|
|
@ -847,7 +847,13 @@ impl<'a> Builder<'a> {
|
|||
rustflags.arg("-Zforce-unstable-if-unmarked");
|
||||
}
|
||||
|
||||
rustflags.arg("-Zexternal-macro-backtrace");
|
||||
// cfg(bootstrap): the flag was renamed from `-Zexternal-macro-backtrace`
|
||||
// to `-Zmacro-backtrace`, keep only the latter after beta promotion.
|
||||
if stage == 0 {
|
||||
rustflags.arg("-Zexternal-macro-backtrace");
|
||||
} else {
|
||||
rustflags.arg("-Zmacro-backtrace");
|
||||
}
|
||||
|
||||
let want_rustdoc = self.doc_tests != DocTests::No;
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 92baf7293dd2d418d2ac4b141b0faa822075d9f7
|
||||
Subproject commit 5bd60bc51efaec04e69e2e18b59678e2af066433
|
|
@ -37,11 +37,11 @@ fn main() {
|
|||
return "foo"
|
||||
};
|
||||
|
||||
match Pin::new(&mut generator).resume() {
|
||||
match Pin::new(&mut generator).resume(()) {
|
||||
GeneratorState::Yielded(1) => {}
|
||||
_ => panic!("unexpected value from resume"),
|
||||
}
|
||||
match Pin::new(&mut generator).resume() {
|
||||
match Pin::new(&mut generator).resume(()) {
|
||||
GeneratorState::Complete("foo") => {}
|
||||
_ => panic!("unexpected value from resume"),
|
||||
}
|
||||
|
@ -71,9 +71,9 @@ fn main() {
|
|||
};
|
||||
|
||||
println!("1");
|
||||
Pin::new(&mut generator).resume();
|
||||
Pin::new(&mut generator).resume(());
|
||||
println!("3");
|
||||
Pin::new(&mut generator).resume();
|
||||
Pin::new(&mut generator).resume(());
|
||||
println!("5");
|
||||
}
|
||||
```
|
||||
|
@ -92,10 +92,10 @@ The `Generator` trait in `std::ops` currently looks like:
|
|||
# use std::ops::GeneratorState;
|
||||
# use std::pin::Pin;
|
||||
|
||||
pub trait Generator {
|
||||
pub trait Generator<R = ()> {
|
||||
type Yield;
|
||||
type Return;
|
||||
fn resume(self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return>;
|
||||
fn resume(self: Pin<&mut Self>, resume: R) -> GeneratorState<Self::Yield, Self::Return>;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -152,10 +152,6 @@ closure-like semantics. Namely:
|
|||
* Whenever a generator is dropped it will drop all captured environment
|
||||
variables.
|
||||
|
||||
Note that unlike closures, generators at this time cannot take any arguments.
|
||||
That is, generators must always look like `|| { ... }`. This restriction may be
|
||||
lifted at a future date, the design is ongoing!
|
||||
|
||||
### Generators as state machines
|
||||
|
||||
In the compiler, generators are currently compiled as state machines. Each
|
||||
|
@ -179,8 +175,8 @@ fn main() {
|
|||
return ret
|
||||
};
|
||||
|
||||
Pin::new(&mut generator).resume();
|
||||
Pin::new(&mut generator).resume();
|
||||
Pin::new(&mut generator).resume(());
|
||||
Pin::new(&mut generator).resume(());
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -205,7 +201,7 @@ fn main() {
|
|||
type Yield = i32;
|
||||
type Return = &'static str;
|
||||
|
||||
fn resume(mut self: Pin<&mut Self>) -> GeneratorState<i32, &'static str> {
|
||||
fn resume(mut self: Pin<&mut Self>, resume: ()) -> GeneratorState<i32, &'static str> {
|
||||
use std::mem;
|
||||
match mem::replace(&mut *self, __Generator::Done) {
|
||||
__Generator::Start(s) => {
|
||||
|
@ -228,8 +224,8 @@ fn main() {
|
|||
__Generator::Start(ret)
|
||||
};
|
||||
|
||||
Pin::new(&mut generator).resume();
|
||||
Pin::new(&mut generator).resume();
|
||||
Pin::new(&mut generator).resume(());
|
||||
Pin::new(&mut generator).resume(());
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -1104,6 +1104,7 @@ impl<T: ?Sized> AsMut<T> for Box<T> {
|
|||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
impl<T: ?Sized> Unpin for Box<T> {}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
#[unstable(feature = "generator_trait", issue = "43122")]
|
||||
impl<G: ?Sized + Generator + Unpin> Generator for Box<G> {
|
||||
type Yield = G::Yield;
|
||||
|
@ -1114,6 +1115,7 @@ impl<G: ?Sized + Generator + Unpin> Generator for Box<G> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
#[unstable(feature = "generator_trait", issue = "43122")]
|
||||
impl<G: ?Sized + Generator> Generator for Pin<Box<G>> {
|
||||
type Yield = G::Yield;
|
||||
|
@ -1124,6 +1126,28 @@ impl<G: ?Sized + Generator> Generator for Pin<Box<G>> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[unstable(feature = "generator_trait", issue = "43122")]
|
||||
impl<G: ?Sized + Generator<R> + Unpin, R> Generator<R> for Box<G> {
|
||||
type Yield = G::Yield;
|
||||
type Return = G::Return;
|
||||
|
||||
fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
|
||||
G::resume(Pin::new(&mut *self), arg)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[unstable(feature = "generator_trait", issue = "43122")]
|
||||
impl<G: ?Sized + Generator<R>, R> Generator<R> for Pin<Box<G>> {
|
||||
type Yield = G::Yield;
|
||||
type Return = G::Return;
|
||||
|
||||
fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
|
||||
G::resume((*self).as_mut(), arg)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
impl<F: ?Sized + Future + Unpin> Future for Box<F> {
|
||||
type Output = F::Output;
|
||||
|
|
|
@ -50,11 +50,11 @@ pub enum GeneratorState<Y, R> {
|
|||
/// return "foo"
|
||||
/// };
|
||||
///
|
||||
/// match Pin::new(&mut generator).resume() {
|
||||
/// match Pin::new(&mut generator).resume(()) {
|
||||
/// GeneratorState::Yielded(1) => {}
|
||||
/// _ => panic!("unexpected return from resume"),
|
||||
/// }
|
||||
/// match Pin::new(&mut generator).resume() {
|
||||
/// match Pin::new(&mut generator).resume(()) {
|
||||
/// GeneratorState::Complete("foo") => {}
|
||||
/// _ => panic!("unexpected return from resume"),
|
||||
/// }
|
||||
|
@ -67,7 +67,7 @@ pub enum GeneratorState<Y, R> {
|
|||
#[lang = "generator"]
|
||||
#[unstable(feature = "generator_trait", issue = "43122")]
|
||||
#[fundamental]
|
||||
pub trait Generator {
|
||||
pub trait Generator<#[cfg(not(bootstrap))] R = ()> {
|
||||
/// The type of value this generator yields.
|
||||
///
|
||||
/// This associated type corresponds to the `yield` expression and the
|
||||
|
@ -110,9 +110,13 @@ pub trait Generator {
|
|||
/// been returned previously. While generator literals in the language are
|
||||
/// guaranteed to panic on resuming after `Complete`, this is not guaranteed
|
||||
/// for all implementations of the `Generator` trait.
|
||||
fn resume(self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return>;
|
||||
fn resume(
|
||||
self: Pin<&mut Self>,
|
||||
#[cfg(not(bootstrap))] arg: R,
|
||||
) -> GeneratorState<Self::Yield, Self::Return>;
|
||||
}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
#[unstable(feature = "generator_trait", issue = "43122")]
|
||||
impl<G: ?Sized + Generator> Generator for Pin<&mut G> {
|
||||
type Yield = G::Yield;
|
||||
|
@ -123,6 +127,7 @@ impl<G: ?Sized + Generator> Generator for Pin<&mut G> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
#[unstable(feature = "generator_trait", issue = "43122")]
|
||||
impl<G: ?Sized + Generator + Unpin> Generator for &mut G {
|
||||
type Yield = G::Yield;
|
||||
|
@ -132,3 +137,25 @@ impl<G: ?Sized + Generator + Unpin> Generator for &mut G {
|
|||
G::resume(Pin::new(&mut *self))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[unstable(feature = "generator_trait", issue = "43122")]
|
||||
impl<G: ?Sized + Generator<R>, R> Generator<R> for Pin<&mut G> {
|
||||
type Yield = G::Yield;
|
||||
type Return = G::Return;
|
||||
|
||||
fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
|
||||
G::resume((*self).as_mut(), arg)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[unstable(feature = "generator_trait", issue = "43122")]
|
||||
impl<G: ?Sized + Generator<R> + Unpin, R> Generator<R> for &mut G {
|
||||
type Yield = G::Yield;
|
||||
type Return = G::Return;
|
||||
|
||||
fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
|
||||
G::resume(Pin::new(&mut *self), arg)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -455,6 +455,12 @@ impl<T> Option<T> {
|
|||
/// Applies a function to the contained value (if any),
|
||||
/// or returns the provided default (if not).
|
||||
///
|
||||
/// Arguments passed to `map_or` are eagerly evaluated; if you are passing
|
||||
/// the result of a function call, it is recommended to use [`map_or_else`],
|
||||
/// which is lazily evaluated.
|
||||
///
|
||||
/// [`map_or_else`]: #method.map_or_else
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
|
|
@ -524,6 +524,12 @@ impl<T, E> Result<T, E> {
|
|||
/// Applies a function to the contained value (if any),
|
||||
/// or returns the provided default (if not).
|
||||
///
|
||||
/// Arguments passed to `map_or` are eagerly evaluated; if you are passing
|
||||
/// the result of a function call, it is recommended to use [`map_or_else`],
|
||||
/// which is lazily evaluated.
|
||||
///
|
||||
/// [`map_or_else`]: #method.map_or_else
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
|
|
@ -744,6 +744,7 @@ where
|
|||
|
||||
substs.as_generator().return_ty(def_id, self.tcx).visit_with(self);
|
||||
substs.as_generator().yield_ty(def_id, self.tcx).visit_with(self);
|
||||
substs.as_generator().resume_ty(def_id, self.tcx).visit_with(self);
|
||||
}
|
||||
_ => {
|
||||
ty.super_visit_with(self);
|
||||
|
|
|
@ -1120,6 +1120,8 @@ pub enum TerminatorKind<'tcx> {
|
|||
value: Operand<'tcx>,
|
||||
/// Where to resume to.
|
||||
resume: BasicBlock,
|
||||
/// The place to store the resume argument in.
|
||||
resume_arg: Place<'tcx>,
|
||||
/// Cleanup to be done if the generator is dropped at this suspend point.
|
||||
drop: Option<BasicBlock>,
|
||||
},
|
||||
|
@ -2645,9 +2647,12 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
|||
target,
|
||||
unwind,
|
||||
},
|
||||
Yield { ref value, resume, drop } => {
|
||||
Yield { value: value.fold_with(folder), resume: resume, drop: drop }
|
||||
}
|
||||
Yield { ref value, resume, ref resume_arg, drop } => Yield {
|
||||
value: value.fold_with(folder),
|
||||
resume,
|
||||
resume_arg: resume_arg.fold_with(folder),
|
||||
drop,
|
||||
},
|
||||
Call { ref func, ref args, ref destination, cleanup, from_hir_call } => {
|
||||
let dest =
|
||||
destination.as_ref().map(|&(ref loc, dest)| (loc.fold_with(folder), dest));
|
||||
|
|
|
@ -516,8 +516,14 @@ macro_rules! make_mir_visitor {
|
|||
TerminatorKind::Yield {
|
||||
value,
|
||||
resume: _,
|
||||
resume_arg,
|
||||
drop: _,
|
||||
} => {
|
||||
self.visit_place(
|
||||
resume_arg,
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Store),
|
||||
source_location,
|
||||
);
|
||||
self.visit_operand(value, source_location);
|
||||
}
|
||||
|
||||
|
|
|
@ -643,8 +643,10 @@ pub fn generator_trait_ref_and_outputs(
|
|||
self_ty: Ty<'tcx>,
|
||||
sig: ty::PolyGenSig<'tcx>,
|
||||
) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> {
|
||||
let trait_ref =
|
||||
ty::TraitRef { def_id: fn_trait_def_id, substs: tcx.mk_substs_trait(self_ty, &[]) };
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: fn_trait_def_id,
|
||||
substs: tcx.mk_substs_trait(self_ty, &[sig.skip_binder().resume_ty.into()]),
|
||||
};
|
||||
ty::Binder::bind((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty))
|
||||
}
|
||||
|
||||
|
|
|
@ -2350,8 +2350,9 @@ impl<'tcx> ty::Instance<'tcx> {
|
|||
]);
|
||||
let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
|
||||
|
||||
tcx.mk_fn_sig(iter::once(env_ty),
|
||||
ret_ty,
|
||||
tcx.mk_fn_sig(
|
||||
[env_ty, sig.resume_ty].iter(),
|
||||
&ret_ty,
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
rustc_target::spec::abi::Abi::Rust
|
||||
|
|
|
@ -598,8 +598,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
|
|||
impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> {
|
||||
type Lifted = ty::GenSig<'tcx>;
|
||||
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
tcx.lift(&(self.yield_ty, self.return_ty))
|
||||
.map(|(yield_ty, return_ty)| ty::GenSig { yield_ty, return_ty })
|
||||
tcx.lift(&(self.resume_ty, self.yield_ty, self.return_ty))
|
||||
.map(|(resume_ty, yield_ty, return_ty)| ty::GenSig { resume_ty, yield_ty, return_ty })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -346,9 +346,17 @@ static_assert_size!(TyKind<'_>, 24);
|
|||
/// ## Generators
|
||||
///
|
||||
/// Generators are handled similarly in `GeneratorSubsts`. The set of
|
||||
/// type parameters is similar, but the role of CK and CS are
|
||||
/// different. CK represents the "yield type" and CS represents the
|
||||
/// "return type" of the generator.
|
||||
/// type parameters is similar, but `CK` and `CS` are replaced by the
|
||||
/// following type parameters:
|
||||
///
|
||||
/// * `GS`: The generator's "resume type", which is the type of the
|
||||
/// argument passed to `resume`, and the type of `yield` expressions
|
||||
/// inside the generator.
|
||||
/// * `GY`: The "yield type", which is the type of values passed to
|
||||
/// `yield` inside the generator.
|
||||
/// * `GR`: The "return type", which is the type of value returned upon
|
||||
/// completion of the generator.
|
||||
/// * `GW`: The "generator witness".
|
||||
#[derive(Copy, Clone, Debug, TypeFoldable)]
|
||||
pub struct ClosureSubsts<'tcx> {
|
||||
/// Lifetime and type parameters from the enclosing function,
|
||||
|
@ -442,6 +450,7 @@ pub struct GeneratorSubsts<'tcx> {
|
|||
}
|
||||
|
||||
struct SplitGeneratorSubsts<'tcx> {
|
||||
resume_ty: Ty<'tcx>,
|
||||
yield_ty: Ty<'tcx>,
|
||||
return_ty: Ty<'tcx>,
|
||||
witness: Ty<'tcx>,
|
||||
|
@ -453,10 +462,11 @@ impl<'tcx> GeneratorSubsts<'tcx> {
|
|||
let generics = tcx.generics_of(def_id);
|
||||
let parent_len = generics.parent_count;
|
||||
SplitGeneratorSubsts {
|
||||
yield_ty: self.substs.type_at(parent_len),
|
||||
return_ty: self.substs.type_at(parent_len + 1),
|
||||
witness: self.substs.type_at(parent_len + 2),
|
||||
upvar_kinds: &self.substs[parent_len + 3..],
|
||||
resume_ty: self.substs.type_at(parent_len),
|
||||
yield_ty: self.substs.type_at(parent_len + 1),
|
||||
return_ty: self.substs.type_at(parent_len + 2),
|
||||
witness: self.substs.type_at(parent_len + 3),
|
||||
upvar_kinds: &self.substs[parent_len + 4..],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -485,6 +495,11 @@ impl<'tcx> GeneratorSubsts<'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Returns the type representing the resume type of the generator.
|
||||
pub fn resume_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
|
||||
self.split(def_id, tcx).resume_ty
|
||||
}
|
||||
|
||||
/// Returns the type representing the yield type of the generator.
|
||||
pub fn yield_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
|
||||
self.split(def_id, tcx).yield_ty
|
||||
|
@ -505,10 +520,14 @@ impl<'tcx> GeneratorSubsts<'tcx> {
|
|||
ty::Binder::dummy(self.sig(def_id, tcx))
|
||||
}
|
||||
|
||||
/// Returns the "generator signature", which consists of its yield
|
||||
/// Returns the "generator signature", which consists of its resume, yield
|
||||
/// and return types.
|
||||
pub fn sig(self, def_id: DefId, tcx: TyCtxt<'_>) -> GenSig<'tcx> {
|
||||
ty::GenSig { yield_ty: self.yield_ty(def_id, tcx), return_ty: self.return_ty(def_id, tcx) }
|
||||
ty::GenSig {
|
||||
resume_ty: self.resume_ty(def_id, tcx),
|
||||
yield_ty: self.yield_ty(def_id, tcx),
|
||||
return_ty: self.return_ty(def_id, tcx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1072,6 +1091,7 @@ impl<'tcx> ProjectionTy<'tcx> {
|
|||
|
||||
#[derive(Clone, Debug, TypeFoldable)]
|
||||
pub struct GenSig<'tcx> {
|
||||
pub resume_ty: Ty<'tcx>,
|
||||
pub yield_ty: Ty<'tcx>,
|
||||
pub return_ty: Ty<'tcx>,
|
||||
}
|
||||
|
@ -1079,6 +1099,9 @@ pub struct GenSig<'tcx> {
|
|||
pub type PolyGenSig<'tcx> = Binder<GenSig<'tcx>>;
|
||||
|
||||
impl<'tcx> PolyGenSig<'tcx> {
|
||||
pub fn resume_ty(&self) -> ty::Binder<Ty<'tcx>> {
|
||||
self.map_bound_ref(|sig| sig.resume_ty)
|
||||
}
|
||||
pub fn yield_ty(&self) -> ty::Binder<Ty<'tcx>> {
|
||||
self.map_bound_ref(|sig| sig.yield_ty)
|
||||
}
|
||||
|
|
|
@ -688,12 +688,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
) -> Option<hir::Movability> {
|
||||
match generator_kind {
|
||||
Some(hir::GeneratorKind::Gen) => {
|
||||
if !decl.inputs.is_empty() {
|
||||
if decl.inputs.len() > 1 {
|
||||
struct_span_err!(
|
||||
self.sess,
|
||||
fn_decl_span,
|
||||
E0628,
|
||||
"generators cannot have explicit parameters"
|
||||
"too many parameters for a generator (expected 0 or 1 parameters)"
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ pub struct PinnedGenerator<I, A, R> {
|
|||
}
|
||||
|
||||
impl<I, A, R> PinnedGenerator<I, A, R> {
|
||||
#[cfg(bootstrap)]
|
||||
pub fn new<T: Generator<Yield = YieldType<I, A>, Return = R> + 'static>(
|
||||
generator: T,
|
||||
) -> (I, Self) {
|
||||
|
@ -39,6 +40,22 @@ impl<I, A, R> PinnedGenerator<I, A, R> {
|
|||
(init, result)
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
pub fn new<T: Generator<Yield = YieldType<I, A>, Return = R> + 'static>(
|
||||
generator: T,
|
||||
) -> (I, Self) {
|
||||
let mut result = PinnedGenerator { generator: Box::pin(generator) };
|
||||
|
||||
// Run it to the first yield to set it up
|
||||
let init = match Pin::new(&mut result.generator).resume(()) {
|
||||
GeneratorState::Yielded(YieldType::Initial(y)) => y,
|
||||
_ => panic!(),
|
||||
};
|
||||
|
||||
(init, result)
|
||||
}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
pub unsafe fn access(&mut self, closure: *mut dyn FnMut()) {
|
||||
BOX_REGION_ARG.with(|i| {
|
||||
i.set(Action::Access(AccessAction(closure)));
|
||||
|
@ -50,6 +67,19 @@ impl<I, A, R> PinnedGenerator<I, A, R> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
pub unsafe fn access(&mut self, closure: *mut dyn FnMut()) {
|
||||
BOX_REGION_ARG.with(|i| {
|
||||
i.set(Action::Access(AccessAction(closure)));
|
||||
});
|
||||
|
||||
// Call the generator, which in turn will call the closure in BOX_REGION_ARG
|
||||
if let GeneratorState::Complete(_) = Pin::new(&mut self.generator).resume(()) {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
pub fn complete(&mut self) -> R {
|
||||
// Tell the generator we want it to complete, consuming it and yielding a result
|
||||
BOX_REGION_ARG.with(|i| i.set(Action::Complete));
|
||||
|
@ -57,6 +87,15 @@ impl<I, A, R> PinnedGenerator<I, A, R> {
|
|||
let result = Pin::new(&mut self.generator).resume();
|
||||
if let GeneratorState::Complete(r) = result { r } else { panic!() }
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
pub fn complete(&mut self) -> R {
|
||||
// Tell the generator we want it to complete, consuming it and yielding a result
|
||||
BOX_REGION_ARG.with(|i| i.set(Action::Complete));
|
||||
|
||||
let result = Pin::new(&mut self.generator).resume(());
|
||||
if let GeneratorState::Complete(r) = result { r } else { panic!() }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Invalid monomorphization of an intrinsic function was used. Erroneous code
|
||||
example:
|
||||
|
||||
```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
|
||||
```compile_fail,E0511
|
||||
#![feature(platform_intrinsics)]
|
||||
|
||||
extern "platform-intrinsic" {
|
||||
|
|
|
@ -2,7 +2,7 @@ The `inline` attribute was malformed.
|
|||
|
||||
Erroneous code example:
|
||||
|
||||
```ignore (compile_fail not working here; see Issue #43707)
|
||||
```compile_fail,E0534
|
||||
#[inline()] // error: expected one argument
|
||||
pub fn something() {}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ An unknown argument was given to the `inline` attribute.
|
|||
|
||||
Erroneous code example:
|
||||
|
||||
```ignore (compile_fail not working here; see Issue #43707)
|
||||
```compile_fail,E0535
|
||||
#[inline(unknown)] // error: invalid argument
|
||||
pub fn something() {}
|
||||
|
||||
|
|
|
@ -2,9 +2,11 @@ A literal was used in a built-in attribute that doesn't support literals.
|
|||
|
||||
Erroneous code example:
|
||||
|
||||
```ignore (compile_fail not working here; see Issue #43707)
|
||||
#[inline("always")] // error: unsupported literal
|
||||
pub fn something() {}
|
||||
```compile_fail,E0565
|
||||
#[repr("C")] // error: meta item in `repr` must be an identifier
|
||||
struct Repr {}
|
||||
|
||||
fn main() {}
|
||||
```
|
||||
|
||||
Literals in attributes are new and largely unsupported in built-in attributes.
|
||||
|
@ -12,6 +14,8 @@ Work to support literals where appropriate is ongoing. Try using an unquoted
|
|||
name instead:
|
||||
|
||||
```
|
||||
#[inline(always)]
|
||||
pub fn something() {}
|
||||
#[repr(C)] // ok!
|
||||
struct Repr {}
|
||||
|
||||
fn main() {}
|
||||
```
|
||||
|
|
|
@ -12,7 +12,7 @@ let mut b = || {
|
|||
yield (); // ...is still in scope here, when the yield occurs.
|
||||
println!("{}", a);
|
||||
};
|
||||
Pin::new(&mut b).resume();
|
||||
Pin::new(&mut b).resume(());
|
||||
```
|
||||
|
||||
At present, it is not permitted to have a yield that occurs while a
|
||||
|
@ -31,7 +31,7 @@ let mut b = || {
|
|||
yield ();
|
||||
println!("{}", a);
|
||||
};
|
||||
Pin::new(&mut b).resume();
|
||||
Pin::new(&mut b).resume(());
|
||||
```
|
||||
|
||||
This is a very simple case, of course. In more complex cases, we may
|
||||
|
@ -50,7 +50,7 @@ let mut b = || {
|
|||
yield x; // ...when this yield occurs.
|
||||
}
|
||||
};
|
||||
Pin::new(&mut b).resume();
|
||||
Pin::new(&mut b).resume(());
|
||||
```
|
||||
|
||||
Such cases can sometimes be resolved by iterating "by value" (or using
|
||||
|
@ -66,7 +66,7 @@ let mut b = || {
|
|||
yield x; // <-- Now yield is OK.
|
||||
}
|
||||
};
|
||||
Pin::new(&mut b).resume();
|
||||
Pin::new(&mut b).resume(());
|
||||
```
|
||||
|
||||
If taking ownership is not an option, using indices can work too:
|
||||
|
@ -83,7 +83,7 @@ let mut b = || {
|
|||
yield x; // <-- Now yield is OK.
|
||||
}
|
||||
};
|
||||
Pin::new(&mut b).resume();
|
||||
Pin::new(&mut b).resume(());
|
||||
|
||||
// (*) -- Unfortunately, these temporaries are currently required.
|
||||
// See <https://github.com/rust-lang/rust/issues/43122>.
|
||||
|
|
|
@ -2,7 +2,9 @@ The `unwind` attribute was malformed.
|
|||
|
||||
Erroneous code example:
|
||||
|
||||
```ignore (compile_fail not working here; see Issue #43707)
|
||||
```compile_fail,E0633
|
||||
#![feature(unwind_attributes)]
|
||||
|
||||
#[unwind()] // error: expected one argument
|
||||
pub extern fn something() {}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ assembly call.
|
|||
|
||||
In particular, it can happen if you forgot the closing bracket of a register
|
||||
constraint (see issue #51430):
|
||||
```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
|
||||
```compile_fail,E0668
|
||||
#![feature(asm)]
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -23,7 +23,7 @@ pub struct AnnotateSnippetEmitterWriter {
|
|||
/// If true, will normalize line numbers with `LL` to prevent noise in UI test diffs.
|
||||
ui_testing: bool,
|
||||
|
||||
external_macro_backtrace: bool,
|
||||
macro_backtrace: bool,
|
||||
}
|
||||
|
||||
impl Emitter for AnnotateSnippetEmitterWriter {
|
||||
|
@ -32,12 +32,12 @@ impl Emitter for AnnotateSnippetEmitterWriter {
|
|||
let mut children = diag.children.clone();
|
||||
let (mut primary_span, suggestions) = self.primary_span_formatted(&diag);
|
||||
|
||||
self.fix_multispans_in_std_macros(
|
||||
self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
|
||||
&self.source_map,
|
||||
&mut primary_span,
|
||||
&mut children,
|
||||
&diag.level,
|
||||
self.external_macro_backtrace,
|
||||
self.macro_backtrace,
|
||||
);
|
||||
|
||||
self.emit_messages_default(
|
||||
|
@ -172,9 +172,9 @@ impl AnnotateSnippetEmitterWriter {
|
|||
pub fn new(
|
||||
source_map: Option<Lrc<SourceMap>>,
|
||||
short_message: bool,
|
||||
external_macro_backtrace: bool,
|
||||
macro_backtrace: bool,
|
||||
) -> Self {
|
||||
Self { source_map, short_message, ui_testing: false, external_macro_backtrace }
|
||||
Self { source_map, short_message, ui_testing: false, macro_backtrace }
|
||||
}
|
||||
|
||||
/// Allows to modify `Self` to enable or disable the `ui_testing` flag.
|
||||
|
|
|
@ -14,7 +14,6 @@ use rustc_span::{MultiSpan, SourceFile, Span};
|
|||
|
||||
use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Style, StyledString};
|
||||
use crate::styled_buffer::StyledBuffer;
|
||||
use crate::Level::Error;
|
||||
use crate::{
|
||||
pluralize, CodeSuggestion, Diagnostic, DiagnosticId, Level, SubDiagnostic, SuggestionStyle,
|
||||
};
|
||||
|
@ -27,6 +26,7 @@ use std::borrow::Cow;
|
|||
use std::cmp::{max, min, Reverse};
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::iter;
|
||||
use std::path::Path;
|
||||
use termcolor::{Ansi, BufferWriter, ColorChoice, ColorSpec, StandardStream};
|
||||
use termcolor::{Buffer, Color, WriteColor};
|
||||
|
@ -54,19 +54,11 @@ impl HumanReadableErrorType {
|
|||
source_map: Option<Lrc<SourceMap>>,
|
||||
teach: bool,
|
||||
terminal_width: Option<usize>,
|
||||
external_macro_backtrace: bool,
|
||||
macro_backtrace: bool,
|
||||
) -> EmitterWriter {
|
||||
let (short, color_config) = self.unzip();
|
||||
let color = color_config.suggests_using_colors();
|
||||
EmitterWriter::new(
|
||||
dst,
|
||||
source_map,
|
||||
short,
|
||||
teach,
|
||||
color,
|
||||
terminal_width,
|
||||
external_macro_backtrace,
|
||||
)
|
||||
EmitterWriter::new(dst, source_map, short, teach, color, terminal_width, macro_backtrace)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,10 +272,7 @@ pub trait Emitter {
|
|||
}
|
||||
}
|
||||
|
||||
// This does a small "fix" for multispans by looking to see if it can find any that
|
||||
// point directly at <*macros>. Since these are often difficult to read, this
|
||||
// will change the span to point at the use site.
|
||||
fn fix_multispans_in_std_macros(
|
||||
fn fix_multispans_in_extern_macros_and_render_macro_backtrace(
|
||||
&self,
|
||||
source_map: &Option<Lrc<SourceMap>>,
|
||||
span: &mut MultiSpan,
|
||||
|
@ -291,127 +280,187 @@ pub trait Emitter {
|
|||
level: &Level,
|
||||
backtrace: bool,
|
||||
) {
|
||||
let mut spans_updated = self.fix_multispan_in_std_macros(source_map, span, backtrace);
|
||||
for child in children.iter_mut() {
|
||||
spans_updated |=
|
||||
self.fix_multispan_in_std_macros(source_map, &mut child.span, backtrace);
|
||||
}
|
||||
let msg = if level == &Error {
|
||||
"this error originates in a macro outside of the current crate \
|
||||
(in Nightly builds, run with -Z external-macro-backtrace \
|
||||
for more info)"
|
||||
.to_string()
|
||||
} else {
|
||||
"this warning originates in a macro outside of the current crate \
|
||||
(in Nightly builds, run with -Z external-macro-backtrace \
|
||||
for more info)"
|
||||
.to_string()
|
||||
};
|
||||
// Check for spans in macros, before `fix_multispans_in_extern_macros`
|
||||
// has a chance to replace them.
|
||||
let has_macro_spans = iter::once(&*span)
|
||||
.chain(children.iter().map(|child| &child.span))
|
||||
.flat_map(|span| span.primary_spans())
|
||||
.copied()
|
||||
.flat_map(|sp| {
|
||||
sp.macro_backtrace().filter_map(|expn_data| {
|
||||
match expn_data.kind {
|
||||
ExpnKind::Root => None,
|
||||
|
||||
if spans_updated {
|
||||
children.push(SubDiagnostic {
|
||||
level: Level::Note,
|
||||
message: vec![(msg, Style::NoStyle)],
|
||||
span: MultiSpan::new(),
|
||||
render_span: None,
|
||||
});
|
||||
// Skip past non-macro entries, just in case there
|
||||
// are some which do actually involve macros.
|
||||
ExpnKind::Desugaring(..) | ExpnKind::AstPass(..) => None,
|
||||
|
||||
ExpnKind::Macro(macro_kind, _) => Some(macro_kind),
|
||||
}
|
||||
})
|
||||
})
|
||||
.next();
|
||||
|
||||
if !backtrace {
|
||||
self.fix_multispans_in_extern_macros(source_map, span, children);
|
||||
}
|
||||
|
||||
self.render_multispans_macro_backtrace(span, children, backtrace);
|
||||
|
||||
if !backtrace {
|
||||
if let Some(macro_kind) = has_macro_spans {
|
||||
let msg = format!(
|
||||
"this {} originates in {} {} \
|
||||
(in Nightly builds, run with -Z macro-backtrace for more info)",
|
||||
level,
|
||||
macro_kind.article(),
|
||||
macro_kind.descr(),
|
||||
);
|
||||
|
||||
children.push(SubDiagnostic {
|
||||
level: Level::Note,
|
||||
message: vec![(msg, Style::NoStyle)],
|
||||
span: MultiSpan::new(),
|
||||
render_span: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This "fixes" MultiSpans that contain Spans that are pointing to locations inside of
|
||||
// <*macros>. Since these locations are often difficult to read, we move these Spans from
|
||||
// <*macros> to their corresponding use site.
|
||||
fn fix_multispan_in_std_macros(
|
||||
fn render_multispans_macro_backtrace(
|
||||
&self,
|
||||
source_map: &Option<Lrc<SourceMap>>,
|
||||
span: &mut MultiSpan,
|
||||
always_backtrace: bool,
|
||||
) -> bool {
|
||||
let sm = match source_map {
|
||||
Some(ref sm) => sm,
|
||||
None => return false,
|
||||
};
|
||||
children: &mut Vec<SubDiagnostic>,
|
||||
backtrace: bool,
|
||||
) {
|
||||
for span in iter::once(span).chain(children.iter_mut().map(|child| &mut child.span)) {
|
||||
self.render_multispan_macro_backtrace(span, backtrace);
|
||||
}
|
||||
}
|
||||
|
||||
let mut before_after: Vec<(Span, Span)> = vec![];
|
||||
fn render_multispan_macro_backtrace(&self, span: &mut MultiSpan, always_backtrace: bool) {
|
||||
let mut new_labels: Vec<(Span, String)> = vec![];
|
||||
|
||||
// First, find all the spans in <*macros> and point instead at their use site
|
||||
for sp in span.primary_spans() {
|
||||
for &sp in span.primary_spans() {
|
||||
if sp.is_dummy() {
|
||||
continue;
|
||||
}
|
||||
let call_sp = sm.call_span_if_macro(*sp);
|
||||
if call_sp != *sp && !always_backtrace {
|
||||
before_after.push((*sp, call_sp));
|
||||
}
|
||||
|
||||
// FIXME(eddyb) use `retain` on `macro_backtrace` to remove all the
|
||||
// entries we don't want to print, to make sure the indices being
|
||||
// printed are contiguous (or omitted if there's only one entry).
|
||||
let macro_backtrace: Vec<_> = sp.macro_backtrace().collect();
|
||||
let backtrace_len = macro_backtrace.len();
|
||||
for (i, trace) in macro_backtrace.iter().rev().enumerate() {
|
||||
// Only show macro locations that are local
|
||||
// and display them like a span_note
|
||||
if trace.def_site.is_dummy() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if always_backtrace {
|
||||
new_labels.push((
|
||||
trace.def_site,
|
||||
format!(
|
||||
"in this expansion of `{}`{}",
|
||||
trace.kind.descr(),
|
||||
if backtrace_len > 2 {
|
||||
// if backtrace_len == 1 it'll be pointed
|
||||
// at by "in this macro invocation"
|
||||
if macro_backtrace.len() > 2 {
|
||||
// if macro_backtrace.len() == 1 it'll be
|
||||
// pointed at by "in this macro invocation"
|
||||
format!(" (#{})", i + 1)
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
},
|
||||
),
|
||||
));
|
||||
}
|
||||
// Check to make sure we're not in any <*macros>
|
||||
if !sm.span_to_filename(trace.def_site).is_macros()
|
||||
&& matches!(trace.kind, ExpnKind::Macro(MacroKind::Bang, _))
|
||||
|
||||
// Don't add a label on the call site if the diagnostic itself
|
||||
// already points to (a part of) that call site, as the label
|
||||
// is meant for showing the relevant invocation when the actual
|
||||
// diagnostic is pointing to some part of macro definition.
|
||||
//
|
||||
// This also handles the case where an external span got replaced
|
||||
// with the call site span by `fix_multispans_in_extern_macros`.
|
||||
//
|
||||
// NB: `-Zmacro-backtrace` overrides this, for uniformity, as the
|
||||
// "in this expansion of" label above is always added in that mode,
|
||||
// and it needs an "in this macro invocation" label to match that.
|
||||
let redundant_span = trace.call_site.contains(sp);
|
||||
|
||||
if !redundant_span && matches!(trace.kind, ExpnKind::Macro(MacroKind::Bang, _))
|
||||
|| always_backtrace
|
||||
{
|
||||
new_labels.push((
|
||||
trace.call_site,
|
||||
format!(
|
||||
"in this macro invocation{}",
|
||||
if backtrace_len > 2 && always_backtrace {
|
||||
if macro_backtrace.len() > 2 && always_backtrace {
|
||||
// only specify order when the macro
|
||||
// backtrace is multiple levels deep
|
||||
format!(" (#{})", i + 1)
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
},
|
||||
),
|
||||
));
|
||||
if !always_backtrace {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !always_backtrace {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (label_span, label_text) in new_labels {
|
||||
span.push_span_label(label_span, label_text);
|
||||
}
|
||||
for sp_label in span.span_labels() {
|
||||
if sp_label.span.is_dummy() {
|
||||
continue;
|
||||
}
|
||||
if sm.span_to_filename(sp_label.span.clone()).is_macros() && !always_backtrace {
|
||||
if let Some(use_site) = sp_label.span.macro_backtrace().last() {
|
||||
before_after.push((sp_label.span, use_site.call_site));
|
||||
}
|
||||
}
|
||||
}
|
||||
// After we have them, make sure we replace these 'bad' def sites with their use sites
|
||||
let spans_updated = !before_after.is_empty();
|
||||
for (before, after) in before_after {
|
||||
span.replace(before, after);
|
||||
}
|
||||
}
|
||||
|
||||
spans_updated
|
||||
// This does a small "fix" for multispans by looking to see if it can find any that
|
||||
// point directly at <*macros>. Since these are often difficult to read, this
|
||||
// will change the span to point at the use site.
|
||||
fn fix_multispans_in_extern_macros(
|
||||
&self,
|
||||
source_map: &Option<Lrc<SourceMap>>,
|
||||
span: &mut MultiSpan,
|
||||
children: &mut Vec<SubDiagnostic>,
|
||||
) {
|
||||
for span in iter::once(span).chain(children.iter_mut().map(|child| &mut child.span)) {
|
||||
self.fix_multispan_in_extern_macros(source_map, span);
|
||||
}
|
||||
}
|
||||
|
||||
// This "fixes" MultiSpans that contain Spans that are pointing to locations inside of
|
||||
// <*macros>. Since these locations are often difficult to read, we move these Spans from
|
||||
// <*macros> to their corresponding use site.
|
||||
fn fix_multispan_in_extern_macros(
|
||||
&self,
|
||||
source_map: &Option<Lrc<SourceMap>>,
|
||||
span: &mut MultiSpan,
|
||||
) {
|
||||
let sm = match source_map {
|
||||
Some(ref sm) => sm,
|
||||
None => return,
|
||||
};
|
||||
|
||||
// First, find all the spans in <*macros> and point instead at their use site
|
||||
let replacements: Vec<(Span, Span)> = span
|
||||
.primary_spans()
|
||||
.iter()
|
||||
.copied()
|
||||
.chain(span.span_labels().iter().map(|sp_label| sp_label.span))
|
||||
.filter_map(|sp| {
|
||||
if !sp.is_dummy() && sm.span_to_filename(sp).is_macros() {
|
||||
let maybe_callsite = sp.source_callsite();
|
||||
if sp != maybe_callsite {
|
||||
return Some((sp, maybe_callsite));
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.collect();
|
||||
|
||||
// After we have them, make sure we replace these 'bad' def sites with their use sites
|
||||
for (from, to) in replacements {
|
||||
span.replace(from, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -424,12 +473,12 @@ impl Emitter for EmitterWriter {
|
|||
let mut children = diag.children.clone();
|
||||
let (mut primary_span, suggestions) = self.primary_span_formatted(&diag);
|
||||
|
||||
self.fix_multispans_in_std_macros(
|
||||
self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
|
||||
&self.sm,
|
||||
&mut primary_span,
|
||||
&mut children,
|
||||
&diag.level,
|
||||
self.external_macro_backtrace,
|
||||
self.macro_backtrace,
|
||||
);
|
||||
|
||||
self.emit_messages_default(
|
||||
|
@ -508,7 +557,7 @@ pub struct EmitterWriter {
|
|||
ui_testing: bool,
|
||||
terminal_width: Option<usize>,
|
||||
|
||||
external_macro_backtrace: bool,
|
||||
macro_backtrace: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -525,7 +574,7 @@ impl EmitterWriter {
|
|||
short_message: bool,
|
||||
teach: bool,
|
||||
terminal_width: Option<usize>,
|
||||
external_macro_backtrace: bool,
|
||||
macro_backtrace: bool,
|
||||
) -> EmitterWriter {
|
||||
let dst = Destination::from_stderr(color_config);
|
||||
EmitterWriter {
|
||||
|
@ -535,7 +584,7 @@ impl EmitterWriter {
|
|||
teach,
|
||||
ui_testing: false,
|
||||
terminal_width,
|
||||
external_macro_backtrace,
|
||||
macro_backtrace,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,7 +595,7 @@ impl EmitterWriter {
|
|||
teach: bool,
|
||||
colored: bool,
|
||||
terminal_width: Option<usize>,
|
||||
external_macro_backtrace: bool,
|
||||
macro_backtrace: bool,
|
||||
) -> EmitterWriter {
|
||||
EmitterWriter {
|
||||
dst: Raw(dst, colored),
|
||||
|
@ -555,7 +604,7 @@ impl EmitterWriter {
|
|||
teach,
|
||||
ui_testing: false,
|
||||
terminal_width,
|
||||
external_macro_backtrace,
|
||||
macro_backtrace,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ pub struct JsonEmitter {
|
|||
pretty: bool,
|
||||
ui_testing: bool,
|
||||
json_rendered: HumanReadableErrorType,
|
||||
external_macro_backtrace: bool,
|
||||
macro_backtrace: bool,
|
||||
}
|
||||
|
||||
impl JsonEmitter {
|
||||
|
@ -45,7 +45,7 @@ impl JsonEmitter {
|
|||
source_map: Lrc<SourceMap>,
|
||||
pretty: bool,
|
||||
json_rendered: HumanReadableErrorType,
|
||||
external_macro_backtrace: bool,
|
||||
macro_backtrace: bool,
|
||||
) -> JsonEmitter {
|
||||
JsonEmitter {
|
||||
dst: Box::new(io::stderr()),
|
||||
|
@ -54,14 +54,14 @@ impl JsonEmitter {
|
|||
pretty,
|
||||
ui_testing: false,
|
||||
json_rendered,
|
||||
external_macro_backtrace,
|
||||
macro_backtrace,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn basic(
|
||||
pretty: bool,
|
||||
json_rendered: HumanReadableErrorType,
|
||||
external_macro_backtrace: bool,
|
||||
macro_backtrace: bool,
|
||||
) -> JsonEmitter {
|
||||
let file_path_mapping = FilePathMapping::empty();
|
||||
JsonEmitter::stderr(
|
||||
|
@ -69,7 +69,7 @@ impl JsonEmitter {
|
|||
Lrc::new(SourceMap::new(file_path_mapping)),
|
||||
pretty,
|
||||
json_rendered,
|
||||
external_macro_backtrace,
|
||||
macro_backtrace,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ impl JsonEmitter {
|
|||
source_map: Lrc<SourceMap>,
|
||||
pretty: bool,
|
||||
json_rendered: HumanReadableErrorType,
|
||||
external_macro_backtrace: bool,
|
||||
macro_backtrace: bool,
|
||||
) -> JsonEmitter {
|
||||
JsonEmitter {
|
||||
dst,
|
||||
|
@ -88,7 +88,7 @@ impl JsonEmitter {
|
|||
pretty,
|
||||
ui_testing: false,
|
||||
json_rendered,
|
||||
external_macro_backtrace,
|
||||
macro_backtrace,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,13 +245,7 @@ impl Diagnostic {
|
|||
let buf = BufWriter::default();
|
||||
let output = buf.clone();
|
||||
je.json_rendered
|
||||
.new_emitter(
|
||||
Box::new(buf),
|
||||
Some(je.sm.clone()),
|
||||
false,
|
||||
None,
|
||||
je.external_macro_backtrace,
|
||||
)
|
||||
.new_emitter(Box::new(buf), Some(je.sm.clone()), false, None, je.macro_backtrace)
|
||||
.ui_testing(je.ui_testing)
|
||||
.emit_diagnostic(diag);
|
||||
let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap();
|
||||
|
|
|
@ -336,9 +336,9 @@ pub struct HandlerFlags {
|
|||
/// If true, immediately print bugs registered with `delay_span_bug`.
|
||||
/// (rustc: see `-Z report-delayed-bugs`)
|
||||
pub report_delayed_bugs: bool,
|
||||
/// show macro backtraces even for non-local macros.
|
||||
/// (rustc: see `-Z external-macro-backtrace`)
|
||||
pub external_macro_backtrace: bool,
|
||||
/// Show macro backtraces.
|
||||
/// (rustc: see `-Z macro-backtrace`)
|
||||
pub macro_backtrace: bool,
|
||||
/// If true, identical diagnostics are reported only once.
|
||||
pub deduplicate_diagnostics: bool,
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ impl Handler {
|
|||
false,
|
||||
false,
|
||||
None,
|
||||
flags.external_macro_backtrace,
|
||||
flags.macro_backtrace,
|
||||
));
|
||||
Self::with_emitter_and_flags(emitter, flags)
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
|||
self.consume_operand(location, index);
|
||||
}
|
||||
}
|
||||
TerminatorKind::Yield { ref value, resume, drop: _ } => {
|
||||
TerminatorKind::Yield { ref value, resume, resume_arg, drop: _ } => {
|
||||
self.consume_operand(location, value);
|
||||
|
||||
// Invalidate all borrows of local places
|
||||
|
@ -170,6 +170,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
|||
self.all_facts.invalidates.push((resume, i));
|
||||
}
|
||||
}
|
||||
|
||||
self.mutate_place(location, resume_arg, Deep, JustWrite);
|
||||
}
|
||||
TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => {
|
||||
// Invalidate all borrows of local places
|
||||
|
|
|
@ -684,7 +684,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx
|
|||
}
|
||||
}
|
||||
|
||||
TerminatorKind::Yield { ref value, resume: _, drop: _ } => {
|
||||
TerminatorKind::Yield { ref value, resume: _, ref resume_arg, drop: _ } => {
|
||||
self.consume_operand(loc, (value, span), flow_state);
|
||||
|
||||
if self.movable_generator {
|
||||
|
@ -697,6 +697,8 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
self.mutate_place(loc, (resume_arg, span), Deep, JustWrite, flow_state);
|
||||
}
|
||||
|
||||
TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => {
|
||||
|
|
|
@ -581,9 +581,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
|
||||
DefiningTy::Generator(def_id, substs, movability) => {
|
||||
assert_eq!(self.mir_def_id, def_id);
|
||||
let resume_ty = substs.as_generator().resume_ty(def_id, tcx);
|
||||
let output = substs.as_generator().return_ty(def_id, tcx);
|
||||
let generator_ty = tcx.mk_generator(def_id, substs, movability);
|
||||
let inputs_and_output = self.infcx.tcx.intern_type_list(&[generator_ty, output]);
|
||||
let inputs_and_output =
|
||||
self.infcx.tcx.intern_type_list(&[generator_ty, resume_ty, output]);
|
||||
ty::Binder::dummy(inputs_and_output)
|
||||
}
|
||||
|
||||
|
|
|
@ -31,10 +31,12 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeStorageLive<'a, 'tcx> {
|
|||
self.body.local_decls.len()
|
||||
}
|
||||
|
||||
fn start_block_effect(&self, _on_entry: &mut BitSet<Local>) {
|
||||
// Nothing is live on function entry (generators only have a self
|
||||
// argument, and we don't care about that)
|
||||
assert_eq!(1, self.body.arg_count);
|
||||
fn start_block_effect(&self, on_entry: &mut BitSet<Local>) {
|
||||
// The resume argument is live on function entry (we don't care about
|
||||
// the `self` argument)
|
||||
for arg in self.body.args_iter().skip(1) {
|
||||
on_entry.insert(arg);
|
||||
}
|
||||
}
|
||||
|
||||
fn statement_effect(&self, trans: &mut GenKillSet<Local>, loc: Location) {
|
||||
|
@ -100,10 +102,12 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
|
|||
self.body.local_decls.len()
|
||||
}
|
||||
|
||||
fn start_block_effect(&self, _sets: &mut BitSet<Local>) {
|
||||
// Nothing is live on function entry (generators only have a self
|
||||
// argument, and we don't care about that)
|
||||
assert_eq!(1, self.body.arg_count);
|
||||
fn start_block_effect(&self, on_entry: &mut BitSet<Local>) {
|
||||
// The resume argument is live on function entry (we don't care about
|
||||
// the `self` argument)
|
||||
for arg in self.body.args_iter().skip(1) {
|
||||
on_entry.insert(arg);
|
||||
}
|
||||
}
|
||||
|
||||
fn before_statement_effect(&self, sets: &mut GenKillSet<Self::Idx>, loc: Location) {
|
||||
|
|
|
@ -380,7 +380,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||
self.gather_operand(discr);
|
||||
}
|
||||
|
||||
TerminatorKind::Yield { ref value, .. } => {
|
||||
TerminatorKind::Yield { ref value, resume_arg: ref place, .. } => {
|
||||
self.create_move_path(place);
|
||||
self.gather_init(place.as_ref(), InitKind::Deep);
|
||||
self.gather_operand(value);
|
||||
}
|
||||
|
||||
|
|
|
@ -192,9 +192,10 @@ const RETURNED: usize = GeneratorSubsts::RETURNED;
|
|||
/// Generator has been poisoned
|
||||
const POISONED: usize = GeneratorSubsts::POISONED;
|
||||
|
||||
struct SuspensionPoint {
|
||||
struct SuspensionPoint<'tcx> {
|
||||
state: usize,
|
||||
resume: BasicBlock,
|
||||
resume_arg: Place<'tcx>,
|
||||
drop: Option<BasicBlock>,
|
||||
storage_liveness: liveness::LiveVarSet,
|
||||
}
|
||||
|
@ -216,7 +217,7 @@ struct TransformVisitor<'tcx> {
|
|||
storage_liveness: FxHashMap<BasicBlock, liveness::LiveVarSet>,
|
||||
|
||||
// A list of suspension points, generated during the transform
|
||||
suspension_points: Vec<SuspensionPoint>,
|
||||
suspension_points: Vec<SuspensionPoint<'tcx>>,
|
||||
|
||||
// The original RETURN_PLACE local
|
||||
new_ret_local: Local,
|
||||
|
@ -303,8 +304,8 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
|
|||
Operand::Move(Place::from(self.new_ret_local)),
|
||||
None,
|
||||
)),
|
||||
TerminatorKind::Yield { ref value, resume, drop } => {
|
||||
Some((VariantIdx::new(0), Some(resume), value.clone(), drop))
|
||||
TerminatorKind::Yield { ref value, resume, resume_arg, drop } => {
|
||||
Some((VariantIdx::new(0), Some((resume, resume_arg)), value.clone(), drop))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
@ -319,13 +320,14 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
|
|||
self.make_state(state_idx, v),
|
||||
)),
|
||||
});
|
||||
let state = if let Some(resume) = resume {
|
||||
let state = if let Some((resume, resume_arg)) = resume {
|
||||
// Yield
|
||||
let state = 3 + self.suspension_points.len();
|
||||
|
||||
self.suspension_points.push(SuspensionPoint {
|
||||
state,
|
||||
resume,
|
||||
resume_arg,
|
||||
drop,
|
||||
storage_liveness: self.storage_liveness.get(&block).unwrap().clone(),
|
||||
});
|
||||
|
@ -378,28 +380,35 @@ fn make_generator_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body
|
|||
PinArgVisitor { ref_gen_ty, tcx }.visit_body(body);
|
||||
}
|
||||
|
||||
fn replace_result_variable<'tcx>(
|
||||
ret_ty: Ty<'tcx>,
|
||||
/// Allocates a new local and replaces all references of `local` with it. Returns the new local.
|
||||
///
|
||||
/// `local` will be changed to a new local decl with type `ty`.
|
||||
///
|
||||
/// Note that the new local will be uninitialized. It is the caller's responsibility to assign some
|
||||
/// valid value to it before its first use.
|
||||
fn replace_local<'tcx>(
|
||||
local: Local,
|
||||
ty: Ty<'tcx>,
|
||||
body: &mut BodyAndCache<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Local {
|
||||
let source_info = source_info(body);
|
||||
let new_ret = LocalDecl {
|
||||
let new_decl = LocalDecl {
|
||||
mutability: Mutability::Mut,
|
||||
ty: ret_ty,
|
||||
ty,
|
||||
user_ty: UserTypeProjections::none(),
|
||||
source_info,
|
||||
internal: false,
|
||||
is_block_tail: None,
|
||||
local_info: LocalInfo::Other,
|
||||
};
|
||||
let new_ret_local = Local::new(body.local_decls.len());
|
||||
body.local_decls.push(new_ret);
|
||||
body.local_decls.swap(RETURN_PLACE, new_ret_local);
|
||||
let new_local = Local::new(body.local_decls.len());
|
||||
body.local_decls.push(new_decl);
|
||||
body.local_decls.swap(local, new_local);
|
||||
|
||||
RenameLocalVisitor { from: RETURN_PLACE, to: new_ret_local, tcx }.visit_body(body);
|
||||
RenameLocalVisitor { from: local, to: new_local, tcx }.visit_body(body);
|
||||
|
||||
new_ret_local
|
||||
new_local
|
||||
}
|
||||
|
||||
struct StorageIgnored(liveness::LiveVarSet);
|
||||
|
@ -792,6 +801,10 @@ fn compute_layout<'tcx>(
|
|||
(remap, layout, storage_liveness)
|
||||
}
|
||||
|
||||
/// Replaces the entry point of `body` with a block that switches on the generator discriminant and
|
||||
/// dispatches to blocks according to `cases`.
|
||||
///
|
||||
/// After this function, the former entry point of the function will be bb1.
|
||||
fn insert_switch<'tcx>(
|
||||
body: &mut BodyAndCache<'tcx>,
|
||||
cases: Vec<(usize, BasicBlock)>,
|
||||
|
@ -885,10 +898,11 @@ fn create_generator_drop_shim<'tcx>(
|
|||
drop_clean: BasicBlock,
|
||||
) -> BodyAndCache<'tcx> {
|
||||
let mut body = body.clone();
|
||||
body.arg_count = 1; // make sure the resume argument is not included here
|
||||
|
||||
let source_info = source_info(&body);
|
||||
|
||||
let mut cases = create_cases(&mut body, transform, |point| point.drop);
|
||||
let mut cases = create_cases(&mut body, transform, Operation::Drop);
|
||||
|
||||
cases.insert(0, (UNRESUMED, drop_clean));
|
||||
|
||||
|
@ -1006,7 +1020,7 @@ fn create_generator_resume_function<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
let mut cases = create_cases(body, &transform, |point| Some(point.resume));
|
||||
let mut cases = create_cases(body, &transform, Operation::Resume);
|
||||
|
||||
use rustc::mir::interpret::PanicInfo::{ResumedAfterPanic, ResumedAfterReturn};
|
||||
|
||||
|
@ -1056,14 +1070,27 @@ fn insert_clean_drop(body: &mut BodyAndCache<'_>) -> BasicBlock {
|
|||
drop_clean
|
||||
}
|
||||
|
||||
fn create_cases<'tcx, F>(
|
||||
/// An operation that can be performed on a generator.
|
||||
#[derive(PartialEq, Copy, Clone)]
|
||||
enum Operation {
|
||||
Resume,
|
||||
Drop,
|
||||
}
|
||||
|
||||
impl Operation {
|
||||
fn target_block(self, point: &SuspensionPoint<'_>) -> Option<BasicBlock> {
|
||||
match self {
|
||||
Operation::Resume => Some(point.resume),
|
||||
Operation::Drop => point.drop,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_cases<'tcx>(
|
||||
body: &mut BodyAndCache<'tcx>,
|
||||
transform: &TransformVisitor<'tcx>,
|
||||
target: F,
|
||||
) -> Vec<(usize, BasicBlock)>
|
||||
where
|
||||
F: Fn(&SuspensionPoint) -> Option<BasicBlock>,
|
||||
{
|
||||
operation: Operation,
|
||||
) -> Vec<(usize, BasicBlock)> {
|
||||
let source_info = source_info(body);
|
||||
|
||||
transform
|
||||
|
@ -1071,12 +1098,19 @@ where
|
|||
.iter()
|
||||
.filter_map(|point| {
|
||||
// Find the target for this suspension point, if applicable
|
||||
target(point).map(|target| {
|
||||
operation.target_block(point).map(|target| {
|
||||
let block = BasicBlock::new(body.basic_blocks().len());
|
||||
let mut statements = Vec::new();
|
||||
|
||||
// Create StorageLive instructions for locals with live storage
|
||||
for i in 0..(body.local_decls.len()) {
|
||||
if i == 2 {
|
||||
// The resume argument is live on function entry. Don't insert a
|
||||
// `StorageLive`, or the following `Assign` will read from uninitialized
|
||||
// memory.
|
||||
continue;
|
||||
}
|
||||
|
||||
let l = Local::new(i);
|
||||
if point.storage_liveness.contains(l) && !transform.remap.contains_key(&l) {
|
||||
statements
|
||||
|
@ -1084,6 +1118,18 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
if operation == Operation::Resume {
|
||||
// Move the resume argument to the destination place of the `Yield` terminator
|
||||
let resume_arg = Local::new(2); // 0 = return, 1 = self
|
||||
statements.push(Statement {
|
||||
source_info,
|
||||
kind: StatementKind::Assign(box (
|
||||
point.resume_arg,
|
||||
Rvalue::Use(Operand::Move(resume_arg.into())),
|
||||
)),
|
||||
});
|
||||
}
|
||||
|
||||
// Then jump to the real target
|
||||
body.basic_blocks_mut().push(BasicBlockData {
|
||||
statements,
|
||||
|
@ -1138,7 +1184,29 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
|
|||
|
||||
// We rename RETURN_PLACE which has type mir.return_ty to new_ret_local
|
||||
// RETURN_PLACE then is a fresh unused local with type ret_ty.
|
||||
let new_ret_local = replace_result_variable(ret_ty, body, tcx);
|
||||
let new_ret_local = replace_local(RETURN_PLACE, ret_ty, body, tcx);
|
||||
|
||||
// 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);
|
||||
|
||||
// When first entering the generator, move the resume argument into its new local.
|
||||
let source_info = source_info(body);
|
||||
let stmts = &mut body.basic_blocks_mut()[BasicBlock::new(0)].statements;
|
||||
stmts.insert(
|
||||
0,
|
||||
Statement {
|
||||
source_info,
|
||||
kind: StatementKind::Assign(box (
|
||||
new_resume_local.into(),
|
||||
Rvalue::Use(Operand::Move(resume_local.into())),
|
||||
)),
|
||||
},
|
||||
);
|
||||
|
||||
// Extract locals which are live across suspension point into `layout`
|
||||
// `remap` gives a mapping from local indices onto generator struct indices
|
||||
|
@ -1162,9 +1230,9 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
|
|||
};
|
||||
transform.visit_body(body);
|
||||
|
||||
// Update our MIR struct to reflect the changed we've made
|
||||
// Update our MIR struct to reflect the changes we've made
|
||||
body.yield_ty = None;
|
||||
body.arg_count = 1;
|
||||
body.arg_count = 2; // self, resume arg
|
||||
body.spread_arg = None;
|
||||
body.generator_layout = Some(layout);
|
||||
|
||||
|
|
|
@ -230,18 +230,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
block = unpack!(this.stmt_expr(block, expr, None));
|
||||
block.and(this.unit_rvalue())
|
||||
}
|
||||
ExprKind::Yield { value } => {
|
||||
let value = unpack!(block = this.as_operand(block, scope, value));
|
||||
let resume = this.cfg.start_new_block();
|
||||
let cleanup = this.generator_drop_cleanup();
|
||||
this.cfg.terminate(
|
||||
block,
|
||||
source_info,
|
||||
TerminatorKind::Yield { value: value, resume: resume, drop: cleanup },
|
||||
);
|
||||
resume.and(this.unit_rvalue())
|
||||
}
|
||||
ExprKind::Literal { .. }
|
||||
ExprKind::Yield { .. }
|
||||
| ExprKind::Literal { .. }
|
||||
| ExprKind::StaticRef { .. }
|
||||
| ExprKind::Block { .. }
|
||||
| ExprKind::Match { .. }
|
||||
|
|
|
@ -50,6 +50,7 @@ impl Category {
|
|||
| ExprKind::Adt { .. }
|
||||
| ExprKind::Borrow { .. }
|
||||
| ExprKind::AddressOf { .. }
|
||||
| ExprKind::Yield { .. }
|
||||
| ExprKind::Call { .. } => Some(Category::Rvalue(RvalueFunc::Into)),
|
||||
|
||||
ExprKind::Array { .. }
|
||||
|
@ -63,7 +64,6 @@ impl Category {
|
|||
| ExprKind::Repeat { .. }
|
||||
| ExprKind::Assign { .. }
|
||||
| ExprKind::AssignOp { .. }
|
||||
| ExprKind::Yield { .. }
|
||||
| ExprKind::InlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
|
||||
|
||||
ExprKind::Literal { .. } | ExprKind::StaticRef { .. } => Some(Category::Constant),
|
||||
|
|
|
@ -365,6 +365,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
block.unit()
|
||||
}
|
||||
|
||||
ExprKind::Yield { value } => {
|
||||
let scope = this.local_scope();
|
||||
let value = unpack!(block = this.as_operand(block, scope, value));
|
||||
let resume = this.cfg.start_new_block();
|
||||
let cleanup = this.generator_drop_cleanup();
|
||||
this.cfg.terminate(
|
||||
block,
|
||||
source_info,
|
||||
TerminatorKind::Yield {
|
||||
value,
|
||||
resume,
|
||||
resume_arg: destination.clone(),
|
||||
drop: cleanup,
|
||||
},
|
||||
);
|
||||
resume.unit()
|
||||
}
|
||||
|
||||
// these are the cases that are more naturally handled by some other mode
|
||||
ExprKind::Unary { .. }
|
||||
| ExprKind::Binary { .. }
|
||||
|
@ -376,8 +394,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
| ExprKind::Tuple { .. }
|
||||
| ExprKind::Closure { .. }
|
||||
| ExprKind::Literal { .. }
|
||||
| ExprKind::StaticRef { .. }
|
||||
| ExprKind::Yield { .. } => {
|
||||
| ExprKind::StaticRef { .. } => {
|
||||
debug_assert!(match Category::of(&expr.kind).unwrap() {
|
||||
// should be handled above
|
||||
Category::Rvalue(RvalueFunc::Into) => false,
|
||||
|
|
|
@ -68,6 +68,12 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
|
|||
let fn_sig = cx.tables().liberated_fn_sigs()[id];
|
||||
let fn_def_id = tcx.hir().local_def_id(id);
|
||||
|
||||
let safety = match fn_sig.unsafety {
|
||||
hir::Unsafety::Normal => Safety::Safe,
|
||||
hir::Unsafety::Unsafe => Safety::FnUnsafe,
|
||||
};
|
||||
|
||||
let body = tcx.hir().body(body_id);
|
||||
let ty = tcx.type_of(fn_def_id);
|
||||
let mut abi = fn_sig.abi;
|
||||
let implicit_argument = match ty.kind {
|
||||
|
@ -75,21 +81,25 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
|
|||
// HACK(eddyb) Avoid having RustCall on closures,
|
||||
// as it adds unnecessary (and wrong) auto-tupling.
|
||||
abi = Abi::Rust;
|
||||
Some(ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None))
|
||||
vec![ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None)]
|
||||
}
|
||||
ty::Generator(..) => {
|
||||
let gen_ty = tcx.body_tables(body_id).node_type(id);
|
||||
Some(ArgInfo(gen_ty, None, None, None))
|
||||
|
||||
// The resume argument may be missing, in that case we need to provide it here.
|
||||
// It will always be `()` in this case.
|
||||
if body.params.is_empty() {
|
||||
vec![
|
||||
ArgInfo(gen_ty, None, None, None),
|
||||
ArgInfo(tcx.mk_unit(), None, None, None),
|
||||
]
|
||||
} else {
|
||||
vec![ArgInfo(gen_ty, None, None, None)]
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
_ => vec![],
|
||||
};
|
||||
|
||||
let safety = match fn_sig.unsafety {
|
||||
hir::Unsafety::Normal => Safety::Safe,
|
||||
hir::Unsafety::Unsafe => Safety::FnUnsafe,
|
||||
};
|
||||
|
||||
let body = tcx.hir().body(body_id);
|
||||
let explicit_arguments = body.params.iter().enumerate().map(|(index, arg)| {
|
||||
let owner_id = tcx.hir().body_owner(body_id);
|
||||
let opt_ty_info;
|
||||
|
|
|
@ -624,7 +624,7 @@ impl DebuggingOptions {
|
|||
treat_err_as_bug: self.treat_err_as_bug,
|
||||
dont_buffer_diagnostics: self.dont_buffer_diagnostics,
|
||||
report_delayed_bugs: self.report_delayed_bugs,
|
||||
external_macro_backtrace: self.external_macro_backtrace,
|
||||
macro_backtrace: self.macro_backtrace,
|
||||
deduplicate_diagnostics: self.deduplicate_diagnostics.unwrap_or(true),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -776,8 +776,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
|||
"treat error number `val` that occurs as bug"),
|
||||
report_delayed_bugs: bool = (false, parse_bool, [TRACKED],
|
||||
"immediately print bugs registered with `delay_span_bug`"),
|
||||
external_macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
|
||||
"show macro backtraces even for non-local macros"),
|
||||
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
|
||||
"show macro backtraces"),
|
||||
teach: bool = (false, parse_bool, [TRACKED],
|
||||
"show extended diagnostic help"),
|
||||
terminal_width: Option<usize> = (None, parse_opt_uint, [UNTRACKED],
|
||||
|
|
|
@ -858,7 +858,7 @@ fn default_emitter(
|
|||
source_map: &Lrc<source_map::SourceMap>,
|
||||
emitter_dest: Option<Box<dyn Write + Send>>,
|
||||
) -> Box<dyn Emitter + sync::Send> {
|
||||
let external_macro_backtrace = sopts.debugging_opts.external_macro_backtrace;
|
||||
let macro_backtrace = sopts.debugging_opts.macro_backtrace;
|
||||
match (sopts.error_format, emitter_dest) {
|
||||
(config::ErrorOutputType::HumanReadable(kind), dst) => {
|
||||
let (short, color_config) = kind.unzip();
|
||||
|
@ -867,7 +867,7 @@ fn default_emitter(
|
|||
let emitter = AnnotateSnippetEmitterWriter::new(
|
||||
Some(source_map.clone()),
|
||||
short,
|
||||
external_macro_backtrace,
|
||||
macro_backtrace,
|
||||
);
|
||||
Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing()))
|
||||
} else {
|
||||
|
@ -878,7 +878,7 @@ fn default_emitter(
|
|||
short,
|
||||
sopts.debugging_opts.teach,
|
||||
sopts.debugging_opts.terminal_width,
|
||||
external_macro_backtrace,
|
||||
macro_backtrace,
|
||||
),
|
||||
Some(dst) => EmitterWriter::new(
|
||||
dst,
|
||||
|
@ -887,7 +887,7 @@ fn default_emitter(
|
|||
false, // no teach messages when writing to a buffer
|
||||
false, // no colors when writing to a buffer
|
||||
None, // no terminal width
|
||||
external_macro_backtrace,
|
||||
macro_backtrace,
|
||||
),
|
||||
};
|
||||
Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing()))
|
||||
|
@ -899,7 +899,7 @@ fn default_emitter(
|
|||
source_map.clone(),
|
||||
pretty,
|
||||
json_rendered,
|
||||
external_macro_backtrace,
|
||||
macro_backtrace,
|
||||
)
|
||||
.ui_testing(sopts.debugging_opts.ui_testing()),
|
||||
),
|
||||
|
@ -910,7 +910,7 @@ fn default_emitter(
|
|||
source_map.clone(),
|
||||
pretty,
|
||||
json_rendered,
|
||||
external_macro_backtrace,
|
||||
macro_backtrace,
|
||||
)
|
||||
.ui_testing(sopts.debugging_opts.ui_testing()),
|
||||
),
|
||||
|
|
|
@ -945,14 +945,6 @@ impl SourceMap {
|
|||
_ => None,
|
||||
})
|
||||
}
|
||||
pub fn call_span_if_macro(&self, sp: Span) -> Span {
|
||||
if self.span_to_filename(sp.clone()).is_macros() {
|
||||
if let Some(use_site) = sp.macro_backtrace().last() {
|
||||
return use_site.call_site;
|
||||
}
|
||||
}
|
||||
sp
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
@ -227,8 +227,8 @@ fn dtorck_constraint_for_ty<'tcx>(
|
|||
// In particular, skipping over `_interior` is safe
|
||||
// because any side-effects from dropping `_interior` can
|
||||
// only take place through references with lifetimes
|
||||
// derived from lifetimes attached to the upvars, and we
|
||||
// *do* incorporate the upvars here.
|
||||
// derived from lifetimes attached to the upvars and resume
|
||||
// argument, and we *do* incorporate those here.
|
||||
|
||||
constraints.outlives.extend(
|
||||
substs
|
||||
|
@ -236,6 +236,7 @@ fn dtorck_constraint_for_ty<'tcx>(
|
|||
.upvar_tys(def_id, tcx)
|
||||
.map(|t| -> ty::subst::GenericArg<'tcx> { t.into() }),
|
||||
);
|
||||
constraints.outlives.push(substs.as_generator().resume_ty(def_id, tcx).into());
|
||||
}
|
||||
|
||||
ty::Adt(def, substs) => {
|
||||
|
|
|
@ -92,8 +92,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
.into(),
|
||||
GenericParamDefKind::Const => span_bug!(expr.span, "closure has const param"),
|
||||
});
|
||||
if let Some(GeneratorTypes { yield_ty, interior, movability }) = generator_types {
|
||||
if let Some(GeneratorTypes { resume_ty, yield_ty, interior, movability }) = generator_types
|
||||
{
|
||||
let generator_substs = substs.as_generator();
|
||||
self.demand_eqtype(
|
||||
expr.span,
|
||||
resume_ty,
|
||||
generator_substs.resume_ty(expr_def_id, self.tcx),
|
||||
);
|
||||
self.demand_eqtype(
|
||||
expr.span,
|
||||
yield_ty,
|
||||
|
@ -259,8 +265,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
_ => return None,
|
||||
}
|
||||
} else {
|
||||
// Generators cannot have explicit arguments.
|
||||
vec![]
|
||||
// Generators with a `()` resume type may be defined with 0 or 1 explicit arguments,
|
||||
// else they must have exactly 1 argument. For now though, just give up in this case.
|
||||
return None;
|
||||
};
|
||||
|
||||
let ret_param_ty = projection.skip_binder().ty;
|
||||
|
|
|
@ -1796,9 +1796,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
expr: &'tcx hir::Expr<'tcx>,
|
||||
src: &'tcx hir::YieldSource,
|
||||
) -> Ty<'tcx> {
|
||||
match self.yield_ty {
|
||||
Some(ty) => {
|
||||
self.check_expr_coercable_to_type(&value, ty);
|
||||
match self.resume_yield_tys {
|
||||
Some((resume_ty, yield_ty)) => {
|
||||
self.check_expr_coercable_to_type(&value, yield_ty);
|
||||
|
||||
resume_ty
|
||||
}
|
||||
// Given that this `yield` expression was generated as a result of lowering a `.await`,
|
||||
// we know that the yield type must be `()`; however, the context won't contain this
|
||||
|
@ -1806,6 +1808,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// value's type against `()` (this check should always hold).
|
||||
None if src == &hir::YieldSource::Await => {
|
||||
self.check_expr_coercable_to_type(&value, self.tcx.mk_unit());
|
||||
self.tcx.mk_unit()
|
||||
}
|
||||
_ => {
|
||||
struct_span_err!(
|
||||
|
@ -1815,9 +1818,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
"yield expression outside of generator literal"
|
||||
)
|
||||
.emit();
|
||||
self.tcx.mk_unit()
|
||||
}
|
||||
}
|
||||
self.tcx.mk_unit()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -573,7 +573,7 @@ pub struct FnCtxt<'a, '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>>,
|
||||
resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>,
|
||||
|
||||
ps: RefCell<UnsafetyState>,
|
||||
|
||||
|
@ -1251,6 +1251,9 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
|
|||
/// includes yield), it returns back some information about the yield
|
||||
/// points.
|
||||
struct GeneratorTypes<'tcx> {
|
||||
/// Type of generator argument / values returned by `yield`.
|
||||
resume_ty: Ty<'tcx>,
|
||||
|
||||
/// Type of value that is yielded.
|
||||
yield_ty: Ty<'tcx>,
|
||||
|
||||
|
@ -1311,7 +1314,11 @@ fn check_fn<'a, 'tcx>(
|
|||
let yield_ty = fcx
|
||||
.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
|
||||
fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
|
||||
fcx.yield_ty = Some(yield_ty);
|
||||
|
||||
// Resume type defaults to `()` if the generator has no argument.
|
||||
let resume_ty = fn_sig.inputs().get(0).map(|ty| *ty).unwrap_or_else(|| tcx.mk_unit());
|
||||
|
||||
fcx.resume_yield_tys = Some((resume_ty, yield_ty));
|
||||
}
|
||||
|
||||
let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id));
|
||||
|
@ -1364,8 +1371,11 @@ fn check_fn<'a, 'tcx>(
|
|||
let interior = fcx
|
||||
.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
|
||||
fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
|
||||
|
||||
let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
|
||||
Some(GeneratorTypes {
|
||||
yield_ty: fcx.yield_ty.unwrap(),
|
||||
resume_ty,
|
||||
yield_ty,
|
||||
interior,
|
||||
movability: can_be_generator.unwrap(),
|
||||
})
|
||||
|
@ -2767,7 +2777,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
err_count_on_creation: inh.tcx.sess.err_count(),
|
||||
ret_coercion: None,
|
||||
ret_coercion_span: RefCell::new(None),
|
||||
yield_ty: None,
|
||||
resume_yield_tys: None,
|
||||
ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
|
||||
diverges: Cell::new(Diverges::Maybe),
|
||||
has_errors: Cell::new(false),
|
||||
|
|
|
@ -1189,7 +1189,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics {
|
|||
// and we don't do that for closures.
|
||||
if let Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(.., gen), .. }) = node {
|
||||
let dummy_args = if gen.is_some() {
|
||||
&["<yield_ty>", "<return_ty>", "<witness>"][..]
|
||||
&["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>"][..]
|
||||
} else {
|
||||
&["<closure_kind>", "<closure_signature>"][..]
|
||||
};
|
||||
|
|
|
@ -40,7 +40,10 @@ impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
|
|||
// Safe because we're !Unpin + !Drop mapping to a ?Unpin value
|
||||
let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
|
||||
let _guard = unsafe { set_task_context(cx) };
|
||||
match gen.resume() {
|
||||
match gen.resume(
|
||||
#[cfg(not(bootstrap))]
|
||||
(),
|
||||
) {
|
||||
GeneratorState::Yielded(()) => Poll::Pending,
|
||||
GeneratorState::Complete(x) => Poll::Ready(x),
|
||||
}
|
||||
|
|
|
@ -78,9 +78,9 @@ fn main() {
|
|||
_zzz(); // #break
|
||||
a = c;
|
||||
};
|
||||
Pin::new(&mut b).resume();
|
||||
Pin::new(&mut b).resume();
|
||||
Pin::new(&mut b).resume();
|
||||
Pin::new(&mut b).resume(());
|
||||
Pin::new(&mut b).resume(());
|
||||
Pin::new(&mut b).resume(());
|
||||
_zzz(); // #break
|
||||
}
|
||||
|
||||
|
|
|
@ -57,11 +57,11 @@ fn main() {
|
|||
println!("{} {} {}", a, c, d);
|
||||
};
|
||||
_zzz(); // #break
|
||||
Pin::new(&mut b).resume();
|
||||
Pin::new(&mut b).resume(());
|
||||
_zzz(); // #break
|
||||
Pin::new(&mut b).resume();
|
||||
Pin::new(&mut b).resume(());
|
||||
_zzz(); // #break
|
||||
Pin::new(&mut b).resume();
|
||||
Pin::new(&mut b).resume(());
|
||||
_zzz(); // #break
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ fn main() {
|
|||
yield;
|
||||
};
|
||||
let mut b = move || {
|
||||
Pin::new(&mut a).resume();
|
||||
Pin::new(&mut a).resume(());
|
||||
yield;
|
||||
};
|
||||
|
||||
|
|
|
@ -13,12 +13,12 @@ fn main() {
|
|||
|
||||
// START rustc.main-{{closure}}.generator_drop.0.mir
|
||||
// bb0: {
|
||||
// _5 = discriminant((*_1));
|
||||
// switchInt(move _5) -> [0u32: bb4, 3u32: bb7, otherwise: bb8];
|
||||
// _7 = discriminant((*_1));
|
||||
// switchInt(move _7) -> [0u32: bb4, 3u32: bb7, otherwise: bb8];
|
||||
// }
|
||||
// bb1: {
|
||||
// StorageDead(_4);
|
||||
// StorageDead(_3);
|
||||
// StorageDead(_2);
|
||||
// goto -> bb5;
|
||||
// }
|
||||
// bb2: {
|
||||
|
@ -37,8 +37,8 @@ fn main() {
|
|||
// goto -> bb3;
|
||||
// }
|
||||
// bb7: {
|
||||
// StorageLive(_2);
|
||||
// StorageLive(_3);
|
||||
// StorageLive(_4);
|
||||
// goto -> bb1;
|
||||
// }
|
||||
// bb8: {
|
||||
|
|
|
@ -31,81 +31,81 @@ fn main() {
|
|||
|
||||
// START rustc.main-{{closure}}.StateTransform.before.mir
|
||||
// ...
|
||||
// let _2: Foo;
|
||||
// let _3: Foo;
|
||||
// ...
|
||||
// let mut _7: Foo;
|
||||
// let mut _8: Foo;
|
||||
// ...
|
||||
// let mut _9: Bar;
|
||||
// let mut _10: Bar;
|
||||
// scope 1 {
|
||||
// debug a => _2;
|
||||
// let _3: Bar;
|
||||
// debug a => _3;
|
||||
// let _4: Bar;
|
||||
// scope 2 {
|
||||
// debug b => _3;
|
||||
// debug b => _4;
|
||||
// }
|
||||
// }
|
||||
// bb0: {
|
||||
// StorageLive(_2);
|
||||
// _2 = Foo(const 5i32,);
|
||||
// StorageLive(_3);
|
||||
// _3 = Bar(const 6i32,);
|
||||
// _3 = Foo(const 5i32,);
|
||||
// StorageLive(_4);
|
||||
// _4 = Bar(const 6i32,);
|
||||
// ...
|
||||
// _1 = suspend(move _5) -> [resume: bb2, drop: bb4];
|
||||
// _1 = suspend(move _6) -> [resume: bb2, drop: bb4];
|
||||
// }
|
||||
// bb1 (cleanup): {
|
||||
// resume;
|
||||
// }
|
||||
// bb2: {
|
||||
// ...
|
||||
// StorageLive(_6);
|
||||
// StorageLive(_7);
|
||||
// _7 = move _2;
|
||||
// _6 = const take::<Foo>(move _7) -> [return: bb7, unwind: bb9];
|
||||
// StorageLive(_8);
|
||||
// _8 = move _3;
|
||||
// _7 = const take::<Foo>(move _8) -> [return: bb7, unwind: bb9];
|
||||
// }
|
||||
// bb3 (cleanup): {
|
||||
// StorageDead(_2);
|
||||
// StorageDead(_3);
|
||||
// drop(_1) -> bb1;
|
||||
// }
|
||||
// bb4: {
|
||||
// ...
|
||||
// StorageDead(_3);
|
||||
// drop(_2) -> [return: bb5, unwind: bb3];
|
||||
// StorageDead(_4);
|
||||
// drop(_3) -> [return: bb5, unwind: bb3];
|
||||
// }
|
||||
// bb5: {
|
||||
// StorageDead(_2);
|
||||
// StorageDead(_3);
|
||||
// drop(_1) -> [return: bb6, unwind: bb1];
|
||||
// }
|
||||
// bb6: {
|
||||
// generator_drop;
|
||||
// }
|
||||
// bb7: {
|
||||
// StorageDead(_8);
|
||||
// StorageDead(_7);
|
||||
// StorageDead(_6);
|
||||
// StorageLive(_8);
|
||||
// StorageLive(_9);
|
||||
// _9 = move _3;
|
||||
// _8 = const take::<Bar>(move _9) -> [return: bb10, unwind: bb11];
|
||||
// StorageLive(_10);
|
||||
// _10 = move _4;
|
||||
// _9 = const take::<Bar>(move _10) -> [return: bb10, unwind: bb11];
|
||||
// }
|
||||
// bb8 (cleanup): {
|
||||
// StorageDead(_4);
|
||||
// StorageDead(_3);
|
||||
// StorageDead(_2);
|
||||
// drop(_1) -> bb1;
|
||||
// }
|
||||
// bb9 (cleanup): {
|
||||
// StorageDead(_8);
|
||||
// StorageDead(_7);
|
||||
// StorageDead(_6);
|
||||
// goto -> bb8;
|
||||
// }
|
||||
// bb10: {
|
||||
// StorageDead(_10);
|
||||
// StorageDead(_9);
|
||||
// StorageDead(_8);
|
||||
// ...
|
||||
// StorageDead(_4);
|
||||
// StorageDead(_3);
|
||||
// StorageDead(_2);
|
||||
// drop(_1) -> [return: bb12, unwind: bb1];
|
||||
// }
|
||||
// bb11 (cleanup): {
|
||||
// StorageDead(_10);
|
||||
// StorageDead(_9);
|
||||
// StorageDead(_8);
|
||||
// goto -> bb8;
|
||||
// }
|
||||
// bb12: {
|
||||
|
|
|
@ -16,7 +16,7 @@ fn main() {
|
|||
yield;
|
||||
};
|
||||
panic::catch_unwind(panic::AssertUnwindSafe(|| {
|
||||
let x = Pin::new(&mut g).resume();
|
||||
let x = Pin::new(&mut g).resume(());
|
||||
}));
|
||||
Pin::new(&mut g).resume();
|
||||
Pin::new(&mut g).resume(());
|
||||
}
|
||||
|
|
|
@ -175,4 +175,5 @@ LL | f!("Foo\nbar [BarF] bar\nbaz");
|
|||
bar [BarF] bar
|
||||
^^^^
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ LL | #[derive(HashStable)]
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/27812
|
||||
= help: add `#![feature(rustc_private)]` to the crate attributes to enable
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ LL | custom_lint_pass_macro!();
|
|||
| -------------------------- in this macro invocation
|
||||
|
|
||||
= help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ LL | static A: usize = 0;
|
|||
| ^^^^^^^^^^^^^^^^^^^^ the trait `std::alloc::GlobalAlloc` is not implemented for `usize`
|
||||
|
|
||||
= note: required by `std::alloc::GlobalAlloc::alloc`
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: the trait bound `usize: std::alloc::GlobalAlloc` is not satisfied
|
||||
--> $DIR/not-an-allocator.rs:2:1
|
||||
|
@ -13,6 +14,7 @@ LL | static A: usize = 0;
|
|||
| ^^^^^^^^^^^^^^^^^^^^ the trait `std::alloc::GlobalAlloc` is not implemented for `usize`
|
||||
|
|
||||
= note: required by `std::alloc::GlobalAlloc::dealloc`
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: the trait bound `usize: std::alloc::GlobalAlloc` is not satisfied
|
||||
--> $DIR/not-an-allocator.rs:2:1
|
||||
|
@ -21,6 +23,7 @@ LL | static A: usize = 0;
|
|||
| ^^^^^^^^^^^^^^^^^^^^ the trait `std::alloc::GlobalAlloc` is not implemented for `usize`
|
||||
|
|
||||
= note: required by `std::alloc::GlobalAlloc::realloc`
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: the trait bound `usize: std::alloc::GlobalAlloc` is not satisfied
|
||||
--> $DIR/not-an-allocator.rs:2:1
|
||||
|
@ -29,6 +32,7 @@ LL | static A: usize = 0;
|
|||
| ^^^^^^^^^^^^^^^^^^^^ the trait `std::alloc::GlobalAlloc` is not implemented for `usize`
|
||||
|
|
||||
= note: required by `std::alloc::GlobalAlloc::alloc_zeroed`
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ LL | static A: System = System;
|
|||
LL | #[global_allocator]
|
||||
LL | static B: System = System;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot define a new global allocator
|
||||
|
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ fn main() {
|
|||
let mut g = || {
|
||||
yield;
|
||||
};
|
||||
Pin::new(&mut g).resume(); // Yields once.
|
||||
Pin::new(&mut g).resume(); // Completes here.
|
||||
Pin::new(&mut g).resume(); // Panics here.
|
||||
Pin::new(&mut g).resume(()); // Yields once.
|
||||
Pin::new(&mut g).resume(()); // Completes here.
|
||||
Pin::new(&mut g).resume(()); // Panics here.
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ LL | x.x[0];
|
|||
| ------ borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ LL | static settings_dir: String = format!("");
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/49146
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ LL | aaa!(D);
|
|||
...
|
||||
LL | sss!();
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ error: requires at least a format string argument
|
|||
LL | format!();
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: expected token: `,`
|
||||
--> $DIR/bad-format-args.rs:3:16
|
||||
|
|
|
@ -3,6 +3,8 @@ error[E0600]: cannot apply unary operator `!` to type `&'static str`
|
|||
|
|
||||
LL | assert!("foo");
|
||||
| ^^^^^^^^^^^^^^^ cannot apply unary operator `!`
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ LL | #[cfg(feature = $expr)]
|
|||
...
|
||||
LL | generate_s10!(concat!("nonexistent"));
|
||||
| -------------------------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ LL | #[cfg_attr(all(), unknown)]
|
|||
...
|
||||
LL | foo!();
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ LL | println!("{:?}", [0_usize; 33]);
|
|||
|
|
||||
= note: required because of the requirements on the impl of `std::fmt::Debug` for `[usize; 33]`
|
||||
= note: required by `std::fmt::Debug::fmt`
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
||||
--> $DIR/core-traits-no-impls-length-33.rs:10:16
|
||||
|
|
|
@ -15,6 +15,7 @@ LL | struct S<T: Debug, const N: usize>([T; N]);
|
|||
= note: required because of the requirements on the impl of `std::fmt::Debug` for `[T; _]`
|
||||
= note: required because of the requirements on the impl of `std::fmt::Debug` for `&[T; _]`
|
||||
= note: required for the cast to the object type `dyn std::fmt::Debug`
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ LL | a: [u32; N],
|
|||
= note: required because of the requirements on the impl of `std::fmt::Debug` for `[u32; _]`
|
||||
= note: required because of the requirements on the impl of `std::fmt::Debug` for `&[u32; _]`
|
||||
= note: required for the cast to the object type `dyn std::fmt::Debug`
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ LL | assert_eq!(Y, 4);
|
|||
| |
|
||||
| referenced constant has errors
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0080]: evaluation of constant expression failed
|
||||
--> $DIR/const_fn_ptr_fail2.rs:22:5
|
||||
|
@ -22,7 +22,7 @@ LL | assert_eq!(Z, 4);
|
|||
| |
|
||||
| referenced constant has errors
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | pub const Z: () = panic!("cheese");
|
|||
| the evaluated program panicked at 'cheese', $DIR/const_panic.rs:4:19
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const_panic.rs:7:19
|
||||
|
@ -17,7 +17,7 @@ LL | pub const Y: () = unreachable!();
|
|||
| |
|
||||
| the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:7:19
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const_panic.rs:10:19
|
||||
|
@ -27,7 +27,7 @@ LL | pub const X: () = unimplemented!();
|
|||
| |
|
||||
| the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:10:19
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | const Z: () = panic!("cheese");
|
|||
| the evaluated program panicked at 'cheese', $DIR/const_panic_libcore.rs:5:15
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const_panic_libcore.rs:8:15
|
||||
|
@ -17,7 +17,7 @@ LL | const Y: () = unreachable!();
|
|||
| |
|
||||
| the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore.rs:8:15
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const_panic_libcore.rs:11:15
|
||||
|
@ -27,7 +27,7 @@ LL | const X: () = unimplemented!();
|
|||
| |
|
||||
| the evaluated program panicked at 'not implemented', $DIR/const_panic_libcore.rs:11:15
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | const Z: () = panic!("cheese");
|
|||
| the evaluated program panicked at 'cheese', $DIR/const_panic_libcore_main.rs:9:15
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const_panic_libcore_main.rs:12:15
|
||||
|
@ -17,7 +17,7 @@ LL | const Y: () = unreachable!();
|
|||
| |
|
||||
| the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore_main.rs:12:15
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/const_panic_libcore_main.rs:15:15
|
||||
|
@ -27,7 +27,7 @@ LL | const X: () = unimplemented!();
|
|||
| |
|
||||
| the evaluated program panicked at 'not implemented', $DIR/const_panic_libcore_main.rs:15:15
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ LL | const Z: () = panic!("cheese");
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/51999
|
||||
= help: add `#![feature(const_panic)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0658]: panicking in constants is unstable
|
||||
--> $DIR/feature-gate-const_panic.rs:9:15
|
||||
|
@ -16,7 +16,7 @@ LL | const X: () = unimplemented!();
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/51999
|
||||
= help: add `#![feature(const_panic)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0658]: panicking in constants is unstable
|
||||
--> $DIR/feature-gate-const_panic.rs:6:15
|
||||
|
@ -26,7 +26,7 @@ LL | const Y: () = unreachable!();
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/51999
|
||||
= help: add `#![feature(const_panic)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ note: the lint level is defined here
|
|||
|
|
||||
LL | #![warn(const_err)]
|
||||
| ^^^^^^^^^
|
||||
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0080]: erroneous constant used
|
||||
--> $DIR/panic-assoc-never-type.rs:16:13
|
||||
|
|
|
@ -11,7 +11,7 @@ note: the lint level is defined here
|
|||
|
|
||||
LL | #![warn(const_err)]
|
||||
| ^^^^^^^^^
|
||||
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0080]: erroneous constant used
|
||||
--> $DIR/panic-never-type.rs:12:13
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | static_assert!(2 + 2 == 5);
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the len is 1 but the index is 1
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | const _: () = assert!(false);
|
|||
| the evaluated program panicked at 'assertion failed: false', $DIR/assert.rs:12:15
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ LL | const _: () = assert!(true);
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/51999
|
||||
= help: add `#![feature(const_panic)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0658]: panicking in constants is unstable
|
||||
--> $DIR/assert.rs:12:15
|
||||
|
@ -16,7 +16,7 @@ LL | const _: () = assert!(false);
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/51999
|
||||
= help: add `#![feature(const_panic)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ LL | const _: () = assert!(true);
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/49146
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const`
|
||||
--> $DIR/assert.rs:12:15
|
||||
|
@ -15,6 +16,7 @@ LL | const _: () = assert!(false);
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/49146
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ LL | const _: () = assert!(true);
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/49146
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const`
|
||||
--> $DIR/assert.rs:12:15
|
||||
|
@ -15,6 +16,7 @@ LL | const _: () = assert!(false);
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/49146
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ LL | Drop = assert_eq!(1, 1)
|
|||
|
|
||||
= note: `if` expressions without `else` evaluate to `()`
|
||||
= help: consider adding an `else` block that evaluates to the expected type
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ LL | Drop = assert_eq!(1, 1)
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/49146
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const`
|
||||
--> $DIR/issue-50577.rs:7:16
|
||||
|
@ -16,7 +16,7 @@ LL | Drop = assert_eq!(1, 1)
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/49146
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0658]: `match` is not allowed in a `const`
|
||||
--> $DIR/issue-50577.rs:7:16
|
||||
|
@ -26,7 +26,7 @@ LL | Drop = assert_eq!(1, 1)
|
|||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/49146
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0317]: `if` may be missing an `else` clause
|
||||
--> $DIR/issue-50577.rs:7:16
|
||||
|
@ -39,7 +39,7 @@ LL | Drop = assert_eq!(1, 1)
|
|||
|
|
||||
= note: `if` expressions without `else` evaluate to `()`
|
||||
= help: consider adding an `else` block that evaluates to the expected type
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | const _: bool = true || panic!();
|
|||
| the evaluated program panicked at 'explicit panic', $DIR/short-circuit.rs:10:25
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/short-circuit.rs:11:26
|
||||
|
@ -17,7 +17,7 @@ LL | const _: bool = false && panic!();
|
|||
| |
|
||||
| the evaluated program panicked at 'explicit panic', $DIR/short-circuit.rs:11:26
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ LL | | B = T,
|
|||
LL | | }
|
||||
| |_- in this macro invocation
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit
|
||||
|
|
||||
LL | $( $v = $s::V.try_into().unwrap(), )*
|
||||
|
@ -27,6 +28,7 @@ LL | | B = T,
|
|||
LL | | }
|
||||
| |_- in this macro invocation
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit
|
||||
|
|
||||
LL | $( $v = $s::V.try_into().unwrap(), )*
|
||||
|
|
|
@ -6,7 +6,7 @@ LL | vec![1, 2, 3]
|
|||
|
|
||||
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ error: 1 positional argument in format string, but no arguments were given
|
|||
LL | myprintln!("{}");
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ LL | _
|
|||
|
|
||||
LL | underscore!();
|
||||
| -------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ LL | fn wrong_kind(){}
|
|||
| ^^^^^^^^^^^^^^^^^ the trait `example_runner::Testable` is not implemented for `test::TestDescAndFn`
|
||||
|
|
||||
= note: required for the cast to the object type `dyn example_runner::Testable`
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ note: the lint level is defined here
|
|||
|
|
||||
LL | #![deny(deprecated)]
|
||||
| ^^^^^^^^^^
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ note: the lint level is defined here
|
|||
|
|
||||
LL | #![deny(deprecated)]
|
||||
| ^^^^^^^^^^
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ LL | ($x:expr) => { &$x }
|
|||
...
|
||||
LL | foo3(borrow!(0));
|
||||
| ---------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/deref-suggestion.rs:36:5
|
||||
|
@ -49,7 +51,7 @@ error[E0308]: mismatched types
|
|||
LL | assert_eq!(3i32, &3i32);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `&i32`
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/deref-suggestion.rs:39:17
|
||||
|
|
|
@ -5,6 +5,7 @@ LL | x: Error
|
|||
| ^^^^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
|
||||
|
|
||||
= note: required by `std::clone::Clone::clone`
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ LL | Error
|
|||
| ^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
|
||||
|
|
||||
= note: required by `std::clone::Clone::clone`
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ LL | x: Error
|
|||
| ^^^^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
|
||||
|
|
||||
= note: required by `std::clone::Clone::clone`
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ LL | Error
|
|||
| ^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
|
||||
|
|
||||
= note: required by `std::clone::Clone::clone`
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ LL | x: Error
|
|||
= note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug`
|
||||
= note: required because of the requirements on the impl of `std::fmt::Debug` for `&Error`
|
||||
= note: required for the cast to the object type `dyn std::fmt::Debug`
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ LL | Error
|
|||
= note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug`
|
||||
= note: required because of the requirements on the impl of `std::fmt::Debug` for `&Error`
|
||||
= note: required for the cast to the object type `dyn std::fmt::Debug`
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ LL | x: Error
|
|||
= note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug`
|
||||
= note: required because of the requirements on the impl of `std::fmt::Debug` for `&Error`
|
||||
= note: required for the cast to the object type `dyn std::fmt::Debug`
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue