diff --git a/compiler/rustc_data_structures/src/intern.rs b/compiler/rustc_data_structures/src/intern.rs index ba94f3776eb90..e0f8c350c2a86 100644 --- a/compiler/rustc_data_structures/src/intern.rs +++ b/compiler/rustc_data_structures/src/intern.rs @@ -1,5 +1,6 @@ use crate::stable_hasher::{HashStable, StableHasher}; use std::cmp::Ordering; +use std::fmt::{self, Debug}; use std::hash::{Hash, Hasher}; use std::ops::Deref; use std::ptr; @@ -20,7 +21,6 @@ mod private { /// The `PrivateZst` field means you can pattern match with `Interned(v, _)` /// but you can only construct a `Interned` with `new_unchecked`, and not /// directly. -#[derive(Debug)] #[rustc_pass_by_value] pub struct Interned<'a, T>(pub &'a T, pub private::PrivateZst); @@ -108,5 +108,11 @@ where } } +impl Debug for Interned<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + #[cfg(test)] mod tests; diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 690f80f6876e4..762232e20f273 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -197,9 +197,11 @@ pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec config_tokens: false, lint_node_id: ast::CRATE_NODE_ID, }; - let attrs: ast::AttrVec = - attrs.iter().flat_map(|attr| strip_unconfigured.process_cfg_attr(attr)).collect(); - if strip_unconfigured.in_cfg(&attrs) { attrs } else { ast::AttrVec::new() } + attrs + .iter() + .flat_map(|attr| strip_unconfigured.process_cfg_attr(attr)) + .take_while(|attr| !is_cfg(attr) || strip_unconfigured.cfg_true(attr)) + .collect() } #[macro_export] diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index dd8863df1953c..9850723a857e9 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1039,7 +1039,12 @@ trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized { ) -> Result { Ok(noop_flat_map(node, collector)) } - fn expand_cfg_false(&mut self, collector: &mut InvocationCollector<'_, '_>, span: Span) { + fn expand_cfg_false( + &mut self, + collector: &mut InvocationCollector<'_, '_>, + _pos: usize, + span: Span, + ) { collector.cx.emit_err(RemoveNodeNotSupported { span, descr: Self::descr() }); } @@ -1409,8 +1414,15 @@ impl InvocationCollectorNode for ast::Crate { fn noop_visit(&mut self, visitor: &mut V) { noop_visit_crate(self, visitor) } - fn expand_cfg_false(&mut self, collector: &mut InvocationCollector<'_, '_>, _span: Span) { - self.attrs.clear(); + fn expand_cfg_false( + &mut self, + collector: &mut InvocationCollector<'_, '_>, + pos: usize, + _span: Span, + ) { + // Attributes above `cfg(FALSE)` are left in place, because we may want to configure + // some global crate properties even on fully unconfigured crates. + self.attrs.truncate(pos); // Standard prelude imports are left in the crate for backward compatibility. self.items.truncate(collector.cx.num_standard_library_imports); } @@ -1804,7 +1816,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { continue; } - node.expand_cfg_false(self, span); + node.expand_cfg_false(self, pos, span); continue; } sym::cfg_attr => { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 3c5feb1ba513d..f03c7ca44ba5f 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2081,13 +2081,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, _ => { // prevent all specified fields from being suggested - let skip_fields = skip_fields.iter().map(|x| x.ident.name); - if let Some(field_name) = self.suggest_field_name( - variant, - field.ident.name, - skip_fields.collect(), - expr_span, - ) { + let skip_fields: Vec<_> = skip_fields.iter().map(|x| x.ident.name).collect(); + if let Some(field_name) = + self.suggest_field_name(variant, field.ident.name, &skip_fields, expr_span) + { err.span_suggestion( field.ident.span, "a field with a similar name exists", @@ -2108,9 +2105,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("`{ty}` does not have this field"), ); } - let available_field_names = + let mut available_field_names = self.available_field_names(variant, expr_span); - if !available_field_names.is_empty() { + available_field_names + .retain(|name| skip_fields.iter().all(|skip| name != skip)); + if available_field_names.is_empty() { + err.note("all struct fields are already assigned"); + } else { err.note(format!( "available fields are: {}", self.name_series_display(available_field_names) @@ -2130,7 +2131,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, variant: &'tcx ty::VariantDef, field: Symbol, - skip: Vec, + skip: &[Symbol], // The span where stability will be checked span: Span, ) -> Option { @@ -2582,7 +2583,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { access_span: Span, ) { if let Some(suggested_field_name) = - self.suggest_field_name(def.non_enum_variant(), field.name, vec![], access_span) + self.suggest_field_name(def.non_enum_variant(), field.name, &[], access_span) { err.span_suggestion( field.span, diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 5af955d313482..2f9871a103a83 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -393,9 +393,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // They can denote both statically and dynamically-sized byte arrays. let mut pat_ty = ty; if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(..), .. }) = lt.kind { - let expected = self.structurally_resolved_type(span, expected); - if let ty::Ref(_, inner_ty, _) = expected.kind() - && matches!(inner_ty.kind(), ty::Slice(_)) + if let ty::Ref(_, inner_ty, _) = *self.structurally_resolved_type(span, expected).kind() + && self.structurally_resolved_type(span, inner_ty).is_slice() { let tcx = self.tcx; trace!(?lt.hir_id.local_id, "polymorphic byte string lit"); diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 478a7db3792da..6d8d99cfb5f1f 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -287,6 +287,27 @@ fn rustc_generator_to_generator( } } +fn rustc_inline_asm_operand_to_inline_asm_operand( + operand: &rustc_middle::mir::InlineAsmOperand<'_>, +) -> stable_mir::mir::InlineAsmOperand { + use rustc_middle::mir::InlineAsmOperand; + + let (in_value, out_place) = match operand { + InlineAsmOperand::In { value, .. } => (Some(rustc_op_to_op(value)), None), + InlineAsmOperand::Out { place, .. } => { + (None, place.map(|place| rustc_place_to_place(&place))) + } + InlineAsmOperand::InOut { in_value, out_place, .. } => { + (Some(rustc_op_to_op(in_value)), out_place.map(|place| rustc_place_to_place(&place))) + } + InlineAsmOperand::Const { .. } + | InlineAsmOperand::SymFn { .. } + | InlineAsmOperand::SymStatic { .. } => (None, None), + }; + + stable_mir::mir::InlineAsmOperand { in_value, out_place, raw_rpr: format!("{:?}", operand) } +} + fn rustc_terminator_to_terminator( terminator: &rustc_middle::mir::Terminator<'_>, ) -> stable_mir::mir::Terminator { @@ -330,7 +351,19 @@ fn rustc_terminator_to_terminator( target: target.as_usize(), unwind: rustc_unwind_to_unwind(unwind), }, - InlineAsm { .. } => todo!(), + InlineAsm { template, operands, options, line_spans, destination, unwind } => { + Terminator::InlineAsm { + template: format!("{:?}", template), + operands: operands + .iter() + .map(|operand| rustc_inline_asm_operand_to_inline_asm_operand(operand)) + .collect(), + options: format!("{:?}", options), + line_spans: format!("{:?}", line_spans), + destination: destination.map(|d| d.as_usize()), + unwind: rustc_unwind_to_unwind(unwind), + } + } Yield { .. } | GeneratorDrop | FalseEdge { .. } | FalseUnwind { .. } => unreachable!(), } } diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index 6328c35aa5982..9df7b4945b70a 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -46,6 +46,23 @@ pub enum Terminator { unwind: UnwindAction, }, GeneratorDrop, + InlineAsm { + template: String, + operands: Vec, + options: String, + line_spans: String, + destination: Option, + unwind: UnwindAction, + }, +} + +#[derive(Clone, Debug)] +pub struct InlineAsmOperand { + pub in_value: Option, + pub out_place: Option, + // This field has a raw debug representation of MIR's InlineAsmOperand. + // For now we care about place/operand + the rest in a debug format. + pub raw_rpr: String, } #[derive(Clone, Debug)] diff --git a/tests/ui/async-await/drop-track-bad-field-in-fru.stderr b/tests/ui/async-await/drop-track-bad-field-in-fru.stderr index 07ab8b3c90353..b49b15db64cee 100644 --- a/tests/ui/async-await/drop-track-bad-field-in-fru.stderr +++ b/tests/ui/async-await/drop-track-bad-field-in-fru.stderr @@ -3,6 +3,8 @@ error[E0559]: variant `Option<_>::None` has no field named `value` | LL | None { value: (), ..Default::default() }.await; | ^^^^^ `Option<_>::None` does not have this field + | + = note: all struct fields are already assigned error[E0277]: `Option<_>` is not a future --> $DIR/drop-track-bad-field-in-fru.rs:7:46 diff --git a/tests/ui/cfg/auxiliary/cfg_false_lib.rs b/tests/ui/cfg/auxiliary/cfg_false_lib.rs index 3c011d72b02c5..6c2dbb44d2a40 100644 --- a/tests/ui/cfg/auxiliary/cfg_false_lib.rs +++ b/tests/ui/cfg/auxiliary/cfg_false_lib.rs @@ -1,6 +1,4 @@ -// It is unclear whether a fully unconfigured crate should link to standard library, -// or what its `no_std`/`no_core`/`compiler_builtins` status, more precisely. -// Currently the usual standard library prelude is added to such crates, -// and therefore they link to libstd. +// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(FALSE)`. +// This crate has no such attribute, therefore this crate does link to libstd. #![cfg(FALSE)] diff --git a/tests/ui/cfg/auxiliary/cfg_false_lib_no_std_after.rs b/tests/ui/cfg/auxiliary/cfg_false_lib_no_std_after.rs new file mode 100644 index 0000000000000..3cfa6c510d020 --- /dev/null +++ b/tests/ui/cfg/auxiliary/cfg_false_lib_no_std_after.rs @@ -0,0 +1,5 @@ +// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(FALSE)`. +// Therefore this crate does link to libstd. + +#![cfg(FALSE)] +#![no_std] diff --git a/tests/ui/cfg/auxiliary/cfg_false_lib_no_std_before.rs b/tests/ui/cfg/auxiliary/cfg_false_lib_no_std_before.rs new file mode 100644 index 0000000000000..8e89545b8f40d --- /dev/null +++ b/tests/ui/cfg/auxiliary/cfg_false_lib_no_std_before.rs @@ -0,0 +1,8 @@ +// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(FALSE)`. +// Therefore this crate doesn't link to libstd. + +// no-prefer-dynamic + +#![no_std] +#![crate_type = "lib"] +#![cfg(FALSE)] diff --git a/tests/ui/cfg/cfg-false-feature.rs b/tests/ui/cfg/cfg-false-feature.rs index 21ea3ec79b4d6..84c231562f1e1 100644 --- a/tests/ui/cfg/cfg-false-feature.rs +++ b/tests/ui/cfg/cfg-false-feature.rs @@ -1,5 +1,4 @@ -// It is unclear which features should be in effect in a fully unconfigured crate (issue #104633). -// Currently none on the features are in effect, so we get the feature gates reported. +// Features above `cfg(FALSE)` are in effect in a fully unconfigured crate (issue #104633). // check-pass // compile-flags: --crate-type lib @@ -8,8 +7,7 @@ #![cfg(FALSE)] #![feature(box_syntax)] -macro mac() {} //~ WARN `macro` is experimental - //~| WARN unstable syntax can change at any point in the future +macro mac() {} // OK trait A = Clone; //~ WARN trait aliases are experimental //~| WARN unstable syntax can change at any point in the future diff --git a/tests/ui/cfg/cfg-false-feature.stderr b/tests/ui/cfg/cfg-false-feature.stderr index 14673fbdb1444..34093036205fe 100644 --- a/tests/ui/cfg/cfg-false-feature.stderr +++ b/tests/ui/cfg/cfg-false-feature.stderr @@ -1,5 +1,5 @@ warning: trait aliases are experimental - --> $DIR/cfg-false-feature.rs:14:1 + --> $DIR/cfg-false-feature.rs:12:1 | LL | trait A = Clone; | ^^^^^^^^^^^^^^^^ @@ -9,19 +9,8 @@ LL | trait A = Clone; = warning: unstable syntax can change at any point in the future, causing a hard error! = note: for more information, see issue #65860 -warning: `macro` is experimental - --> $DIR/cfg-false-feature.rs:11:1 - | -LL | macro mac() {} - | ^^^^^^^^^^^^^^ - | - = note: see issue #39412 for more information - = help: add `#![feature(decl_macro)]` to the crate attributes to enable - = warning: unstable syntax can change at any point in the future, causing a hard error! - = note: for more information, see issue #65860 - warning: box pattern syntax is experimental - --> $DIR/cfg-false-feature.rs:18:9 + --> $DIR/cfg-false-feature.rs:16:9 | LL | let box _ = Box::new(0); | ^^^^^ @@ -31,5 +20,5 @@ LL | let box _ = Box::new(0); = warning: unstable syntax can change at any point in the future, causing a hard error! = note: for more information, see issue #65860 -warning: 3 warnings emitted +warning: 2 warnings emitted diff --git a/tests/ui/cfg/cfg_false_no_std-1.rs b/tests/ui/cfg/cfg_false_no_std-1.rs new file mode 100644 index 0000000000000..bcb49e5135364 --- /dev/null +++ b/tests/ui/cfg/cfg_false_no_std-1.rs @@ -0,0 +1,10 @@ +// No error, panic handler is supplied by libstd linked though the empty library. + +// check-pass +// aux-build: cfg_false_lib_no_std_after.rs + +#![no_std] + +extern crate cfg_false_lib_no_std_after as _; + +fn main() {} diff --git a/tests/ui/cfg/cfg_false_no_std-2.rs b/tests/ui/cfg/cfg_false_no_std-2.rs new file mode 100644 index 0000000000000..0a2bfd5f68b12 --- /dev/null +++ b/tests/ui/cfg/cfg_false_no_std-2.rs @@ -0,0 +1,11 @@ +// Error, the linked empty library is `no_std` and doesn't provide a panic handler. + +// dont-check-compiler-stderr +// error-pattern: `#[panic_handler]` function required, but not found +// aux-build: cfg_false_lib_no_std_before.rs + +#![no_std] + +extern crate cfg_false_lib_no_std_before as _; + +fn main() {} diff --git a/tests/ui/cfg/cfg_false_no_std.rs b/tests/ui/cfg/cfg_false_no_std.rs index 319ea078187c2..4fa831715ede1 100644 --- a/tests/ui/cfg/cfg_false_no_std.rs +++ b/tests/ui/cfg/cfg_false_no_std.rs @@ -1,5 +1,4 @@ -// Currently no error because the panic handler is supplied by libstd linked though the empty -// library, but the desirable behavior is unclear (see comments in cfg_false_lib.rs). +// No error, panic handler is supplied by libstd linked though the empty library. // check-pass // aux-build: cfg_false_lib.rs diff --git a/tests/ui/did_you_mean/issue-42599_available_fields_note.stderr b/tests/ui/did_you_mean/issue-42599_available_fields_note.stderr index dbd9dc1bc404f..c20bbce3f24a9 100644 --- a/tests/ui/did_you_mean/issue-42599_available_fields_note.stderr +++ b/tests/ui/did_you_mean/issue-42599_available_fields_note.stderr @@ -10,7 +10,7 @@ error[E0560]: struct `Demo` has no field named `egregiously_nonexistent_field` LL | Self { secret_integer: 3, egregiously_nonexistent_field: () } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Demo` does not have this field | - = note: available fields are: `favorite_integer`, `secret_integer`, `innocently_misspellable`, `another_field`, `yet_another_field` ... and 2 others + = note: available fields are: `favorite_integer`, `innocently_misspellable`, `another_field`, `yet_another_field`, `always_more_fields`, `and_ever` error[E0609]: no field `inocently_mispellable` on type `Demo` --> $DIR/issue-42599_available_fields_note.rs:32:41 diff --git a/tests/ui/error-codes/E0560.stderr b/tests/ui/error-codes/E0560.stderr index 6b634f1855dc1..bb5ce478ae1a7 100644 --- a/tests/ui/error-codes/E0560.stderr +++ b/tests/ui/error-codes/E0560.stderr @@ -4,7 +4,7 @@ error[E0560]: struct `Simba` has no field named `father` LL | let s = Simba { mother: 1, father: 0 }; | ^^^^^^ `Simba` does not have this field | - = note: available fields are: `mother` + = note: all struct fields are already assigned error: aborting due to previous error diff --git a/tests/ui/issues/issue-5439.stderr b/tests/ui/issues/issue-5439.stderr index dc8f8b878d730..a91e4b31f4bdf 100644 --- a/tests/ui/issues/issue-5439.stderr +++ b/tests/ui/issues/issue-5439.stderr @@ -4,7 +4,7 @@ error[E0560]: struct `Foo` has no field named `nonexistent` LL | return Box::new(Foo { nonexistent: self, foo: i }); | ^^^^^^^^^^^ `Foo` does not have this field | - = note: available fields are: `foo` + = note: all struct fields are already assigned error: aborting due to previous error diff --git a/tests/ui/proc-macro/span-preservation.stderr b/tests/ui/proc-macro/span-preservation.stderr index 66c68be2f09de..8c15cb9de9823 100644 --- a/tests/ui/proc-macro/span-preservation.stderr +++ b/tests/ui/proc-macro/span-preservation.stderr @@ -32,7 +32,7 @@ error[E0560]: struct `Foo` has no field named `b` LL | let y = Foo { a: 10, b: 10isize }; | ^ `Foo` does not have this field | - = note: available fields are: `a` + = note: all struct fields are already assigned error[E0308]: mismatched types --> $DIR/span-preservation.rs:39:5 diff --git a/tests/ui/structs/struct-field-cfg.stderr b/tests/ui/structs/struct-field-cfg.stderr index 5ec47c093a9b0..2b9ba85ddcb88 100644 --- a/tests/ui/structs/struct-field-cfg.stderr +++ b/tests/ui/structs/struct-field-cfg.stderr @@ -10,7 +10,7 @@ error[E0560]: struct `Foo` has no field named `absent` LL | let _ = Foo { present: (), #[cfg(all())] absent: () }; | ^^^^^^ `Foo` does not have this field | - = note: available fields are: `present` + = note: all struct fields are already assigned error[E0027]: pattern does not mention field `present` --> $DIR/struct-field-cfg.rs:13:9 diff --git a/tests/ui/structs/struct-fields-shorthand.stderr b/tests/ui/structs/struct-fields-shorthand.stderr index a285a392168c7..d89d45b39033a 100644 --- a/tests/ui/structs/struct-fields-shorthand.stderr +++ b/tests/ui/structs/struct-fields-shorthand.stderr @@ -4,7 +4,7 @@ error[E0560]: struct `Foo` has no field named `z` LL | x, y, z | ^ `Foo` does not have this field | - = note: available fields are: `x`, `y` + = note: all struct fields are already assigned error: aborting due to previous error diff --git a/tests/ui/structs/struct-fields-too-many.stderr b/tests/ui/structs/struct-fields-too-many.stderr index a1b7a7a311080..9342607ebce25 100644 --- a/tests/ui/structs/struct-fields-too-many.stderr +++ b/tests/ui/structs/struct-fields-too-many.stderr @@ -4,7 +4,7 @@ error[E0560]: struct `BuildData` has no field named `bar` LL | bar: 0 | ^^^ `BuildData` does not have this field | - = note: available fields are: `foo` + = note: all struct fields are already assigned error: aborting due to previous error diff --git a/tests/ui/traits/new-solver/slice-match-byte-lit.rs b/tests/ui/traits/new-solver/slice-match-byte-lit.rs new file mode 100644 index 0000000000000..4f848062595da --- /dev/null +++ b/tests/ui/traits/new-solver/slice-match-byte-lit.rs @@ -0,0 +1,11 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +fn test(s: &[u8]) { + match &s[0..3] { + b"uwu" => {} + _ => {} + } +} + +fn main() {} diff --git a/tests/ui/union/union-fields-2.mirunsafeck.stderr b/tests/ui/union/union-fields-2.mirunsafeck.stderr index 90ad16402f7db..1157f0c2ae770 100644 --- a/tests/ui/union/union-fields-2.mirunsafeck.stderr +++ b/tests/ui/union/union-fields-2.mirunsafeck.stderr @@ -16,7 +16,7 @@ error[E0560]: union `U` has no field named `c` LL | let u = U { a: 0, b: 1, c: 2 }; | ^ `U` does not have this field | - = note: available fields are: `a`, `b` + = note: all struct fields are already assigned error[E0784]: union expressions should have exactly one field --> $DIR/union-fields-2.rs:13:13 diff --git a/tests/ui/union/union-fields-2.thirunsafeck.stderr b/tests/ui/union/union-fields-2.thirunsafeck.stderr index 90ad16402f7db..1157f0c2ae770 100644 --- a/tests/ui/union/union-fields-2.thirunsafeck.stderr +++ b/tests/ui/union/union-fields-2.thirunsafeck.stderr @@ -16,7 +16,7 @@ error[E0560]: union `U` has no field named `c` LL | let u = U { a: 0, b: 1, c: 2 }; | ^ `U` does not have this field | - = note: available fields are: `a`, `b` + = note: all struct fields are already assigned error[E0784]: union expressions should have exactly one field --> $DIR/union-fields-2.rs:13:13 diff --git a/triagebot.toml b/triagebot.toml index 42190061ef90d..0f0b31e9f38a1 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -378,7 +378,7 @@ Portable SIMD is developed in its own repository. If possible, consider \ making this change to [rust-lang/portable-simd](https://github.com/rust-lang/portable-simd) \ instead. """ -cc = ["@calebzulawski"] +cc = ["@calebzulawski", "@programmerjake"] [mentions."src/librustdoc/clean/types.rs"] cc = ["@camelid"]