diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 5ef68c6aeaa59..77e0b6c55a80e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -15,7 +15,6 @@ pub fn expand_deriving_copy( ) { let trait_def = TraitDef { span, - attributes: Vec::new(), path: path_std!(marker::Copy), additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 7755ff779c4d9..ee4c5aea1a352 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -71,7 +71,6 @@ pub fn expand_deriving_clone( let attrs = vec![cx.attribute(inline)]; let trait_def = TraitDef { span, - attributes: Vec::new(), path: path_std!(clone::Clone), additional_bounds: bounds, generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index 4e798bf6acb10..f99ee8cb2d53c 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -23,7 +23,6 @@ pub fn expand_deriving_eq( let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)]; let trait_def = TraitDef { span, - attributes: Vec::new(), path: path_std!(cmp::Eq), additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs index 1612be862377b..8aa16dfeb0f1f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs @@ -18,7 +18,6 @@ pub fn expand_deriving_ord( let attrs = vec![cx.attribute(inline)]; let trait_def = TraitDef { span, - attributes: Vec::new(), path: path_std!(cmp::Ord), additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs index 0141b33772621..73be9362e4eb4 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs @@ -98,7 +98,6 @@ pub fn expand_deriving_partial_eq( let trait_def = TraitDef { span, - attributes: Vec::new(), path: path_std!(cmp::PartialEq), additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs index 2ebb01cc8a035..137c779f81b84 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -36,7 +36,6 @@ pub fn expand_deriving_partial_ord( let trait_def = TraitDef { span, - attributes: vec![], path: path_std!(cmp::PartialOrd), additional_bounds: vec![], generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 5ab70e441b814..f82175af4f6f2 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -19,7 +19,6 @@ pub fn expand_deriving_debug( let trait_def = TraitDef { span, - attributes: Vec::new(), path: path_std!(fmt::Debug), additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs index d688143a2a5c6..47da0862b52fc 100644 --- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs @@ -22,7 +22,6 @@ pub fn expand_deriving_rustc_decodable( let trait_def = TraitDef { span, - attributes: Vec::new(), path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global), additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 5177690917f21..a431832080c0c 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -25,7 +25,6 @@ pub fn expand_deriving_default( let attrs = vec![cx.attribute(inline)]; let trait_def = TraitDef { span, - attributes: Vec::new(), path: Path::new(vec![kw::Default, sym::Default]), additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs index 70167cac68a7e..d43c66a5fa644 100644 --- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs @@ -106,7 +106,6 @@ pub fn expand_deriving_rustc_encodable( let trait_def = TraitDef { span, - attributes: Vec::new(), path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global), additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 9f3a80ea7cbdc..9882f7958aaa5 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -184,8 +184,6 @@ pub struct TraitDef<'a> { /// The span for the current #[derive(Foo)] header. pub span: Span, - pub attributes: Vec, - /// Path of the trait, including any type parameters pub path: Path, @@ -605,7 +603,7 @@ impl<'a> TraitDef<'a> { param.bounds.iter().cloned() ).collect(); - cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, vec![], bounds, None) + cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, bounds, None) } GenericParamKind::Const { ty, kw_span, .. } => { let const_nodefault_kind = GenericParamKind::Const { @@ -718,15 +716,13 @@ impl<'a> TraitDef<'a> { let self_type = cx.ty_path(path); let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived)); + let attrs = vec![attr]; let opt_trait_ref = Some(trait_ref); - let mut a = vec![attr]; - a.extend(self.attributes.iter().cloned()); - cx.item( self.span, Ident::empty(), - a, + attrs, ast::ItemKind::Impl(Box::new(ast::Impl { unsafety: ast::Unsafe::No, polarity: ast::ImplPolarity::Positive, diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs index 4d46f7cd48a51..36e2e29308694 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs @@ -146,7 +146,6 @@ fn mk_ty_param( cx: &ExtCtxt<'_>, span: Span, name: Symbol, - attrs: &[ast::Attribute], bounds: &[Path], self_ident: Ident, self_generics: &Generics, @@ -158,7 +157,7 @@ fn mk_ty_param( cx.trait_bound(path) }) .collect(); - cx.typaram(span, Ident::new(name, span), attrs.to_owned(), bounds, None) + cx.typaram(span, Ident::new(name, span), bounds, None) } /// Bounds on type parameters. @@ -183,7 +182,7 @@ impl Bounds { .iter() .map(|t| { let (name, ref bounds) = *t; - mk_ty_param(cx, span, name, &[], &bounds, self_ty, self_generics) + mk_ty_param(cx, span, name, &bounds, self_ty, self_generics) }) .collect(); diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 32ae3d3447896..9aa170bec14d8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -21,7 +21,6 @@ pub fn expand_deriving_hash( let arg = Path::new_local(typaram); let hash_trait_def = TraitDef { span, - attributes: Vec::new(), path, additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_error_messages/locales/en-US/expand.ftl b/compiler/rustc_error_messages/locales/en-US/expand.ftl index bdfa22e77eb2f..ee76a4f45005d 100644 --- a/compiler/rustc_error_messages/locales/en-US/expand.ftl +++ b/compiler/rustc_error_messages/locales/en-US/expand.ftl @@ -3,3 +3,20 @@ expand_explain_doc_comment_outer = expand_explain_doc_comment_inner = inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match + +expand_expr_repeat_no_syntax_vars = + attempted to repeat an expression containing no syntax variables matched as repeating at this depth + +expand_must_repeat_once = + this must repeat at least once + +expand_count_repetition_misplaced = + `count` can not be placed inside the inner-most repetition + +expand_meta_var_expr_unrecognized_var = + variable `{$key}` is not recognized in meta-variable expression + +expand_var_still_repeating = + variable '{$ident}' is still repeating at this depth + +expand_meta_var_dif_seq_matchers = {$msg} \ No newline at end of file diff --git a/compiler/rustc_error_messages/locales/en-US/typeck.ftl b/compiler/rustc_error_messages/locales/en-US/typeck.ftl index 494b8f913934f..0014da17c88e5 100644 --- a/compiler/rustc_error_messages/locales/en-US/typeck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/typeck.ftl @@ -123,3 +123,11 @@ typeck_manual_implementation = .help = add `#![feature(unboxed_closures)]` to the crate attributes to enable typeck_substs_on_overridden_impl = could not resolve substs on overridden impl + +typeck_unused_extern_crate = + unused extern crate + .suggestion = remove it + +typeck_extern_crate_not_idiomatic = + `extern crate` is not idiomatic in the new edition + .suggestion = convert it to a `{$msg_code}` diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 17e6c9e9575fd..356f9dfdb3b2e 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -8,7 +8,7 @@ use rustc_error_messages::FluentValue; use rustc_hir as hir; use rustc_lint_defs::{Applicability, LintExpectationId}; use rustc_span::edition::LATEST_STABLE_EDITION; -use rustc_span::symbol::{Ident, Symbol}; +use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol}; use rustc_span::{edition::Edition, Span, DUMMY_SP}; use std::borrow::Cow; use std::fmt; @@ -87,6 +87,7 @@ into_diagnostic_arg_using_display!( hir::Target, Edition, Ident, + MacroRulesNormalizedIdent, ); impl IntoDiagnosticArg for bool { diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index b971a63ec8977..0440bca53b232 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -107,14 +107,13 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, ident: Ident, - attrs: Vec, bounds: ast::GenericBounds, default: Option>, ) -> ast::GenericParam { ast::GenericParam { ident: ident.with_span_pos(span), id: ast::DUMMY_NODE_ID, - attrs: attrs.into(), + attrs: AttrVec::new(), bounds, kind: ast::GenericParamKind::Type { default }, is_placeholder: false, diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs new file mode 100644 index 0000000000000..0d7e137c7dd0c --- /dev/null +++ b/compiler/rustc_expand/src/errors.rs @@ -0,0 +1,48 @@ +use rustc_macros::SessionDiagnostic; +use rustc_span::symbol::MacroRulesNormalizedIdent; +use rustc_span::Span; + +#[derive(SessionDiagnostic)] +#[error(expand::expr_repeat_no_syntax_vars)] +pub(crate) struct NoSyntaxVarsExprRepeat { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(expand::must_repeat_once)] +pub(crate) struct MustRepeatOnce { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(expand::count_repetition_misplaced)] +pub(crate) struct CountRepetitionMisplaced { + #[primary_span] + pub span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(expand::meta_var_expr_unrecognized_var)] +pub(crate) struct MetaVarExprUnrecognizedVar { + #[primary_span] + pub span: Span, + pub key: MacroRulesNormalizedIdent, +} + +#[derive(SessionDiagnostic)] +#[error(expand::var_still_repeating)] +pub(crate) struct VarStillRepeating { + #[primary_span] + pub span: Span, + pub ident: MacroRulesNormalizedIdent, +} + +#[derive(SessionDiagnostic)] +#[error(expand::meta_var_dif_seq_matchers)] +pub(crate) struct MetaVarsDifSeqMatchers { + #[primary_span] + pub span: Span, + pub msg: String, +} diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 91a183427843e..e1dde1672c190 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -25,6 +25,7 @@ pub mod base; pub mod build; #[macro_use] pub mod config; +pub mod errors; pub mod expand; pub mod module; pub mod proc_macro; diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index e47ea83ac3809..bec6d1a2df7d8 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -1,4 +1,8 @@ use crate::base::ExtCtxt; +use crate::errors::{ + CountRepetitionMisplaced, MetaVarExprUnrecognizedVar, MetaVarsDifSeqMatchers, MustRepeatOnce, + NoSyntaxVarsExprRepeat, VarStillRepeating, +}; use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, MatchedTokenTree, NamedMatch}; use crate::mbe::{self, MetaVarExpr}; use rustc_ast::mut_visit::{self, MutVisitor}; @@ -165,11 +169,7 @@ pub(super) fn transcribe<'a>( seq @ mbe::TokenTree::Sequence(_, delimited) => { match lockstep_iter_size(&seq, interp, &repeats) { LockstepIterSize::Unconstrained => { - return Err(cx.struct_span_err( - seq.span(), /* blame macro writer */ - "attempted to repeat an expression containing no syntax variables \ - matched as repeating at this depth", - )); + return Err(cx.create_err(NoSyntaxVarsExprRepeat { span: seq.span() })); } LockstepIterSize::Contradiction(msg) => { @@ -177,7 +177,7 @@ pub(super) fn transcribe<'a>( // happens when two meta-variables are used in the same repetition in a // sequence, but they come from different sequence matchers and repeat // different amounts. - return Err(cx.struct_span_err(seq.span(), &msg)); + return Err(cx.create_err(MetaVarsDifSeqMatchers { span: seq.span(), msg })); } LockstepIterSize::Constraint(len, _) => { @@ -193,10 +193,7 @@ pub(super) fn transcribe<'a>( // FIXME: this really ought to be caught at macro definition // time... It happens when the Kleene operator in the matcher and // the body for the same meta-variable do not match. - return Err(cx.struct_span_err( - sp.entire(), - "this must repeat at least once", - )); + return Err(cx.create_err(MustRepeatOnce { span: sp.entire() })); } } else { // 0 is the initial counter (we have done 0 repetitions so far). `len` @@ -239,10 +236,7 @@ pub(super) fn transcribe<'a>( } MatchedSeq(..) => { // We were unable to descend far enough. This is an error. - return Err(cx.struct_span_err( - sp, /* blame the macro writer */ - &format!("variable '{}' is still repeating at this depth", ident), - )); + return Err(cx.create_err(VarStillRepeating { span: sp, ident })); } } } else { @@ -448,10 +442,7 @@ fn count_repetitions<'a>( match matched { MatchedTokenTree(_) | MatchedNonterminal(_) => { if declared_lhs_depth == 0 { - return Err(cx.struct_span_err( - sp.entire(), - "`count` can not be placed inside the inner-most repetition", - )); + return Err(cx.create_err(CountRepetitionMisplaced { span: sp.entire() })); } match depth_opt { None => Ok(1), @@ -499,12 +490,7 @@ where { let span = ident.span; let key = MacroRulesNormalizedIdent::new(ident); - interp.get(&key).ok_or_else(|| { - cx.struct_span_err( - span, - &format!("variable `{}` is not recognized in meta-variable expression", key), - ) - }) + interp.get(&key).ok_or_else(|| cx.create_err(MetaVarExprUnrecognizedVar { span, key })) } /// Used by meta-variable expressions when an user input is out of the actual declared bounds. For diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index 772e297b7b445..be03c8b5bae98 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -174,7 +174,14 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { #[instrument(skip(self), level = "debug")] fn tys(&mut self, pattern: Ty<'tcx>, value: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { - if pattern == value { Ok(pattern) } else { relate::super_relate_tys(self, pattern, value) } + if let ty::Error(_) = pattern.kind() { + // Unlike normal `TypeRelation` rules, `ty::Error` does not equal any type. + self.no_match() + } else if pattern == value { + Ok(pattern) + } else { + relate::super_relate_tys(self, pattern, value) + } } #[instrument(skip(self), level = "debug")] diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 834c114ee1c58..a1c111ae372a8 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -79,7 +79,7 @@ impl<'tcx> ConstValue<'tcx> { } pub fn try_to_scalar_int(&self) -> Option { - Some(self.try_to_scalar()?.assert_int()) + self.try_to_scalar()?.try_to_int().ok() } pub fn try_to_bits(&self, size: Size) -> Option { @@ -368,6 +368,7 @@ impl<'tcx, Prov: Provenance> Scalar { } #[inline(always)] + #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) pub fn assert_int(self) -> ScalarInt { self.try_to_int().unwrap() } @@ -389,6 +390,7 @@ impl<'tcx, Prov: Provenance> Scalar { } #[inline(always)] + #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) pub fn assert_bits(self, target_size: Size) -> u128 { self.to_bits(target_size).unwrap() } diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index ade0f4fbc86a2..cac39f8f25fb8 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -34,7 +34,7 @@ impl<'a> Parser<'a> { })) } - /// If `force_capture` is true, forces collection of tokens regardless of whether + /// If `force_collect` is [`ForceCollect::Yes`], forces collection of tokens regardless of whether /// or not we have attributes pub(crate) fn parse_stmt_without_recovery( &mut self, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 09c1f44826fa4..4175527da470c 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -161,6 +161,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { msg: String, fallback_label: String, span: Span, + span_label: Option<(Span, &'a str)>, could_be_expr: bool, suggestion: Option<(Span, &'a str, String)>, } @@ -172,6 +173,12 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { msg: format!("expected {}, found {} `{}`", expected, res.descr(), path_str), fallback_label: format!("not a {expected}"), span, + span_label: match res { + Res::Def(kind, def_id) if kind == DefKind::TyParam => { + self.def_span(def_id).map(|span| (span, "found this type pararmeter")) + } + _ => None, + }, could_be_expr: match res { Res::Def(DefKind::Fn, _) => { // Verify whether this is a fn call or an Fn used as a type. @@ -251,6 +258,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { format!("not found in {mod_str}") }, span: item_span, + span_label: None, could_be_expr: false, suggestion, } @@ -262,6 +270,10 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span); + if let Some((span, label)) = base_error.span_label { + err.span_label(span, label); + } + if let Some(sugg) = base_error.suggestion { err.span_suggestion_verbose(sugg.0, sugg.1, sugg.2, Applicability::MaybeIncorrect); } diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index d4f8001493c8b..85a0d4e449906 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -457,7 +457,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> { } #[derive(Default)] -pub struct SuspendCheckData<'a, 'tcx> { +struct SuspendCheckData<'a, 'tcx> { expr: Option<&'tcx Expr<'tcx>>, source_span: Span, yield_span: Span, @@ -472,7 +472,7 @@ pub struct SuspendCheckData<'a, 'tcx> { // // Note that this technique was chosen over things like a `Suspend` marker trait // as it is simpler and has precedent in the compiler -pub fn check_must_not_suspend_ty<'tcx>( +fn check_must_not_suspend_ty<'tcx>( fcx: &FnCtxt<'_, 'tcx>, ty: Ty<'tcx>, hir_id: HirId, @@ -489,6 +489,8 @@ pub fn check_must_not_suspend_ty<'tcx>( let plural_suffix = pluralize!(data.plural_len); + debug!("Checking must_not_suspend for {}", ty); + match *ty.kind() { ty::Adt(..) if ty.is_box() => { let boxed_ty = ty.boxed_ty(); @@ -580,6 +582,12 @@ pub fn check_must_not_suspend_ty<'tcx>( }, ) } + // If drop tracking is enabled, we want to look through references, since the referrent + // may not be considered live across the await point. + ty::Ref(_region, ty, _mutability) if fcx.sess().opts.unstable_opts.drop_tracking => { + let descr_pre = &format!("{}reference{} to ", data.descr_pre, plural_suffix); + check_must_not_suspend_ty(fcx, ty, hir_id, SuspendCheckData { descr_pre, ..data }) + } _ => false, } } diff --git a/compiler/rustc_typeck/src/check_unused.rs b/compiler/rustc_typeck/src/check_unused.rs index 4a3cfa1ca376a..1d23ed9292180 100644 --- a/compiler/rustc_typeck/src/check_unused.rs +++ b/compiler/rustc_typeck/src/check_unused.rs @@ -1,5 +1,5 @@ +use crate::errors::{ExternCrateNotIdiomatic, UnusedExternCrate}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -108,25 +108,16 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) { // We do this in any edition. if extern_crate.warn_if_unused { if let Some(&span) = unused_extern_crates.get(&def_id) { + // Removal suggestion span needs to include attributes (Issue #54400) let id = tcx.hir().local_def_id_to_hir_id(def_id); - tcx.struct_span_lint_hir(lint, id, span, |lint| { - // Removal suggestion span needs to include attributes (Issue #54400) - let span_with_attrs = tcx - .hir() - .attrs(id) - .iter() - .map(|attr| attr.span) - .fold(span, |acc, attr_span| acc.to(attr_span)); - - lint.build("unused extern crate") - .span_suggestion_short( - span_with_attrs, - "remove it", - "", - Applicability::MachineApplicable, - ) - .emit(); - }); + let span_with_attrs = tcx + .hir() + .attrs(id) + .iter() + .map(|attr| attr.span) + .fold(span, |acc, attr_span| acc.to(attr_span)); + + tcx.emit_spanned_lint(lint, id, span, UnusedExternCrate { span: span_with_attrs }); continue; } } @@ -158,23 +149,23 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) { if !tcx.hir().attrs(id).is_empty() { continue; } - tcx.struct_span_lint_hir(lint, id, extern_crate.span, |lint| { - // Otherwise, we can convert it into a `use` of some kind. - let base_replacement = match extern_crate.orig_name { - Some(orig_name) => format!("use {} as {};", orig_name, item.ident.name), - None => format!("use {};", item.ident.name), - }; - let vis = tcx.sess.source_map().span_to_snippet(item.vis_span).unwrap_or_default(); - let add_vis = |to| if vis.is_empty() { to } else { format!("{} {}", vis, to) }; - lint.build("`extern crate` is not idiomatic in the new edition") - .span_suggestion_short( - extern_crate.span, - &format!("convert it to a `{}`", add_vis("use".to_string())), - add_vis(base_replacement), - Applicability::MachineApplicable, - ) - .emit(); - }) + + let base_replacement = match extern_crate.orig_name { + Some(orig_name) => format!("use {} as {};", orig_name, item.ident.name), + None => format!("use {};", item.ident.name), + }; + let vis = tcx.sess.source_map().span_to_snippet(item.vis_span).unwrap_or_default(); + let add_vis = |to| if vis.is_empty() { to } else { format!("{} {}", vis, to) }; + tcx.emit_spanned_lint( + lint, + id, + extern_crate.span, + ExternCrateNotIdiomatic { + span: extern_crate.span, + msg_code: add_vis("use".to_string()), + suggestion_code: add_vis(base_replacement), + }, + ); } } diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index 0438ac02ea91a..76599721e586f 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -1,6 +1,6 @@ //! Errors emitted by typeck. use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed}; -use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; +use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; use rustc_session::{parse::ParseSess, SessionDiagnostic}; use rustc_span::{symbol::Ident, Span, Symbol}; @@ -324,3 +324,19 @@ pub struct SubstsOnOverriddenImpl { #[primary_span] pub span: Span, } + +#[derive(LintDiagnostic)] +#[lint(typeck::unused_extern_crate)] +pub struct UnusedExternCrate { + #[suggestion(applicability = "machine-applicable", code = "")] + pub span: Span, +} + +#[derive(LintDiagnostic)] +#[lint(typeck::extern_crate_not_idiomatic)] +pub struct ExternCrateNotIdiomatic { + #[suggestion_short(applicability = "machine-applicable", code = "{suggestion_code}")] + pub span: Span, + pub msg_code: String, + pub suggestion_code: String, +} diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md index c526e4d1fa822..8b204949a6eef 100644 --- a/src/doc/rustc/src/platform-support/fuchsia.md +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -121,7 +121,10 @@ following files inside: **`package/meta/package`** ```json -{"name":"hello_fuchsia","version":0} +{ + "name": "hello_fuchsia", + "version": "0" +} ``` The `package` file describes our package's name and version number. Every @@ -232,10 +235,17 @@ ${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: +Once the emulator is running, start a package repository server to serve our +package to the emulator: ```sh -${SDK_PATH}/tools/${ARCH}/ffx target repository register +${SDK_PATH}/tools/${ARCH}/ffx repository server start +``` + +Once the repository server is up and running, register our repository: + +```sh +${SDK_PATH}/tools/${ARCH}/ffx target repository register --repository hello-fuchsia ``` And watch the logs from the emulator in a separate terminal: @@ -253,6 +263,10 @@ ${SDK_PATH}/tools/${ARCH}/ffx component run fuchsia-pkg://hello-fuchsia/hello_fu On reruns of the component, the `--recreate` argument may also need to be passed. +```sh +${SDK_PATH}/tools/${ARCH}/ffx component run --recreate fuchsia-pkg://hello-fuchsia/hello_fuchsia#meta/hello_fuchsia.cm +``` + ## Testing ### Running unit tests diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 1a4786c9b0664..2a38713d43b8a 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -820,8 +820,6 @@ pub(crate) trait AttributesExt { fn inner_docs(&self) -> bool; - fn other_attrs(&self) -> Vec; - fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet) -> Option>; } @@ -848,10 +846,6 @@ impl AttributesExt for [ast::Attribute] { self.iter().find(|a| a.doc_str().is_some()).map_or(true, |a| a.style == AttrStyle::Inner) } - fn other_attrs(&self) -> Vec { - self.iter().filter(|attr| attr.doc_str().is_none()).cloned().collect() - } - fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet) -> Option> { let sess = tcx.sess; let doc_cfg_active = tcx.features().doc_cfg; diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr index 7a083733a2cd1..5ad457d547a69 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr @@ -2,7 +2,9 @@ error[E0423]: expected value, found type parameter `T` --> $DIR/issue-69654.rs:5:25 | LL | impl Bar for [u8; T] {} - | ^ not a value + | - ^ not a value + | | + | found this type pararmeter error[E0599]: the function or associated item `foo` exists for struct `Foo<_>`, but its trait bounds were not satisfied --> $DIR/issue-69654.rs:17:10 diff --git a/src/test/ui/lexical-scopes.stderr b/src/test/ui/lexical-scopes.stderr index 3b2a062c1c254..ad11f72a31d37 100644 --- a/src/test/ui/lexical-scopes.stderr +++ b/src/test/ui/lexical-scopes.stderr @@ -1,6 +1,8 @@ error[E0574]: expected struct, variant or union type, found type parameter `T` --> $DIR/lexical-scopes.rs:3:13 | +LL | fn f() { + | - found this type pararmeter LL | let t = T { i: 0 }; | ^ not a struct, variant or union type diff --git a/src/test/ui/lint/must_not_suspend/ref-drop-tracking.rs b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.rs new file mode 100644 index 0000000000000..1bc4a38125753 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.rs @@ -0,0 +1,30 @@ +// edition:2018 +// compile-flags: -Zdrop-tracking +#![feature(must_not_suspend)] +#![deny(must_not_suspend)] + +#[must_not_suspend = "You gotta use Umm's, ya know?"] +struct Umm { + i: i64 +} + +struct Bar { + u: Umm, +} + +async fn other() {} + +impl Bar { + async fn uhoh(&mut self) { + let guard = &mut self.u; //~ ERROR `Umm` held across + + other().await; + + *guard = Umm { + i: 2 + } + } +} + +fn main() { +} diff --git a/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr new file mode 100644 index 0000000000000..c49d271285371 --- /dev/null +++ b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr @@ -0,0 +1,27 @@ +error: reference to `Umm` held across a suspend point, but should not be + --> $DIR/ref-drop-tracking.rs:19:13 + | +LL | let guard = &mut self.u; + | ^^^^^ +LL | +LL | other().await; + | ------ the value is held across this suspend point + | +note: the lint level is defined here + --> $DIR/ref-drop-tracking.rs:4:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ +note: You gotta use Umm's, ya know? + --> $DIR/ref-drop-tracking.rs:19:13 + | +LL | let guard = &mut self.u; + | ^^^^^ +help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point + --> $DIR/ref-drop-tracking.rs:19:13 + | +LL | let guard = &mut self.u; + | ^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/regions/outlives-with-missing.rs b/src/test/ui/regions/outlives-with-missing.rs new file mode 100644 index 0000000000000..29d89718b5867 --- /dev/null +++ b/src/test/ui/regions/outlives-with-missing.rs @@ -0,0 +1,16 @@ +trait HandlerFamily { + type Target; +} + +struct HandlerWrapper(H); + +impl HandlerWrapper { + pub fn set_handler(&self, handler: &H::Target) + where + T: Send + Sync + 'static, + //~^ ERROR cannot find type `T` in this scope + { + } +} + +fn main() {} diff --git a/src/test/ui/regions/outlives-with-missing.stderr b/src/test/ui/regions/outlives-with-missing.stderr new file mode 100644 index 0000000000000..e204c918724fe --- /dev/null +++ b/src/test/ui/regions/outlives-with-missing.stderr @@ -0,0 +1,12 @@ +error[E0412]: cannot find type `T` in this scope + --> $DIR/outlives-with-missing.rs:10:9 + | +LL | impl HandlerWrapper { + | - similarly named type parameter `H` defined here +... +LL | T: Send + Sync + 'static, + | ^ help: a type parameter with a similar name exists: `H` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.rs b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.rs new file mode 100644 index 0000000000000..bd496875e80b9 --- /dev/null +++ b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.rs @@ -0,0 +1,21 @@ +trait Foo { + fn foo(&self, name: T) -> usize; +} + +struct Bar { + baz: Baz, +} + +struct Baz { + num: usize, +} + +impl Foo for Bar { + fn foo(&self, _name: Baz) -> usize { + match self.baz { + Baz { num } => num, //~ ERROR expected struct, variant or union type, found type parameter `Baz` + } + } +} + +fn main() {} diff --git a/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr new file mode 100644 index 0000000000000..d9c404e94acb4 --- /dev/null +++ b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr @@ -0,0 +1,12 @@ +error[E0574]: expected struct, variant or union type, found type parameter `Baz` + --> $DIR/point-at-type-parameter-shadowing-another-type.rs:16:13 + | +LL | impl Foo for Bar { + | --- found this type pararmeter +... +LL | Baz { num } => num, + | ^^^ not a struct, variant or union type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0574`. diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr index 2bc3ff4c3b619..ea9c4c82c3610 100644 --- a/src/test/ui/span/issue-35987.stderr +++ b/src/test/ui/span/issue-35987.stderr @@ -2,7 +2,9 @@ error[E0404]: expected trait, found type parameter `Add` --> $DIR/issue-35987.rs:5:21 | LL | impl Add for Foo { - | ^^^ not a trait + | --- ^^^ not a trait + | | + | found this type pararmeter | help: consider importing this trait instead | diff --git a/src/tools/rust-analyzer/bench_data/glorious_old_parser b/src/tools/rust-analyzer/bench_data/glorious_old_parser index 7e900dfeb1eeb..764893daa12ad 100644 --- a/src/tools/rust-analyzer/bench_data/glorious_old_parser +++ b/src/tools/rust-analyzer/bench_data/glorious_old_parser @@ -1988,7 +1988,7 @@ impl<'a> Parser<'a> { err.span_suggestion( span, "declare the type after the parameter binding", - String::from(": "), + ": ", Applicability::HasPlaceholders, ); } else if require_name && is_trait_item {