diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 028a5048d5438..a8c3fb55bad85 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -335,15 +335,11 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_expr(&mut self, e: &'a ast::Expr) { match e.kind { ast::ExprKind::TryBlock(_, None) => { + // `try { ... }` is old and is only gated post-expansion here. gate!(&self, try_blocks, e.span, "`try` expression is experimental"); } ast::ExprKind::TryBlock(_, Some(_)) => { - gate!( - &self, - try_blocks_heterogeneous, - e.span, - "`try bikeshed` expression is experimental" - ); + // `try_blocks_heterogeneous` is new, and gated pre-expansion instead. } ast::ExprKind::Lit(token::Lit { kind: token::LitKind::Float | token::LitKind::Integer, @@ -505,6 +501,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { half_open_range_patterns_in_slices, "half-open range patterns in slices are unstable" ); + gate_all!(try_blocks_heterogeneous, "`try bikeshed` expression is experimental"); gate_all!(yeet_expr, "`do yeet` expression is experimental"); gate_all!(const_closures, "const closures are experimental"); gate_all!(builtin_syntax, "`builtin #` syntax is unstable"); diff --git a/compiler/rustc_mir_transform/src/liveness.rs b/compiler/rustc_mir_transform/src/liveness.rs index 38f844b6fe060..fc120d82b38c9 100644 --- a/compiler/rustc_mir_transform/src/liveness.rs +++ b/compiler/rustc_mir_transform/src/liveness.rs @@ -1286,6 +1286,7 @@ impl<'tcx> Visitor<'tcx> for TransferFunction<'_, 'tcx> { TerminatorKind::Return | TerminatorKind::Yield { .. } | TerminatorKind::Goto { target: START_BLOCK } // Inserted for the `FnMut` case. + | TerminatorKind::Call { target: None, .. } // unwinding could be caught if self.capture_kind != CaptureKind::None => { // All indirect captures have an effect on the environment, so we mark them as live. diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 0ed6dea40cd4c..148a0309b0a0c 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1521,7 +1521,7 @@ impl<'a> Parser<'a> { }, ) } else if this.check_inline_const(0) { - this.parse_const_block(lo) + this.parse_const_block(lo, false) } else if this.may_recover() && this.is_do_catch_block() { this.recover_do_catch() } else if this.is_try_block() { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index c39e8351f0bd8..a8a3934c42f77 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1315,7 +1315,7 @@ impl<'a> Parser<'a> { } /// Parses inline const expressions. - fn parse_const_block(&mut self, span: Span) -> PResult<'a, Box> { + fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, Box> { self.expect_keyword(exp!(Const))?; let (attrs, blk) = self.parse_inner_attrs_and_block(None)?; let anon_const = AnonConst { @@ -1324,7 +1324,18 @@ impl<'a> Parser<'a> { mgca_disambiguation: MgcaDisambiguation::AnonConst, }; let blk_span = anon_const.value.span; - let kind = ExprKind::ConstBlock(anon_const); + let kind = if pat { + let guar = self + .dcx() + .struct_span_err(blk_span, "const blocks cannot be used as patterns") + .with_help( + "use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead", + ) + .emit(); + ExprKind::Err(guar) + } else { + ExprKind::ConstBlock(anon_const) + }; Ok(self.mk_expr_with_attrs(span.to(blk_span), kind, attrs)) } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index d7f3a36122e59..0e9796c04c8ab 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -785,10 +785,8 @@ impl<'a> Parser<'a> { } else if self.eat_keyword(exp!(Box)) { self.parse_pat_box()? } else if self.check_inline_const(0) { - // Parse `const pat`. - // NOTE: This will always error later during AST lowering because - // inline const cannot be used as patterns. - let const_expr = self.parse_const_block(lo.to(self.token.span))?; + // Parse `const pat` + let const_expr = self.parse_const_block(lo.to(self.token.span), true)?; if let Some(re) = self.parse_range_end() { self.parse_pat_range_begin_with(const_expr, re)? @@ -1283,7 +1281,7 @@ impl<'a> Parser<'a> { .then_some(self.prev_token.span); let bound = if self.check_inline_const(0) { - self.parse_const_block(self.token.span) + self.parse_const_block(self.token.span, true) } else if self.check_path() { let lo = self.token.span; let (qself, path) = if self.eat_lt() { diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index d7cbaa7c497f7..34af161b45760 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -366,6 +366,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // - A glob decl is overwritten by its clone after setting ambiguity in it. // FIXME: avoid this by removing `warn_ambiguity`, or by triggering glob re-fetch // with the same decl in some way. + // - A glob decl is overwritten by a glob decl with larger visibility. + // FIXME: avoid this by updating this visibility in place. // - A glob decl is overwritten by a glob decl re-fetching an // overwritten decl from other module (the recursive case). // Here we are detecting all such re-fetches and overwrite old decls @@ -379,7 +381,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // FIXME: reenable the asserts when `warn_ambiguity` is removed (#149195). // assert_ne!(old_deep_decl, deep_decl); // assert!(old_deep_decl.is_glob_import()); - assert!(!deep_decl.is_glob_import()); + // FIXME: reenable the assert when visibility is updated in place. + // assert!(!deep_decl.is_glob_import()); if old_glob_decl.ambiguity.get().is_some() && glob_decl.ambiguity.get().is_none() { // Do not lose glob ambiguities when re-fetching the glob. glob_decl.ambiguity.set_unchecked(old_glob_decl.ambiguity.get()); diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index bebc0707e26d9..5a41e46f3a6bd 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -777,7 +777,9 @@ fn layout_of_uncached<'tcx>( let err = if ty.has_param() || !cx.typing_env.param_env.caller_bounds().is_empty() { LayoutError::TooGeneric(ty) } else { - unreachable!("invalid rigid alias in layout_of after normalization: {ty:?}"); + LayoutError::ReferencesError(cx.tcx().dcx().delayed_bug(format!( + "unexpected rigid alias in layout_of after normalization: {ty:?}" + ))) }; return Err(error(cx, err)); } diff --git a/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.rs b/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.rs index 9f0073eac9adc..5a20370e2eeb8 100644 --- a/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.rs +++ b/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.rs @@ -6,4 +6,11 @@ pub fn main() { x }; assert_eq!(try_result, Some(5)); + + // The heterogenous form is new, so is gated even under a `cfg(false)`. + // See + + #[cfg(false)] + try bikeshed () {} + //~^ error `try bikeshed` expression is experimental } diff --git a/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.stderr b/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.stderr index 0d31dc507fdde..e448945b2ba81 100644 --- a/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.stderr +++ b/tests/ui/feature-gates/feature-gate-try_blocks_heterogeneous.stderr @@ -12,6 +12,16 @@ LL | | }; = help: add `#![feature(try_blocks_heterogeneous)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 1 previous error +error[E0658]: `try bikeshed` expression is experimental + --> $DIR/feature-gate-try_blocks_heterogeneous.rs:14:5 + | +LL | try bikeshed () {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: see issue #149488 for more information + = help: add `#![feature(try_blocks_heterogeneous)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/imports/overwrite-different-vis-3.rs b/tests/ui/imports/overwrite-different-vis-3.rs new file mode 100644 index 0000000000000..f45c5cdfb3abf --- /dev/null +++ b/tests/ui/imports/overwrite-different-vis-3.rs @@ -0,0 +1,14 @@ +// Regression test for issue #152606. + +//@ check-pass + +mod outer { + mod inner { + use super::*; // should go before the ambiguous glob imports + } + + use crate::*; + pub use crate::*; +} + +fn main() {} diff --git a/tests/ui/inline-const/in-pat-recovery.rs b/tests/ui/inline-const/in-pat-recovery.rs index d519217fad3b5..037c58d3bf98c 100644 --- a/tests/ui/inline-const/in-pat-recovery.rs +++ b/tests/ui/inline-const/in-pat-recovery.rs @@ -4,63 +4,63 @@ fn main() { match 1 { const { 1 + 7 } => {} - //~^ ERROR arbitrary expressions aren't allowed in patterns + //~^ ERROR const blocks cannot be used as patterns 2 => {} _ => {} } match 5 { const { 1 } ..= 10 => {} - //~^ ERROR arbitrary expressions aren't allowed in patterns + //~^ ERROR const blocks cannot be used as patterns _ => {} } match 5 { 1 ..= const { 10 } => {} - //~^ ERROR arbitrary expressions aren't allowed in patterns + //~^ ERROR const blocks cannot be used as patterns _ => {} } match 5 { const { 1 } ..= const { 10 } => {} - //~^ ERROR arbitrary expressions aren't allowed in patterns - //~| ERROR arbitrary expressions aren't allowed in patterns + //~^ ERROR const blocks cannot be used as patterns + //~| ERROR const blocks cannot be used as patterns _ => {} } match 5 { const { 1 } .. 10 => {} - //~^ ERROR arbitrary expressions aren't allowed in patterns + //~^ ERROR const blocks cannot be used as patterns _ => {} } match 5 { 1 .. const { 10 } => {} - //~^ ERROR arbitrary expressions aren't allowed in patterns + //~^ ERROR const blocks cannot be used as patterns _ => {} } match 5 { const { 1 + 2 } ..= 10 => {} - //~^ ERROR arbitrary expressions aren't allowed in patterns + //~^ ERROR const blocks cannot be used as patterns _ => {} } match 5 { 1 ..= const { 5 + 5 } => {} - //~^ ERROR arbitrary expressions aren't allowed in patterns + //~^ ERROR const blocks cannot be used as patterns _ => {} } match 5 { const { 3 } .. => {} - //~^ ERROR arbitrary expressions aren't allowed in patterns + //~^ ERROR const blocks cannot be used as patterns _ => {} } match 5 { ..= const { 7 } => {} - //~^ ERROR arbitrary expressions aren't allowed in patterns + //~^ ERROR const blocks cannot be used as patterns _ => {} } } diff --git a/tests/ui/inline-const/in-pat-recovery.stderr b/tests/ui/inline-const/in-pat-recovery.stderr index 376c43aaecca6..55adb5c49a6d1 100644 --- a/tests/ui/inline-const/in-pat-recovery.stderr +++ b/tests/ui/inline-const/in-pat-recovery.stderr @@ -1,88 +1,88 @@ -error: arbitrary expressions aren't allowed in patterns - --> $DIR/in-pat-recovery.rs:6:9 +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:6:15 | LL | const { 1 + 7 } => {} - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^ | = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead -error: arbitrary expressions aren't allowed in patterns - --> $DIR/in-pat-recovery.rs:13:9 +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:13:15 | LL | const { 1 } ..= 10 => {} - | ^^^^^^^^^^^ + | ^^^^^ | = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead -error: arbitrary expressions aren't allowed in patterns - --> $DIR/in-pat-recovery.rs:19:15 +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:19:21 | LL | 1 ..= const { 10 } => {} - | ^^^^^^^^^^^^ + | ^^^^^^ | = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead -error: arbitrary expressions aren't allowed in patterns - --> $DIR/in-pat-recovery.rs:25:9 +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:25:15 | LL | const { 1 } ..= const { 10 } => {} - | ^^^^^^^^^^^ + | ^^^^^ | = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead -error: arbitrary expressions aren't allowed in patterns - --> $DIR/in-pat-recovery.rs:25:25 +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:25:31 | LL | const { 1 } ..= const { 10 } => {} - | ^^^^^^^^^^^^ + | ^^^^^^ | = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead -error: arbitrary expressions aren't allowed in patterns - --> $DIR/in-pat-recovery.rs:32:9 +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:32:15 | LL | const { 1 } .. 10 => {} - | ^^^^^^^^^^^ + | ^^^^^ | = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead -error: arbitrary expressions aren't allowed in patterns - --> $DIR/in-pat-recovery.rs:38:14 +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:38:20 | LL | 1 .. const { 10 } => {} - | ^^^^^^^^^^^^ + | ^^^^^^ | = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead -error: arbitrary expressions aren't allowed in patterns - --> $DIR/in-pat-recovery.rs:44:9 +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:44:15 | LL | const { 1 + 2 } ..= 10 => {} - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^ | = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead -error: arbitrary expressions aren't allowed in patterns - --> $DIR/in-pat-recovery.rs:50:15 +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:50:21 | LL | 1 ..= const { 5 + 5 } => {} - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^ | = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead -error: arbitrary expressions aren't allowed in patterns - --> $DIR/in-pat-recovery.rs:56:9 +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:56:15 | LL | const { 3 } .. => {} - | ^^^^^^^^^^^ + | ^^^^^ | = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead -error: arbitrary expressions aren't allowed in patterns - --> $DIR/in-pat-recovery.rs:62:13 +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:62:19 | LL | ..= const { 7 } => {} - | ^^^^^^^^^^^ + | ^^^^^ | = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead diff --git a/tests/ui/inline-const/reject-const-block-pat-pre-expansion.rs b/tests/ui/inline-const/reject-const-block-pat-pre-expansion.rs new file mode 100644 index 0000000000000..9af4925c0432a --- /dev/null +++ b/tests/ui/inline-const/reject-const-block-pat-pre-expansion.rs @@ -0,0 +1,12 @@ +//! Regression test for : reject inline const +//! patterns pre-expansion when possible. + +macro_rules! analyze { ($p:pat) => {}; } +analyze!(const { 0 }); +//~^ ERROR: const blocks cannot be used as patterns + +#[cfg(false)] +fn scope() { let const { 0 }; } +//~^ ERROR: const blocks cannot be used as patterns + +fn main() {} diff --git a/tests/ui/inline-const/reject-const-block-pat-pre-expansion.stderr b/tests/ui/inline-const/reject-const-block-pat-pre-expansion.stderr new file mode 100644 index 0000000000000..034b97699396e --- /dev/null +++ b/tests/ui/inline-const/reject-const-block-pat-pre-expansion.stderr @@ -0,0 +1,18 @@ +error: const blocks cannot be used as patterns + --> $DIR/reject-const-block-pat-pre-expansion.rs:9:24 + | +LL | fn scope() { let const { 0 }; } + | ^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: const blocks cannot be used as patterns + --> $DIR/reject-const-block-pat-pre-expansion.rs:5:16 + | +LL | analyze!(const { 0 }); + | ^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: aborting due to 2 previous errors + diff --git a/tests/ui/layout/rigid-alias-due-to-broken-impl.rs b/tests/ui/layout/rigid-alias-due-to-broken-impl.rs new file mode 100644 index 0000000000000..912c660cb7cad --- /dev/null +++ b/tests/ui/layout/rigid-alias-due-to-broken-impl.rs @@ -0,0 +1,17 @@ +// Make sure we don't ICE if `layout_of` encounters an alias +// which is rigid due to a malformed program. A regression test +// for #152545. +// +// This specific ICE happens in the `KnownPanicsLint` visitor. + +//@ compile-flags: --crate-type=rlib +trait Foo { + type Assoc; +} + +// The trait solver only treats missng associated items +// as rigid if the self-type is known to be unsized. +impl Foo for str {} +//~^ ERROR not all trait items implemented + +fn foo(_: [u32; std::mem::size_of::<::Assoc>()]) {} diff --git a/tests/ui/layout/rigid-alias-due-to-broken-impl.stderr b/tests/ui/layout/rigid-alias-due-to-broken-impl.stderr new file mode 100644 index 0000000000000..e9ba6df2fdc71 --- /dev/null +++ b/tests/ui/layout/rigid-alias-due-to-broken-impl.stderr @@ -0,0 +1,12 @@ +error[E0046]: not all trait items implemented, missing: `Assoc` + --> $DIR/rigid-alias-due-to-broken-impl.rs:14:1 + | +LL | type Assoc; + | ---------- `Assoc` from trait +... +LL | impl Foo for str {} + | ^^^^^^^^^^^^^^^^ missing `Assoc` in implementation + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/lint/unused/diverging-path.rs b/tests/ui/lint/unused/diverging-path.rs new file mode 100644 index 0000000000000..7f364518fe976 --- /dev/null +++ b/tests/ui/lint/unused/diverging-path.rs @@ -0,0 +1,21 @@ +//! Assignments to a captured variable within a diverging closure should not be considered unused if +//! the divergence is caught. +//! +//! Regression test for https://github.com/rust-lang/rust/issues/152079 +//@ compile-flags: -Wunused +//@ check-pass + +fn main() { + let mut x = 1; + catch(|| { + x = 2; + panic!(); + }); + dbg!(x); +} + +fn catch(f: F) { + if let Ok(true) = std::fs::exists("may_or_may_not_call_f") { + _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)); + } +} diff --git a/tests/ui/try-block/try-block-homogeneous-pre-expansion.rs b/tests/ui/try-block/try-block-homogeneous-pre-expansion.rs new file mode 100644 index 0000000000000..980f97ca0672e --- /dev/null +++ b/tests/ui/try-block/try-block-homogeneous-pre-expansion.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ edition: 2018 + +// For historical reasons this is only a warning, not an error. +// See + +fn main() { + #[cfg(false)] + try {} + //~^ warn `try` blocks are unstable + //~| warn unstable syntax can change at any point +} diff --git a/tests/ui/try-block/try-block-homogeneous-pre-expansion.stderr b/tests/ui/try-block/try-block-homogeneous-pre-expansion.stderr new file mode 100644 index 0000000000000..dc92d7e64aff3 --- /dev/null +++ b/tests/ui/try-block/try-block-homogeneous-pre-expansion.stderr @@ -0,0 +1,14 @@ +warning: `try` blocks are unstable + --> $DIR/try-block-homogeneous-pre-expansion.rs:9:5 + | +LL | try {} + | ^^^^^^ + | + = note: see issue #31436 for more information + = help: add `#![feature(try_blocks)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 + +warning: 1 warning emitted +