From 86ab4a06ebd04151bf6aa48a546018be6386c158 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Wed, 13 Jul 2022 23:22:43 -0600 Subject: [PATCH 01/20] word-wrap the comments. --- compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index 8d6130a8a7936..f747e735f56c2 100644 --- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs @@ -4,9 +4,17 @@ //! //! Please ping @Lokathor if changes are needed. //! -//! This target profile assumes that you have the ARM binutils in your path (specifically the linker, `arm-none-eabi-ld`). They can be obtained for free for all major OSes from the ARM developer's website, and they may also be available in your system's package manager. Unfortunately, the standard linker that Rust uses (`lld`) only supports as far back as `ARMv5TE`, so we must use the GNU `ld` linker. +//! This target profile assumes that you have the ARM binutils in your path +//! (specifically the linker, `arm-none-eabi-ld`). They can be obtained for free +//! for all major OSes from the ARM developer's website, and they may also be +//! available in your system's package manager. Unfortunately, the standard +//! linker that Rust uses (`lld`) only supports as far back as `ARMv5TE`, so we +//! must use the GNU `ld` linker. //! -//! **Important:** This target profile **does not** specify a linker script. You just get the default link script when you build a binary for this target. The default link script is very likely wrong, so you should use `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. +//! **Important:** This target profile **does not** specify a linker script. You +//! just get the default link script when you build a binary for this target. +//! The default link script is very likely wrong, so you should use +//! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. use crate::spec::{cvs, LinkerFlavor, Target, TargetOptions}; From 7be0b877f4b188e81e6310cdc4e585f427501239 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Wed, 13 Jul 2022 23:24:57 -0600 Subject: [PATCH 02/20] Update thumbv4t_none_eabi.rs --- compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index f747e735f56c2..e4bede3efbd82 100644 --- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs @@ -46,6 +46,13 @@ pub fn target() -> Target { // minimum extra features, these cannot be disabled via -C features: "+soft-float,+strict-align".into(), + + panic_strategy: PanicStrategy::Abort, + relocation_model: RelocModel::Static, + // suggested from thumb_base, rust-lang/rust#44993. + emit_debug_gdb_scripts: false, + // suggested from thumb_base, with no-os gcc/clang use 8-bit enums + c_enum_min_bits: 8, main_needs_argc_argv: false, @@ -53,7 +60,7 @@ pub fn target() -> Target { atomic_cas: false, has_thumb_interworking: true, - ..super::thumb_base::opts() + ..Default::default() }, } } From 6c22b44537005ffd0cfb8513c5ac09fe9906e13f Mon Sep 17 00:00:00 2001 From: Lokathor Date: Wed, 13 Jul 2022 23:37:08 -0600 Subject: [PATCH 03/20] add missing imports. --- compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index e4bede3efbd82..705340ad8ea05 100644 --- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs @@ -16,7 +16,7 @@ //! The default link script is very likely wrong, so you should use //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. -use crate::spec::{cvs, LinkerFlavor, Target, TargetOptions}; +use crate::spec::{cvs, LinkerFlavor, Target, TargetOptions, PanicStrategy, RelocModel}; pub fn target() -> Target { Target { From 0e78c73b7403a9037838dc1ac2544725fc038003 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Wed, 13 Jul 2022 23:51:50 -0600 Subject: [PATCH 04/20] conform to the tidy expectations --- compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index 705340ad8ea05..8415ab0acf21e 100644 --- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs @@ -16,7 +16,7 @@ //! The default link script is very likely wrong, so you should use //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. -use crate::spec::{cvs, LinkerFlavor, Target, TargetOptions, PanicStrategy, RelocModel}; +use crate::spec::{cvs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { From 26e07879be269ba2f1b5f05fd34e45e4fcaf16b5 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Thu, 14 Jul 2022 00:03:59 -0600 Subject: [PATCH 05/20] tidy demands this whitespace go away --- compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index 8415ab0acf21e..11e89a84b7454 100644 --- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs @@ -46,7 +46,7 @@ pub fn target() -> Target { // minimum extra features, these cannot be disabled via -C features: "+soft-float,+strict-align".into(), - + panic_strategy: PanicStrategy::Abort, relocation_model: RelocModel::Static, // suggested from thumb_base, rust-lang/rust#44993. From 9b566401068cb8450912f6ab48f3d0e60f5cb482 Mon Sep 17 00:00:00 2001 From: Ding Xiang Fei Date: Thu, 21 Jul 2022 00:35:12 +0800 Subject: [PATCH 06/20] break out scopes when let-else fails to match --- compiler/rustc_mir_build/src/build/block.rs | 1 + .../rustc_mir_build/src/build/matches/mod.rs | 86 ++++++++++--------- compiler/rustc_mir_build/src/build/scope.rs | 4 +- .../ui/let-else/let-else-temp-borrowck.rs | 26 ++++++ .../let-else/let-else-temporary-lifetime.rs | 35 ++++++++ 5 files changed, 110 insertions(+), 42 deletions(-) create mode 100644 src/test/ui/let-else/let-else-temp-borrowck.rs diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index cb8be51a08562..6875600129a8f 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -132,6 +132,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { initializer_span, else_block, visibility_scope, + *remainder_scope, remainder_span, pattern, ) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 7067a48b783ec..58b1564cc5d8c 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -2282,49 +2282,55 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { initializer_span: Span, else_block: &Block, visibility_scope: Option, + remainder_scope: region::Scope, remainder_span: Span, pattern: &Pat<'tcx>, ) -> BlockAnd<()> { - let scrutinee = unpack!(block = self.lower_scrutinee(block, init, initializer_span)); - let pat = Pat { ty: init.ty, span: else_block.span, kind: Box::new(PatKind::Wild) }; - let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false); - self.declare_bindings( - visibility_scope, - remainder_span, - pattern, - ArmHasGuard(false), - Some((None, initializer_span)), - ); - let mut candidate = Candidate::new(scrutinee.clone(), pattern, false); - let fake_borrow_temps = self.lower_match_tree( - block, - initializer_span, - pattern.span, - false, - &mut [&mut candidate, &mut wildcard], - ); - // This block is for the matching case - let matching = self.bind_pattern( - self.source_info(pattern.span), - candidate, - None, - &fake_borrow_temps, - initializer_span, - None, - None, - None, - ); - // This block is for the failure case - let failure = self.bind_pattern( - self.source_info(else_block.span), - wildcard, - None, - &fake_borrow_temps, - initializer_span, - None, - None, - None, - ); + let (matching, failure) = self.in_if_then_scope(remainder_scope, |this| { + let scrutinee = unpack!(block = this.lower_scrutinee(block, init, initializer_span)); + let pat = Pat { ty: init.ty, span: else_block.span, kind: Box::new(PatKind::Wild) }; + let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false); + this.declare_bindings( + visibility_scope, + remainder_span, + pattern, + ArmHasGuard(false), + Some((None, initializer_span)), + ); + let mut candidate = Candidate::new(scrutinee.clone(), pattern, false); + let fake_borrow_temps = this.lower_match_tree( + block, + initializer_span, + pattern.span, + false, + &mut [&mut candidate, &mut wildcard], + ); + // This block is for the matching case + let matching = this.bind_pattern( + this.source_info(pattern.span), + candidate, + None, + &fake_borrow_temps, + initializer_span, + None, + None, + None, + ); + // This block is for the failure case + let failure = this.bind_pattern( + this.source_info(else_block.span), + wildcard, + None, + &fake_borrow_temps, + initializer_span, + None, + None, + None, + ); + this.break_for_else(failure, remainder_scope, this.source_info(initializer_span)); + matching.unit() + }); + // This place is not really used because this destination place // should never be used to take values at the end of the failure // block. diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index b9fd8c50e6a04..b2fd9f25bdde7 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -690,7 +690,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } drops.add_entry(block, drop_idx); - // `build_drop_tree` doesn't have access to our source_info, so we + // `build_drop_trees` doesn't have access to our source_info, so we // create a dummy terminator now. `TerminatorKind::Resume` is used // because MIR type checking will panic if it hasn't been overwritten. self.cfg.terminate(block, source_info, TerminatorKind::Resume); @@ -722,7 +722,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } drops.add_entry(block, drop_idx); - // `build_drop_tree` doesn't have access to our source_info, so we + // `build_drop_trees` doesn't have access to our source_info, so we // create a dummy terminator now. `TerminatorKind::Resume` is used // because MIR type checking will panic if it hasn't been overwritten. self.cfg.terminate(block, source_info, TerminatorKind::Resume); diff --git a/src/test/ui/let-else/let-else-temp-borrowck.rs b/src/test/ui/let-else/let-else-temp-borrowck.rs new file mode 100644 index 0000000000000..3910d35e77676 --- /dev/null +++ b/src/test/ui/let-else/let-else-temp-borrowck.rs @@ -0,0 +1,26 @@ +// run-pass +// +// from issue #93951, where borrowck complained the temporary that `foo(&x)` was stored in was to +// be dropped sometime after `x` was. It then suggested adding a semicolon that was already there. + +#![feature(let_else)] +use std::fmt::Debug; + +fn foo<'a>(x: &'a str) -> Result { + Ok(x) +} + +fn let_else() { + let x = String::from("Hey"); + let Ok(_) = foo(&x) else { return }; +} + +fn if_let() { + let x = String::from("Hey"); + let _ = if let Ok(s) = foo(&x) { s } else { return }; +} + +fn main() { + let_else(); + if_let(); +} diff --git a/src/test/ui/let-else/let-else-temporary-lifetime.rs b/src/test/ui/let-else/let-else-temporary-lifetime.rs index 624c2ea37a70b..28c69ba1ce66f 100644 --- a/src/test/ui/let-else/let-else-temporary-lifetime.rs +++ b/src/test/ui/let-else/let-else-temporary-lifetime.rs @@ -1,6 +1,7 @@ // run-pass #![feature(let_else)] +use std::rc::Rc; use std::sync::atomic::{AtomicU8, Ordering}; static TRACKER: AtomicU8 = AtomicU8::new(0); @@ -22,4 +23,38 @@ fn main() { let 0 = Droppy::default().inner else { return }; assert_eq!(TRACKER.load(Ordering::Acquire), 1); println!("Should have dropped 👆"); + + { + // test let-else drops temps after statement + let rc = Rc::new(0); + let 0 = *rc.clone() else { unreachable!() }; + Rc::try_unwrap(rc).unwrap(); + } + { + let mut rc = Rc::new(0); + let mut i = 0; + loop { + if i > 3 { + break; + } + let 1 = *rc.clone() else { + if let Ok(v) = Rc::try_unwrap(rc) { + rc = Rc::new(v); + } else { + panic!() + } + i += 1; + continue + }; + } + } + { + // test let-else drops temps before else block + let rc = Rc::new(0); + let 1 = *rc.clone() else { + Rc::try_unwrap(rc).unwrap(); + return; + }; + unreachable!(); + } } From baf9a7cb57120ec1411196214fd0d1c33fb18bf6 Mon Sep 17 00:00:00 2001 From: Ding Xiang Fei Date: Thu, 21 Jul 2022 23:39:01 +0800 Subject: [PATCH 07/20] provide a test for #93951 --- src/test/ui/let-else/let-else-temporary-lifetime.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/ui/let-else/let-else-temporary-lifetime.rs b/src/test/ui/let-else/let-else-temporary-lifetime.rs index 28c69ba1ce66f..064f28b4d9408 100644 --- a/src/test/ui/let-else/let-else-temporary-lifetime.rs +++ b/src/test/ui/let-else/let-else-temporary-lifetime.rs @@ -1,6 +1,7 @@ // run-pass #![feature(let_else)] +use std::fmt::Display; use std::rc::Rc; use std::sync::atomic::{AtomicU8, Ordering}; @@ -18,12 +19,22 @@ impl Drop for Droppy { } } +fn foo<'a>(x: &'a str) -> Result { + Ok(x) +} + fn main() { assert_eq!(TRACKER.load(Ordering::Acquire), 0); let 0 = Droppy::default().inner else { return }; assert_eq!(TRACKER.load(Ordering::Acquire), 1); println!("Should have dropped 👆"); + { + let x = String::from("Hey"); + + let Ok(s) = foo(&x) else { panic!() }; + assert_eq!(s.to_string(), x); + } { // test let-else drops temps after statement let rc = Rc::new(0); From 60be2de8b7b8a1c4eee7e065b8cef38ea629a6a3 Mon Sep 17 00:00:00 2001 From: Ding Xiang Fei Date: Fri, 22 Jul 2022 18:13:17 +0800 Subject: [PATCH 08/20] include a demo that more programs can be compiled --- .../ui/let-else/let-else-temporary-lifetime.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/ui/let-else/let-else-temporary-lifetime.rs b/src/test/ui/let-else/let-else-temporary-lifetime.rs index 064f28b4d9408..9c86901b97f03 100644 --- a/src/test/ui/let-else/let-else-temporary-lifetime.rs +++ b/src/test/ui/let-else/let-else-temporary-lifetime.rs @@ -29,6 +29,21 @@ fn main() { assert_eq!(TRACKER.load(Ordering::Acquire), 1); println!("Should have dropped 👆"); + { + // cf. https://github.com/rust-lang/rust/pull/99518#issuecomment-1191520030 + struct Foo<'a>(&'a mut u32); + + impl<'a> Drop for Foo<'a> { + fn drop(&mut self) { + *self.0 = 0; + } + } + let mut foo = 0; + let Foo(0) = Foo(&mut foo) else { + *&mut foo = 1; + todo!() + }; + } { let x = String::from("Hey"); @@ -61,6 +76,8 @@ fn main() { } { // test let-else drops temps before else block + // NOTE: this test has to be the last block in the `main` + // body. let rc = Rc::new(0); let 1 = *rc.clone() else { Rc::try_unwrap(rc).unwrap(); From 1d4ddab1bf5c523bdf6e3b7e9cff3c3224c6ed04 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sun, 24 Jul 2022 22:26:44 +0900 Subject: [PATCH 09/20] suggest dereferencing index when trying to use a reference of usize as index --- .../src/traits/error_reporting/mod.rs | 1 + .../src/traits/error_reporting/suggestions.rs | 27 ++++++++++++++++ compiler/rustc_typeck/src/check/expr.rs | 13 ++++++++ src/test/ui/index-help.stderr | 4 +-- src/test/ui/indexing-requires-a-uint.stderr | 4 +-- src/test/ui/integral-indexing.stderr | 32 +++++++++---------- .../ui/on-unimplemented/slice-index.stderr | 8 ++--- src/test/ui/str/str-idx.stderr | 8 ++--- src/test/ui/str/str-mut-idx.stderr | 8 ++--- .../suggest-dereferencing-index.fixed | 7 ++++ .../suggest-dereferencing-index.rs | 7 ++++ .../suggest-dereferencing-index.stderr | 17 ++++++++++ 12 files changed, 104 insertions(+), 32 deletions(-) create mode 100644 src/test/ui/suggestions/suggest-dereferencing-index.fixed create mode 100644 src/test/ui/suggestions/suggest-dereferencing-index.rs create mode 100644 src/test/ui/suggestions/suggest-dereferencing-index.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 2f92a77a7957d..1b7928a10bd12 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -534,6 +534,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } self.suggest_floating_point_literal(&obligation, &mut err, &trait_ref); + self.suggest_dereferencing_index(&obligation, &mut err, trait_predicate); let mut suggested = self.suggest_dereferences(&obligation, &mut err, trait_predicate); suggested |= self.suggest_fn_call(&obligation, &mut err, trait_predicate); 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 7ab85e7fa663e..c51f3dacd5466 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -320,6 +320,13 @@ pub trait InferCtxtExt<'tcx> { err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ); + + fn suggest_dereferencing_index( + &self, + obligation: &PredicateObligation<'tcx>, + err: &mut Diagnostic, + trait_pred: ty::PolyTraitPredicate<'tcx>, + ); } fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) { @@ -2927,6 +2934,26 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ); } } + + fn suggest_dereferencing_index( + &self, + obligation: &PredicateObligation<'tcx>, + err: &mut Diagnostic, + trait_pred: ty::PolyTraitPredicate<'tcx>, + ) { + if let ObligationCauseCode::ImplDerivedObligation(_) = obligation.cause.code() + && self.tcx.is_diagnostic_item(sym::SliceIndex, trait_pred.skip_binder().trait_ref.def_id) + && let ty::Ref(_, inner_ty, _) = trait_pred.skip_binder().self_ty().kind() + && let ty::Uint(ty::UintTy::Usize) = inner_ty.kind() + { + err.span_suggestion_verbose( + obligation.cause.span.shrink_to_lo(), + "consider dereferencing here", + '*', + Applicability::MaybeIncorrect, + ); + } + } } /// Collect all the returned expressions within the input expression. diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 8e4cd2392e03b..4c0a2bd9199aa 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -2648,6 +2648,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some((index_ty, element_ty)) => { // two-phase not needed because index_ty is never mutable self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No); + self.select_obligations_where_possible(false, |errors| { + for error in errors { + match error.obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Trait(predicate) + if self.tcx.is_diagnostic_item( + sym::SliceIndex, + predicate.trait_ref.def_id, + ) => {} + _ => continue, + } + error.obligation.cause.span = idx.span; + } + }); element_ty } None => { diff --git a/src/test/ui/index-help.stderr b/src/test/ui/index-help.stderr index 7f51a48111b78..b36f4dab8291d 100644 --- a/src/test/ui/index-help.stderr +++ b/src/test/ui/index-help.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `[{integer}]` cannot be indexed by `i32` - --> $DIR/index-help.rs:3:5 + --> $DIR/index-help.rs:3:7 | LL | x[0i32]; - | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32` = help: the trait `SliceIndex<[T]>` is implemented for `usize` diff --git a/src/test/ui/indexing-requires-a-uint.stderr b/src/test/ui/indexing-requires-a-uint.stderr index 0a24855a6a79c..fbff20f8deeab 100644 --- a/src/test/ui/indexing-requires-a-uint.stderr +++ b/src/test/ui/indexing-requires-a-uint.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `[{integer}]` cannot be indexed by `u8` - --> $DIR/indexing-requires-a-uint.rs:6:5 + --> $DIR/indexing-requires-a-uint.rs:6:9 | LL | [0][0u8]; - | ^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8` = help: the trait `SliceIndex<[T]>` is implemented for `usize` diff --git a/src/test/ui/integral-indexing.stderr b/src/test/ui/integral-indexing.stderr index be3398552dc0a..3f9094d124eea 100644 --- a/src/test/ui/integral-indexing.stderr +++ b/src/test/ui/integral-indexing.stderr @@ -1,78 +1,78 @@ error[E0277]: the type `[isize]` cannot be indexed by `u8` - --> $DIR/integral-indexing.rs:6:5 + --> $DIR/integral-indexing.rs:6:7 | LL | v[3u8]; - | ^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `u8` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `Vec` error[E0277]: the type `[isize]` cannot be indexed by `i8` - --> $DIR/integral-indexing.rs:7:5 + --> $DIR/integral-indexing.rs:7:7 | LL | v[3i8]; - | ^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `i8` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `Vec` error[E0277]: the type `[isize]` cannot be indexed by `u32` - --> $DIR/integral-indexing.rs:8:5 + --> $DIR/integral-indexing.rs:8:7 | LL | v[3u32]; - | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `u32` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `Vec` error[E0277]: the type `[isize]` cannot be indexed by `i32` - --> $DIR/integral-indexing.rs:9:5 + --> $DIR/integral-indexing.rs:9:7 | LL | v[3i32]; - | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `i32` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `Vec` error[E0277]: the type `[u8]` cannot be indexed by `u8` - --> $DIR/integral-indexing.rs:12:5 + --> $DIR/integral-indexing.rs:12:18 | LL | s.as_bytes()[3u8]; - | ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `u8` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `[u8]` error[E0277]: the type `[u8]` cannot be indexed by `i8` - --> $DIR/integral-indexing.rs:13:5 + --> $DIR/integral-indexing.rs:13:18 | LL | s.as_bytes()[3i8]; - | ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `i8` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `[u8]` error[E0277]: the type `[u8]` cannot be indexed by `u32` - --> $DIR/integral-indexing.rs:14:5 + --> $DIR/integral-indexing.rs:14:18 | LL | s.as_bytes()[3u32]; - | ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `u32` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `[u8]` error[E0277]: the type `[u8]` cannot be indexed by `i32` - --> $DIR/integral-indexing.rs:15:5 + --> $DIR/integral-indexing.rs:15:18 | LL | s.as_bytes()[3i32]; - | ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `i32` = help: the trait `SliceIndex<[T]>` is implemented for `usize` diff --git a/src/test/ui/on-unimplemented/slice-index.stderr b/src/test/ui/on-unimplemented/slice-index.stderr index ae7d2e1d82393..72f67a685156d 100644 --- a/src/test/ui/on-unimplemented/slice-index.stderr +++ b/src/test/ui/on-unimplemented/slice-index.stderr @@ -1,18 +1,18 @@ error[E0277]: the type `[i32]` cannot be indexed by `i32` - --> $DIR/slice-index.rs:8:5 + --> $DIR/slice-index.rs:8:7 | LL | x[1i32]; - | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[i32]>` is not implemented for `i32` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index` for `[i32]` error[E0277]: the type `[i32]` cannot be indexed by `RangeTo` - --> $DIR/slice-index.rs:9:5 + --> $DIR/slice-index.rs:9:7 | LL | x[..1i32]; - | ^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | ^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[i32]>` is not implemented for `RangeTo` = help: the following other types implement trait `SliceIndex`: diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr index 45450788b9cbd..9079a18d6a67b 100644 --- a/src/test/ui/str/str-idx.stderr +++ b/src/test/ui/str/str-idx.stderr @@ -1,8 +1,8 @@ error[E0277]: the type `str` cannot be indexed by `{integer}` - --> $DIR/str-idx.rs:3:17 + --> $DIR/str-idx.rs:3:19 | LL | let _: u8 = s[4]; - | ^^^^ string indices are ranges of `usize` + | ^ string indices are ranges of `usize` | = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` @@ -47,10 +47,10 @@ LL | pub const unsafe fn get_unchecked>(&self, i: | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get_unchecked` error[E0277]: the type `str` cannot be indexed by `char` - --> $DIR/str-idx.rs:6:17 + --> $DIR/str-idx.rs:6:19 | LL | let _: u8 = s['c']; - | ^^^^^^ string indices are ranges of `usize` + | ^^^ string indices are ranges of `usize` | = help: the trait `SliceIndex` is not implemented for `char` = note: required because of the requirements on the impl of `Index` for `str` diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr index 9ae085630279e..2d062e56a9bdd 100644 --- a/src/test/ui/str/str-mut-idx.stderr +++ b/src/test/ui/str/str-mut-idx.stderr @@ -25,10 +25,10 @@ LL | s[1..2] = bot(); = note: the left-hand-side of an assignment must have a statically known size error[E0277]: the type `str` cannot be indexed by `usize` - --> $DIR/str-mut-idx.rs:7:5 + --> $DIR/str-mut-idx.rs:7:7 | LL | s[1usize] = bot(); - | ^^^^^^^^^ string indices are ranges of `usize` + | ^^^^^^ string indices are ranges of `usize` | = help: the trait `SliceIndex` is not implemented for `usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` @@ -71,10 +71,10 @@ LL | pub const unsafe fn get_unchecked_mut>( | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get_unchecked_mut` error[E0277]: the type `str` cannot be indexed by `char` - --> $DIR/str-mut-idx.rs:13:5 + --> $DIR/str-mut-idx.rs:13:7 | LL | s['c']; - | ^^^^^^ string indices are ranges of `usize` + | ^^^ string indices are ranges of `usize` | = help: the trait `SliceIndex` is not implemented for `char` = note: required because of the requirements on the impl of `Index` for `str` diff --git a/src/test/ui/suggestions/suggest-dereferencing-index.fixed b/src/test/ui/suggestions/suggest-dereferencing-index.fixed new file mode 100644 index 0000000000000..dd4ae4eb14c30 --- /dev/null +++ b/src/test/ui/suggestions/suggest-dereferencing-index.fixed @@ -0,0 +1,7 @@ +// run-rustfix +#![allow(unused_variables)] + +fn main() { + let i: &usize = &1; + let one_item_please: i32 = [1, 2, 3][*i]; //~ ERROR the type `[{integer}]` cannot be indexed by `&usize` +} diff --git a/src/test/ui/suggestions/suggest-dereferencing-index.rs b/src/test/ui/suggestions/suggest-dereferencing-index.rs new file mode 100644 index 0000000000000..82ebacc49f235 --- /dev/null +++ b/src/test/ui/suggestions/suggest-dereferencing-index.rs @@ -0,0 +1,7 @@ +// run-rustfix +#![allow(unused_variables)] + +fn main() { + let i: &usize = &1; + let one_item_please: i32 = [1, 2, 3][i]; //~ ERROR the type `[{integer}]` cannot be indexed by `&usize` +} diff --git a/src/test/ui/suggestions/suggest-dereferencing-index.stderr b/src/test/ui/suggestions/suggest-dereferencing-index.stderr new file mode 100644 index 0000000000000..c0bb5044338c2 --- /dev/null +++ b/src/test/ui/suggestions/suggest-dereferencing-index.stderr @@ -0,0 +1,17 @@ +error[E0277]: the type `[{integer}]` cannot be indexed by `&usize` + --> $DIR/suggest-dereferencing-index.rs:6:42 + | +LL | let one_item_please: i32 = [1, 2, 3][i]; + | ^ slice indices are of type `usize` or ranges of `usize` + | + = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize` + = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = note: required because of the requirements on the impl of `Index<&usize>` for `[{integer}]` +help: consider dereferencing here + | +LL | let one_item_please: i32 = [1, 2, 3][*i]; + | + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From 9cf5b2d81c9641ebf06cd9d0652cec92b5692916 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Thu, 28 Jul 2022 10:43:05 -0600 Subject: [PATCH 10/20] Update thumbv4t_none_eabi.rs --- compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index 11e89a84b7454..8fed1b58eba4c 100644 --- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs @@ -16,7 +16,7 @@ //! The default link script is very likely wrong, so you should use //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. -use crate::spec::{cvs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions}; +use crate::spec::{cvs, LinkerFlavor, FramePointer, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -53,6 +53,7 @@ pub fn target() -> Target { emit_debug_gdb_scripts: false, // suggested from thumb_base, with no-os gcc/clang use 8-bit enums c_enum_min_bits: 8, + frame_pointer: FramePointer::MayOmit, main_needs_argc_argv: false, @@ -60,7 +61,7 @@ pub fn target() -> Target { atomic_cas: false, has_thumb_interworking: true, - ..Default::default() + ..super::thumb_base::opts() }, } } From 2eac6f30c8a1cd59dc640bf68bc58eb7fe656d61 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Thu, 28 Jul 2022 10:58:42 -0600 Subject: [PATCH 11/20] once again tidy was unhappy --- compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index 8fed1b58eba4c..7125d141af7f5 100644 --- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs @@ -16,7 +16,9 @@ //! The default link script is very likely wrong, so you should use //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. -use crate::spec::{cvs, LinkerFlavor, FramePointer, PanicStrategy, RelocModel, Target, TargetOptions}; +use crate::spec::{ + cvs, FramePointer, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions, +}; pub fn target() -> Target { Target { From 0fcb86b129b9ec119cf1d81abfaeb8ff2d07ad10 Mon Sep 17 00:00:00 2001 From: David Koloski Date: Wed, 20 Jul 2022 15:42:17 -0400 Subject: [PATCH 12/20] Add Fuchsia platform support documentation --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support/fuchsia.md | 295 ++++++++++++++++++ 2 files changed, 296 insertions(+) create mode 100644 src/doc/rustc/src/platform-support/fuchsia.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index f6348b2bddc88..0bb230d31977f 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -21,6 +21,7 @@ - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md) - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) + - [\*-fuchsia](platform-support/fuchsia.md) - [\*-kmc-solid_\*](platform-support/kmc-solid.md) - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md) - [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md) diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md new file mode 100644 index 0000000000000..61bd1b425bc35 --- /dev/null +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -0,0 +1,295 @@ +# `aarch64-fuchsia` and `x86_64-fuchsia` + +**Tier: 2** + +[Fuchsia] is a modern open source operating system that's simple, secure, +updatable, and performant. + +[Fuchsia]: https://fuchsia.dev/ + +## Target maintainers + +The [Fuchsia team]: + +[Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json + +- Tyler Mandry ([@tmandry](https://github.com/tmandry)) +- Dan Johnson ([@computerdruid](https://github.com/computerdruid)) +- David Koloski ([@djkoloski](https://github.com/djkoloski)) +- Andrew Pollack ([@andrewpollack](https://github.com/andrewpollack)) +- Joseph Ryan ([@P1n3appl3](https://github.com/P1n3appl3)) + +As the team evolves over time, the specific members listed here may differ from +the members reported by the API. The API should be considered to be +authoritative if this occurs. Instead of pinging individual members, use +`@rustbot ping fuchsia` to contact the team on GitHub. + +## Requirements + +This target is cross-compiled from a host environment. Development may be done +from the [source tree] or using the Fuchsia SDK. + +[source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build + +Fuchsia targets support std and follow the `sysv64` calling convention on +x86_64. Fuchsia binaries use the ELF file format. + +## Building the target + +Before building Rust for Fuchsia, you'll need a clang toolchain that supports +Fuchsia as well. A recent version (14+) of clang should be sufficient to compile +Rust for Fuchsia. + +You'll also need a recent copy of the [Fuchsia SDK], which provides the tools +and binaries required to build and link programs for Fuchsia. + +[Fuchsia SDK]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core + +x86-64 and AArch64 Fuchsia targets can be enabled using the following +configuration. + +In `config.toml`, add: + +```toml +[build] +target = ["", "aarch64-fuchsia", "x86_64-fuchsia"] + +[target.x86_64-fuchsia] +llvm-libunwind = "in-tree" + +[target.aarch64-fuchsia] +llvm-libunwind = "in-tree" +``` + +Additionally, the following environment variables must be configured (for +example, using a script like `config-env.sh`): + +```sh +# Configure this environment variable to be the path to the downloaded SDK +export SDK_PATH="" + +export CFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include" +export CXXFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include" +export LDFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -L${SDK_PATH}/arch/arm64/lib" +export CARGO_TARGET_AARCH64_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/arm64/sysroot -Lnative=${SDK_PATH}/arch/arm64/sysroot/lib -Lnative=${SDK_PATH}/arch/arm64/lib" +export CFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include" +export CXXFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include" +export LDFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -L${SDK_PATH}/arch/x64/lib" +export CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/x64/sysroot -Lnative=${SDK_PATH}/arch/x64/sysroot/lib -Lnative=${SDK_PATH}/arch/x64/lib" +``` + +These can be run together in a shell environment by executing +`(source config-env.sh && ./x.py install)`. + +## Building Rust programs + +After compiling Rust binaries, you'll need to build a component, package it, and +serve it to a Fuchsia device or emulator. All of this can be done using the +Fuchsia SDK. + +As an example, we'll compile and run this simple program on a Fuchsia emulator: + +**`hello_fuchsia.rs`** +```rust +fn main() { + println!("Hello Fuchsia!"); +} + +#[test] +fn it_works() { + assert_eq!(2 + 2, 4); +} +``` + +Create a new file named `hello_fuchsia.rs` and fill out its contents with that +code. + +### Create a package + +On Fuchsia, a package is the unit of distribution for software. We'll need to +create a new package directory where we will place files like our finished +binary and any data it may need. The working directory will have this layout: + +```txt +hello_fuchsia.rs +hello_fuchsia.cml +package +┣━ bin +┃ ┗━ hello_fuchsia +┣━ meta +┃ ┣━ package +┃ ┗━ hello_fuchsia.cm +┗━ hello_fuchsia.manifest +``` + +Make the `package`, `package/bin`, and `package/meta` directories and create the +following files inside: + +**`package/meta/package`** +```json +{"name":"hello_fuchsia","version":0} +``` + +The `package` file describes our package's name and version number. Every +package must contain one. + +**`package/hello_fuchsia.manifest`** +```txt +bin/hello_fuchsia=package/bin/hello_fuchsia +lib/ld.so.1=/arch/x64/sysroot/dist/lib/ld.so.1 +lib/libfdio.so=/arch/x64/dist/libfdio.so +meta/package=package/meta/package +meta/hello_fuchsia.cm=package/meta/hello_fuchsia.cm +``` + +*Note: Relative manifest paths are resolved starting from the working directory +of `pm`. Make sure to fill out `` with the path to the downloaded +SDK.* + +The `.manifest` file will be used to describe the contents of the package by +relating their location when installed to their location on the file system. You +can use this to make a package pull files from other places, but for this +example we'll just be placing everything in the `package` directory. + +### Compiling a binary + +Using your freshly compiled `rustc`, you can compile a binary for Fuchsia using +the following options: + +* `--target x86_64-fuchsia`/`--target aarch64-fuchsia`: Targets the Fuchsia + platform of your choice +* `-Lnative ${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from + the SDK +* `-Lnative ${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia kernel + libraries from the SDK + +Putting it all together: + +```sh +# Configure these for the Fuchsia target of your choice +TARGET_ARCH="" +ARCH="" + +rustc --target ${TARGET_ARCH} -Lnative=${SDK_PATH}/arch/${ARCH}/lib -Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib -o package/bin/hello_fuchsia hello_fuchsia.rs +``` + +### Bulding a component + +On Fuchsia, components require a component manifest written in Fuchia's markup +language called CML. The Fuchsia devsite contains an [overview of CML] and a +[reference for the file format]. Here's a basic one that can run our single binary: + +[overview of CML]: https://fuchsia.dev/fuchsia-src/concepts/components/v2/component_manifests +[reference for the file format]: https://fuchsia.dev/reference/cml + +**`hello_fuchsia.cml`** +```txt +{ + include: [ "syslog/client.shard.cml" ], + program: { + runner: "elf", + binary: "bin/hello_fuchsia", + }, +} +``` + +Now we can compile that CML into a component manifest: + +```sh +${SDK_PATH}/tools/${ARCH}/cmc compile hello_fuchsia.cml --includepath ${SDK_PATH}/pkg -o package/meta/hello_fuchsia.cm +``` + +`--includepath` tells the compiler where to look for `include`s from our CML. +In our case, we're only using `syslog/client.shard.cml`. + +### Building and publishing a package + +Next, we'll build our package as defined by our manifest: + +```sh +${SDK_PATH}/tools/${ARCH}/pm -o hello_fuchsia -m package/hello_fuchsia.manifest build -output-package-manifest hello_fuchsia_manifest +``` + +This will produce `hello_fuchsia_manifest` which is a package manifest we can +publish directly to a repository. We can set up that repository with: + +```sh +${SDK_PATH}/tools/${ARCH}/pm newrepo -repo repo +``` + +And then publish our new package to that repository with: + +```sh +${SDK_PATH}/tools/${ARCH}/pm publish -repo repo -lp -f <(echo "hello_fuchsia_manifest") +``` + +Then we can add it to `ffx`'s package server as `hello-fuchsia` using: + +```sh +${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm repo -r hello-fuchsia +``` + +### Starting the emulator + +Start a Fuchsia emulator in a new terminal using: + +```sh +${SDK_PATH}/tools/${ARCH}/ffx product-bundle get workstation_eng.qemu-${ARCH} +${SDK_PATH}/tools/${ARCH}/ffx emu start workstation_eng.qemu-${ARCH} --headless +``` + +Then, once the emulator has been started: + +```sh +${SDK_PATH}/tools/${ARCH}/ffx target repository register +``` + +And watch the logs from the emulator in a separate terminal: + +```sh +${SDK_PATH}/tools/${ARCH}/ffx log --since now +``` + +Finally, run the component: + +```sh +${SDK_PATH}/tools/${ARCH}/ffx component run fuchsia-pkg://hello-fuchsia/hello_fuchsia#meta/hello_fuchsia.cm +``` + +On reruns of the component, the `--recreate` argument may also need to be +passed. + +## Testing + +### Running unit tests + +Tests can be run in the same way as a regular binary, simply by passing `--test` +to the `rustc` invocation and then repackaging and rerunning. The test harness +will run the applicable unit tests. + +Often when testing, you may want to pass additional command line arguments to +your binary. Additional arguments can be set in the component manifest: + +**`hello_fuchsia.cml`** +```txt +{ + include: [ "syslog/client.shard.cml" ], + program: { + runner: "elf", + binary: "bin/hello_fuchsia", + args: ["it_works"], + }, +} +``` + +This will pass the argument `it_works` to the binary, filtering the tests to +only those tests that match the pattern. There are many more configuration +options available in CML including environment variables. More documentation is +available on the [Fuchsia devsite](https://fuchsia.dev/reference/cml). + +### Running the compiler test suite + +Running the Rust test suite on Fuchsia is [not currently supported], but work is +underway to enable it. + +[not currently supported]: https://fxbug.dev/105393 From b67ba9ba208ac918228a18321fc3a11a99b1c62b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 29 Jul 2022 00:40:07 +0000 Subject: [PATCH 13/20] fix ICE when computing codegen_fn_attrs on closure with non-fn parent --- compiler/rustc_typeck/src/collect.rs | 8 +++++--- .../ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs | 9 +++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 60c0694ca0e45..36111637a561c 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -3165,9 +3165,11 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { // #73631: closures inherit `#[target_feature]` annotations if tcx.features().target_feature_11 && tcx.is_closure(did.to_def_id()) { let owner_id = tcx.parent(did.to_def_id()); - codegen_fn_attrs - .target_features - .extend(tcx.codegen_fn_attrs(owner_id).target_features.iter().copied()) + if tcx.def_kind(owner_id).has_codegen_attrs() { + codegen_fn_attrs + .target_features + .extend(tcx.codegen_fn_attrs(owner_id).target_features.iter().copied()); + } } // If a function uses #[target_feature] it can't be inlined into general diff --git a/src/test/ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs b/src/test/ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs new file mode 100644 index 0000000000000..033dcdfc08db0 --- /dev/null +++ b/src/test/ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs @@ -0,0 +1,9 @@ +// check-pass + +#![feature(target_feature_11)] + +struct S(T) +where + [T; (|| {}, 1).1]: Copy; + +fn main() {} From 06f89b7924af4657e847742bf0e40eafaaee52f9 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 29 Jul 2022 14:12:17 +0900 Subject: [PATCH 14/20] implement `point_at_index_if_possible` --- compiler/rustc_typeck/src/check/expr.rs | 28 +++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 4c0a2bd9199aa..b2a5c055e462e 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -2649,17 +2649,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // two-phase not needed because index_ty is never mutable self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No); self.select_obligations_where_possible(false, |errors| { - for error in errors { - match error.obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Trait(predicate) - if self.tcx.is_diagnostic_item( - sym::SliceIndex, - predicate.trait_ref.def_id, - ) => {} - _ => continue, - } - error.obligation.cause.span = idx.span; - } + self.point_at_index_if_possible(errors, idx.span) }); element_ty } @@ -2704,6 +2694,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn point_at_index_if_possible( + &self, + errors: &mut Vec>, + span: Span, + ) { + for error in errors { + match error.obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Trait(predicate) + if self.tcx.is_diagnostic_item(sym::SliceIndex, predicate.trait_ref.def_id) => { + } + _ => continue, + } + error.obligation.cause.span = span; + } + } + fn check_expr_yield( &self, value: &'tcx hir::Expr<'tcx>, From 3ae669d758f7a7c0498d9208ef231718e50fb0ae Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 29 Jul 2022 14:12:37 +0900 Subject: [PATCH 15/20] check if T is slice fix msg --- .../src/traits/error_reporting/suggestions.rs | 5 +++-- src/test/ui/suggestions/suggest-dereferencing-index.stderr | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) 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 c51f3dacd5466..6ad7ee32a4f34 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2943,14 +2943,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ) { if let ObligationCauseCode::ImplDerivedObligation(_) = obligation.cause.code() && self.tcx.is_diagnostic_item(sym::SliceIndex, trait_pred.skip_binder().trait_ref.def_id) + && let ty::Slice(_) = trait_pred.skip_binder().trait_ref.substs.type_at(1).kind() && let ty::Ref(_, inner_ty, _) = trait_pred.skip_binder().self_ty().kind() && let ty::Uint(ty::UintTy::Usize) = inner_ty.kind() { err.span_suggestion_verbose( obligation.cause.span.shrink_to_lo(), - "consider dereferencing here", + "dereference this index", '*', - Applicability::MaybeIncorrect, + Applicability::MachineApplicable, ); } } diff --git a/src/test/ui/suggestions/suggest-dereferencing-index.stderr b/src/test/ui/suggestions/suggest-dereferencing-index.stderr index c0bb5044338c2..c8b87af7bd80c 100644 --- a/src/test/ui/suggestions/suggest-dereferencing-index.stderr +++ b/src/test/ui/suggestions/suggest-dereferencing-index.stderr @@ -7,7 +7,7 @@ LL | let one_item_please: i32 = [1, 2, 3][i]; = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required because of the requirements on the impl of `Index<&usize>` for `[{integer}]` -help: consider dereferencing here +help: dereference this index | LL | let one_item_please: i32 = [1, 2, 3][*i]; | + From ab44b5a408ec42be8e4045120a9a2a1121618384 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 29 Jul 2022 10:25:49 +1000 Subject: [PATCH 16/20] Remove some early `check_*` functions. They're not used by rustc or clippy. --- compiler/rustc_lint/src/early.rs | 17 ----------------- compiler/rustc_lint/src/passes.rs | 19 ------------------- 2 files changed, 36 deletions(-) diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index b0a7a87fda4f7..d13711c3ab598 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -90,9 +90,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> fn visit_foreign_item(&mut self, it: &'a ast::ForeignItem) { self.with_lint_attrs(it.id, &it.attrs, |cx| { - run_early_pass!(cx, check_foreign_item, it); ast_visit::walk_foreign_item(cx, it); - run_early_pass!(cx, check_foreign_item_post, it); }) } @@ -104,7 +102,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> } fn visit_anon_const(&mut self, c: &'a ast::AnonConst) { - run_early_pass!(self, check_anon_const, c); self.check_id(c.id); ast_visit::walk_anon_const(self, c); } @@ -154,22 +151,17 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> self.check_id(closure_id); } } - - run_early_pass!(self, check_fn_post, fk, span, id); } fn visit_variant_data(&mut self, s: &'a ast::VariantData) { - run_early_pass!(self, check_struct_def, s); if let Some(ctor_hir_id) = s.ctor_id() { self.check_id(ctor_hir_id); } ast_visit::walk_struct_def(self, s); - run_early_pass!(self, check_struct_def_post, s); } fn visit_field_def(&mut self, s: &'a ast::FieldDef) { self.with_lint_attrs(s.id, &s.attrs, |cx| { - run_early_pass!(cx, check_field_def, s); ast_visit::walk_field_def(cx, s); }) } @@ -178,7 +170,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> self.with_lint_attrs(v.id, &v.attrs, |cx| { run_early_pass!(cx, check_variant, v); ast_visit::walk_variant(cx, v); - run_early_pass!(cx, check_variant_post, v); }) } @@ -203,7 +194,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> run_early_pass!(self, check_block, b); self.check_id(b.id); ast_visit::walk_block(self, b); - run_early_pass!(self, check_block_post, b); } fn visit_arm(&mut self, a: &'a ast::Arm) { @@ -214,8 +204,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> } fn visit_expr_post(&mut self, e: &'a ast::Expr) { - run_early_pass!(self, check_expr_post, e); - // Explicitly check for lints associated with 'closure_id', since // it does not have a corresponding AST node match e.kind { @@ -242,7 +230,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> } fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) { - run_early_pass!(self, check_where_predicate, p); ast_visit::walk_where_predicate(self, p); } @@ -256,23 +243,19 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> ast_visit::AssocCtxt::Trait => { run_early_pass!(cx, check_trait_item, item); ast_visit::walk_assoc_item(cx, item, ctxt); - run_early_pass!(cx, check_trait_item_post, item); } ast_visit::AssocCtxt::Impl => { run_early_pass!(cx, check_impl_item, item); ast_visit::walk_assoc_item(cx, item, ctxt); - run_early_pass!(cx, check_impl_item_post, item); } }); } fn visit_lifetime(&mut self, lt: &'a ast::Lifetime, _: ast_visit::LifetimeCtxt) { - run_early_pass!(self, check_lifetime, lt); self.check_id(lt.id); } fn visit_path(&mut self, p: &'a ast::Path, id: ast::NodeId) { - run_early_pass!(self, check_path, p, id); self.check_id(id); ast_visit::walk_path(self, p); } diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index b1b4229b1f738..d53b96f231d54 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -161,44 +161,25 @@ macro_rules! early_lint_methods { fn check_ident(a: Ident); fn check_crate(a: &ast::Crate); fn check_crate_post(a: &ast::Crate); - fn check_foreign_item(a: &ast::ForeignItem); - fn check_foreign_item_post(a: &ast::ForeignItem); fn check_item(a: &ast::Item); fn check_item_post(a: &ast::Item); fn check_local(a: &ast::Local); fn check_block(a: &ast::Block); - fn check_block_post(a: &ast::Block); fn check_stmt(a: &ast::Stmt); fn check_arm(a: &ast::Arm); fn check_pat(a: &ast::Pat); - fn check_anon_const(a: &ast::AnonConst); fn check_pat_post(a: &ast::Pat); fn check_expr(a: &ast::Expr); - fn check_expr_post(a: &ast::Expr); fn check_ty(a: &ast::Ty); fn check_generic_arg(a: &ast::GenericArg); fn check_generic_param(a: &ast::GenericParam); fn check_generics(a: &ast::Generics); - fn check_where_predicate(a: &ast::WherePredicate); fn check_poly_trait_ref(a: &ast::PolyTraitRef, b: &ast::TraitBoundModifier); fn check_fn(a: rustc_ast::visit::FnKind<'_>, c: Span, d_: ast::NodeId); - fn check_fn_post( - a: rustc_ast::visit::FnKind<'_>, - c: Span, - d: ast::NodeId - ); fn check_trait_item(a: &ast::AssocItem); - fn check_trait_item_post(a: &ast::AssocItem); fn check_impl_item(a: &ast::AssocItem); - fn check_impl_item_post(a: &ast::AssocItem); - fn check_struct_def(a: &ast::VariantData); - fn check_struct_def_post(a: &ast::VariantData); - fn check_field_def(a: &ast::FieldDef); fn check_variant(a: &ast::Variant); - fn check_variant_post(a: &ast::Variant); - fn check_lifetime(a: &ast::Lifetime); - fn check_path(a: &ast::Path, b: ast::NodeId); fn check_attribute(a: &ast::Attribute); fn check_mac_def(a: &ast::MacroDef, b: ast::NodeId); fn check_mac(a: &ast::MacCall); From 6dced80b86942e577ed820bc47845d1c9b50af6c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 29 Jul 2022 13:43:28 +1000 Subject: [PATCH 17/20] Remove `visit_name` from the AST visitor. Because the default is empty and it's never overridden. This means `walk_ident` can also be removed, because it does nothing. --- compiler/rustc_ast/src/visit.rs | 19 +++---------------- compiler/rustc_ast_passes/src/node_count.rs | 3 +-- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 3f830acbf27a6..d9594b323dd0d 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -15,7 +15,7 @@ use crate::ast::*; -use rustc_span::symbol::{Ident, Symbol}; +use rustc_span::symbol::Ident; use rustc_span::Span; #[derive(Copy, Clone, Debug, PartialEq)] @@ -109,12 +109,7 @@ pub enum LifetimeCtxt { /// to monitor future changes to `Visitor` in case a new method with a /// new default implementation gets introduced.) pub trait Visitor<'ast>: Sized { - fn visit_name(&mut self, _span: Span, _name: Symbol) { - // Nothing to do. - } - fn visit_ident(&mut self, ident: Ident) { - walk_ident(self, ident); - } + fn visit_ident(&mut self, _ident: Ident) {} fn visit_foreign_item(&mut self, i: &'ast ForeignItem) { walk_foreign_item(self, i) } @@ -267,10 +262,6 @@ macro_rules! walk_list { } } -pub fn walk_ident<'a, V: Visitor<'a>>(visitor: &mut V, ident: Ident) { - visitor.visit_name(ident.span, ident.name); -} - pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) { walk_list!(visitor, visit_item, &krate.items); walk_list!(visitor, visit_attribute, &krate.attrs); @@ -315,11 +306,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { visitor.visit_vis(&item.vis); visitor.visit_ident(item.ident); match item.kind { - ItemKind::ExternCrate(orig_name) => { - if let Some(orig_name) = orig_name { - visitor.visit_name(item.span, orig_name); - } - } + ItemKind::ExternCrate(_) => {} ItemKind::Use(ref use_tree) => visitor.visit_use_tree(use_tree, item.id, false), ItemKind::Static(ref typ, _, ref expr) | ItemKind::Const(_, ref typ, ref expr) => { visitor.visit_ty(typ); diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs index ee166f7570307..9c7369c83e2da 100644 --- a/compiler/rustc_ast_passes/src/node_count.rs +++ b/compiler/rustc_ast_passes/src/node_count.rs @@ -16,9 +16,8 @@ impl NodeCounter { } impl<'ast> Visitor<'ast> for NodeCounter { - fn visit_ident(&mut self, ident: Ident) { + fn visit_ident(&mut self, _ident: Ident) { self.count += 1; - walk_ident(self, ident); } fn visit_foreign_item(&mut self, i: &ForeignItem) { self.count += 1; From 74e9a29f6e96f63035aed3026374921c1ba57c00 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 29 Jul 2022 11:28:51 +1000 Subject: [PATCH 18/20] Remove some late `check_*` functions. They're not used by rustc or clippy. --- compiler/rustc_lint/src/late.rs | 14 -------------- compiler/rustc_lint/src/lib.rs | 2 +- compiler/rustc_lint/src/passes.rs | 20 +------------------- 3 files changed, 2 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index afb18451cf398..a329b37519d98 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -81,7 +81,6 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> { fn process_mod(&mut self, m: &'tcx hir::Mod<'tcx>, s: Span, n: hir::HirId) { lint_callback!(self, check_mod, m, s, n); hir_visit::walk_mod(self, m, n); - lint_callback!(self, check_mod_post, m, s, n); } } @@ -118,7 +117,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) { self.with_lint_attrs(param.hir_id, |cx| { - lint_callback!(cx, check_param, param); hir_visit::walk_param(cx, param); }); } @@ -151,7 +149,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas cx.with_param_env(it.hir_id(), |cx| { lint_callback!(cx, check_foreign_item, it); hir_visit::walk_foreign_item(cx, it); - lint_callback!(cx, check_foreign_item_post, it); }); }) } @@ -193,7 +190,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas let body = self.context.tcx.hir().body(body_id); lint_callback!(self, check_fn, fk, decl, body, span, id); hir_visit::walk_fn(self, fk, decl, body_id, span, id); - lint_callback!(self, check_fn_post, fk, decl, body, span, id); self.context.enclosing_body = old_enclosing_body; self.context.cached_typeck_results.set(old_cached_typeck_results); } @@ -208,7 +204,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas ) { lint_callback!(self, check_struct_def, s); hir_visit::walk_struct_def(self, s); - lint_callback!(self, check_struct_def_post, s); } fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) { @@ -227,7 +222,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas self.with_lint_attrs(v.id, |cx| { lint_callback!(cx, check_variant, v); hir_visit::walk_variant(cx, v, g, item_id); - lint_callback!(cx, check_variant_post, v); }) } @@ -237,14 +231,9 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas } fn visit_infer(&mut self, inf: &'tcx hir::InferArg) { - lint_callback!(self, check_infer, inf); hir_visit::walk_inf(self, inf); } - fn visit_name(&mut self, sp: Span, name: Symbol) { - lint_callback!(self, check_name, sp, name); - } - fn visit_mod(&mut self, m: &'tcx hir::Mod<'tcx>, s: Span, n: hir::HirId) { if !self.context.only_module { self.process_mod(m, s, n); @@ -280,7 +269,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas } fn visit_where_predicate(&mut self, p: &'tcx hir::WherePredicate<'tcx>) { - lint_callback!(self, check_where_predicate, p); hir_visit::walk_where_predicate(self, p); } @@ -300,7 +288,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas cx.with_param_env(trait_item.hir_id(), |cx| { lint_callback!(cx, check_trait_item, trait_item); hir_visit::walk_trait_item(cx, trait_item); - lint_callback!(cx, check_trait_item_post, trait_item); }); }); self.context.generics = generics; @@ -320,7 +307,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas } fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) { - lint_callback!(self, check_lifetime, lt); hir_visit::walk_lifetime(self, lt); } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 8726d36498bed..ec96f354021fa 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -75,7 +75,7 @@ use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::{ BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, }; -use rustc_span::symbol::{Ident, Symbol}; +use rustc_span::symbol::Ident; use rustc_span::Span; use array_into_iter::ArrayIntoIter; diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index d53b96f231d54..cb7bd407ed4c8 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -5,23 +5,19 @@ use rustc_data_structures::sync; use rustc_hir as hir; use rustc_session::lint::builtin::HardwiredLints; use rustc_session::lint::LintPass; -use rustc_span::symbol::{Ident, Symbol}; +use rustc_span::symbol::Ident; use rustc_span::Span; #[macro_export] macro_rules! late_lint_methods { ($macro:path, $args:tt, [$hir:tt]) => ( $macro!($args, [$hir], [ - fn check_param(a: &$hir hir::Param<$hir>); fn check_body(a: &$hir hir::Body<$hir>); fn check_body_post(a: &$hir hir::Body<$hir>); - fn check_name(a: Span, b: Symbol); fn check_crate(); fn check_crate_post(); fn check_mod(a: &$hir hir::Mod<$hir>, b: Span, c: hir::HirId); - fn check_mod_post(a: &$hir hir::Mod<$hir>, b: Span, c: hir::HirId); fn check_foreign_item(a: &$hir hir::ForeignItem<$hir>); - fn check_foreign_item_post(a: &$hir hir::ForeignItem<$hir>); fn check_item(a: &$hir hir::Item<$hir>); fn check_item_post(a: &$hir hir::Item<$hir>); fn check_local(a: &$hir hir::Local<$hir>); @@ -33,11 +29,8 @@ macro_rules! late_lint_methods { fn check_expr(a: &$hir hir::Expr<$hir>); fn check_expr_post(a: &$hir hir::Expr<$hir>); fn check_ty(a: &$hir hir::Ty<$hir>); - fn check_infer(a: &$hir hir::InferArg); - fn check_generic_arg(a: &$hir hir::GenericArg<$hir>); fn check_generic_param(a: &$hir hir::GenericParam<$hir>); fn check_generics(a: &$hir hir::Generics<$hir>); - fn check_where_predicate(a: &$hir hir::WherePredicate<$hir>); fn check_poly_trait_ref(a: &$hir hir::PolyTraitRef<$hir>, b: hir::TraitBoundModifier); fn check_fn( a: rustc_hir::intravisit::FnKind<$hir>, @@ -45,23 +38,12 @@ macro_rules! late_lint_methods { c: &$hir hir::Body<$hir>, d: Span, e: hir::HirId); - fn check_fn_post( - a: rustc_hir::intravisit::FnKind<$hir>, - b: &$hir hir::FnDecl<$hir>, - c: &$hir hir::Body<$hir>, - d: Span, - e: hir::HirId - ); fn check_trait_item(a: &$hir hir::TraitItem<$hir>); - fn check_trait_item_post(a: &$hir hir::TraitItem<$hir>); fn check_impl_item(a: &$hir hir::ImplItem<$hir>); fn check_impl_item_post(a: &$hir hir::ImplItem<$hir>); fn check_struct_def(a: &$hir hir::VariantData<$hir>); - fn check_struct_def_post(a: &$hir hir::VariantData<$hir>); fn check_field_def(a: &$hir hir::FieldDef<$hir>); fn check_variant(a: &$hir hir::Variant<$hir>); - fn check_variant_post(a: &$hir hir::Variant<$hir>); - fn check_lifetime(a: &$hir hir::Lifetime); fn check_path(a: &$hir hir::Path<$hir>, b: hir::HirId); fn check_attribute(a: &$hir ast::Attribute); From dec29b158258d5a0fd2362feee707ff416fc9787 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 29 Jul 2022 06:02:11 +0000 Subject: [PATCH 19/20] Adjust an expr span to account for macros --- compiler/rustc_typeck/src/check/_match.rs | 3 ++- compiler/rustc_typeck/src/check/fn_ctxt/checks.rs | 4 +++- src/test/ui/suggestions/pattern-slice-vec.fixed | 4 ++++ src/test/ui/suggestions/pattern-slice-vec.rs | 4 ++++ src/test/ui/suggestions/pattern-slice-vec.stderr | 10 +++++++++- 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index 147d87e7594c5..df315b8a3bc3d 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -39,8 +39,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let scrut_diverges = self.diverges.replace(Diverges::Maybe); // #55810: Type check patterns first so we get types for all bindings. + let scrut_span = scrut.span.find_ancestor_inside(expr.span).unwrap_or(scrut.span); for arm in arms { - self.check_pat_top(&arm.pat, scrutinee_ty, Some(scrut.span), true); + self.check_pat_top(&arm.pat, scrutinee_ty, Some(scrut_span), true); } // Now typecheck the blocks. diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index eb22938fb61c4..abde4d9acfe1d 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1234,7 +1234,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Does the expected pattern type originate from an expression and what is the span? let (origin_expr, ty_span) = match (decl.ty, decl.init) { (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type. - (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee. + (_, Some(init)) => { + (true, Some(init.span.find_ancestor_inside(decl.span).unwrap_or(init.span))) + } // No explicit type; so use the scrutinee. _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained. }; diff --git a/src/test/ui/suggestions/pattern-slice-vec.fixed b/src/test/ui/suggestions/pattern-slice-vec.fixed index 447337c39c4c4..f8144641f3c31 100644 --- a/src/test/ui/suggestions/pattern-slice-vec.fixed +++ b/src/test/ui/suggestions/pattern-slice-vec.fixed @@ -24,4 +24,8 @@ fn main() { //~^ ERROR: expected an array or slice _ => {} } + + let [..] = vec![1, 2, 3][..]; + //~^ ERROR: expected an array or slice + //~| HELP: consider slicing here } diff --git a/src/test/ui/suggestions/pattern-slice-vec.rs b/src/test/ui/suggestions/pattern-slice-vec.rs index 1153ca026bb2f..444687c85789e 100644 --- a/src/test/ui/suggestions/pattern-slice-vec.rs +++ b/src/test/ui/suggestions/pattern-slice-vec.rs @@ -24,4 +24,8 @@ fn main() { //~^ ERROR: expected an array or slice _ => {} } + + let [..] = vec![1, 2, 3]; + //~^ ERROR: expected an array or slice + //~| HELP: consider slicing here } diff --git a/src/test/ui/suggestions/pattern-slice-vec.stderr b/src/test/ui/suggestions/pattern-slice-vec.stderr index 403a816ba11ff..f69e7de971a96 100644 --- a/src/test/ui/suggestions/pattern-slice-vec.stderr +++ b/src/test/ui/suggestions/pattern-slice-vec.stderr @@ -31,6 +31,14 @@ LL | LL | [5] => {} | ^^^ pattern cannot match with input type `Vec<_>` -error: aborting due to 4 previous errors +error[E0529]: expected an array or slice, found `Vec<{integer}>` + --> $DIR/pattern-slice-vec.rs:28:9 + | +LL | let [..] = vec![1, 2, 3]; + | ^^^^ ------------- help: consider slicing here: `vec![1, 2, 3][..]` + | | + | pattern cannot match with input type `Vec<{integer}>` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0529`. From 6149cf982c6c275d73345bc3d476ded733e7bc2f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 29 Jul 2022 14:32:48 +0200 Subject: [PATCH 20/20] Remove unwanted extra white space characters from HTML --- src/librustdoc/html/render/print_item.rs | 22 ++++++++++--------- src/librustdoc/html/templates/page.html | 14 ++++++------ src/librustdoc/html/templates/print_item.html | 4 ++-- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 69d66693f752e..547d6696a431d 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -311,7 +311,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: w, "

