From fdf8f024ad71c6e9c46867fb31b74df0fcaaf3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sat, 15 Jun 2024 21:34:44 +0200 Subject: [PATCH] Improve the impl and diag output of lint type_alias_bounds --- compiler/rustc_lint/messages.ftl | 19 +- compiler/rustc_lint/src/builtin.rs | 92 +++++---- compiler/rustc_lint/src/lints.rs | 154 ++++++++------- .../type-alias-bounds.rs | 2 +- .../type-alias-bounds.stderr | 15 +- .../associated-type-bounds/type-alias.stderr | 180 ++++++++++-------- tests/ui/privacy/private-in-public-warn.rs | 4 +- .../ui/privacy/private-in-public-warn.stderr | 30 +-- .../trivial-bounds-inconsistent.stderr | 15 +- ...67690-type-alias-bound-diagnostic-crash.rs | 2 +- ...0-type-alias-bound-diagnostic-crash.stderr | 15 +- tests/ui/type/type-alias-bounds.rs | 21 +- tests/ui/type/type-alias-bounds.stderr | 155 ++++++++------- 13 files changed, 385 insertions(+), 319 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 7d7b97e2eb1..ce99c8686ba 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -139,13 +139,18 @@ lint_builtin_special_module_name_used_main = found module declaration for main.r lint_builtin_trivial_bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters -lint_builtin_type_alias_bounds_help = use fully disambiguated paths (i.e., `::Assoc`) to refer to associated types in type aliases - -lint_builtin_type_alias_generic_bounds = bounds on generic parameters are not enforced in type aliases - .suggestion = the bound will not be checked when the type alias is used, and should be removed - -lint_builtin_type_alias_where_clause = where clauses are not enforced in type aliases - .suggestion = the clause will not be checked when the type alias is used, and should be removed +lint_builtin_type_alias_bounds_enable_feat_help = add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics +lint_builtin_type_alias_bounds_label = will not be checked at usage sites of the type alias +lint_builtin_type_alias_bounds_limitation_note = this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information +lint_builtin_type_alias_bounds_param_bounds = bounds on generic parameters in type aliases are not enforced + .suggestion = remove {$count -> + [one] this bound + *[other] these bounds + } +lint_builtin_type_alias_bounds_qualify_assoc_tys_sugg = fully qualify this associated type +lint_builtin_type_alias_bounds_where_clause = where clauses on type aliases are not enforced + .suggestion = remove this where clause lint_builtin_unpermitted_type_init_label = this code causes undefined behavior when executed lint_builtin_unpermitted_type_init_label_suggestion = help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 90555007607..a8c8c71927a 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -31,12 +31,12 @@ use crate::{ BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents, BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc, BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns, - BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasGenericBounds, - BuiltinTypeAliasGenericBoundsSuggestion, BuiltinTypeAliasWhereClause, - BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit, - BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe, - BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub, - BuiltinWhileTrue, InvalidAsmLabel, SuggestChangingAssocTypes, + BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasBounds, + BuiltinTypeAliasParamBoundsSuggestion, BuiltinUngatedAsyncFnTrackCaller, + BuiltinUnpermittedTypeInit, BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, + BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment, + BuiltinUnusedDocCommentSub, BuiltinWhileTrue, InvalidAsmLabel, + TypeAliasBoundsQualifyAssocTysSugg, }, EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext, }; @@ -1406,23 +1406,6 @@ declare_lint_pass!( TypeAliasBounds => [TYPE_ALIAS_BOUNDS] ); -impl TypeAliasBounds { - pub(crate) fn is_type_variable_assoc(qpath: &hir::QPath<'_>) -> bool { - match *qpath { - hir::QPath::TypeRelative(ty, _) => { - // If this is a type variable, we found a `T::Assoc`. - match ty.kind { - hir::TyKind::Path(hir::QPath::Resolved(None, path)) => { - matches!(path.res, Res::Def(DefKind::TyParam, _)) - } - _ => false, - } - } - hir::QPath::Resolved(..) | hir::QPath::LangItem(..) => false, - } - } -} - impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { let hir::ItemKind::TyAlias(hir_ty, generics) = &item.kind else { return }; @@ -1437,7 +1420,6 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { return; } - // FIXME(generic_const_exprs): Revisit this before stabilization. // See also `tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs`. let ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); @@ -1455,6 +1437,8 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { let mut where_spans = Vec::new(); let mut inline_spans = Vec::new(); let mut inline_sugg = Vec::new(); + let mut affects_object_lifetime_defaults = false; + for p in generics.predicates { let span = p.span(); if p.in_where_clause() { @@ -1465,31 +1449,61 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { } inline_sugg.push((span, String::new())); } + + // FIXME(fmease): Move this into a "diagnostic decorator" for increased laziness + // Bounds of the form `T: 'a` where `T` is a type param of + // the type alias affect object lifetime defaults. + if !affects_object_lifetime_defaults + && let hir::WherePredicate::BoundPredicate(pred) = p + && pred.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Outlives(_))) + && pred.bound_generic_params.is_empty() + && let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = pred.bounded_ty.kind + && let Res::Def(DefKind::TyParam, _) = path.res + { + affects_object_lifetime_defaults = true; + } } - let mut suggested_changing_assoc_types = false; - if !where_spans.is_empty() { - let sub = (!suggested_changing_assoc_types).then(|| { - suggested_changing_assoc_types = true; - SuggestChangingAssocTypes { ty: hir_ty } - }); + // FIXME(fmease): Add a disclaimer (in the form of a multi-span note) that the removal of + // type-param-outlives-bounds affects OLDs and explicit object lifetime + // bounds might be required [...]. + // FIXME(fmease): The applicability should also depend on the outcome of the HIR walker + // inside of `TypeAliasBoundsQualifyAssocTysSugg`: Whether it found a + // shorthand projection or not. + let applicability = if affects_object_lifetime_defaults { + Applicability::MaybeIncorrect + } else { + Applicability::MachineApplicable + }; + + let mut qualify_assoc_tys_sugg = Some(TypeAliasBoundsQualifyAssocTysSugg { ty: hir_ty }); + let enable_feat_help = cx.tcx.sess.is_nightly_build().then_some(()); + + if let [.., label_sp] = *where_spans { cx.emit_span_lint( TYPE_ALIAS_BOUNDS, where_spans, - BuiltinTypeAliasWhereClause { suggestion: generics.where_clause_span, sub }, + BuiltinTypeAliasBounds::WhereClause { + label: label_sp, + enable_feat_help, + suggestion: (generics.where_clause_span, applicability), + qualify_assoc_tys_sugg: qualify_assoc_tys_sugg.take(), + }, ); } - - if !inline_spans.is_empty() { - let suggestion = BuiltinTypeAliasGenericBoundsSuggestion { suggestions: inline_sugg }; - let sub = (!suggested_changing_assoc_types).then(|| { - suggested_changing_assoc_types = true; - SuggestChangingAssocTypes { ty: hir_ty } - }); + if let [.., label_sp] = *inline_spans { cx.emit_span_lint( TYPE_ALIAS_BOUNDS, inline_spans, - BuiltinTypeAliasGenericBounds { suggestion, sub }, + BuiltinTypeAliasBounds::ParamBounds { + label: label_sp, + enable_feat_help, + suggestion: BuiltinTypeAliasParamBoundsSuggestion { + suggestions: inline_sugg, + applicability, + }, + qualify_assoc_tys_sugg, + }, ); } } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 6c5f366727f..6cf8b9330fc 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -9,7 +9,7 @@ use rustc_errors::{ ElidedLifetimeInPathSubdiag, EmissionGuarantee, LintDiagnostic, MultiSpan, SubdiagMessageOp, Subdiagnostic, SuggestionStyle, }; -use rustc_hir::{def::Namespace, def_id::DefId}; +use rustc_hir::{self as hir, def::Namespace, def_id::DefId}; use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{ inhabitedness::InhabitedPredicate, Clause, PolyExistentialTraitRef, Ty, TyCtxt, @@ -22,9 +22,7 @@ use rustc_span::{ Span, Symbol, }; -use crate::{ - builtin::InitError, builtin::TypeAliasBounds, errors::OverruledAttributeSub, LateContext, -}; +use crate::{builtin::InitError, errors::OverruledAttributeSub, LateContext}; // array_into_iter.rs #[derive(LintDiagnostic)] @@ -263,62 +261,6 @@ pub struct BuiltinUnreachablePub<'a> { pub help: Option<()>, } -pub struct SuggestChangingAssocTypes<'a, 'b> { - pub ty: &'a rustc_hir::Ty<'b>, -} - -impl<'a, 'b> Subdiagnostic for SuggestChangingAssocTypes<'a, 'b> { - fn add_to_diag_with>( - self, - diag: &mut Diag<'_, G>, - _f: &F, - ) { - // Access to associates types should use `::Assoc`, which does not need a - // bound. Let's see if this type does that. - - // We use a HIR visitor to walk the type. - use rustc_hir::intravisit::{self, Visitor}; - struct WalkAssocTypes<'a, 'b, G: EmissionGuarantee> { - err: &'a mut Diag<'b, G>, - } - impl<'a, 'b, G: EmissionGuarantee> Visitor<'_> for WalkAssocTypes<'a, 'b, G> { - fn visit_qpath( - &mut self, - qpath: &rustc_hir::QPath<'_>, - id: rustc_hir::HirId, - span: Span, - ) { - if TypeAliasBounds::is_type_variable_assoc(qpath) { - self.err.span_help(span, fluent::lint_builtin_type_alias_bounds_help); - } - intravisit::walk_qpath(self, qpath, id) - } - } - - // Let's go for a walk! - let mut visitor = WalkAssocTypes { err: diag }; - visitor.visit_ty(self.ty); - } -} - -#[derive(LintDiagnostic)] -#[diag(lint_builtin_type_alias_where_clause)] -pub struct BuiltinTypeAliasWhereClause<'a, 'b> { - #[suggestion(code = "", applicability = "machine-applicable")] - pub suggestion: Span, - #[subdiagnostic] - pub sub: Option>, -} - -#[derive(LintDiagnostic)] -#[diag(lint_builtin_type_alias_generic_bounds)] -pub struct BuiltinTypeAliasGenericBounds<'a, 'b> { - #[subdiagnostic] - pub suggestion: BuiltinTypeAliasGenericBoundsSuggestion, - #[subdiagnostic] - pub sub: Option>, -} - #[derive(LintDiagnostic)] #[diag(lint_macro_expr_fragment_specifier_2024_migration)] pub struct MacroExprFragment2024 { @@ -326,21 +268,97 @@ pub struct MacroExprFragment2024 { pub suggestion: Span, } -pub struct BuiltinTypeAliasGenericBoundsSuggestion { - pub suggestions: Vec<(Span, String)>, +#[derive(LintDiagnostic)] +pub enum BuiltinTypeAliasBounds<'a, 'hir> { + #[diag(lint_builtin_type_alias_bounds_where_clause)] + #[note(lint_builtin_type_alias_bounds_limitation_note)] + WhereClause { + #[label(lint_builtin_type_alias_bounds_label)] + label: Span, + #[help(lint_builtin_type_alias_bounds_enable_feat_help)] + enable_feat_help: Option<()>, + #[suggestion(code = "")] + suggestion: (Span, Applicability), + #[subdiagnostic] + qualify_assoc_tys_sugg: Option>, + }, + #[diag(lint_builtin_type_alias_bounds_param_bounds)] + #[note(lint_builtin_type_alias_bounds_limitation_note)] + ParamBounds { + #[label(lint_builtin_type_alias_bounds_label)] + label: Span, + #[help(lint_builtin_type_alias_bounds_enable_feat_help)] + enable_feat_help: Option<()>, + #[subdiagnostic] + suggestion: BuiltinTypeAliasParamBoundsSuggestion, + #[subdiagnostic] + qualify_assoc_tys_sugg: Option>, + }, } -impl Subdiagnostic for BuiltinTypeAliasGenericBoundsSuggestion { +pub struct BuiltinTypeAliasParamBoundsSuggestion { + pub suggestions: Vec<(Span, String)>, + pub applicability: Applicability, +} + +impl Subdiagnostic for BuiltinTypeAliasParamBoundsSuggestion { fn add_to_diag_with>( self, diag: &mut Diag<'_, G>, _f: &F, ) { - diag.multipart_suggestion( - fluent::lint_suggestion, - self.suggestions, - Applicability::MachineApplicable, - ); + diag.arg("count", self.suggestions.len()); + diag.multipart_suggestion(fluent::lint_suggestion, self.suggestions, self.applicability); + } +} + +pub struct TypeAliasBoundsQualifyAssocTysSugg<'a, 'hir> { + pub ty: &'a hir::Ty<'hir>, +} + +impl<'a, 'hir> Subdiagnostic for TypeAliasBoundsQualifyAssocTysSugg<'a, 'hir> { + fn add_to_diag_with>( + self, + diag: &mut Diag<'_, G>, + _f: &F, + ) { + // We perform the walk in here instead of in `` to + // avoid doing throwaway work in case the lint ends up getting suppressed. + + use hir::intravisit::Visitor; + struct ProbeShorthandAssocTys<'a, 'b, G: EmissionGuarantee> { + diag: &'a mut Diag<'b, G>, + } + impl<'a, 'b, G: EmissionGuarantee> Visitor<'_> for ProbeShorthandAssocTys<'a, 'b, G> { + fn visit_qpath(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, _: Span) { + // Look for "type-parameter shorthand-associated-types". I.e., paths of the + // form `T::Assoc` with `T` type param. These are reliant on trait bounds. + // Suggest fully qualifying them via `::Assoc`. + // + // Instead of attempting to figure out the necessary trait ref, just use a + // placeholder. Since we don't record type-dependent resolutions for non-body + // items like type aliases, we can't simply deduce the corresp. trait from + // the HIR path alone without rerunning parts of HIR ty lowering here + // (namely `probe_single_ty_param_bound_for_assoc_ty`) which is infeasible. + // + // (We could employ some simple heuristics but that's likely not worth it). + if let hir::QPath::TypeRelative(qself, _) = qpath + && let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = qself.kind + && let hir::def::Res::Def(hir::def::DefKind::TyParam, _) = path.res + { + self.diag.multipart_suggestion( + fluent::lint_builtin_type_alias_bounds_qualify_assoc_tys_sugg, + vec![ + (qself.span.shrink_to_lo(), "<".into()), + (qself.span.shrink_to_hi(), " as /* Trait */>".into()), + ], + Applicability::HasPlaceholders, + ); + } + hir::intravisit::walk_qpath(self, qpath, id) + } + } + ProbeShorthandAssocTys { diag }.visit_ty(self.ty); } } diff --git a/tests/ui/associated-inherent-types/type-alias-bounds.rs b/tests/ui/associated-inherent-types/type-alias-bounds.rs index c27bcbed43a..61641a83994 100644 --- a/tests/ui/associated-inherent-types/type-alias-bounds.rs +++ b/tests/ui/associated-inherent-types/type-alias-bounds.rs @@ -19,7 +19,7 @@ // automatically lead to full wfchecking and lint TAB getting suppressed. pub type Alias = (Source::Assoc,); -//~^ WARN bounds on generic parameters are not enforced in type aliases +//~^ WARN bounds on generic parameters in type aliases are not enforced pub struct Source(T); pub trait Bound {} diff --git a/tests/ui/associated-inherent-types/type-alias-bounds.stderr b/tests/ui/associated-inherent-types/type-alias-bounds.stderr index c5d0e9e5041..c56dd498f77 100644 --- a/tests/ui/associated-inherent-types/type-alias-bounds.stderr +++ b/tests/ui/associated-inherent-types/type-alias-bounds.stderr @@ -1,15 +1,16 @@ -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias-bounds.rs:21:19 | LL | pub type Alias = (Source::Assoc,); - | ^^^^^ + | --^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics = note: `#[warn(type_alias_bounds)]` on by default -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - pub type Alias = (Source::Assoc,); -LL + pub type Alias = (Source::Assoc,); - | warning: 1 warning emitted diff --git a/tests/ui/associated-type-bounds/type-alias.stderr b/tests/ui/associated-type-bounds/type-alias.stderr index 072c471467c..d59952b4a14 100644 --- a/tests/ui/associated-type-bounds/type-alias.stderr +++ b/tests/ui/associated-type-bounds/type-alias.stderr @@ -1,147 +1,159 @@ -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias.rs:3:25 | LL | type _TaWhere1 where T: Iterator = T; - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ------^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics = note: `#[warn(type_alias_bounds)]` on by default -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type _TaWhere1 where T: Iterator = T; -LL + type _TaWhere1 = T; - | -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias.rs:4:25 | LL | type _TaWhere2 where T: Iterator = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type _TaWhere2 where T: Iterator = T; -LL + type _TaWhere2 = T; + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias.rs:5:25 | LL | type _TaWhere3 where T: Iterator = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type _TaWhere3 where T: Iterator = T; -LL + type _TaWhere3 = T; + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias.rs:6:25 | LL | type _TaWhere4 where T: Iterator = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type _TaWhere4 where T: Iterator = T; -LL + type _TaWhere4 = T; + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias.rs:7:25 | LL | type _TaWhere5 where T: Iterator Into<&'a u8>> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type _TaWhere5 where T: Iterator Into<&'a u8>> = T; -LL + type _TaWhere5 = T; + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias.rs:8:25 | LL | type _TaWhere6 where T: Iterator> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type _TaWhere6 where T: Iterator> = T; -LL + type _TaWhere6 = T; + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias.rs:10:20 | LL | type _TaInline1> = T; - | ^^^^^^^^^^^^^^^^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type _TaInline1> = T; -LL + type _TaInline1 = T; + | --^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias.rs:11:20 | LL | type _TaInline2> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type _TaInline2> = T; -LL + type _TaInline2 = T; + | --^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias.rs:12:20 | LL | type _TaInline3> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type _TaInline3> = T; -LL + type _TaInline3 = T; + | --^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias.rs:13:20 | LL | type _TaInline4> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type _TaInline4> = T; -LL + type _TaInline4 = T; + | --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias.rs:14:20 | LL | type _TaInline5 Into<&'a u8>>> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type _TaInline5 Into<&'a u8>>> = T; -LL + type _TaInline5 = T; + | --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias.rs:15:20 | LL | type _TaInline6>> = T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type _TaInline6>> = T; -LL + type _TaInline6 = T; + | --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics warning: 12 warnings emitted diff --git a/tests/ui/privacy/private-in-public-warn.rs b/tests/ui/privacy/private-in-public-warn.rs index 99d318e36be..746b98fbd07 100644 --- a/tests/ui/privacy/private-in-public-warn.rs +++ b/tests/ui/privacy/private-in-public-warn.rs @@ -39,7 +39,7 @@ mod traits { pub trait PubTr {} pub type Alias = T; //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Alias` - //~^ WARNING bounds on generic parameters are not enforced in type aliases + //~^ WARNING bounds on generic parameters in type aliases are not enforced pub trait Tr1: PrivTr {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr1` pub trait Tr2 {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr2` pub trait Tr3 { @@ -58,7 +58,7 @@ mod traits_where { pub type Alias where T: PrivTr = T; //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Alias` - //~| WARNING where clauses are not enforced in type aliases + //~| WARNING where clauses on type aliases are not enforced pub trait Tr2 where T: PrivTr {} //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2` pub trait Tr3 { diff --git a/tests/ui/privacy/private-in-public-warn.stderr b/tests/ui/privacy/private-in-public-warn.stderr index ac7e5547de9..3f7b8c281e7 100644 --- a/tests/ui/privacy/private-in-public-warn.stderr +++ b/tests/ui/privacy/private-in-public-warn.stderr @@ -395,30 +395,32 @@ note: but type `Priv2` is only usable at visibility `pub(self)` LL | struct Priv2; | ^^^^^^^^^^^^ -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/private-in-public-warn.rs:41:23 | LL | pub type Alias = T; - | ^^^^^^ + | --^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics = note: `#[warn(type_alias_bounds)]` on by default -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - pub type Alias = T; -LL + pub type Alias = T; - | -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/private-in-public-warn.rs:59:29 | LL | pub type Alias where T: PrivTr = T; - | ^^^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - pub type Alias where T: PrivTr = T; -LL + pub type Alias = T; + | ------^^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics error: aborting due to 34 previous errors; 2 warnings emitted diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr b/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr index d66e468873b..0eae68bfcf0 100644 --- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr +++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr @@ -24,18 +24,19 @@ warning: trait bound i32: Foo does not depend on any type or lifetime parameters LL | union U where i32: Foo { f: i32 } | ^^^ -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/trivial-bounds-inconsistent.rs:22:14 | LL | type Y where i32: Foo = (); - | ^^^^^^^^ + | ------^^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics = note: `#[warn(type_alias_bounds)]` on by default -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type Y where i32: Foo = (); -LL + type Y = (); - | warning: trait bound i32: Foo does not depend on any type or lifetime parameters --> $DIR/trivial-bounds-inconsistent.rs:22:19 diff --git a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs index 5ee3c027f40..52e0887175d 100644 --- a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs +++ b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs @@ -3,6 +3,6 @@ //@ check-pass pub type T = P; -//~^ WARN bounds on generic parameters are not enforced in type aliases +//~^ WARN bounds on generic parameters in type aliases are not enforced fn main() {} diff --git a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr index 125ffbbb417..9fd0fe4913b 100644 --- a/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr +++ b/tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr @@ -1,15 +1,16 @@ -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/issue-67690-type-alias-bound-diagnostic-crash.rs:5:15 | LL | pub type T = P; - | ^^^^ ^^^^ ^^^^ + | --^^^^---^^^^---^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics = note: `#[warn(type_alias_bounds)]` on by default -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - pub type T = P; -LL + pub type T

= P; - | warning: 1 warning emitted diff --git a/tests/ui/type/type-alias-bounds.rs b/tests/ui/type/type-alias-bounds.rs index 6d63c0c7e1b..37c073fe1f9 100644 --- a/tests/ui/type/type-alias-bounds.rs +++ b/tests/ui/type/type-alias-bounds.rs @@ -6,15 +6,15 @@ use std::rc::Rc; type SVec = Vec; -//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] +//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds] type S2Vec where T: Send = Vec; -//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] +//~^ WARN where clauses on type aliases are not enforced [type_alias_bounds] type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); -//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] +//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds] type WVec<'b, T: 'b + 'b> = (&'b u32, Vec); -//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] +//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds] type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); -//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] +//~^ WARN where clauses on type aliases are not enforced [type_alias_bounds] static STATIC: u32 = 0; @@ -42,10 +42,11 @@ fn foo<'a>(y: &'a i32) { struct Sendable(T); type MySendable = Sendable; // no error here! -// However, bounds *are* taken into account when accessing associated types +// Bounds on type params do enable shorthand type alias paths. +// However, that doesn't actually mean that they are properly enforced. trait Bound { type Assoc; } -type T1 = U::Assoc; //~ WARN not enforced in type aliases -type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases +type T1 = U::Assoc; //~ WARN are not enforced +type T2 where U: Bound = U::Assoc; //~ WARN are not enforced // This errors: // `type T3 = U::Assoc;` @@ -53,7 +54,7 @@ type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases type T4 = ::Assoc; // Make sure the help about associated types is not shown incorrectly -type T5 = ::Assoc; //~ WARN not enforced in type aliases -type T6 = ::std::vec::Vec; //~ WARN not enforced in type aliases +type T5 = ::Assoc; //~ WARN are not enforced +type T6 = ::std::vec::Vec; //~ WARN are not enforced fn main() {} diff --git a/tests/ui/type/type-alias-bounds.stderr b/tests/ui/type/type-alias-bounds.stderr index 92e573393c9..15c00901066 100644 --- a/tests/ui/type/type-alias-bounds.stderr +++ b/tests/ui/type/type-alias-bounds.stderr @@ -1,121 +1,132 @@ -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias-bounds.rs:8:14 | LL | type SVec = Vec; - | ^^^^ ^^^^ + | --^^^^---^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics = note: `#[warn(type_alias_bounds)]` on by default -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type SVec = Vec; -LL + type SVec = Vec; - | -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias-bounds.rs:10:21 | LL | type S2Vec where T: Send = Vec; - | ^^^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type S2Vec where T: Send = Vec; -LL + type S2Vec = Vec; + | ------^^^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias-bounds.rs:12:19 | LL | type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); - | ^^ ^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); -LL + type VVec<'b, 'a> = (&'b u32, Vec<&'a i32>); + | --^^---^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias-bounds.rs:14:18 | LL | type WVec<'b, T: 'b + 'b> = (&'b u32, Vec); - | ^^ ^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type WVec<'b, T: 'b + 'b> = (&'b u32, Vec); -LL + type WVec<'b, T> = (&'b u32, Vec); + | --^^---^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: where clauses are not enforced in type aliases +warning: where clauses on type aliases are not enforced --> $DIR/type-alias-bounds.rs:16:25 | LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); - | ^^^^^ ^^^^^ - | -help: the clause will not be checked when the type alias is used, and should be removed - | -LL - type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); -LL + type W2Vec<'b, T> = (&'b u32, Vec); + | ------^^^^^--^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this where clause | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:47:12 +warning: bounds on generic parameters in type aliases are not enforced + --> $DIR/type-alias-bounds.rs:48:12 | LL | type T1 = U::Assoc; - | ^^^^^ + | ^^^^^ will not be checked at usage sites of the type alias | -help: use fully disambiguated paths (i.e., `::Assoc`) to refer to associated types in type aliases - --> $DIR/type-alias-bounds.rs:47:21 - | -LL | type T1 = U::Assoc; - | ^^^^^^^^ -help: the bound will not be checked when the type alias is used, and should be removed + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics +help: remove this bound | LL - type T1 = U::Assoc; LL + type T1 = U::Assoc; | +help: fully qualify this associated type + | +LL | type T1 = ::Assoc; + | + +++++++++++++++ -warning: where clauses are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:48:18 +warning: where clauses on type aliases are not enforced + --> $DIR/type-alias-bounds.rs:49:18 | LL | type T2 where U: Bound = U::Assoc; - | ^^^^^^^^ + | ^^^^^^^^ will not be checked at usage sites of the type alias | -help: use fully disambiguated paths (i.e., `::Assoc`) to refer to associated types in type aliases - --> $DIR/type-alias-bounds.rs:48:29 - | -LL | type T2 where U: Bound = U::Assoc; - | ^^^^^^^^ -help: the clause will not be checked when the type alias is used, and should be removed + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics +help: remove this where clause | LL - type T2 where U: Bound = U::Assoc; LL + type T2 = U::Assoc; | +help: fully qualify this associated type + | +LL | type T2 where U: Bound = ::Assoc; + | + +++++++++++++++ -warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:56:12 - | -LL | type T5 = ::Assoc; - | ^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type T5 = ::Assoc; -LL + type T5 = ::Assoc; - | - -warning: bounds on generic parameters are not enforced in type aliases +warning: bounds on generic parameters in type aliases are not enforced --> $DIR/type-alias-bounds.rs:57:12 | +LL | type T5 = ::Assoc; + | --^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound + | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics + +warning: bounds on generic parameters in type aliases are not enforced + --> $DIR/type-alias-bounds.rs:58:12 + | LL | type T6 = ::std::vec::Vec; - | ^^^^^ - | -help: the bound will not be checked when the type alias is used, and should be removed - | -LL - type T6 = ::std::vec::Vec; -LL + type T6 = ::std::vec::Vec; + | --^^^^^ + | | | + | | will not be checked at usage sites of the type alias + | help: remove this bound | + = note: this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information + = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics warning: 9 warnings emitted