diff options
Diffstat (limited to 'compiler')
21 files changed, 304 insertions, 241 deletions
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 6c33dfb4ec0..3bdd1b48666 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -17,6 +17,24 @@ hir_typeck_base_expression_double_dot_enable_default_field_values = add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields hir_typeck_base_expression_double_dot_remove = remove the `..` as all the fields are already present +hir_typeck_break_inside_closure = + `{$name}` inside of a closure + .label = cannot `{$name}` inside of a closure + .closure_label = enclosing closure + +hir_typeck_break_inside_coroutine = + `{$name}` inside `{$kind}` {$source} + .label = cannot `{$name}` inside `{$kind}` {$source} + .coroutine_label = enclosing `{$kind}` {$source} + +hir_typeck_break_non_loop = + `break` with value from a `{$kind}` loop + .label = can only break with a value inside `loop` or breakable block + .label2 = you can't `break` with a value in a `{$kind}` loop + .suggestion = use `break` on its own without a value inside this `{$kind}` loop + .break_expr_suggestion = alternatively, you might have meant to use the available loop label + + hir_typeck_candidate_trait_note = `{$trait_name}` defines an item `{$item_name}`{$action_or_ty -> [NONE] {""} [implement] , perhaps you need to implement it @@ -64,6 +82,12 @@ hir_typeck_const_select_must_be_fn = this argument must be a function item .note = expected a function item, found {$ty} .help = consult the documentation on `const_eval_select` for more information +hir_typeck_continue_labeled_block = + `continue` pointing to a labeled block + .label = labeled blocks cannot be `continue`'d + .block_label = labeled block the `continue` points to + + hir_typeck_convert_to_str = try converting the passed type into a `&str` hir_typeck_convert_using_method = try using `{$sugg}` to convert `{$found}` to `{$expected}` @@ -182,6 +206,19 @@ hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expecte hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}` hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}` +hir_typeck_outside_loop = + `{$name}` outside of a loop{$is_break -> + [true] {" or labeled block"} + *[false] {""} + } + .label = cannot `{$name}` outside of a loop{$is_break -> + [true] {" or labeled block"} + *[false] {""} + } + +hir_typeck_outside_loop_suggestion = consider labeling this block to be able to break within it + + hir_typeck_params_not_allowed = referencing function parameters is not allowed in naked functions .help = follow the calling convention in asm block to use parameters @@ -254,6 +291,13 @@ hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns hir_typeck_union_pat_multiple_fields = union patterns should have exactly one field +hir_typeck_unlabeled_cf_in_while_condition = + `break` or `continue` with no label in the condition of a `while` loop + .label = unlabeled `{$cf_type}` in the condition of a `while` loop + +hir_typeck_unlabeled_in_labeled_block = + unlabeled `{$cf_type}` inside of a labeled block + .label = `{$cf_type}` statements that would diverge to or through a labeled block need to bear a label hir_typeck_use_is_empty = consider using the `is_empty` method on `{$expr_ty}` to determine if it contains anything diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 97a90548fc5..774815015d5 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -2,11 +2,14 @@ use std::borrow::Cow; +use rustc_ast::Label; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic, }; +use rustc_hir as hir; +use rustc_hir::ExprKind; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{self, Ty}; use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; @@ -721,6 +724,131 @@ pub(crate) struct TrivialCast<'tcx> { pub cast_ty: Ty<'tcx>, } +pub(crate) struct BreakNonLoop<'a> { + pub span: Span, + pub head: Option<Span>, + pub kind: &'a str, + pub suggestion: String, + pub loop_label: Option<Label>, + pub break_label: Option<Label>, + pub break_expr_kind: &'a ExprKind<'a>, + pub break_expr_span: Span, +} + +impl<'a, G: EmissionGuarantee> Diagnostic<'_, G> for BreakNonLoop<'a> { + #[track_caller] + fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { + let mut diag = Diag::new(dcx, level, fluent::hir_typeck_break_non_loop); + diag.span(self.span); + diag.code(E0571); + diag.arg("kind", self.kind); + diag.span_label(self.span, fluent::hir_typeck_label); + if let Some(head) = self.head { + diag.span_label(head, fluent::hir_typeck_label2); + } + diag.span_suggestion( + self.span, + fluent::hir_typeck_suggestion, + self.suggestion, + Applicability::MaybeIncorrect, + ); + if let (Some(label), None) = (self.loop_label, self.break_label) { + match self.break_expr_kind { + ExprKind::Path(hir::QPath::Resolved( + None, + hir::Path { segments: [segment], res: hir::def::Res::Err, .. }, + )) if label.ident.to_string() == format!("'{}", segment.ident) => { + // This error is redundant, we will have already emitted a + // suggestion to use the label when `segment` wasn't found + // (hence the `Res::Err` check). + diag.downgrade_to_delayed_bug(); + } + _ => { + diag.span_suggestion( + self.break_expr_span, + fluent::hir_typeck_break_expr_suggestion, + label.ident, + Applicability::MaybeIncorrect, + ); + } + } + } + diag + } +} + +#[derive(Diagnostic)] +#[diag(hir_typeck_continue_labeled_block, code = E0696)] +pub(crate) struct ContinueLabeledBlock { + #[primary_span] + #[label] + pub span: Span, + #[label(hir_typeck_block_label)] + pub block_span: Span, +} + +#[derive(Diagnostic)] +#[diag(hir_typeck_break_inside_closure, code = E0267)] +pub(crate) struct BreakInsideClosure<'a> { + #[primary_span] + #[label] + pub span: Span, + #[label(hir_typeck_closure_label)] + pub closure_span: Span, + pub name: &'a str, +} + +#[derive(Diagnostic)] +#[diag(hir_typeck_break_inside_coroutine, code = E0267)] +pub(crate) struct BreakInsideCoroutine<'a> { + #[primary_span] + #[label] + pub span: Span, + #[label(hir_typeck_coroutine_label)] + pub coroutine_span: Span, + pub name: &'a str, + pub kind: &'a str, + pub source: &'a str, +} + +#[derive(Diagnostic)] +#[diag(hir_typeck_outside_loop, code = E0268)] +pub(crate) struct OutsideLoop<'a> { + #[primary_span] + #[label] + pub spans: Vec<Span>, + pub name: &'a str, + pub is_break: bool, + #[subdiagnostic] + pub suggestion: Option<OutsideLoopSuggestion>, +} +#[derive(Subdiagnostic)] +#[multipart_suggestion(hir_typeck_outside_loop_suggestion, applicability = "maybe-incorrect")] +pub(crate) struct OutsideLoopSuggestion { + #[suggestion_part(code = "'block: ")] + pub block_span: Span, + #[suggestion_part(code = " 'block")] + pub break_spans: Vec<Span>, +} + +#[derive(Diagnostic)] +#[diag(hir_typeck_unlabeled_in_labeled_block, code = E0695)] +pub(crate) struct UnlabeledInLabeledBlock<'a> { + #[primary_span] + #[label] + pub span: Span, + pub cf_type: &'a str, +} + +#[derive(Diagnostic)] +#[diag(hir_typeck_unlabeled_cf_in_while_condition, code = E0590)] +pub(crate) struct UnlabeledCfInWhileCondition<'a> { + #[primary_span] + #[label] + pub span: Span, + pub cf_type: &'a str, +} + #[derive(Diagnostic)] #[diag(hir_typeck_no_associated_item, code = E0599)] pub(crate) struct NoAssociatedItem { diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 741a616631a..a45a7715340 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -28,6 +28,7 @@ mod fallback; mod fn_ctxt; mod gather_locals; mod intrinsicck; +mod loops; mod method; mod naked_functions; mod op; @@ -149,6 +150,7 @@ fn typeck_with_inspect<'tcx>( }; check_abi(tcx, id, span, fn_sig.abi()); + loops::check(tcx, def_id, body); // Compute the function signature from point of view of inside the fn. let mut fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig); @@ -189,6 +191,8 @@ fn typeck_with_inspect<'tcx>( tcx.type_of(def_id).instantiate_identity() }; + loops::check(tcx, def_id, body); + let expected_type = fcx.normalize(body.value.span, expected_type); let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id))); diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_hir_typeck/src/loops.rs index b06f16cc7bd..b06e0704b6f 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_hir_typeck/src/loops.rs @@ -3,11 +3,11 @@ use std::fmt; use Context::*; use rustc_hir as hir; -use rustc_hir::def_id::{LocalDefId, LocalModDefId}; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Destination, Node}; use rustc_middle::hir::nested_filter; -use rustc_middle::query::Providers; use rustc_middle::span_bug; use rustc_middle::ty::TyCtxt; use rustc_span::hygiene::DesugaringKind; @@ -73,17 +73,17 @@ struct CheckLoopVisitor<'tcx> { block_breaks: BTreeMap<Span, BlockInfo>, } -fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { +pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<'tcx>) { let mut check = CheckLoopVisitor { tcx, cx_stack: vec![Normal], block_breaks: Default::default() }; - tcx.hir_visit_item_likes_in_module(module_def_id, &mut check); + let cx = match tcx.def_kind(def_id) { + DefKind::AnonConst => AnonConst, + _ => Fn, + }; + check.with_context(cx, |v| v.visit_body(body)); check.report_outside_loop_error(); } -pub(crate) fn provide(providers: &mut Providers) { - *providers = Providers { check_mod_loops, ..*providers }; -} - impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> { type NestedFilter = nested_filter::OnlyBodies; @@ -91,33 +91,14 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> { self.tcx } - fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) { - self.with_context(AnonConst, |v| intravisit::walk_anon_const(v, c)); + fn visit_anon_const(&mut self, _: &'hir hir::AnonConst) { + // Typecked on its own. } fn visit_inline_const(&mut self, c: &'hir hir::ConstBlock) { self.with_context(ConstBlock, |v| intravisit::walk_inline_const(v, c)); } - fn visit_fn( - &mut self, - fk: hir::intravisit::FnKind<'hir>, - fd: &'hir hir::FnDecl<'hir>, - b: hir::BodyId, - _: Span, - id: LocalDefId, - ) { - self.with_context(Fn, |v| intravisit::walk_fn(v, fk, fd, b, id)); - } - - fn visit_trait_item(&mut self, trait_item: &'hir hir::TraitItem<'hir>) { - self.with_context(Fn, |v| intravisit::walk_trait_item(v, trait_item)); - } - - fn visit_impl_item(&mut self, impl_item: &'hir hir::ImplItem<'hir>) { - self.with_context(Fn, |v| intravisit::walk_impl_item(v, impl_item)); - } - fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) { match e.kind { hir::ExprKind::If(cond, then, else_opt) => { diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 2086483b94a..6f6791804d3 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -238,6 +238,9 @@ impl<'tcx> ut::UnifyKey for TyVidEqKey<'tcx> { fn tag() -> &'static str { "TyVidEqKey" } + fn order_roots(a: Self, _: &Self::Value, b: Self, _: &Self::Value) -> Option<(Self, Self)> { + if a.vid.as_u32() < b.vid.as_u32() { Some((a, b)) } else { Some((b, a)) } + } } impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> { diff --git a/compiler/rustc_infer/src/infer/unify_key.rs b/compiler/rustc_infer/src/infer/unify_key.rs index 3ba8aea1d3a..5e5d0e063a0 100644 --- a/compiler/rustc_infer/src/infer/unify_key.rs +++ b/compiler/rustc_infer/src/infer/unify_key.rs @@ -137,6 +137,9 @@ impl<'tcx> UnifyKey for ConstVidKey<'tcx> { fn tag() -> &'static str { "ConstVidKey" } + fn order_roots(a: Self, _: &Self::Value, b: Self, _: &Self::Value) -> Option<(Self, Self)> { + if a.vid.as_u32() < b.vid.as_u32() { Some((a, b)) } else { Some((b, a)) } + } } impl<'tcx> UnifyValue for ConstVariableValue<'tcx> { diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 2643e5c1926..99520a3fea3 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -954,7 +954,6 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { tcx.ensure_ok().exportable_items(LOCAL_CRATE); tcx.ensure_ok().stable_order_of_exportable_impls(LOCAL_CRATE); tcx.par_hir_for_each_module(|module| { - tcx.ensure_ok().check_mod_loops(module); tcx.ensure_ok().check_mod_attrs(module); tcx.ensure_ok().check_mod_unstable_api_usage(module); }); diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 6035056baaf..7c998761a9d 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -389,6 +389,7 @@ tcx_lifetime! { rustc_middle::ty::layout::FnAbiError, rustc_middle::ty::layout::LayoutError, rustc_middle::ty::ParamEnv, + rustc_middle::ty::TypingEnv, rustc_middle::ty::Predicate, rustc_middle::ty::SymbolName, rustc_middle::ty::TraitRef, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index d03f01bf863..d8c927e00db 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1115,11 +1115,6 @@ rustc_queries! { desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) } } - /// Checks the loops in the module. - query check_mod_loops(key: LocalModDefId) { - desc { |tcx| "checking loops in {}", describe_as_module(key, tcx) } - } - query check_mod_privacy(key: LocalModDefId) { desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) } } @@ -1571,7 +1566,7 @@ rustc_queries! { /// Like `param_env`, but returns the `ParamEnv` after all opaque types have been /// replaced with their hidden type. This is used in the old trait solver /// when in `PostAnalysis` mode and should not be called directly. - query param_env_normalized_for_post_analysis(def_id: DefId) -> ty::ParamEnv<'tcx> { + query typing_env_normalized_for_post_analysis(def_id: DefId) -> ty::TypingEnv<'tcx> { desc { |tcx| "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index af31f7ed33b..dc3f2844e5a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1116,10 +1116,7 @@ impl<'tcx> TypingEnv<'tcx> { } pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam<DefId>) -> TypingEnv<'tcx> { - TypingEnv { - typing_mode: TypingMode::PostAnalysis, - param_env: tcx.param_env_normalized_for_post_analysis(def_id), - } + tcx.typing_env_normalized_for_post_analysis(def_id) } /// Modify the `typing_mode` to `PostAnalysis` and eagerly reveal all @@ -1133,7 +1130,7 @@ impl<'tcx> TypingEnv<'tcx> { // No need to reveal opaques with the new solver enabled, // since we have lazy norm. let param_env = if tcx.next_trait_solver_globally() { - ParamEnv::new(param_env.caller_bounds()) + param_env } else { ParamEnv::new(tcx.reveal_opaque_types_in_bounds(param_env.caller_bounds())) }; diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 983e562cdf3..a4ef065ea2c 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -56,23 +56,6 @@ passes_autodiff_attr = passes_both_ffi_const_and_pure = `#[ffi_const]` function cannot be `#[ffi_pure]` -passes_break_inside_closure = - `{$name}` inside of a closure - .label = cannot `{$name}` inside of a closure - .closure_label = enclosing closure - -passes_break_inside_coroutine = - `{$name}` inside `{$kind}` {$source} - .label = cannot `{$name}` inside `{$kind}` {$source} - .coroutine_label = enclosing `{$kind}` {$source} - -passes_break_non_loop = - `break` with value from a `{$kind}` loop - .label = can only break with a value inside `loop` or breakable block - .label2 = you can't `break` with a value in a `{$kind}` loop - .suggestion = use `break` on its own without a value inside this `{$kind}` loop - .break_expr_suggestion = alternatively, you might have meant to use the available loop label - passes_cannot_stabilize_deprecated = an API can't be stabilized after it is deprecated .label = invalid version @@ -103,10 +86,6 @@ passes_const_stable_not_stable = attribute `#[rustc_const_stable]` can only be applied to functions that are declared `#[stable]` .label = attribute specified here -passes_continue_labeled_block = - `continue` pointing to a labeled block - .label = labeled blocks cannot be `continue`'d - .block_label = labeled block the `continue` points to passes_coroutine_on_non_closure = attribute should be applied to closures @@ -574,17 +553,6 @@ passes_optimize_invalid_target = passes_outer_crate_level_attr = crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` -passes_outside_loop = - `{$name}` outside of a loop{$is_break -> - [true] {" or labeled block"} - *[false] {""} - } - .label = cannot `{$name}` outside of a loop{$is_break -> - [true] {" or labeled block"} - *[false] {""} - } - -passes_outside_loop_suggestion = consider labeling this block to be able to break within it passes_panic_unwind_without_std = unwinding panics are not supported without std @@ -752,14 +720,6 @@ passes_unknown_lang_item = definition of an unknown lang item: `{$name}` .label = definition of unknown lang item `{$name}` -passes_unlabeled_cf_in_while_condition = - `break` or `continue` with no label in the condition of a `while` loop - .label = unlabeled `{$cf_type}` in the condition of a `while` loop - -passes_unlabeled_in_labeled_block = - unlabeled `{$cf_type}` inside of a labeled block - .label = `{$cf_type}` statements that would diverge to or through a labeled block need to bear a label - passes_unnecessary_partial_stable_feature = the feature `{$feature}` has been partially stabilized since {$since} and is succeeded by the feature `{$implies}` .suggestion = if you are using features which are still unstable, change to using `{$implies}` .suggestion_remove = if you are using features which are now stable, remove this line diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index b995781719b..74ce92624bd 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1,13 +1,12 @@ use std::io::Error; use std::path::{Path, PathBuf}; -use rustc_ast::Label; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level, MultiSpan, Subdiagnostic, }; -use rustc_hir::{self as hir, ExprKind, Target}; +use rustc_hir::Target; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{MainDefinition, Ty}; use rustc_span::{DUMMY_SP, Span, Symbol}; @@ -1071,131 +1070,6 @@ pub(crate) struct FeaturePreviouslyDeclared<'a> { pub prev_declared: &'a str, } -pub(crate) struct BreakNonLoop<'a> { - pub span: Span, - pub head: Option<Span>, - pub kind: &'a str, - pub suggestion: String, - pub loop_label: Option<Label>, - pub break_label: Option<Label>, - pub break_expr_kind: &'a ExprKind<'a>, - pub break_expr_span: Span, -} - -impl<'a, G: EmissionGuarantee> Diagnostic<'_, G> for BreakNonLoop<'a> { - #[track_caller] - fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, fluent::passes_break_non_loop); - diag.span(self.span); - diag.code(E0571); - diag.arg("kind", self.kind); - diag.span_label(self.span, fluent::passes_label); - if let Some(head) = self.head { - diag.span_label(head, fluent::passes_label2); - } - diag.span_suggestion( - self.span, - fluent::passes_suggestion, - self.suggestion, - Applicability::MaybeIncorrect, - ); - if let (Some(label), None) = (self.loop_label, self.break_label) { - match self.break_expr_kind { - ExprKind::Path(hir::QPath::Resolved( - None, - hir::Path { segments: [segment], res: hir::def::Res::Err, .. }, - )) if label.ident.to_string() == format!("'{}", segment.ident) => { - // This error is redundant, we will have already emitted a - // suggestion to use the label when `segment` wasn't found - // (hence the `Res::Err` check). - diag.downgrade_to_delayed_bug(); - } - _ => { - diag.span_suggestion( - self.break_expr_span, - fluent::passes_break_expr_suggestion, - label.ident, - Applicability::MaybeIncorrect, - ); - } - } - } - diag - } -} - -#[derive(Diagnostic)] -#[diag(passes_continue_labeled_block, code = E0696)] -pub(crate) struct ContinueLabeledBlock { - #[primary_span] - #[label] - pub span: Span, - #[label(passes_block_label)] - pub block_span: Span, -} - -#[derive(Diagnostic)] -#[diag(passes_break_inside_closure, code = E0267)] -pub(crate) struct BreakInsideClosure<'a> { - #[primary_span] - #[label] - pub span: Span, - #[label(passes_closure_label)] - pub closure_span: Span, - pub name: &'a str, -} - -#[derive(Diagnostic)] -#[diag(passes_break_inside_coroutine, code = E0267)] -pub(crate) struct BreakInsideCoroutine<'a> { - #[primary_span] - #[label] - pub span: Span, - #[label(passes_coroutine_label)] - pub coroutine_span: Span, - pub name: &'a str, - pub kind: &'a str, - pub source: &'a str, -} - -#[derive(Diagnostic)] -#[diag(passes_outside_loop, code = E0268)] -pub(crate) struct OutsideLoop<'a> { - #[primary_span] - #[label] - pub spans: Vec<Span>, - pub name: &'a str, - pub is_break: bool, - #[subdiagnostic] - pub suggestion: Option<OutsideLoopSuggestion>, -} -#[derive(Subdiagnostic)] -#[multipart_suggestion(passes_outside_loop_suggestion, applicability = "maybe-incorrect")] -pub(crate) struct OutsideLoopSuggestion { - #[suggestion_part(code = "'block: ")] - pub block_span: Span, - #[suggestion_part(code = " 'block")] - pub break_spans: Vec<Span>, -} - -#[derive(Diagnostic)] -#[diag(passes_unlabeled_in_labeled_block, code = E0695)] -pub(crate) struct UnlabeledInLabeledBlock<'a> { - #[primary_span] - #[label] - pub span: Span, - pub cf_type: &'a str, -} - -#[derive(Diagnostic)] -#[diag(passes_unlabeled_cf_in_while_condition, code = E0590)] -pub(crate) struct UnlabeledCfInWhileCondition<'a> { - #[primary_span] - #[label] - pub span: Span, - pub cf_type: &'a str, -} - #[derive(Diagnostic)] #[diag(passes_naked_functions_incompatible_attribute, code = E0736)] pub(crate) struct NakedFunctionIncompatibleAttribute { diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 1831f45a9ec..af7ecf0830c 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -29,7 +29,6 @@ mod lang_items; pub mod layout_test; mod lib_features; mod liveness; -pub mod loops; mod reachable; pub mod stability; mod upvars; @@ -45,7 +44,6 @@ pub fn provide(providers: &mut Providers) { entry::provide(providers); lang_items::provide(providers); lib_features::provide(providers); - loops::provide(providers); liveness::provide(providers); reachable::provide(providers); stability::provide(providers); diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index bac5c9066f1..ef8c88355f6 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -16,7 +16,7 @@ use rustc_middle::ty::{ }; use rustc_middle::{mir, ty}; use rustc_span::def_id::LOCAL_CRATE; -use stable_mir::abi::{FnAbi, Layout, LayoutShape}; +use stable_mir::abi::{FnAbi, Layout, LayoutShape, ReprOptions}; use stable_mir::mir::alloc::GlobalAlloc; use stable_mir::mir::mono::{InstanceDef, StaticDef}; use stable_mir::mir::{BinOp, Body, Place, UnOp}; @@ -397,6 +397,13 @@ impl<'tcx> SmirCtxt<'tcx> { tables.tcx.is_lang_item(def_id, LangItem::CStr) } + /// Returns the representation options for this ADT + pub fn adt_repr(&self, def: AdtDef) -> ReprOptions { + let mut tables = self.0.borrow_mut(); + let tcx = tables.tcx; + def.internal(&mut *tables, tcx).repr().stable(&mut *tables) + } + /// Retrieve the function signature for the given generic arguments. pub fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig { let mut tables = self.0.borrow_mut(); diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs index 64901ee0502..46f1ca61cec 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs @@ -6,9 +6,9 @@ use rustc_abi::{ArmCall, CanonAbi, InterruptKind, X86Call}; use rustc_middle::ty; use rustc_target::callconv; use stable_mir::abi::{ - AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength, Layout, - LayoutShape, PassMode, Primitive, Scalar, TagEncoding, TyAndLayout, ValueAbi, VariantsShape, - WrappingRange, + AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength, + IntegerType, Layout, LayoutShape, PassMode, Primitive, ReprFlags, ReprOptions, Scalar, + TagEncoding, TyAndLayout, ValueAbi, VariantsShape, WrappingRange, }; use stable_mir::opaque; use stable_mir::target::MachineSize as Size; @@ -310,3 +310,42 @@ impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange { WrappingRange { start: self.start, end: self.end } } } + +impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags { + type T = ReprFlags; + + fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + ReprFlags { + is_simd: self.intersects(Self::IS_SIMD), + is_c: self.intersects(Self::IS_C), + is_transparent: self.intersects(Self::IS_TRANSPARENT), + is_linear: self.intersects(Self::IS_LINEAR), + } + } +} + +impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType { + type T = IntegerType; + + fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + match self { + rustc_abi::IntegerType::Pointer(signed) => IntegerType::Pointer { is_signed: *signed }, + rustc_abi::IntegerType::Fixed(integer, signed) => { + IntegerType::Fixed { length: integer.stable(tables), is_signed: *signed } + } + } + } +} + +impl<'tcx> Stable<'tcx> for rustc_abi::ReprOptions { + type T = ReprOptions; + + fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + ReprOptions { + int: self.int.map(|int| int.stable(tables)), + align: self.align.map(|align| align.stable(tables)), + pack: self.pack.map(|pack| pack.stable(tables)), + flags: self.flags.stable(tables), + } + } +} diff --git a/compiler/rustc_smir/src/stable_mir/abi.rs b/compiler/rustc_smir/src/stable_mir/abi.rs index 3842cb7e653..347c6ed16a2 100644 --- a/compiler/rustc_smir/src/stable_mir/abi.rs +++ b/compiler/rustc_smir/src/stable_mir/abi.rs @@ -455,3 +455,38 @@ pub enum CallConvention { RiscvInterrupt, } + +#[non_exhaustive] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)] +pub struct ReprFlags { + pub is_simd: bool, + pub is_c: bool, + pub is_transparent: bool, + pub is_linear: bool, +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)] +pub enum IntegerType { + /// Pointer-sized integer type, i.e. `isize` and `usize`. + Pointer { + /// Signedness. e.g. `true` for `isize` + is_signed: bool, + }, + /// Fixed-sized integer type, e.g. `i8`, `u32`, `i128`. + Fixed { + /// Length of this integer type. e.g. `IntegerLength::I8` for `u8`. + length: IntegerLength, + /// Signedness. e.g. `false` for `u8` + is_signed: bool, + }, +} + +/// Representation options provided by the user +#[non_exhaustive] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)] +pub struct ReprOptions { + pub int: Option<IntegerType>, + pub align: Option<Align>, + pub pack: Option<Align>, + pub flags: ReprFlags, +} diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs index bb35e23a728..3967ad13eeb 100644 --- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs +++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs @@ -6,7 +6,7 @@ use std::cell::Cell; use rustc_smir::context::SmirCtxt; -use stable_mir::abi::{FnAbi, Layout, LayoutShape}; +use stable_mir::abi::{FnAbi, Layout, LayoutShape, ReprOptions}; use stable_mir::crate_def::Attribute; use stable_mir::mir::alloc::{AllocId, GlobalAlloc}; use stable_mir::mir::mono::{Instance, InstanceDef, StaticDef}; @@ -200,6 +200,11 @@ impl<'tcx> SmirInterface<'tcx> { self.cx.adt_is_cstr(def) } + /// Returns the representation options for this ADT + pub(crate) fn adt_repr(&self, def: AdtDef) -> ReprOptions { + self.cx.adt_repr(def) + } + /// Retrieve the function signature for the given generic arguments. pub(crate) fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig { self.cx.fn_sig(def, args) diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index e331e593471..4461b4ae125 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -9,6 +9,7 @@ use stable_mir::mir::mono::StaticDef; use stable_mir::target::MachineInfo; use stable_mir::{Filename, Opaque}; +use super::abi::ReprOptions; use super::mir::{Body, Mutability, Safety}; use super::{DefId, Error, Symbol, with}; use crate::stable_mir; @@ -818,6 +819,10 @@ impl AdtDef { pub fn variant(&self, idx: VariantIdx) -> Option<VariantDef> { (idx.to_index() < self.num_variants()).then_some(VariantDef { idx, adt_def: *self }) } + + pub fn repr(&self) -> ReprOptions { + with(|cx| cx.adt_repr(*self)) + } } /// Definition of a variant, which can be either a struct / union field or an enum variant. diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 06f81ac554e..7bf49056e29 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -759,7 +759,8 @@ pub enum ExplicitLifetimeRequired<'a> { #[suggestion( trait_selection_explicit_lifetime_required_sugg_with_ident, code = "{new_ty}", - applicability = "unspecified" + applicability = "unspecified", + style = "verbose" )] new_ty_span: Span, #[skip_arg] @@ -774,7 +775,8 @@ pub enum ExplicitLifetimeRequired<'a> { #[suggestion( trait_selection_explicit_lifetime_required_sugg_with_param_type, code = "{new_ty}", - applicability = "unspecified" + applicability = "unspecified", + style = "verbose" )] new_ty_span: Span, #[skip_arg] @@ -1462,7 +1464,8 @@ pub enum SuggestAccessingField<'a> { #[suggestion( trait_selection_suggest_accessing_field, code = "{snippet}.{name}", - applicability = "maybe-incorrect" + applicability = "maybe-incorrect", + style = "verbose" )] Safe { #[primary_span] @@ -1474,7 +1477,8 @@ pub enum SuggestAccessingField<'a> { #[suggestion( trait_selection_suggest_accessing_field, code = "unsafe {{ {snippet}.{name} }}", - applicability = "maybe-incorrect" + applicability = "maybe-incorrect", + style = "verbose" )] Unsafe { #[primary_span] diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 4dc27622d23..79ac622df32 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -255,10 +255,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { } } -fn param_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { - // This is a bit ugly but the easiest way to avoid code duplication. - let typing_env = ty::TypingEnv::non_body_analysis(tcx, def_id); - typing_env.with_post_analysis_normalized(tcx).param_env +fn typing_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TypingEnv<'_> { + ty::TypingEnv::non_body_analysis(tcx, def_id).with_post_analysis_normalized(tcx) } /// Check if a function is async. @@ -374,7 +372,7 @@ pub(crate) fn provide(providers: &mut Providers) { asyncness, adt_sized_constraint, param_env, - param_env_normalized_for_post_analysis, + typing_env_normalized_for_post_analysis, defaultness, unsizing_params_for_adt, impl_self_is_guaranteed_unsized, diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 0cd98b5aa53..9669772d1a6 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -771,23 +771,6 @@ pub enum InferTy { FreshFloatTy(u32), } -/// Raw `TyVid` are used as the unification key for `sub_relations`; -/// they carry no values. -impl UnifyKey for TyVid { - type Value = (); - #[inline] - fn index(&self) -> u32 { - self.as_u32() - } - #[inline] - fn from_index(i: u32) -> TyVid { - TyVid::from_u32(i) - } - fn tag() -> &'static str { - "TyVid" - } -} - impl UnifyValue for IntVarValue { type Error = NoError; |