\ {name}\ -

\n{}", + {}", ITEM_TABLE_OPEN, id = cx.derive_id(my_section.id().to_owned()), name = my_section.name(), @@ -415,10 +415,10 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items: write!( w, "
\ - {name}\ - {visibility_emoji}\ - {unsafety_flag}\ - {stab_tags}\ + {name}\ + {visibility_emoji}\ + {unsafety_flag}\ + {stab_tags}\
\
{docs}
", name = myitem.name.unwrap(), @@ -1126,7 +1126,8 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean: write!( w, "

\ - Fields

" + Fields\ + " ); for (field, ty) in fields { let name = field.name.expect("union field name"); @@ -1238,7 +1239,8 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: write!( w, "

\ - Variants{}

", + Variants{}\ + ", document_non_exhaustive_header(it) ); document_non_exhaustive(w, it); @@ -1294,9 +1296,9 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: w, "
\ \ - \ - {f}: {t}\ - ", + \ + {f}: {t}\ + ", id = id, f = field.name.unwrap(), t = ty.print(cx) diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index 9a551b68279d6..8e25f6764a9c5 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -82,10 +82,10 @@ {%- else -%} {#- -#} {%- endif -%} -
+ {#- -#} {#- -#} -

- +

{#- -#} + {#- -#} {#- -#} @@ -122,12 +122,12 @@

{#- -#} {#- -#}
{#- -#} -
+
{#- -#} {#- -#} Change settings {#- -#} {#- -#} -
+
{#- -#} {#- -#} {#- -#} {#- -#} @@ -143,6 +143,6 @@

data-resource-suffix="{{page.resource_suffix}}" {# -#} data-rustdoc-version="{{rustdoc_version}}" {# -#} > {#- -#} - + {#- -#} {#- -#} {#- -#} diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html index 62b1b7ca7292a..c755157d27687 100644 --- a/src/librustdoc/html/templates/print_item.html +++ b/src/librustdoc/html/templates/print_item.html @@ -1,4 +1,4 @@ -
+
{#- -#}

{#- -#} {#- -#} {{-typ-}} @@ -27,4 +27,4 @@

{#- -#} [] {#- -#} {#- -#} {#- -#} -

+
{#- -#}