diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 188ca8048055c..924bacb7aae21 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2017,9 +2017,7 @@ pub enum ProjectionElem { from_end: bool, }, - /// "Downcast" to a variant of an ADT. Currently, we only introduce - /// this for ADTs with more than one variant. It may be better to - /// just introduce it always, or always for enums. + /// "Downcast" to a variant of an enum or a generator. /// /// The included Symbol is the name of the variant, used for printing MIR. Downcast(Option, VariantIdx), diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 597ade4223684..f1d5201454d69 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -12,7 +12,7 @@ use rustc_target::abi::VariantIdx; #[derive(Copy, Clone, Debug, TypeFoldable)] pub struct PlaceTy<'tcx> { pub ty: Ty<'tcx>, - /// Downcast to a particular variant of an enum, if included. + /// Downcast to a particular variant of an enum or a generator, if included. pub variant_index: Option, } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index a3d3c7c0cf3aa..bfb8ce6f1051c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -866,7 +866,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { return false; } - let orig_ty = old_pred.self_ty().skip_binder(); + // This is a quick fix to resolve an ICE (#96223). + // This change should probably be deeper. + // As suggested by @jackh726, `mk_trait_obligation_with_new_self_ty` could take a `Binder<(TraitRef, Ty)> + // instead of `Binder` leading to some changes to its call places. + let Some(orig_ty) = old_pred.self_ty().no_bound_vars() else { + return false; + }; let mk_result = |new_ty| { let obligation = self.mk_trait_obligation_with_new_self_ty(param_env, old_pred, new_ty); diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index edfe31319e8d0..2224bf5f66e90 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1405,7 +1405,8 @@ impl<'a> Builder<'a> { // FIXME(davidtwco): #[cfg(not(bootstrap))] - #95612 needs to be in the bootstrap compiler // for this conditional to be removed. if !target.contains("windows") || compiler.stage >= 1 { - if target.contains("linux") || target.contains("windows") { + if target.contains("linux") || target.contains("windows") || target.contains("openbsd") + { rustflags.arg("-Zunstable-options"); } match self.config.rust_split_debuginfo { diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md index 7bd46fafadf83..fbec3cd9baf50 100644 --- a/src/doc/rustc/src/lints/levels.md +++ b/src/doc/rustc/src/lints/levels.md @@ -100,9 +100,8 @@ This lint level gives you that. 'force-warn' does for 'warn'. It's the same as 'deny' in that a lint at this level will produce an error, but unlike the 'deny' level, the 'forbid' level can not be overridden to be anything lower than an error. However, lint -levels may still be capped with `--cap-lints` (see below) so `rustc --cap- -lints warn` will make lints set to 'forbid' just -warn. +levels may still be capped with `--cap-lints` (see below) so `rustc --cap-lints warn` +will make lints set to 'forbid' just warn. ## Configuring warning levels diff --git a/src/test/rustdoc-ui/block-doc-comment.rs b/src/test/rustdoc-ui/block-doc-comment.rs index c60dfa3f9518e..ce529916e5ede 100644 --- a/src/test/rustdoc-ui/block-doc-comment.rs +++ b/src/test/rustdoc-ui/block-doc-comment.rs @@ -1,5 +1,6 @@ // check-pass // compile-flags:--test +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" // This test ensures that no code block is detected in the doc comments. diff --git a/src/test/rustdoc-ui/block-doc-comment.stdout b/src/test/rustdoc-ui/block-doc-comment.stdout index e5c27bebbdb23..7326c0a25a069 100644 --- a/src/test/rustdoc-ui/block-doc-comment.stdout +++ b/src/test/rustdoc-ui/block-doc-comment.stdout @@ -1,5 +1,5 @@ running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/src/test/ui/suggestions/issue-96223.rs b/src/test/ui/suggestions/issue-96223.rs new file mode 100644 index 0000000000000..85667bb849bd4 --- /dev/null +++ b/src/test/ui/suggestions/issue-96223.rs @@ -0,0 +1,52 @@ +// Previously ICEd because we didn't properly track binders in suggestions +// check-fail + +pub trait Foo<'de>: Sized {} + +pub trait Bar<'a>: 'static { + type Inner: 'a; +} + +pub trait Fubar { + type Bar: for<'a> Bar<'a>; +} + +pub struct Baz(pub T); + +impl<'de, T> Foo<'de> for Baz where T: Foo<'de> {} + +struct Empty; + +impl Dummy for Empty +where + M: Fubar, + for<'de> Baz<>::Inner>: Foo<'de>, +{ +} + +pub trait Dummy +where + M: Fubar, +{ +} + +pub struct EmptyBis<'a>(&'a [u8]); + +impl<'a> Bar<'a> for EmptyBis<'static> { + type Inner = EmptyBis<'a>; +} + +pub struct EmptyMarker; + +impl Fubar for EmptyMarker { + type Bar = EmptyBis<'static>; +} + +fn icey_bounds>(p: &D) {} + +fn trigger_ice() { + let p = Empty; + icey_bounds(&p); //~ERROR the trait bound +} + +fn main() {} diff --git a/src/test/ui/suggestions/issue-96223.stderr b/src/test/ui/suggestions/issue-96223.stderr new file mode 100644 index 0000000000000..513725d99628c --- /dev/null +++ b/src/test/ui/suggestions/issue-96223.stderr @@ -0,0 +1,28 @@ +error[E0277]: the trait bound `for<'de> EmptyBis<'de>: Foo<'_>` is not satisfied + --> $DIR/issue-96223.rs:49:17 + | +LL | icey_bounds(&p); + | ----------- ^^ the trait `for<'de> Foo<'_>` is not implemented for `EmptyBis<'de>` + | | + | required by a bound introduced by this call + | + = help: the trait `Foo<'de>` is implemented for `Baz` +note: required because of the requirements on the impl of `for<'de> Foo<'de>` for `Baz>` + --> $DIR/issue-96223.rs:16:14 + | +LL | impl<'de, T> Foo<'de> for Baz where T: Foo<'de> {} + | ^^^^^^^^ ^^^^^^ +note: required because of the requirements on the impl of `Dummy` for `Empty` + --> $DIR/issue-96223.rs:20:9 + | +LL | impl Dummy for Empty + | ^^^^^^^^ ^^^^^ +note: required by a bound in `icey_bounds` + --> $DIR/issue-96223.rs:45:19 + | +LL | fn icey_bounds>(p: &D) {} + | ^^^^^^^^^^^^^^^^^^ required by this bound in `icey_bounds` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs new file mode 100644 index 0000000000000..6c838f410036a --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs @@ -0,0 +1,9 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl Fn() -> Foo; + +fn foo() -> Foo { + foo //~ ERROR: overflow evaluating the requirement `fn() -> Foo {foo}: Sized` +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr new file mode 100644 index 0000000000000..a9c2c18630c01 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr @@ -0,0 +1,11 @@ +error[E0275]: overflow evaluating the requirement `fn() -> Foo {foo}: Sized` + --> $DIR/issue-53398-cyclic-types.rs:6:5 + | +LL | foo + | ^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_53398_cyclic_types`) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs b/src/test/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs new file mode 100644 index 0000000000000..f20ddf020718e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs @@ -0,0 +1,39 @@ +// check-pass + +#![feature(generators, generator_trait)] +#![feature(type_alias_impl_trait)] + +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; + +type RandGenerator<'a> = impl Generator + 'a; +fn rand_generator<'a>(rng: &'a ()) -> RandGenerator<'a> { + move || { + let _rng = rng; + loop { + yield 0; + } + } +} + +pub type RandGeneratorWithIndirection<'a> = impl Generator + 'a; +pub fn rand_generator_with_indirection<'a>(rng: &'a ()) -> RandGeneratorWithIndirection<'a> { + fn helper<'b>(rng: &'b ()) -> impl 'b + Generator { + move || { + let _rng = rng; + loop { + yield 0; + } + } + } + + helper(rng) +} + +fn main() { + let mut gen = rand_generator(&()); + match unsafe { Pin::new_unchecked(&mut gen) }.resume(()) { + GeneratorState::Yielded(_) => {} + GeneratorState::Complete(_) => {} + }; +} diff --git a/src/test/ui/type-alias-impl-trait/issue-89952.rs b/src/test/ui/type-alias-impl-trait/issue-89952.rs new file mode 100644 index 0000000000000..dc0f19c042af7 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-89952.rs @@ -0,0 +1,31 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +trait SomeTrait {} +impl SomeTrait for () {} + +trait MyFuture { + type Output; +} +impl MyFuture for T { + type Output = T; +} + +trait ReturnsFuture { + type Output: SomeTrait; + type Future: MyFuture>; + fn func() -> Self::Future; +} + +struct Foo; + +impl ReturnsFuture for Foo { + type Output = impl SomeTrait; + type Future = impl MyFuture>; + fn func() -> Self::Future { + Result::<(), ()>::Err(()) + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-94429.rs b/src/test/ui/type-alias-impl-trait/issue-94429.rs new file mode 100644 index 0000000000000..51d69c1271e02 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-94429.rs @@ -0,0 +1,22 @@ +#![feature(type_alias_impl_trait, generator_trait, generators)] +use std::ops::Generator; + +trait Runnable { + type Gen: Generator; + + fn run(&mut self) -> Self::Gen; +} + +struct Implementor {} + +impl Runnable for Implementor { + type Gen = impl Generator; + + fn run(&mut self) -> Self::Gen { + move || { //~ ERROR: type mismatch resolving + yield 1; + } + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-94429.stderr b/src/test/ui/type-alias-impl-trait/issue-94429.stderr new file mode 100644 index 0000000000000..4546f82b83b85 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-94429.stderr @@ -0,0 +1,11 @@ +error[E0271]: type mismatch resolving `<[generator@$DIR/issue-94429.rs:16:9: 18:10] as Generator>::Yield == ()` + --> $DIR/issue-94429.rs:16:9 + | +LL | / move || { +LL | | yield 1; +LL | | } + | |_________^ expected integer, found `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`.