diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 3f830acbf27..d9594b323dd 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 ee166f75703..9c7369c83e2 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; diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index b0a7a87fda4..d13711c3ab5 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/late.rs b/compiler/rustc_lint/src/late.rs index afb18451cf3..a329b37519d 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 7b0702dad75..ae2088fbeb6 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 b1b4229b1f7..cb7bd407ed4 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); @@ -161,44 +143,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); diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index cb8be51a085..6875600129a 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 7067a48b783..58b1564cc5d 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 b9fd8c50e6a..b2fd9f25bdd 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/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index 8d6130a8a79..7125d141af7 100644 --- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs @@ -4,11 +4,21 @@ //! //! 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}; +use crate::spec::{ + cvs, FramePointer, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions, +}; pub fn target() -> Target { Target { @@ -39,6 +49,14 @@ 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, + frame_pointer: FramePointer::MayOmit, + main_needs_argc_argv: false, // don't have atomic compare-and-swap 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 25ba520ace2..7ee3fe844b5 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -531,6 +531,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 6c8faed0df4..1f72c96406d 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) { @@ -2895,6 +2902,27 @@ 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::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(), + "dereference this index", + '*', + Applicability::MachineApplicable, + ); + } + } } /// Collect all the returned expressions within the input expression. diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index 147d87e7594..df315b8a3bc 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/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index ba5ef5edc86..65a562060eb 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -2648,6 +2648,9 @@ 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| { + self.point_at_index_if_possible(errors, idx.span) + }); element_ty } None => { @@ -2691,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>, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index eb22938fb61..abde4d9acfe 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/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 60c0694ca0e..36111637a56 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/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 736c30694cd..d168af60c2d 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 00000000000..61bd1b425bc --- /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 diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 69d66693f75..547d6696a43 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 9a551b68279..8e25f6764a9 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 62b1b7ca729..c755157d276 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 @@ [] {#- -#} {#- -#} {#- -#} -

+
{#- -#} diff --git a/src/test/ui/index-help.stderr b/src/test/ui/index-help.stderr index 7f51a48111b..b36f4dab829 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 0a24855a6a7..fbff20f8dee 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 be3398552dc..3f9094d124e 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/let-else/let-else-temp-borrowck.rs b/src/test/ui/let-else/let-else-temp-borrowck.rs new file mode 100644 index 00000000000..3910d35e776 --- /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 624c2ea37a7..9c86901b97f 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,8 @@ // run-pass #![feature(let_else)] +use std::fmt::Display; +use std::rc::Rc; use std::sync::atomic::{AtomicU8, Ordering}; static TRACKER: AtomicU8 = AtomicU8::new(0); @@ -17,9 +19,70 @@ 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 👆"); + + { + // 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"); + + 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); + 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 + // 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(); + return; + }; + unreachable!(); + } } diff --git a/src/test/ui/on-unimplemented/slice-index.stderr b/src/test/ui/on-unimplemented/slice-index.stderr index ae7d2e1d823..72f67a68515 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/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 00000000000..033dcdfc08d --- /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() {} diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr index 45450788b9c..9079a18d6a6 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 9ae08563027..2d062e56a9b 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/pattern-slice-vec.fixed b/src/test/ui/suggestions/pattern-slice-vec.fixed index 447337c39c4..f8144641f3c 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 1153ca026bb..444687c8578 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 403a816ba11..f69e7de971a 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`. 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 00000000000..dd4ae4eb14c --- /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 00000000000..82ebacc49f2 --- /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 00000000000..c8b87af7bd8 --- /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: dereference this index + | +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`.