authorbors <bors@rust-lang.org> 2024-07-26 08:26:17 UTC
committerbors <bors@rust-lang.org> 2024-07-26 08:26:17 UTC
log83d67685acb520fe68d5d5adde4b25fb725490de
treec9d069da3bff063adb089082f8703c2c4c993d83
parent6ef11b81c2c02c3c4b7556d1991a98572fe9af87
parent97eade42f73f9ba081df3811e0ecfd2510e79aff

Auto merge of #128222 - tgross35:rollup-fk7qdo3, r=tgross35

Rollup of 7 pull requests Successful merges: - #126575 (Make it crystal clear what lint `type_alias_bounds` actually signifies) - #127017 (Extend rules of dead code analysis for impls for adts to impls for types refer to adts) - #127523 (Migrate `dump-ice-to-disk` and `panic-abort-eh_frame` `run-make` tests to rmake) - #127557 (Add a label to point to the lacking macro name definition) - #127989 (Migrate `interdependent-c-libraries`, `compiler-rt-works-on-mingw` and `incr-foreign-head-span` `run-make` tests to rmake) - #128099 (migrate tests/run-make/extern-flag-disambiguates to rmake) - #128170 (Make Clone::clone a lang item) r? `@ghost` `@rustbot` modify labels: rollup

59 files changed, 1205 insertions(+), 664 deletions(-)

compiler/rustc_hir/src/lang_items.rs+1
...@@ -162,6 +162,7 @@ language_item_table! {...@@ -162,6 +162,7 @@ language_item_table! {
162 StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None;162 StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None;
163 Copy, sym::copy, copy_trait, Target::Trait, GenericRequirement::Exact(0);163 Copy, sym::copy, copy_trait, Target::Trait, GenericRequirement::Exact(0);
164 Clone, sym::clone, clone_trait, Target::Trait, GenericRequirement::None;164 Clone, sym::clone, clone_trait, Target::Trait, GenericRequirement::None;
165 CloneFn, sym::clone_fn, clone_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
165 Sync, sym::sync, sync_trait, Target::Trait, GenericRequirement::Exact(0);166 Sync, sym::sync, sync_trait, Target::Trait, GenericRequirement::Exact(0);
166 DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, Target::Trait, GenericRequirement::None;167 DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, Target::Trait, GenericRequirement::None;
167 /// The associated item of the `DiscriminantKind` trait.168 /// The associated item of the `DiscriminantKind` trait.
compiler/rustc_hir_analysis/messages.ftl+9-4
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_name}` in bounds of `{$ty_param_name}`1hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_name}` in bounds of `{$qself}`
2 .label = ambiguous associated {$assoc_kind} `{$assoc_name}`2 .label = ambiguous associated {$assoc_kind} `{$assoc_name}`
33
4hir_analysis_ambiguous_lifetime_bound =4hir_analysis_ambiguous_lifetime_bound =
...@@ -12,16 +12,21 @@ hir_analysis_assoc_item_is_private = {$kind} `{$name}` is private...@@ -12,16 +12,21 @@ hir_analysis_assoc_item_is_private = {$kind} `{$name}` is private
12 .label = private {$kind}12 .label = private {$kind}
13 .defined_here_label = the {$kind} is defined here13 .defined_here_label = the {$kind} is defined here
1414
15hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$ty_param_name}`15hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$qself}`
1616
17hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named ->17hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named ->
18 [true] an18 [true] an
19 *[false] a similarly named19 *[false] a similarly named
20 } associated {$assoc_kind} `{$suggested_name}` in the trait `{$trait_name}`20 } associated {$assoc_kind} `{$suggested_name}` in the trait `{$trait_name}`
21hir_analysis_assoc_item_not_found_label = associated {$assoc_kind} `{$assoc_name}` not found21hir_analysis_assoc_item_not_found_label = associated {$assoc_kind} `{$assoc_name}` not found
22hir_analysis_assoc_item_not_found_other_sugg = `{$ty_param_name}` has the following associated {$assoc_kind}22hir_analysis_assoc_item_not_found_other_sugg = `{$qself}` has the following associated {$assoc_kind}
23hir_analysis_assoc_item_not_found_similar_in_other_trait_qpath_sugg =
24 consider fully qualifying{$identically_named ->
25 [true] {""}
26 *[false] {" "}and renaming
27 } the associated {$assoc_kind}
23hir_analysis_assoc_item_not_found_similar_in_other_trait_sugg = change the associated {$assoc_kind} name to use `{$suggested_name}` from `{$trait_name}`28hir_analysis_assoc_item_not_found_similar_in_other_trait_sugg = change the associated {$assoc_kind} name to use `{$suggested_name}` from `{$trait_name}`
24hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg = and also change the associated {$assoc_kind} name29hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg = ...and changing the associated {$assoc_kind} name
25hir_analysis_assoc_item_not_found_similar_sugg = there is an associated {$assoc_kind} with a similar name30hir_analysis_assoc_item_not_found_similar_sugg = there is an associated {$assoc_kind} with a similar name
2631
27hir_analysis_assoc_kind_mismatch = expected {$expected}, found {$got}32hir_analysis_assoc_kind_mismatch = expected {$expected}, found {$got}
compiler/rustc_hir_analysis/src/errors.rs+25-6
...@@ -22,7 +22,7 @@ pub struct AmbiguousAssocItem<'a> {...@@ -22,7 +22,7 @@ pub struct AmbiguousAssocItem<'a> {
22 pub span: Span,22 pub span: Span,
23 pub assoc_kind: &'static str,23 pub assoc_kind: &'static str,
24 pub assoc_name: Ident,24 pub assoc_name: Ident,
25 pub ty_param_name: &'a str,25 pub qself: &'a str,
26}26}
2727
28#[derive(Diagnostic)]28#[derive(Diagnostic)]
...@@ -75,7 +75,7 @@ pub struct AssocItemNotFound<'a> {...@@ -75,7 +75,7 @@ pub struct AssocItemNotFound<'a> {
75 pub span: Span,75 pub span: Span,
76 pub assoc_name: Ident,76 pub assoc_name: Ident,
77 pub assoc_kind: &'static str,77 pub assoc_kind: &'static str,
78 pub ty_param_name: &'a str,78 pub qself: &'a str,
79 #[subdiagnostic]79 #[subdiagnostic]
80 pub label: Option<AssocItemNotFoundLabel<'a>>,80 pub label: Option<AssocItemNotFoundLabel<'a>>,
81 #[subdiagnostic]81 #[subdiagnostic]
...@@ -126,13 +126,32 @@ pub enum AssocItemNotFoundSugg<'a> {...@@ -126,13 +126,32 @@ pub enum AssocItemNotFoundSugg<'a> {
126 assoc_kind: &'static str,126 assoc_kind: &'static str,
127 suggested_name: Symbol,127 suggested_name: Symbol,
128 },128 },
129 #[suggestion(hir_analysis_assoc_item_not_found_other_sugg, code = "{suggested_name}")]129 #[multipart_suggestion(
130 hir_analysis_assoc_item_not_found_similar_in_other_trait_qpath_sugg,
131 style = "verbose"
132 )]
133 SimilarInOtherTraitQPath {
134 #[suggestion_part(code = "<")]
135 lo: Span,
136 #[suggestion_part(code = " as {trait_ref}>")]
137 mi: Span,
138 #[suggestion_part(code = "{suggested_name}")]
139 hi: Option<Span>,
140 trait_ref: String,
141 suggested_name: Symbol,
142 identically_named: bool,
143 #[applicability]
144 applicability: Applicability,
145 },
146 #[suggestion(
147 hir_analysis_assoc_item_not_found_other_sugg,
148 code = "{suggested_name}",
149 applicability = "maybe-incorrect"
150 )]
130 Other {151 Other {
131 #[primary_span]152 #[primary_span]
132 span: Span,153 span: Span,
133 #[applicability]154 qself: &'a str,
134 applicability: Applicability,
135 ty_param_name: &'a str,
136 assoc_kind: &'static str,155 assoc_kind: &'static str,
137 suggested_name: Symbol,156 suggested_name: Symbol,
138 },157 },
compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs+3-6
...@@ -6,7 +6,6 @@ use rustc_hir as hir;...@@ -6,7 +6,6 @@ use rustc_hir as hir;
6use rustc_hir::def::{DefKind, Res};6use rustc_hir::def::{DefKind, Res};
7use rustc_hir::def_id::{DefId, LocalDefId};7use rustc_hir::def_id::{DefId, LocalDefId};
8use rustc_middle::bug;8use rustc_middle::bug;
9use rustc_middle::ty::print::PrintTraitRefExt as _;
10use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt};9use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt};
11use rustc_span::symbol::Ident;10use rustc_span::symbol::Ident;
12use rustc_span::{ErrorGuaranteed, Span, Symbol};11use rustc_span::{ErrorGuaranteed, Span, Symbol};
...@@ -16,9 +15,8 @@ use smallvec::SmallVec;...@@ -16,9 +15,8 @@ use smallvec::SmallVec;
1615
17use crate::bounds::Bounds;16use crate::bounds::Bounds;
18use crate::errors;17use crate::errors;
19use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};18use crate::hir_ty_lowering::HirTyLowerer;
2019use crate::hir_ty_lowering::{AssocItemQSelf, OnlySelfBounds, PredicateFilter, RegionInferReason};
21use super::RegionInferReason;
2220
23impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {21impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24 /// Add a `Sized` bound to the `bounds` if appropriate.22 /// Add a `Sized` bound to the `bounds` if appropriate.
...@@ -288,8 +286,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -288,8 +286,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
288 // one that does define it.286 // one that does define it.
289 self.probe_single_bound_for_assoc_item(287 self.probe_single_bound_for_assoc_item(
290 || traits::supertraits(tcx, trait_ref),288 || traits::supertraits(tcx, trait_ref),
291 trait_ref.skip_binder().print_only_trait_name(),289 AssocItemQSelf::Trait(trait_ref.def_id()),
292 None,
293 assoc_kind,290 assoc_kind,
294 constraint.ident,291 constraint.ident,
295 path_span,292 path_span,
compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs+78-49
...@@ -3,7 +3,7 @@ use crate::errors::{...@@ -3,7 +3,7 @@ use crate::errors::{
3 ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits,3 ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits,
4};4};
5use crate::fluent_generated as fluent;5use crate::fluent_generated as fluent;
6use crate::hir_ty_lowering::HirTyLowerer;6use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer};
7use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};7use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
8use rustc_data_structures::sorted_map::SortedMap;8use rustc_data_structures::sorted_map::SortedMap;
9use rustc_data_structures::unord::UnordMap;9use rustc_data_structures::unord::UnordMap;
...@@ -11,9 +11,9 @@ use rustc_errors::MultiSpan;...@@ -11,9 +11,9 @@ use rustc_errors::MultiSpan;
11use rustc_errors::{11use rustc_errors::{
12 codes::*, pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed,12 codes::*, pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed,
13};13};
14use rustc_hir as hir;
14use rustc_hir::def::{DefKind, Res};15use rustc_hir::def::{DefKind, Res};
15use rustc_hir::def_id::{DefId, LocalDefId};16use rustc_hir::def_id::DefId;
16use rustc_hir::{self as hir, Node};
17use rustc_middle::bug;17use rustc_middle::bug;
18use rustc_middle::query::Key;18use rustc_middle::query::Key;
19use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};19use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
...@@ -116,8 +116,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -116,8 +116,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
116 pub(super) fn complain_about_assoc_item_not_found<I>(116 pub(super) fn complain_about_assoc_item_not_found<I>(
117 &self,117 &self,
118 all_candidates: impl Fn() -> I,118 all_candidates: impl Fn() -> I,
119 ty_param_name: &str,119 qself: AssocItemQSelf,
120 ty_param_def_id: Option<LocalDefId>,
121 assoc_kind: ty::AssocKind,120 assoc_kind: ty::AssocKind,
122 assoc_name: Ident,121 assoc_name: Ident,
123 span: Span,122 span: Span,
...@@ -139,7 +138,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -139,7 +138,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
139 );138 );
140 }139 }
141140
142 let assoc_kind_str = super::assoc_kind_str(assoc_kind);141 let assoc_kind_str = assoc_kind_str(assoc_kind);
142 let qself_str = qself.to_string(tcx);
143143
144 // The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a144 // The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a
145 // valid span, so we point at the whole path segment instead.145 // valid span, so we point at the whole path segment instead.
...@@ -149,7 +149,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -149,7 +149,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
149 span: if is_dummy { span } else { assoc_name.span },149 span: if is_dummy { span } else { assoc_name.span },
150 assoc_name,150 assoc_name,
151 assoc_kind: assoc_kind_str,151 assoc_kind: assoc_kind_str,
152 ty_param_name,152 qself: &qself_str,
153 label: None,153 label: None,
154 sugg: None,154 sugg: None,
155 };155 };
...@@ -219,19 +219,28 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -219,19 +219,28 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
219 suggested_name,219 suggested_name,
220 identically_named: suggested_name == assoc_name.name,220 identically_named: suggested_name == assoc_name.name,
221 });221 });
222 let hir = tcx.hir();222 if let AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span) = qself
223 if let Some(def_id) = ty_param_def_id223 // Not using `self.item_def_id()` here as that would yield the opaque type itself if we're
224 && let parent = hir.get_parent_item(tcx.local_def_id_to_hir_id(def_id))224 // inside an opaque type while we're interested in the overarching type alias (TAIT).
225 && let Some(generics) = hir.get_generics(parent.def_id)225 // FIXME: However, for trait aliases, this incorrectly returns the enclosing module...
226 && let item_def_id =
227 tcx.hir().get_parent_item(tcx.local_def_id_to_hir_id(ty_param_def_id))
228 // FIXME: ...which obviously won't have any generics.
229 && let Some(generics) = tcx.hir().get_generics(item_def_id.def_id)
226 {230 {
227 if generics.bounds_for_param(def_id).flat_map(|pred| pred.bounds.iter()).any(231 // FIXME: Suggest adding supertrait bounds if we have a `Self` type param.
228 |b| match b {232 // FIXME(trait_alias): Suggest adding `Self: Trait` to
233 // `trait Alias = where Self::Proj:;` with `trait Trait { type Proj; }`.
234 if generics
235 .bounds_for_param(ty_param_def_id)
236 .flat_map(|pred| pred.bounds.iter())
237 .any(|b| match b {
229 hir::GenericBound::Trait(t, ..) => {238 hir::GenericBound::Trait(t, ..) => {
230 t.trait_ref.trait_def_id() == Some(best_trait)239 t.trait_ref.trait_def_id() == Some(best_trait)
231 }240 }
232 _ => false,241 _ => false,
233 },242 })
234 ) {243 {
235 // The type param already has a bound for `trait_name`, we just need to244 // The type param already has a bound for `trait_name`, we just need to
236 // change the associated item.245 // change the associated item.
237 err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTrait {246 err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTrait {
...@@ -242,48 +251,60 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -242,48 +251,60 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
242 return self.dcx().emit_err(err);251 return self.dcx().emit_err(err);
243 }252 }
244253
245 let mut err = self.dcx().create_err(err);254 let trait_args = &ty::GenericArgs::identity_for_item(tcx, best_trait)[1..];
246 if suggest_constraining_type_param(255 let mut trait_ref = trait_name.clone();
247 tcx,256 let applicability = if let [arg, args @ ..] = trait_args {
248 generics,257 use std::fmt::Write;
249 &mut err,258 write!(trait_ref, "</* {arg}").unwrap();
250 &ty_param_name,259 args.iter().try_for_each(|arg| write!(trait_ref, ", {arg}")).unwrap();
251 &trait_name,260 trait_ref += " */>";
252 None,261 Applicability::HasPlaceholders
253 None,262 } else {
254 ) && suggested_name != assoc_name.name263 Applicability::MaybeIncorrect
264 };
265
266 let identically_named = suggested_name == assoc_name.name;
267
268 if let DefKind::TyAlias = tcx.def_kind(item_def_id)
269 && !tcx.type_alias_is_lazy(item_def_id)
255 {270 {
256 // We suggested constraining a type parameter, but the associated item on it271 err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTraitQPath {
257 // was also not an exact match, so we also suggest changing it.272 lo: ty_param_span.shrink_to_lo(),
258 err.span_suggestion_verbose(273 mi: ty_param_span.shrink_to_hi(),
259 assoc_name.span,274 hi: (!identically_named).then_some(assoc_name.span),
260 fluent::hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg,275 trait_ref,
276 identically_named,
261 suggested_name,277 suggested_name,
262 Applicability::MaybeIncorrect,278 applicability,
263 );279 });
280 } else {
281 let mut err = self.dcx().create_err(err);
282 if suggest_constraining_type_param(
283 tcx, generics, &mut err, &qself_str, &trait_ref, None, None,
284 ) && !identically_named
285 {
286 // We suggested constraining a type parameter, but the associated item on it
287 // was also not an exact match, so we also suggest changing it.
288 err.span_suggestion_verbose(
289 assoc_name.span,
290 fluent::hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg,
291 suggested_name,
292 Applicability::MaybeIncorrect,
293 );
294 }
295 return err.emit();
264 }296 }
265 return err.emit();
266 }297 }
267 return self.dcx().emit_err(err);298 return self.dcx().emit_err(err);
268 }299 }
269 }300 }
270301
271 // If we still couldn't find any associated item, and only one associated item exists,302 // If we still couldn't find any associated item, and only one associated item exists,
272 // suggests using it.303 // suggest using it.
273 if let [candidate_name] = all_candidate_names.as_slice() {304 if let [candidate_name] = all_candidate_names.as_slice() {
274 // This should still compile, except on `#![feature(associated_type_defaults)]`
275 // where it could suggests `type A = Self::A`, thus recursing infinitely.
276 let applicability =
277 if assoc_kind == ty::AssocKind::Type && tcx.features().associated_type_defaults {
278 Applicability::Unspecified
279 } else {
280 Applicability::MaybeIncorrect
281 };
282
283 err.sugg = Some(errors::AssocItemNotFoundSugg::Other {305 err.sugg = Some(errors::AssocItemNotFoundSugg::Other {
284 span: assoc_name.span,306 span: assoc_name.span,
285 applicability,307 qself: &qself_str,
286 ty_param_name,
287 assoc_kind: assoc_kind_str,308 assoc_kind: assoc_kind_str,
288 suggested_name: *candidate_name,309 suggested_name: *candidate_name,
289 });310 });
...@@ -349,10 +370,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -349,10 +370,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
349370
350 self.dcx().emit_err(errors::AssocKindMismatch {371 self.dcx().emit_err(errors::AssocKindMismatch {
351 span,372 span,
352 expected: super::assoc_kind_str(expected),373 expected: assoc_kind_str(expected),
353 got: super::assoc_kind_str(got),374 got: assoc_kind_str(got),
354 expected_because_label,375 expected_because_label,
355 assoc_kind: super::assoc_kind_str(assoc_item.kind),376 assoc_kind: assoc_kind_str(assoc_item.kind),
356 def_span: tcx.def_span(assoc_item.def_id),377 def_span: tcx.def_span(assoc_item.def_id),
357 bound_on_assoc_const_label,378 bound_on_assoc_const_label,
358 wrap_in_braces_sugg,379 wrap_in_braces_sugg,
...@@ -746,7 +767,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -746,7 +767,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
746 if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) {767 if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) {
747 let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id));768 let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id));
748 in_expr_or_pat = match grandparent {769 in_expr_or_pat = match grandparent {
749 Node::Expr(_) | Node::Pat(_) => true,770 hir::Node::Expr(_) | hir::Node::Pat(_) => true,
750 _ => false,771 _ => false,
751 };772 };
752 match bound.trait_ref.path.segments {773 match bound.trait_ref.path.segments {
...@@ -1612,3 +1633,11 @@ fn generics_args_err_extend<'a>(...@@ -1612,3 +1633,11 @@ fn generics_args_err_extend<'a>(
1612 _ => {}1633 _ => {}
1613 }1634 }
1614}1635}
1636
1637pub(super) fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
1638 match kind {
1639 ty::AssocKind::Fn => "function",
1640 ty::AssocKind::Const => "constant",
1641 ty::AssocKind::Type => "type",
1642 }
1643}
compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs+41-36
...@@ -55,7 +55,6 @@ use rustc_trait_selection::infer::InferCtxtExt;...@@ -55,7 +55,6 @@ use rustc_trait_selection::infer::InferCtxtExt;
55use rustc_trait_selection::traits::wf::object_region_bounds;55use rustc_trait_selection::traits::wf::object_region_bounds;
56use rustc_trait_selection::traits::{self, ObligationCtxt};56use rustc_trait_selection::traits::{self, ObligationCtxt};
5757
58use std::fmt::Display;
59use std::slice;58use std::slice;
6059
61/// A path segment that is semantically allowed to have generic arguments.60/// A path segment that is semantically allowed to have generic arguments.
...@@ -193,6 +192,25 @@ pub trait HirTyLowerer<'tcx> {...@@ -193,6 +192,25 @@ pub trait HirTyLowerer<'tcx> {
193 }192 }
194}193}
195194
195/// The "qualified self" of an associated item path.
196///
197/// For diagnostic purposes only.
198enum AssocItemQSelf {
199 Trait(DefId),
200 TyParam(LocalDefId, Span),
201 SelfTyAlias,
202}
203
204impl AssocItemQSelf {
205 fn to_string(&self, tcx: TyCtxt<'_>) -> String {
206 match *self {
207 Self::Trait(def_id) => tcx.def_path_str(def_id),
208 Self::TyParam(def_id, _) => tcx.hir().ty_param_name(def_id).to_string(),
209 Self::SelfTyAlias => kw::SelfUpper.to_string(),
210 }
211 }
212}
213
196/// New-typed boolean indicating whether explicit late-bound lifetimes214/// New-typed boolean indicating whether explicit late-bound lifetimes
197/// are present in a set of generic arguments.215/// are present in a set of generic arguments.
198///216///
...@@ -802,6 +820,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -802,6 +820,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
802 fn probe_single_ty_param_bound_for_assoc_ty(820 fn probe_single_ty_param_bound_for_assoc_ty(
803 &self,821 &self,
804 ty_param_def_id: LocalDefId,822 ty_param_def_id: LocalDefId,
823 ty_param_span: Span,
805 assoc_name: Ident,824 assoc_name: Ident,
806 span: Span,825 span: Span,
807 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {826 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
...@@ -811,19 +830,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -811,19 +830,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
811 let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_name).predicates;830 let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_name).predicates;
812 debug!("predicates={:#?}", predicates);831 debug!("predicates={:#?}", predicates);
813832
814 let param_name = tcx.hir().ty_param_name(ty_param_def_id);
815 self.probe_single_bound_for_assoc_item(833 self.probe_single_bound_for_assoc_item(
816 || {834 || {
817 traits::transitive_bounds_that_define_assoc_item(835 let trait_refs = predicates
818 tcx,836 .iter()
819 predicates837 .filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
820 .iter()838 traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_name)
821 .filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref))),
822 assoc_name,
823 )
824 },839 },
825 param_name,840 AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
826 Some(ty_param_def_id),
827 ty::AssocKind::Type,841 ty::AssocKind::Type,
828 assoc_name,842 assoc_name,
829 span,843 span,
...@@ -835,12 +849,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -835,12 +849,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
835 ///849 ///
836 /// This fails if there is no such bound in the list of candidates or if there are multiple850 /// This fails if there is no such bound in the list of candidates or if there are multiple
837 /// candidates in which case it reports ambiguity.851 /// candidates in which case it reports ambiguity.
838 #[instrument(level = "debug", skip(self, all_candidates, ty_param_name, constraint), ret)]852 #[instrument(level = "debug", skip(self, all_candidates, qself, constraint), ret)]
839 fn probe_single_bound_for_assoc_item<I>(853 fn probe_single_bound_for_assoc_item<I>(
840 &self,854 &self,
841 all_candidates: impl Fn() -> I,855 all_candidates: impl Fn() -> I,
842 ty_param_name: impl Display,856 qself: AssocItemQSelf,
843 ty_param_def_id: Option<LocalDefId>,
844 assoc_kind: ty::AssocKind,857 assoc_kind: ty::AssocKind,
845 assoc_name: Ident,858 assoc_name: Ident,
846 span: Span,859 span: Span,
...@@ -858,8 +871,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -858,8 +871,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
858 let Some(bound) = matching_candidates.next() else {871 let Some(bound) = matching_candidates.next() else {
859 let reported = self.complain_about_assoc_item_not_found(872 let reported = self.complain_about_assoc_item_not_found(
860 all_candidates,873 all_candidates,
861 &ty_param_name.to_string(),874 qself,
862 ty_param_def_id,
863 assoc_kind,875 assoc_kind,
864 assoc_name,876 assoc_name,
865 span,877 span,
...@@ -872,13 +884,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -872,13 +884,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
872 if let Some(bound2) = matching_candidates.next() {884 if let Some(bound2) = matching_candidates.next() {
873 debug!(?bound2);885 debug!(?bound2);
874886
875 let assoc_kind_str = assoc_kind_str(assoc_kind);887 let assoc_kind_str = errors::assoc_kind_str(assoc_kind);
876 let ty_param_name = &ty_param_name.to_string();888 let qself_str = qself.to_string(tcx);
877 let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {889 let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
878 span,890 span,
879 assoc_kind: assoc_kind_str,891 assoc_kind: assoc_kind_str,
880 assoc_name,892 assoc_name,
881 ty_param_name,893 qself: &qself_str,
882 });894 });
883 // Provide a more specific error code index entry for equality bindings.895 // Provide a more specific error code index entry for equality bindings.
884 err.code(896 err.code(
...@@ -929,7 +941,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -929,7 +941,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
929 err.span_suggestion_verbose(941 err.span_suggestion_verbose(
930 span.with_hi(assoc_name.span.lo()),942 span.with_hi(assoc_name.span.lo()),
931 "use fully-qualified syntax to disambiguate",943 "use fully-qualified syntax to disambiguate",
932 format!("<{ty_param_name} as {}>::", bound.print_only_trait_path()),944 format!("<{qself_str} as {}>::", bound.print_only_trait_path()),
933 Applicability::MaybeIncorrect,945 Applicability::MaybeIncorrect,
934 );946 );
935 }947 }
...@@ -943,7 +955,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -943,7 +955,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
943 if !where_bounds.is_empty() {955 if !where_bounds.is_empty() {
944 err.help(format!(956 err.help(format!(
945 "consider introducing a new type parameter `T` and adding `where` constraints:\957 "consider introducing a new type parameter `T` and adding `where` constraints:\
946 \n where\n T: {ty_param_name},\n{}",958 \n where\n T: {qself_str},\n{}",
947 where_bounds.join(",\n"),959 where_bounds.join(",\n"),
948 ));960 ));
949 }961 }
...@@ -997,11 +1009,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -997,11 +1009,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
997 let tcx = self.tcx();1009 let tcx = self.tcx();
9981010
999 let assoc_ident = assoc_segment.ident;1011 let assoc_ident = assoc_segment.ident;
1000 let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
1001 path.res
1002 } else {
1003 Res::Err
1004 };
10051012
1006 // Check if we have an enum variant or an inherent associated type.1013 // Check if we have an enum variant or an inherent associated type.
1007 let mut variant_resolution = None;1014 let mut variant_resolution = None;
...@@ -1038,6 +1045,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -1038,6 +1045,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1038 }1045 }
1039 }1046 }
10401047
1048 let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
1049 path.res
1050 } else {
1051 Res::Err
1052 };
1053
1041 // Find the type of the associated item, and the trait where the associated1054 // Find the type of the associated item, and the trait where the associated
1042 // item is declared.1055 // item is declared.
1043 let bound = match (&qself_ty.kind(), qself_res) {1056 let bound = match (&qself_ty.kind(), qself_res) {
...@@ -1056,8 +1069,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -1056,8 +1069,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1056 ty::Binder::dummy(trait_ref.instantiate_identity()),1069 ty::Binder::dummy(trait_ref.instantiate_identity()),
1057 )1070 )
1058 },1071 },
1059 kw::SelfUpper,1072 AssocItemQSelf::SelfTyAlias,
1060 None,
1061 ty::AssocKind::Type,1073 ty::AssocKind::Type,
1062 assoc_ident,1074 assoc_ident,
1063 span,1075 span,
...@@ -1069,6 +1081,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -1069,6 +1081,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1069 Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),1081 Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
1070 ) => self.probe_single_ty_param_bound_for_assoc_ty(1082 ) => self.probe_single_ty_param_bound_for_assoc_ty(
1071 param_did.expect_local(),1083 param_did.expect_local(),
1084 qself.span,
1072 assoc_ident,1085 assoc_ident,
1073 span,1086 span,
1074 )?,1087 )?,
...@@ -2522,11 +2535,3 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {...@@ -2522,11 +2535,3 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
2522 Some(r)2535 Some(r)
2523 }2536 }
2524}2537}
2525
2526fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
2527 match kind {
2528 ty::AssocKind::Fn => "function",
2529 ty::AssocKind::Const => "constant",
2530 ty::AssocKind::Type => "type",
2531 }
2532}
compiler/rustc_lint/messages.ftl+12-7
...@@ -144,13 +144,18 @@ lint_builtin_special_module_name_used_main = found module declaration for main.r...@@ -144,13 +144,18 @@ lint_builtin_special_module_name_used_main = found module declaration for main.r
144144
145lint_builtin_trivial_bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters145lint_builtin_trivial_bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters
146146
147lint_builtin_type_alias_bounds_help = use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases147lint_builtin_type_alias_bounds_enable_feat_help = add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
148148lint_builtin_type_alias_bounds_label = will not be checked at usage sites of the type alias
149lint_builtin_type_alias_generic_bounds = bounds on generic parameters are not enforced in type aliases149lint_builtin_type_alias_bounds_limitation_note = this is a known limitation of the type checker that may be lifted in a future edition.
150 .suggestion = the bound will not be checked when the type alias is used, and should be removed150 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
151151lint_builtin_type_alias_bounds_param_bounds = bounds on generic parameters in type aliases are not enforced
152lint_builtin_type_alias_where_clause = where clauses are not enforced in type aliases152 .suggestion = remove {$count ->
153 .suggestion = the clause will not be checked when the type alias is used, and should be removed153 [one] this bound
154 *[other] these bounds
155 }
156lint_builtin_type_alias_bounds_qualify_assoc_tys_sugg = fully qualify this associated type
157lint_builtin_type_alias_bounds_where_clause = where clauses on type aliases are not enforced
158 .suggestion = remove this where clause
154159
155lint_builtin_unpermitted_type_init_label = this code causes undefined behavior when executed160lint_builtin_unpermitted_type_init_label = this code causes undefined behavior when executed
156lint_builtin_unpermitted_type_init_label_suggestion = help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done161lint_builtin_unpermitted_type_init_label_suggestion = help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
compiler/rustc_lint/src/builtin.rs+87-52
...@@ -31,12 +31,11 @@ use crate::{...@@ -31,12 +31,11 @@ use crate::{
31 BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents,31 BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents,
32 BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc,32 BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc,
33 BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns,33 BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns,
34 BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasGenericBounds,34 BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasBounds,
35 BuiltinTypeAliasGenericBoundsSuggestion, BuiltinTypeAliasWhereClause,
36 BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit,35 BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit,
37 BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe,36 BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe,
38 BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub,37 BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub,
39 BuiltinWhileTrue, InvalidAsmLabel, SuggestChangingAssocTypes,38 BuiltinWhileTrue, InvalidAsmLabel,
40 },39 },
41 EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext,40 EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext,
42};41};
...@@ -1391,64 +1390,80 @@ declare_lint! {...@@ -1391,64 +1390,80 @@ declare_lint! {
1391 ///1390 ///
1392 /// ### Explanation1391 /// ### Explanation
1393 ///1392 ///
1394 /// The trait bounds in a type alias are currently ignored, and should not1393 /// Trait and lifetime bounds on generic parameters and in where clauses of
1395 /// be included to avoid confusion. This was previously allowed1394 /// type aliases are not checked at usage sites of the type alias. Moreover,
1396 /// unintentionally; this may become a hard error in the future.1395 /// they are not thoroughly checked for correctness at their definition site
1396 /// either similar to the aliased type.
1397 ///
1398 /// This is a known limitation of the type checker that may be lifted in a
1399 /// future edition. Permitting such bounds in light of this was unintentional.
1400 ///
1401 /// While these bounds may have secondary effects such as enabling the use of
1402 /// "shorthand" associated type paths[^1] and affecting the default trait
1403 /// object lifetime[^2] of trait object types passed to the type alias, this
1404 /// should not have been allowed until the aforementioned restrictions of the
1405 /// type checker have been lifted.
1406 ///
1407 /// Using such bounds is highly discouraged as they are actively misleading.
1408 ///
1409 /// [^1]: I.e., paths of the form `T::Assoc` where `T` is a type parameter
1410 /// bounded by trait `Trait` which defines an associated type called `Assoc`
1411 /// as opposed to a fully qualified path of the form `<T as Trait>::Assoc`.
1412 /// [^2]: <https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes>
1397 TYPE_ALIAS_BOUNDS,1413 TYPE_ALIAS_BOUNDS,
1398 Warn,1414 Warn,
1399 "bounds in type aliases are not enforced"1415 "bounds in type aliases are not enforced"
1400}1416}
14011417
1402declare_lint_pass!(1418declare_lint_pass!(TypeAliasBounds => [TYPE_ALIAS_BOUNDS]);
1403 /// Lint for trait and lifetime bounds in type aliases being mostly ignored.
1404 /// They are relevant when using associated types, but otherwise neither checked
1405 /// at definition site nor enforced at use site.
1406 TypeAliasBounds => [TYPE_ALIAS_BOUNDS]
1407);
14081419
1409impl TypeAliasBounds {1420impl TypeAliasBounds {
1410 pub(crate) fn is_type_variable_assoc(qpath: &hir::QPath<'_>) -> bool {1421 pub(crate) fn affects_object_lifetime_defaults(pred: &hir::WherePredicate<'_>) -> bool {
1411 match *qpath {1422 // Bounds of the form `T: 'a` with `T` type param affect object lifetime defaults.
1412 hir::QPath::TypeRelative(ty, _) => {1423 if let hir::WherePredicate::BoundPredicate(pred) = pred
1413 // If this is a type variable, we found a `T::Assoc`.1424 && pred.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Outlives(_)))
1414 match ty.kind {1425 && pred.bound_generic_params.is_empty() // indeed, even if absent from the RHS
1415 hir::TyKind::Path(hir::QPath::Resolved(None, path)) => {1426 && pred.bounded_ty.as_generic_param().is_some()
1416 matches!(path.res, Res::Def(DefKind::TyParam, _))1427 {
1417 }1428 return true;
1418 _ => false,
1419 }
1420 }
1421 hir::QPath::Resolved(..) | hir::QPath::LangItem(..) => false,
1422 }1429 }
1430 false
1423 }1431 }
1424}1432}
14251433
1426impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {1434impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
1427 fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {1435 fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
1428 let hir::ItemKind::TyAlias(hir_ty, type_alias_generics) = &item.kind else { return };1436 let hir::ItemKind::TyAlias(hir_ty, generics) = item.kind else { return };
14291437
1430 // Bounds of lazy type aliases and TAITs are respected.1438 // There must not be a where clause.
1431 if cx.tcx.type_alias_is_lazy(item.owner_id) {1439 if generics.predicates.is_empty() {
1432 return;1440 return;
1433 }1441 }
14341442
1435 let ty = cx.tcx.type_of(item.owner_id).skip_binder();1443 // Bounds of lazy type aliases and TAITs are respected.
1436 if ty.has_inherent_projections() {1444 if cx.tcx.type_alias_is_lazy(item.owner_id) {
1437 // Bounds of type aliases that contain opaque types or inherent projections are
1438 // respected. E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`, `type X =
1439 // Type::Inherent;`.
1440 return;1445 return;
1441 }1446 }
14421447
1443 // There must not be a where clause1448 // FIXME(generic_const_exprs): Revisit this before stabilization.
1444 if type_alias_generics.predicates.is_empty() {1449 // See also `tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs`.
1450 let ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
1451 if ty.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION)
1452 && cx.tcx.features().generic_const_exprs
1453 {
1445 return;1454 return;
1446 }1455 }
14471456
1457 // NOTE(inherent_associated_types): While we currently do take some bounds in type
1458 // aliases into consideration during IAT *selection*, we don't perform full use+def
1459 // site wfchecking for such type aliases. Therefore TAB should still trigger.
1460 // See also `tests/ui/associated-inherent-types/type-alias-bounds.rs`.
1461
1448 let mut where_spans = Vec::new();1462 let mut where_spans = Vec::new();
1449 let mut inline_spans = Vec::new();1463 let mut inline_spans = Vec::new();
1450 let mut inline_sugg = Vec::new();1464 let mut inline_sugg = Vec::new();
1451 for p in type_alias_generics.predicates {1465
1466 for p in generics.predicates {
1452 let span = p.span();1467 let span = p.span();
1453 if p.in_where_clause() {1468 if p.in_where_clause() {
1454 where_spans.push(span);1469 where_spans.push(span);
...@@ -1460,37 +1475,57 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {...@@ -1460,37 +1475,57 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
1460 }1475 }
1461 }1476 }
14621477
1463 let mut suggested_changing_assoc_types = false;1478 let mut ty = Some(hir_ty);
1464 if !where_spans.is_empty() {1479 let enable_feat_help = cx.tcx.sess.is_nightly_build();
1465 let sub = (!suggested_changing_assoc_types).then(|| {1480
1466 suggested_changing_assoc_types = true;1481 if let [.., label_sp] = *where_spans {
1467 SuggestChangingAssocTypes { ty: hir_ty }
1468 });
1469 cx.emit_span_lint(1482 cx.emit_span_lint(
1470 TYPE_ALIAS_BOUNDS,1483 TYPE_ALIAS_BOUNDS,
1471 where_spans,1484 where_spans,
1472 BuiltinTypeAliasWhereClause {1485 BuiltinTypeAliasBounds {
1473 suggestion: type_alias_generics.where_clause_span,1486 in_where_clause: true,
1474 sub,1487 label: label_sp,
1488 enable_feat_help,
1489 suggestions: vec![(generics.where_clause_span, String::new())],
1490 preds: generics.predicates,
1491 ty: ty.take(),
1475 },1492 },
1476 );1493 );
1477 }1494 }
14781495 if let [.., label_sp] = *inline_spans {
1479 if !inline_spans.is_empty() {
1480 let suggestion = BuiltinTypeAliasGenericBoundsSuggestion { suggestions: inline_sugg };
1481 let sub = (!suggested_changing_assoc_types).then(|| {
1482 suggested_changing_assoc_types = true;
1483 SuggestChangingAssocTypes { ty: hir_ty }
1484 });
1485 cx.emit_span_lint(1496 cx.emit_span_lint(
1486 TYPE_ALIAS_BOUNDS,1497 TYPE_ALIAS_BOUNDS,
1487 inline_spans,1498 inline_spans,
1488 BuiltinTypeAliasGenericBounds { suggestion, sub },1499 BuiltinTypeAliasBounds {
1500 in_where_clause: false,
1501 label: label_sp,
1502 enable_feat_help,
1503 suggestions: inline_sugg,
1504 preds: generics.predicates,
1505 ty,
1506 },
1489 );1507 );
1490 }1508 }
1491 }1509 }
1492}1510}
14931511
1512pub(crate) struct ShorthandAssocTyCollector {
1513 pub(crate) qselves: Vec<Span>,
1514}
1515
1516impl hir::intravisit::Visitor<'_> for ShorthandAssocTyCollector {
1517 fn visit_qpath(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, _: Span) {
1518 // Look for "type-parameter shorthand-associated-types". I.e., paths of the
1519 // form `T::Assoc` with `T` type param. These are reliant on trait bounds.
1520 if let hir::QPath::TypeRelative(qself, _) = qpath
1521 && qself.as_generic_param().is_some()
1522 {
1523 self.qselves.push(qself.span);
1524 }
1525 hir::intravisit::walk_qpath(self, qpath, id)
1526 }
1527}
1528
1494declare_lint! {1529declare_lint! {
1495 /// The `trivial_bounds` lint detects trait bounds that don't depend on1530 /// The `trivial_bounds` lint detects trait bounds that don't depend on
1496 /// any type parameters.1531 /// any type parameters.
compiler/rustc_lint/src/lints.rs+67-74
...@@ -2,14 +2,16 @@...@@ -2,14 +2,16 @@
2#![allow(rustc::untranslatable_diagnostic)]2#![allow(rustc::untranslatable_diagnostic)]
3use std::num::NonZero;3use std::num::NonZero;
44
5use crate::errors::RequestedLevel;5use crate::builtin::{InitError, ShorthandAssocTyCollector, TypeAliasBounds};
6use crate::errors::{OverruledAttributeSub, RequestedLevel};
6use crate::fluent_generated as fluent;7use crate::fluent_generated as fluent;
8use crate::LateContext;
7use rustc_errors::{9use rustc_errors::{
8 codes::*, Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString,10 codes::*, Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString,
9 ElidedLifetimeInPathSubdiag, EmissionGuarantee, LintDiagnostic, MultiSpan, SubdiagMessageOp,11 ElidedLifetimeInPathSubdiag, EmissionGuarantee, LintDiagnostic, MultiSpan, SubdiagMessageOp,
10 Subdiagnostic, SuggestionStyle,12 Subdiagnostic, SuggestionStyle,
11};13};
12use rustc_hir::{def::Namespace, def_id::DefId};14use rustc_hir::{self as hir, def::Namespace, def_id::DefId};
13use rustc_macros::{LintDiagnostic, Subdiagnostic};15use rustc_macros::{LintDiagnostic, Subdiagnostic};
14use rustc_middle::ty::{16use rustc_middle::ty::{
15 inhabitedness::InhabitedPredicate, Clause, PolyExistentialTraitRef, Ty, TyCtxt,17 inhabitedness::InhabitedPredicate, Clause, PolyExistentialTraitRef, Ty, TyCtxt,
...@@ -22,10 +24,6 @@ use rustc_span::{...@@ -22,10 +24,6 @@ use rustc_span::{
22 Span, Symbol,24 Span, Symbol,
23};25};
2426
25use crate::{
26 builtin::InitError, builtin::TypeAliasBounds, errors::OverruledAttributeSub, LateContext,
27};
28
29// array_into_iter.rs27// array_into_iter.rs
30#[derive(LintDiagnostic)]28#[derive(LintDiagnostic)]
31#[diag(lint_shadowed_into_iter)]29#[diag(lint_shadowed_into_iter)]
...@@ -263,62 +261,6 @@ pub struct BuiltinUnreachablePub<'a> {...@@ -263,62 +261,6 @@ pub struct BuiltinUnreachablePub<'a> {
263 pub help: Option<()>,261 pub help: Option<()>,
264}262}
265263
266pub struct SuggestChangingAssocTypes<'a, 'b> {
267 pub ty: &'a rustc_hir::Ty<'b>,
268}
269
270impl<'a, 'b> Subdiagnostic for SuggestChangingAssocTypes<'a, 'b> {
271 fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
272 self,
273 diag: &mut Diag<'_, G>,
274 _f: &F,
275 ) {
276 // Access to associates types should use `<T as Bound>::Assoc`, which does not need a
277 // bound. Let's see if this type does that.
278
279 // We use a HIR visitor to walk the type.
280 use rustc_hir::intravisit::{self, Visitor};
281 struct WalkAssocTypes<'a, 'b, G: EmissionGuarantee> {
282 err: &'a mut Diag<'b, G>,
283 }
284 impl<'a, 'b, G: EmissionGuarantee> Visitor<'_> for WalkAssocTypes<'a, 'b, G> {
285 fn visit_qpath(
286 &mut self,
287 qpath: &rustc_hir::QPath<'_>,
288 id: rustc_hir::HirId,
289 span: Span,
290 ) {
291 if TypeAliasBounds::is_type_variable_assoc(qpath) {
292 self.err.span_help(span, fluent::lint_builtin_type_alias_bounds_help);
293 }
294 intravisit::walk_qpath(self, qpath, id)
295 }
296 }
297
298 // Let's go for a walk!
299 let mut visitor = WalkAssocTypes { err: diag };
300 visitor.visit_ty(self.ty);
301 }
302}
303
304#[derive(LintDiagnostic)]
305#[diag(lint_builtin_type_alias_where_clause)]
306pub struct BuiltinTypeAliasWhereClause<'a, 'b> {
307 #[suggestion(code = "", applicability = "machine-applicable")]
308 pub suggestion: Span,
309 #[subdiagnostic]
310 pub sub: Option<SuggestChangingAssocTypes<'a, 'b>>,
311}
312
313#[derive(LintDiagnostic)]
314#[diag(lint_builtin_type_alias_generic_bounds)]
315pub struct BuiltinTypeAliasGenericBounds<'a, 'b> {
316 #[subdiagnostic]
317 pub suggestion: BuiltinTypeAliasGenericBoundsSuggestion,
318 #[subdiagnostic]
319 pub sub: Option<SuggestChangingAssocTypes<'a, 'b>>,
320}
321
322#[derive(LintDiagnostic)]264#[derive(LintDiagnostic)]
323#[diag(lint_macro_expr_fragment_specifier_2024_migration)]265#[diag(lint_macro_expr_fragment_specifier_2024_migration)]
324pub struct MacroExprFragment2024 {266pub struct MacroExprFragment2024 {
...@@ -326,21 +268,72 @@ pub struct MacroExprFragment2024 {...@@ -326,21 +268,72 @@ pub struct MacroExprFragment2024 {
326 pub suggestion: Span,268 pub suggestion: Span,
327}269}
328270
329pub struct BuiltinTypeAliasGenericBoundsSuggestion {271pub struct BuiltinTypeAliasBounds<'a, 'hir> {
272 pub in_where_clause: bool,
273 pub label: Span,
274 pub enable_feat_help: bool,
330 pub suggestions: Vec<(Span, String)>,275 pub suggestions: Vec<(Span, String)>,
276 pub preds: &'hir [hir::WherePredicate<'hir>],
277 pub ty: Option<&'a hir::Ty<'hir>>,
331}278}
332279
333impl Subdiagnostic for BuiltinTypeAliasGenericBoundsSuggestion {280impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_, '_> {
334 fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(281 fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
335 self,282 diag.primary_message(if self.in_where_clause {
336 diag: &mut Diag<'_, G>,283 fluent::lint_builtin_type_alias_bounds_where_clause
337 _f: &F,284 } else {
338 ) {285 fluent::lint_builtin_type_alias_bounds_param_bounds
339 diag.multipart_suggestion(286 });
340 fluent::lint_suggestion,287 diag.span_label(self.label, fluent::lint_builtin_type_alias_bounds_label);
341 self.suggestions,288 diag.note(fluent::lint_builtin_type_alias_bounds_limitation_note);
342 Applicability::MachineApplicable,289 if self.enable_feat_help {
343 );290 diag.help(fluent::lint_builtin_type_alias_bounds_enable_feat_help);
291 }
292
293 // We perform the walk in here instead of in `<TypeAliasBounds as LateLintPass>` to
294 // avoid doing throwaway work in case the lint ends up getting suppressed.
295 let mut collector = ShorthandAssocTyCollector { qselves: Vec::new() };
296 if let Some(ty) = self.ty {
297 hir::intravisit::Visitor::visit_ty(&mut collector, ty);
298 }
299
300 let affect_object_lifetime_defaults = self
301 .preds
302 .iter()
303 .filter(|pred| pred.in_where_clause() == self.in_where_clause)
304 .any(|pred| TypeAliasBounds::affects_object_lifetime_defaults(pred));
305
306 // If there are any shorthand assoc tys, then the bounds can't be removed automatically.
307 // The user first needs to fully qualify the assoc tys.
308 let applicability = if !collector.qselves.is_empty() || affect_object_lifetime_defaults {
309 Applicability::MaybeIncorrect
310 } else {
311 Applicability::MachineApplicable
312 };
313
314 diag.arg("count", self.suggestions.len());
315 diag.multipart_suggestion(fluent::lint_suggestion, self.suggestions, applicability);
316
317 // Suggest fully qualifying paths of the form `T::Assoc` with `T` type param via
318 // `<T as /* Trait */>::Assoc` to remove their reliance on any type param bounds.
319 //
320 // Instead of attempting to figure out the necessary trait ref, just use a
321 // placeholder. Since we don't record type-dependent resolutions for non-body
322 // items like type aliases, we can't simply deduce the corresp. trait from
323 // the HIR path alone without rerunning parts of HIR ty lowering here
324 // (namely `probe_single_ty_param_bound_for_assoc_ty`) which is infeasible.
325 //
326 // (We could employ some simple heuristics but that's likely not worth it).
327 for qself in collector.qselves {
328 diag.multipart_suggestion(
329 fluent::lint_builtin_type_alias_bounds_qualify_assoc_tys_sugg,
330 vec![
331 (qself.shrink_to_lo(), "<".into()),
332 (qself.shrink_to_hi(), " as /* Trait */>".into()),
333 ],
334 Applicability::HasPlaceholders,
335 );
336 }
344 }337 }
345}338}
346339
compiler/rustc_mir_transform/src/instsimplify.rs+2-2
...@@ -3,6 +3,7 @@...@@ -3,6 +3,7 @@
3use crate::simplify::simplify_duplicate_switch_targets;3use crate::simplify::simplify_duplicate_switch_targets;
4use crate::take_array;4use crate::take_array;
5use rustc_ast::attr;5use rustc_ast::attr;
6use rustc_hir::LangItem;
6use rustc_middle::bug;7use rustc_middle::bug;
7use rustc_middle::mir::*;8use rustc_middle::mir::*;
8use rustc_middle::ty::layout;9use rustc_middle::ty::layout;
...@@ -271,8 +272,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {...@@ -271,8 +272,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
271 return;272 return;
272 }273 }
273274
274 let trait_def_id = self.tcx.trait_of_item(fn_def_id);275 if !self.tcx.is_lang_item(fn_def_id, LangItem::CloneFn) {
275 if trait_def_id.is_none() || trait_def_id != self.tcx.lang_items().clone_trait() {
276 return;276 return;
277 }277 }
278278
compiler/rustc_passes/src/dead.rs+22-10
...@@ -54,7 +54,24 @@ impl Publicness {...@@ -54,7 +54,24 @@ impl Publicness {
54 }54 }
55}55}
5656
57fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: DefId) -> bool {57fn adt_of<'tcx>(ty: &hir::Ty<'tcx>) -> Option<(LocalDefId, DefKind)> {
58 match ty.kind {
59 TyKind::Path(hir::QPath::Resolved(_, path)) => {
60 if let Res::Def(def_kind, def_id) = path.res
61 && let Some(local_def_id) = def_id.as_local()
62 {
63 Some((local_def_id, def_kind))
64 } else {
65 None
66 }
67 }
68 TyKind::Slice(ty) | TyKind::Array(ty, _) => adt_of(ty),
69 TyKind::Ptr(ty) | TyKind::Ref(_, ty) => adt_of(ty.ty),
70 _ => None,
71 }
72}
73
74fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: LocalDefId) -> bool {
58 // treat PhantomData and positional ZST as public,75 // treat PhantomData and positional ZST as public,
59 // we don't want to lint types which only have them,76 // we don't want to lint types which only have them,
60 // cause it's a common way to use such types to check things like well-formedness77 // cause it's a common way to use such types to check things like well-formedness
...@@ -79,10 +96,7 @@ fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: DefId) -> bool {...@@ -79,10 +96,7 @@ fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: DefId) -> bool {
79/// for enum and union, just check they are public,96/// for enum and union, just check they are public,
80/// and doesn't solve types like &T for now, just skip them97/// and doesn't solve types like &T for now, just skip them
81fn ty_ref_to_pub_struct(tcx: TyCtxt<'_>, ty: &hir::Ty<'_>) -> Publicness {98fn ty_ref_to_pub_struct(tcx: TyCtxt<'_>, ty: &hir::Ty<'_>) -> Publicness {
82 if let TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind99 if let Some((def_id, def_kind)) = adt_of(ty) {
83 && let Res::Def(def_kind, def_id) = path.res
84 && def_id.is_local()
85 {
86 return match def_kind {100 return match def_kind {
87 DefKind::Enum | DefKind::Union => {101 DefKind::Enum | DefKind::Union => {
88 let ty_is_public = tcx.visibility(def_id).is_public();102 let ty_is_public = tcx.visibility(def_id).is_public();
...@@ -565,10 +579,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {...@@ -565,10 +579,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
565 }579 }
566580
567 fn impl_item_with_used_self(&mut self, impl_id: hir::ItemId, impl_item_id: LocalDefId) -> bool {581 fn impl_item_with_used_self(&mut self, impl_id: hir::ItemId, impl_item_id: LocalDefId) -> bool {
568 if let TyKind::Path(hir::QPath::Resolved(_, path)) =582 if let Some((local_def_id, def_kind)) =
569 self.tcx.hir().item(impl_id).expect_impl().self_ty.kind583 adt_of(self.tcx.hir().item(impl_id).expect_impl().self_ty)
570 && let Res::Def(def_kind, def_id) = path.res
571 && let Some(local_def_id) = def_id.as_local()
572 && matches!(def_kind, DefKind::Struct | DefKind::Enum | DefKind::Union)584 && matches!(def_kind, DefKind::Struct | DefKind::Enum | DefKind::Union)
573 {585 {
574 if let Some(trait_item_id) = self.tcx.associated_item(impl_item_id).trait_item_def_id586 if let Some(trait_item_id) = self.tcx.associated_item(impl_item_id).trait_item_def_id
...@@ -915,7 +927,7 @@ fn create_and_seed_worklist(...@@ -915,7 +927,7 @@ fn create_and_seed_worklist(
915 match tcx.def_kind(id) {927 match tcx.def_kind(id) {
916 DefKind::Impl { .. } => false,928 DefKind::Impl { .. } => false,
917 DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => !matches!(tcx.associated_item(id).container, AssocItemContainer::ImplContainer),929 DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => !matches!(tcx.associated_item(id).container, AssocItemContainer::ImplContainer),
918 DefKind::Struct => struct_all_fields_are_public(tcx, id.to_def_id()) || has_allow_dead_code_or_lang_attr(tcx, id).is_some(),930 DefKind::Struct => struct_all_fields_are_public(tcx, id) || has_allow_dead_code_or_lang_attr(tcx, id).is_some(),
919 _ => true931 _ => true
920 })932 })
921 .map(|id| (id, ComesFromAllowExpect::No))933 .map(|id| (id, ComesFromAllowExpect::No))
compiler/rustc_resolve/src/diagnostics.rs+4-1
...@@ -1448,7 +1448,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {...@@ -1448,7 +1448,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1448 );1448 );
14491449
1450 if macro_kind == MacroKind::Bang && ident.name == sym::macro_rules {1450 if macro_kind == MacroKind::Bang && ident.name == sym::macro_rules {
1451 err.subdiagnostic(MaybeMissingMacroRulesName { span: ident.span });1451 let label_span = ident.span.shrink_to_hi();
1452 let mut spans = MultiSpan::from_span(label_span);
1453 spans.push_span_label(label_span, "put a macro name here");
1454 err.subdiagnostic(MaybeMissingMacroRulesName { spans: spans });
1452 return;1455 return;
1453 }1456 }
14541457
compiler/rustc_resolve/src/errors.rs+1-1
...@@ -669,7 +669,7 @@ pub(crate) struct MacroSuggMovePosition {...@@ -669,7 +669,7 @@ pub(crate) struct MacroSuggMovePosition {
669#[note(resolve_missing_macro_rules_name)]669#[note(resolve_missing_macro_rules_name)]
670pub(crate) struct MaybeMissingMacroRulesName {670pub(crate) struct MaybeMissingMacroRulesName {
671 #[primary_span]671 #[primary_span]
672 pub(crate) span: Span,672 pub(crate) spans: MultiSpan,
673}673}
674674
675#[derive(Subdiagnostic)]675#[derive(Subdiagnostic)]
compiler/rustc_span/src/symbol.rs+1
...@@ -557,6 +557,7 @@ symbols! {...@@ -557,6 +557,7 @@ symbols! {
557 clobber_abi,557 clobber_abi,
558 clone,558 clone,
559 clone_closures,559 clone_closures,
560 clone_fn,
560 clone_from,561 clone_from,
561 closure,562 closure,
562 closure_lifetime_binder,563 closure_lifetime_binder,
compiler/rustc_type_ir/src/visit.rs-4
...@@ -241,10 +241,6 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {...@@ -241,10 +241,6 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
241 self.has_type_flags(TypeFlags::HAS_ALIAS)241 self.has_type_flags(TypeFlags::HAS_ALIAS)
242 }242 }
243243
244 fn has_inherent_projections(&self) -> bool {
245 self.has_type_flags(TypeFlags::HAS_TY_INHERENT)
246 }
247
248 fn has_opaque_types(&self) -> bool {244 fn has_opaque_types(&self) -> bool {
249 self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)245 self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
250 }246 }
library/core/src/clone.rs+3
...@@ -160,6 +160,9 @@ pub trait Clone: Sized {...@@ -160,6 +160,9 @@ pub trait Clone: Sized {
160 /// ```160 /// ```
161 #[stable(feature = "rust1", since = "1.0.0")]161 #[stable(feature = "rust1", since = "1.0.0")]
162 #[must_use = "cloning is often expensive and is not expected to have side effects"]162 #[must_use = "cloning is often expensive and is not expected to have side effects"]
163 // Clone::clone is special because the compiler generates MIR to implement it for some types.
164 // See InstanceKind::CloneShim.
165 #[cfg_attr(not(bootstrap), lang = "clone_fn")]
163 fn clone(&self) -> Self;166 fn clone(&self) -> Self;
164167
165 /// Performs copy-assignment from `source`.168 /// Performs copy-assignment from `source`.
src/tools/compiletest/src/command-list.rs+1
...@@ -201,6 +201,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[...@@ -201,6 +201,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
201 "only-wasm32-wasip1",201 "only-wasm32-wasip1",
202 "only-watchos",202 "only-watchos",
203 "only-windows",203 "only-windows",
204 "only-windows-gnu",
204 "only-x86",205 "only-x86",
205 "only-x86_64",206 "only-x86_64",
206 "only-x86_64-fortanix-unknown-sgx",207 "only-x86_64-fortanix-unknown-sgx",
src/tools/run-make-support/src/external_deps/cc.rs+23
...@@ -15,6 +15,13 @@ pub fn cc() -> Cc {...@@ -15,6 +15,13 @@ pub fn cc() -> Cc {
15 Cc::new()15 Cc::new()
16}16}
1717
18/// Construct a new platform-specific CXX compiler invocation.
19/// CXX_DEFAULT_FLAGS is passed from compiletest.
20#[track_caller]
21pub fn cxx() -> Cc {
22 Cc::new_cxx()
23}
24
18/// A platform-specific C compiler invocation builder. The specific C compiler used is25/// A platform-specific C compiler invocation builder. The specific C compiler used is
19/// passed down from compiletest.26/// passed down from compiletest.
20#[derive(Debug)]27#[derive(Debug)]
...@@ -44,6 +51,22 @@ impl Cc {...@@ -44,6 +51,22 @@ impl Cc {
44 Self { cmd }51 Self { cmd }
45 }52 }
4653
54 /// Construct a new platform-specific CXX compiler invocation.
55 /// CXX_DEFAULT_FLAGS is passed from compiletest.
56 #[track_caller]
57 pub fn new_cxx() -> Self {
58 let compiler = env_var("CXX");
59
60 let mut cmd = Command::new(compiler);
61
62 let default_cflags = env_var("CXX_DEFAULT_FLAGS");
63 for flag in default_cflags.split(char::is_whitespace) {
64 cmd.arg(flag);
65 }
66
67 Self { cmd }
68 }
69
47 /// Specify path of the input file.70 /// Specify path of the input file.
48 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {71 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
49 self.cmd.arg(path.as_ref());72 self.cmd.arg(path.as_ref());
src/tools/run-make-support/src/lib.rs+1-1
...@@ -44,7 +44,7 @@ pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rust...@@ -44,7 +44,7 @@ pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rust
4444
45// These rely on external dependencies.45// These rely on external dependencies.
46pub use c_build::{build_native_dynamic_lib, build_native_static_lib};46pub use c_build::{build_native_dynamic_lib, build_native_static_lib};
47pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc};47pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
48pub use clang::{clang, Clang};48pub use clang::{clang, Clang};
49pub use htmldocck::htmldocck;49pub use htmldocck::htmldocck;
50pub use llvm::{50pub use llvm::{
src/tools/tidy/src/allowed_run_make_makefiles.txt-6
...@@ -2,7 +2,6 @@ run-make/branch-protection-check-IBT/Makefile...@@ -2,7 +2,6 @@ run-make/branch-protection-check-IBT/Makefile
2run-make/c-unwind-abi-catch-lib-panic/Makefile2run-make/c-unwind-abi-catch-lib-panic/Makefile
3run-make/cat-and-grep-sanity-check/Makefile3run-make/cat-and-grep-sanity-check/Makefile
4run-make/cdylib-dylib-linkage/Makefile4run-make/cdylib-dylib-linkage/Makefile
5run-make/compiler-rt-works-on-mingw/Makefile
6run-make/cross-lang-lto-clang/Makefile5run-make/cross-lang-lto-clang/Makefile
7run-make/cross-lang-lto-pgo-smoketest/Makefile6run-make/cross-lang-lto-pgo-smoketest/Makefile
8run-make/cross-lang-lto-upstream-rlibs/Makefile7run-make/cross-lang-lto-upstream-rlibs/Makefile
...@@ -10,18 +9,14 @@ run-make/cross-lang-lto/Makefile...@@ -10,18 +9,14 @@ run-make/cross-lang-lto/Makefile
10run-make/dep-info-doesnt-run-much/Makefile9run-make/dep-info-doesnt-run-much/Makefile
11run-make/dep-info-spaces/Makefile10run-make/dep-info-spaces/Makefile
12run-make/dep-info/Makefile11run-make/dep-info/Makefile
13run-make/dump-ice-to-disk/Makefile
14run-make/emit-to-stdout/Makefile12run-make/emit-to-stdout/Makefile
15run-make/export-executable-symbols/Makefile13run-make/export-executable-symbols/Makefile
16run-make/extern-flag-disambiguates/Makefile
17run-make/extern-fn-reachable/Makefile14run-make/extern-fn-reachable/Makefile
18run-make/fmt-write-bloat/Makefile15run-make/fmt-write-bloat/Makefile
19run-make/foreign-double-unwind/Makefile16run-make/foreign-double-unwind/Makefile
20run-make/foreign-exceptions/Makefile17run-make/foreign-exceptions/Makefile
21run-make/foreign-rust-exceptions/Makefile18run-make/foreign-rust-exceptions/Makefile
22run-make/incr-add-rust-src-component/Makefile19run-make/incr-add-rust-src-component/Makefile
23run-make/incr-foreign-head-span/Makefile
24run-make/interdependent-c-libraries/Makefile
25run-make/issue-35164/Makefile20run-make/issue-35164/Makefile
26run-make/issue-36710/Makefile21run-make/issue-36710/Makefile
27run-make/issue-47551/Makefile22run-make/issue-47551/Makefile
...@@ -42,7 +37,6 @@ run-make/native-link-modifier-bundle/Makefile...@@ -42,7 +37,6 @@ run-make/native-link-modifier-bundle/Makefile
42run-make/native-link-modifier-whole-archive/Makefile37run-make/native-link-modifier-whole-archive/Makefile
43run-make/no-alloc-shim/Makefile38run-make/no-alloc-shim/Makefile
44run-make/no-builtins-attribute/Makefile39run-make/no-builtins-attribute/Makefile
45run-make/panic-abort-eh_frame/Makefile
46run-make/pdb-buildinfo-cl-cmd/Makefile40run-make/pdb-buildinfo-cl-cmd/Makefile
47run-make/pgo-gen-lto/Makefile41run-make/pgo-gen-lto/Makefile
48run-make/pgo-indirect-call-promotion/Makefile42run-make/pgo-indirect-call-promotion/Makefile
tests/run-make/README.md+5
...@@ -41,3 +41,8 @@ The setup for the `rmake.rs` version is a 3-stage process:...@@ -41,3 +41,8 @@ The setup for the `rmake.rs` version is a 3-stage process:
4141
42[`run_make_support`]: ../../src/tools/run-make-support42[`run_make_support`]: ../../src/tools/run-make-support
43[extern_prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude43[extern_prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude
44
45### Formatting
46
47Note that files under `tests/` are not formatted by `./x fmt`,
48use `rustfmt tests/path/to/file.rs` to format a specific file if desired.
tests/run-make/compiler-rt-works-on-mingw/Makefile deleted-9
...@@ -1,9 +0,0 @@
1include ../tools.mk
2
3# only-windows-gnu
4
5all:
6 $(CXX) foo.cpp -c -o $(TMPDIR)/foo.o
7 $(AR) crus $(TMPDIR)/libfoo.a $(TMPDIR)/foo.o
8 $(RUSTC) foo.rs -lfoo -lstdc++
9 $(call RUN,foo)
tests/run-make/compiler-rt-works-on-mingw/rmake.rs created+15
...@@ -0,0 +1,15 @@
1// `compiler-rt` ("runtime") is a suite of LLVM features compatible with rustc.
2// After building it was enabled on Windows-gnu in #29874, this test is a basic smoke test to
3// check if building and linking to it can work at all.
4// See https://github.com/rust-lang/rust/pull/29478
5
6//@ only-windows-gnu
7
8use run_make_support::{cxx, is_msvc, llvm_ar, run, rustc, static_lib_name};
9
10fn main() {
11 cxx().input("foo.cpp").arg("-c").out_exe("foo.o").run();
12 llvm_ar().obj_to_ar().output_input(static_lib_name("foo"), "foo.o").run();
13 rustc().input("foo.rs").arg("-lfoo").arg("-lstdc++").run();
14 run("foo");
15}
tests/run-make/dump-ice-to-disk/Makefile deleted-10
...@@ -1,10 +0,0 @@
1include ../tools.mk
2
3# ignore-windows
4
5export RUSTC := $(RUSTC_ORIGINAL)
6export LD_LIBRARY_PATH := $(HOST_RPATH_DIR)
7export TMPDIR := $(TMPDIR)
8
9all:
10 bash check.sh
tests/run-make/dump-ice-to-disk/check.sh deleted-64
...@@ -1,64 +0,0 @@
1#!/bin/sh
2
3# Default nightly behavior (write ICE to current directory)
4# FIXME(estebank): these are failing on CI, but passing locally.
5# $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-default.log 2>&1
6# default=$(cat ./rustc-ice-*.txt | wc -l)
7# rm ./rustc-ice-*.txt
8
9# Explicit directory set
10export RUSTC_ICE=$TMPDIR
11$RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-default-set.log 2>&1
12default_set=$(cat $TMPDIR/rustc-ice-*.txt | wc -l)
13content=$(cat $TMPDIR/rustc-ice-*.txt)
14# Ensure that the ICE dump path doesn't contain `:` because they cause problems on Windows
15windows_safe=$(echo rustc-ice-*.txt | grep ':')
16if [ ! -z "$windows_safe" ]; then
17 exit 1
18fi
19
20rm $TMPDIR/rustc-ice-*.txt
21RUST_BACKTRACE=short $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-short.log 2>&1
22short=$(cat $TMPDIR/rustc-ice-*.txt | wc -l)
23rm $TMPDIR/rustc-ice-*.txt
24RUST_BACKTRACE=full $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-full.log 2>&1
25full=$(cat $TMPDIR/rustc-ice-*.txt | wc -l)
26rm $TMPDIR/rustc-ice-*.txt
27
28# Explicitly disabling ICE dump
29export RUSTC_ICE=0
30$RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-disabled.log 2>&1
31should_be_empty_tmp=$(ls -l $TMPDIR/rustc-ice-*.txt 2>/dev/null | wc -l)
32should_be_empty_dot=$(ls -l ./rustc-ice-*.txt 2>/dev/null | wc -l)
33
34echo "#### ICE Dump content:"
35echo $content
36echo "#### default length:"
37echo $default
38echo "#### short length:"
39echo $short
40echo "#### default_set length:"
41echo $default_set
42echo "#### full length:"
43echo $full
44echo "#### should_be_empty_dot length:"
45echo $should_be_empty_dot
46echo "#### should_be_empty_tmp length:"
47echo $should_be_empty_tmp
48
49## Verify that a the ICE dump file is created in the appropriate directories, that
50## their lengths are the same regardless of other backtrace configuration options,
51## that the file is not created when asked to (RUSTC_ICE=0) and that the file
52## contains at least part of the expected content.
53if [ $short -eq $default_set ] &&
54 #[ $default -eq $short ] &&
55 [ $default_set -eq $full ] &&
56 [[ $content == *"thread 'rustc' panicked at "* ]] &&
57 [[ $content == *"stack backtrace:"* ]] &&
58 #[ $default -gt 0 ] &&
59 [ $should_be_empty_dot -eq 0 ] &&
60 [ $should_be_empty_tmp -eq 0 ]; then
61 exit 0
62else
63 exit 1
64fi
tests/run-make/dump-ice-to-disk/lib.rs created+7
...@@ -0,0 +1,7 @@
1fn func(s: &str) {
2 println!("{}", s);
3}
4
5fn main() {
6 func(1);
7}
tests/run-make/dump-ice-to-disk/rmake.rs created+81
...@@ -0,0 +1,81 @@
1// This test checks if internal compilation error (ICE) log files work as expected.
2// - Get the number of lines from the log files without any configuration options,
3// then check that the line count doesn't change if the backtrace gets configured to be short
4// or full.
5// - Check that disabling ICE logging results in zero files created.
6// - Check that the ICE files contain some of the expected strings.
7// See https://github.com/rust-lang/rust/pull/108714
8
9use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files};
10
11fn main() {
12 rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
13 let default = get_text_from_ice(".").lines().count();
14 clear_ice_files();
15
16 rustc().env("RUSTC_ICE", cwd()).input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
17 let ice_text = get_text_from_ice(cwd());
18 let default_set = ice_text.lines().count();
19 let content = ice_text;
20 let ice_files = shallow_find_files(cwd(), |path| {
21 has_prefix(path, "rustc-ice") && has_extension(path, "txt")
22 });
23 assert_eq!(ice_files.len(), 1); // There should only be 1 ICE file.
24 let ice_file_name =
25 ice_files.first().and_then(|f| f.file_name()).and_then(|n| n.to_str()).unwrap();
26 // Ensure that the ICE dump path doesn't contain `:`, because they cause problems on Windows.
27 assert!(!ice_file_name.contains(":"), "{ice_file_name}");
28
29 clear_ice_files();
30 rustc()
31 .env("RUSTC_ICE", cwd())
32 .input("lib.rs")
33 .env("RUST_BACKTRACE", "short")
34 .arg("-Ztreat-err-as-bug=1")
35 .run_fail();
36 let short = get_text_from_ice(cwd()).lines().count();
37 clear_ice_files();
38 rustc()
39 .env("RUSTC_ICE", cwd())
40 .input("lib.rs")
41 .env("RUST_BACKTRACE", "full")
42 .arg("-Ztreat-err-as-bug=1")
43 .run_fail();
44 let full = get_text_from_ice(cwd()).lines().count();
45 clear_ice_files();
46
47 // The ICE dump is explicitly disabled. Therefore, this should produce no files.
48 rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
49 let ice_files = shallow_find_files(cwd(), |path| {
50 has_prefix(path, "rustc-ice") && has_extension(path, "txt")
51 });
52 assert!(ice_files.is_empty()); // There should be 0 ICE files.
53
54 // The line count should not change.
55 assert_eq!(short, default_set);
56 assert_eq!(short, default);
57 assert_eq!(full, default_set);
58 assert!(default > 0);
59 // Some of the expected strings in an ICE file should appear.
60 assert!(content.contains("thread 'rustc' panicked at"));
61 assert!(content.contains("stack backtrace:"));
62}
63
64fn clear_ice_files() {
65 let ice_files = shallow_find_files(cwd(), |path| {
66 has_prefix(path, "rustc-ice") && has_extension(path, "txt")
67 });
68 for file in ice_files {
69 rfs::remove_file(file);
70 }
71}
72
73#[track_caller]
74fn get_text_from_ice(dir: impl AsRef<std::path::Path>) -> String {
75 let ice_files =
76 shallow_find_files(dir, |path| has_prefix(path, "rustc-ice") && has_extension(path, "txt"));
77 assert_eq!(ice_files.len(), 1); // There should only be 1 ICE file.
78 let ice_file = ice_files.get(0).unwrap();
79 let output = rfs::read_to_string(ice_file);
80 output
81}
tests/run-make/dump-ice-to-disk/src/lib.rs deleted-7
...@@ -1,7 +0,0 @@
1fn func(s: &str) {
2 println!("{}", s);
3}
4
5fn main() {
6 func(1);
7}
tests/run-make/extern-flag-disambiguates/Makefile deleted-26
...@@ -1,26 +0,0 @@
1# ignore-cross-compile
2include ../tools.mk
3
4# Attempt to build this dependency tree:
5#
6# A.1 A.2
7# |\ |
8# | \ |
9# B \ C
10# \ | /
11# \|/
12# D
13#
14# Note that A.1 and A.2 are crates with the same name.
15
16all:
17 $(RUSTC) -C metadata=1 -C extra-filename=-1 a.rs
18 $(RUSTC) -C metadata=2 -C extra-filename=-2 a.rs
19 $(RUSTC) b.rs --extern a=$(TMPDIR)/liba-1.rlib
20 $(RUSTC) c.rs --extern a=$(TMPDIR)/liba-2.rlib
21 @echo before
22 $(RUSTC) --cfg before d.rs --extern a=$(TMPDIR)/liba-1.rlib
23 $(call RUN,d)
24 @echo after
25 $(RUSTC) --cfg after d.rs --extern a=$(TMPDIR)/liba-1.rlib
26 $(call RUN,d)
tests/run-make/extern-flag-disambiguates/rmake.rs created+30
...@@ -0,0 +1,30 @@
1//@ ignore-cross-compile
2
3use run_make_support::{cwd, run, rustc};
4
5// Attempt to build this dependency tree:
6//
7// A.1 A.2
8// |\ |
9// | \ |
10// B \ C
11// \ | /
12// \|/
13// D
14//
15// Note that A.1 and A.2 are crates with the same name.
16
17// original Makefile at https://github.com/rust-lang/rust/issues/14469
18
19fn main() {
20 rustc().metadata("1").extra_filename("-1").input("a.rs").run();
21 rustc().metadata("2").extra_filename("-2").input("a.rs").run();
22 rustc().input("b.rs").extern_("a", "liba-1.rlib").run();
23 rustc().input("c.rs").extern_("a", "liba-2.rlib").run();
24 println!("before");
25 rustc().cfg("before").input("d.rs").extern_("a", "liba-1.rlib").run();
26 run("d");
27 println!("after");
28 rustc().cfg("after").input("d.rs").extern_("a", "liba-1.rlib").run();
29 run("d");
30}
tests/run-make/incr-foreign-head-span/Makefile deleted-21
...@@ -1,21 +0,0 @@
1include ../tools.mk
2
3# ignore-none no-std is not supported
4# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for 'std'
5
6# Ensure that modifying a crate on disk (without recompiling it)
7# does not cause ICEs in downstream crates.
8# Previously, we would call `SourceMap.guess_head_span` on a span
9# from an external crate, which would cause us to read an upstream
10# source file from disk during compilation of a downstream crate
11# See #86480 for more details
12
13INCR=$(TMPDIR)/incr
14
15all:
16 cp first_crate.rs second_crate.rs $(TMPDIR)
17 $(RUSTC) $(TMPDIR)/first_crate.rs -C incremental=$(INCR) --target $(TARGET) --crate-type lib
18 $(RUSTC) $(TMPDIR)/second_crate.rs -C incremental=$(INCR) --target $(TARGET) --extern first_crate=$(TMPDIR)/libfirst_crate.rlib --crate-type lib
19 rm $(TMPDIR)/first_crate.rs
20 $(RUSTC) $(TMPDIR)/second_crate.rs -C incremental=$(INCR) --target $(TARGET) --cfg second_run --crate-type lib
21
tests/run-make/incr-foreign-head-span/rmake.rs created+25
...@@ -0,0 +1,25 @@
1// Ensure that modifying a crate on disk (without recompiling it)
2// does not cause ICEs (internal compiler errors) in downstream crates.
3// Previously, we would call `SourceMap.guess_head_span` on a span
4// from an external crate, which would cause us to read an upstream
5// source file from disk during compilation of a downstream crate.
6// See https://github.com/rust-lang/rust/issues/86480
7
8//@ ignore-none
9// Reason: no-std is not supported
10//@ ignore-nvptx64-nvidia-cuda
11// Reason: can't find crate for 'std'
12
13use run_make_support::{rfs, rust_lib_name, rustc};
14
15fn main() {
16 rustc().input("first_crate.rs").incremental("incr").crate_type("lib").run();
17 rustc()
18 .input("second_crate.rs")
19 .incremental("incr")
20 .extern_("first_crate", rust_lib_name("first_crate"))
21 .crate_type("lib")
22 .run();
23 rfs::remove_file("first_crate.rs");
24 rustc().input("second_crate.rs").incremental("incr").cfg("second_run").crate_type("lib").run();
25}
tests/run-make/interdependent-c-libraries/Makefile deleted-15
...@@ -1,15 +0,0 @@
1# ignore-cross-compile
2include ../tools.mk
3
4# The rust crate foo will link to the native library foo, while the rust crate
5# bar will link to the native library bar. There is also a dependency between
6# the native library bar to the natibe library foo.
7#
8# This test ensures that the ordering of -lfoo and -lbar on the command line is
9# correct to complete the linkage. If passed as "-lfoo -lbar", then the 'foo'
10# library will be stripped out, and the linkage will fail.
11
12all: $(call NATIVE_STATICLIB,foo) $(call NATIVE_STATICLIB,bar)
13 $(RUSTC) foo.rs
14 $(RUSTC) bar.rs
15 $(RUSTC) main.rs --print link-args
tests/run-make/interdependent-c-libraries/rmake.rs created+21
...@@ -0,0 +1,21 @@
1// The rust crate foo will link to the native library foo, while the rust crate
2// bar will link to the native library bar. There is also a dependency between
3// the native library bar to the natibe library foo.
4// This test ensures that the ordering of -lfoo and -lbar on the command line is
5// correct to complete the linkage. If passed as "-lfoo -lbar", then the 'foo'
6// library will be stripped out, and the linkage will fail.
7// See https://github.com/rust-lang/rust/commit/e6072fa0c4c22d62acf3dcb78c8ee260a1368bd7
8
9//@ ignore-cross-compile
10// Reason: linkage still fails as the object files produced are not in the correct
11// format in the `build_native_static_lib` step
12
13use run_make_support::{build_native_static_lib, rustc};
14
15fn main() {
16 build_native_static_lib("foo");
17 build_native_static_lib("bar");
18 rustc().input("foo.rs").run();
19 rustc().input("bar.rs").run();
20 rustc().input("main.rs").print("link-args").run();
21}
tests/run-make/panic-abort-eh_frame/Makefile deleted-10
...@@ -1,10 +0,0 @@
1# only-linux
2#
3# This test ensures that `panic=abort` code (without `C-unwind`, that is) should not have any
4# unwinding related `.eh_frame` sections emitted.
5
6include ../tools.mk
7
8all:
9 $(RUSTC) foo.rs --crate-type=lib --emit=obj=$(TMPDIR)/foo.o -Cpanic=abort --edition 2021 -Z validate-mir
10 objdump --dwarf=frames $(TMPDIR)/foo.o | $(CGREP) -v 'DW_CFA'
tests/run-make/panic-abort-eh_frame/rmake.rs created+24
...@@ -0,0 +1,24 @@
1// An `.eh_frame` section in an object file is a symptom of an UnwindAction::Terminate
2// being inserted, useful for determining whether or not unwinding is necessary.
3// This is useless when panics would NEVER unwind due to -C panic=abort. This section should
4// therefore never appear in the emit file of a -C panic=abort compilation, and this test
5// checks that this is respected.
6// See https://github.com/rust-lang/rust/pull/112403
7
8//@ only-linux
9// FIXME(Oneirical): the DW_CFA symbol appears on Windows-gnu, because uwtable
10// is forced to true on Windows targets (see #128136).
11
12use run_make_support::{llvm_objdump, rustc};
13
14fn main() {
15 rustc()
16 .input("foo.rs")
17 .crate_type("lib")
18 .emit("obj=foo.o")
19 .panic("abort")
20 .edition("2021")
21 .arg("-Zvalidate-mir")
22 .run();
23 llvm_objdump().arg("--dwarf=frames").input("foo.o").run().assert_stdout_not_contains("DW_CFA");
24}
tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs deleted-20
...@@ -1,20 +0,0 @@
1//@ compile-flags: --crate-type=lib
2//@ check-pass
3
4#![feature(inherent_associated_types)]
5#![allow(incomplete_features)]
6
7// Bounds on the self type play a major role in the resolution of inherent associated types (*).
8// As a result of that, if a type alias contains any then its bounds have to be respected and the
9// lint `type_alias_bounds` should not fire.
10
11#![deny(type_alias_bounds)]
12
13pub type Alias<T: Bound> = (Source<T>::Assoc,);
14
15pub struct Source<T>(T);
16pub trait Bound {}
17
18impl<T: Bound> Source<T> {
19 pub type Assoc = ();
20}
tests/ui/associated-inherent-types/type-alias-bounds.rs created+29
...@@ -0,0 +1,29 @@
1//@ compile-flags: --crate-type=lib
2//@ check-pass
3
4#![feature(inherent_associated_types)]
5#![allow(incomplete_features)]
6
7// FIXME(inherent_associated_types):
8// While we currently do take some clauses of the ParamEnv into consideration
9// when performing IAT selection, we do not perform full well-formedness checking
10// for (eager) type alias definition and usage sites.
11//
12// Therefore it's *correct* for lint `type_alias_bounds` to fire here despite the
13// fact that removing `Bound` from `T` in `Alias` would lead to an error!
14//
15// Obviously, the present situation isn't ideal and we should fix it in one way
16// or another. Either we somehow delay IAT selection until after HIR ty lowering
17// to avoid the need to specify any bounds inside (eager) type aliases or we
18// force the overarching type alias to be *lazy* (similar to TAITs) which would
19// automatically lead to full wfchecking and lint TAB getting suppressed.
20
21pub type Alias<T: Bound> = (Source<T>::Assoc,);
22//~^ WARN bounds on generic parameters in type aliases are not enforced
23
24pub struct Source<T>(T);
25pub trait Bound {}
26
27impl<T: Bound> Source<T> {
28 pub type Assoc = ();
29}
tests/ui/associated-inherent-types/type-alias-bounds.stderr created+16
...@@ -0,0 +1,16 @@
1warning: bounds on generic parameters in type aliases are not enforced
2 --> $DIR/type-alias-bounds.rs:21:19
3 |
4LL | pub type Alias<T: Bound> = (Source<T>::Assoc,);
5 | --^^^^^
6 | | |
7 | | will not be checked at usage sites of the type alias
8 | help: remove this bound
9 |
10 = note: this is a known limitation of the type checker that may be lifted in a future edition.
11 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
12 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
13 = note: `#[warn(type_alias_bounds)]` on by default
14
15warning: 1 warning emitted
16
tests/ui/associated-type-bounds/type-alias.stderr+108-96
...@@ -1,147 +1,159 @@...@@ -1,147 +1,159 @@
1warning: where clauses are not enforced in type aliases1warning: where clauses on type aliases are not enforced
2 --> $DIR/type-alias.rs:3:252 --> $DIR/type-alias.rs:3:25
3 |3 |
4LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T;4LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
5 | ^^^^^^^^^^^^^^^^^^^^^^^5 | ------^^^^^^^^^^^^^^^^^^^^^^^
6 |6 | | |
7 | | will not be checked at usage sites of the type alias
8 | help: remove this where clause
9 |
10 = note: this is a known limitation of the type checker that may be lifted in a future edition.
11 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
12 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
7 = note: `#[warn(type_alias_bounds)]` on by default13 = note: `#[warn(type_alias_bounds)]` on by default
8help: the clause will not be checked when the type alias is used, and should be removed
9 |
10LL - type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
11LL + type _TaWhere1<T> = T;
12 |
1314
14warning: where clauses are not enforced in type aliases15warning: where clauses on type aliases are not enforced
15 --> $DIR/type-alias.rs:4:2516 --> $DIR/type-alias.rs:4:25
16 |17 |
17LL | type _TaWhere2<T> where T: Iterator<Item: 'static> = T;18LL | type _TaWhere2<T> where T: Iterator<Item: 'static> = T;
18 | ^^^^^^^^^^^^^^^^^^^^^^^^^^19 | ------^^^^^^^^^^^^^^^^^^^^^^^^^^
19 |20 | | |
20help: the clause will not be checked when the type alias is used, and should be removed21 | | will not be checked at usage sites of the type alias
21 |22 | help: remove this where clause
22LL - type _TaWhere2<T> where T: Iterator<Item: 'static> = T;23 |
23LL + type _TaWhere2<T> = T;24 = note: this is a known limitation of the type checker that may be lifted in a future edition.
24 |25 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
26 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
2527
26warning: where clauses are not enforced in type aliases28warning: where clauses on type aliases are not enforced
27 --> $DIR/type-alias.rs:5:2529 --> $DIR/type-alias.rs:5:25
28 |30 |
29LL | type _TaWhere3<T> where T: Iterator<Item: 'static> = T;31LL | type _TaWhere3<T> where T: Iterator<Item: 'static> = T;
30 | ^^^^^^^^^^^^^^^^^^^^^^^^^^32 | ------^^^^^^^^^^^^^^^^^^^^^^^^^^
31 |33 | | |
32help: the clause will not be checked when the type alias is used, and should be removed34 | | will not be checked at usage sites of the type alias
33 |35 | help: remove this where clause
34LL - type _TaWhere3<T> where T: Iterator<Item: 'static> = T;36 |
35LL + type _TaWhere3<T> = T;37 = note: this is a known limitation of the type checker that may be lifted in a future edition.
36 |38 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
39 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
3740
38warning: where clauses are not enforced in type aliases41warning: where clauses on type aliases are not enforced
39 --> $DIR/type-alias.rs:6:2542 --> $DIR/type-alias.rs:6:25
40 |43 |
41LL | type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T;44LL | type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T;
42 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^45 | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
43 |46 | | |
44help: the clause will not be checked when the type alias is used, and should be removed47 | | will not be checked at usage sites of the type alias
45 |48 | help: remove this where clause
46LL - type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T;49 |
47LL + type _TaWhere4<T> = T;50 = note: this is a known limitation of the type checker that may be lifted in a future edition.
48 |51 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
52 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
4953
50warning: where clauses are not enforced in type aliases54warning: where clauses on type aliases are not enforced
51 --> $DIR/type-alias.rs:7:2555 --> $DIR/type-alias.rs:7:25
52 |56 |
53LL | type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T;57LL | type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T;
54 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^58 | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
55 |59 | | |
56help: the clause will not be checked when the type alias is used, and should be removed60 | | will not be checked at usage sites of the type alias
57 |61 | help: remove this where clause
58LL - type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T;62 |
59LL + type _TaWhere5<T> = T;63 = note: this is a known limitation of the type checker that may be lifted in a future edition.
60 |64 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
65 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
6166
62warning: where clauses are not enforced in type aliases67warning: where clauses on type aliases are not enforced
63 --> $DIR/type-alias.rs:8:2568 --> $DIR/type-alias.rs:8:25
64 |69 |
65LL | type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T;70LL | type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T;
66 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^71 | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
67 |72 | | |
68help: the clause will not be checked when the type alias is used, and should be removed73 | | will not be checked at usage sites of the type alias
69 |74 | help: remove this where clause
70LL - type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T;75 |
71LL + type _TaWhere6<T> = T;76 = note: this is a known limitation of the type checker that may be lifted in a future edition.
72 |77 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
78 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
7379
74warning: bounds on generic parameters are not enforced in type aliases80warning: bounds on generic parameters in type aliases are not enforced
75 --> $DIR/type-alias.rs:10:2081 --> $DIR/type-alias.rs:10:20
76 |82 |
77LL | type _TaInline1<T: Iterator<Item: Copy>> = T;83LL | type _TaInline1<T: Iterator<Item: Copy>> = T;
78 | ^^^^^^^^^^^^^^^^^^^^84 | --^^^^^^^^^^^^^^^^^^^^
79 |85 | | |
80help: the bound will not be checked when the type alias is used, and should be removed86 | | will not be checked at usage sites of the type alias
81 |87 | help: remove this bound
82LL - type _TaInline1<T: Iterator<Item: Copy>> = T;88 |
83LL + type _TaInline1<T> = T;89 = note: this is a known limitation of the type checker that may be lifted in a future edition.
84 |90 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
91 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
8592
86warning: bounds on generic parameters are not enforced in type aliases93warning: bounds on generic parameters in type aliases are not enforced
87 --> $DIR/type-alias.rs:11:2094 --> $DIR/type-alias.rs:11:20
88 |95 |
89LL | type _TaInline2<T: Iterator<Item: 'static>> = T;96LL | type _TaInline2<T: Iterator<Item: 'static>> = T;
90 | ^^^^^^^^^^^^^^^^^^^^^^^97 | --^^^^^^^^^^^^^^^^^^^^^^^
91 |98 | | |
92help: the bound will not be checked when the type alias is used, and should be removed99 | | will not be checked at usage sites of the type alias
93 |100 | help: remove this bound
94LL - type _TaInline2<T: Iterator<Item: 'static>> = T;101 |
95LL + type _TaInline2<T> = T;102 = note: this is a known limitation of the type checker that may be lifted in a future edition.
96 |103 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
104 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
97105
98warning: bounds on generic parameters are not enforced in type aliases106warning: bounds on generic parameters in type aliases are not enforced
99 --> $DIR/type-alias.rs:12:20107 --> $DIR/type-alias.rs:12:20
100 |108 |
101LL | type _TaInline3<T: Iterator<Item: 'static>> = T;109LL | type _TaInline3<T: Iterator<Item: 'static>> = T;
102 | ^^^^^^^^^^^^^^^^^^^^^^^110 | --^^^^^^^^^^^^^^^^^^^^^^^
103 |111 | | |
104help: the bound will not be checked when the type alias is used, and should be removed112 | | will not be checked at usage sites of the type alias
105 |113 | help: remove this bound
106LL - type _TaInline3<T: Iterator<Item: 'static>> = T;114 |
107LL + type _TaInline3<T> = T;115 = note: this is a known limitation of the type checker that may be lifted in a future edition.
108 |116 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
117 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
109118
110warning: bounds on generic parameters are not enforced in type aliases119warning: bounds on generic parameters in type aliases are not enforced
111 --> $DIR/type-alias.rs:13:20120 --> $DIR/type-alias.rs:13:20
112 |121 |
113LL | type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T;122LL | type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T;
114 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^123 | --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
115 |124 | | |
116help: the bound will not be checked when the type alias is used, and should be removed125 | | will not be checked at usage sites of the type alias
117 |126 | help: remove this bound
118LL - type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T;127 |
119LL + type _TaInline4<T> = T;128 = note: this is a known limitation of the type checker that may be lifted in a future edition.
120 |129 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
130 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
121131
122warning: bounds on generic parameters are not enforced in type aliases132warning: bounds on generic parameters in type aliases are not enforced
123 --> $DIR/type-alias.rs:14:20133 --> $DIR/type-alias.rs:14:20
124 |134 |
125LL | type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T;135LL | type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T;
126 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^136 | --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
127 |137 | | |
128help: the bound will not be checked when the type alias is used, and should be removed138 | | will not be checked at usage sites of the type alias
129 |139 | help: remove this bound
130LL - type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T;140 |
131LL + type _TaInline5<T> = T;141 = note: this is a known limitation of the type checker that may be lifted in a future edition.
132 |142 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
143 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
133144
134warning: bounds on generic parameters are not enforced in type aliases145warning: bounds on generic parameters in type aliases are not enforced
135 --> $DIR/type-alias.rs:15:20146 --> $DIR/type-alias.rs:15:20
136 |147 |
137LL | type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T;148LL | type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T;
138 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^149 | --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
139 |150 | | |
140help: the bound will not be checked when the type alias is used, and should be removed151 | | will not be checked at usage sites of the type alias
141 |152 | help: remove this bound
142LL - type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T;153 |
143LL + type _TaInline6<T> = T;154 = note: this is a known limitation of the type checker that may be lifted in a future edition.
144 |155 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
156 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
145157
146warning: 12 warnings emitted158warning: 12 warnings emitted
147159
tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr created+63
...@@ -0,0 +1,63 @@
1error[E0277]: the trait bound `String: Copy` is not satisfied
2 --> $DIR/type-alias-bounds.rs:23:12
3 |
4LL | let _: AliasConstUnused<String>;
5 | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
6 |
7note: required by a bound in `ct_unused_0::AliasConstUnused`
8 --> $DIR/type-alias-bounds.rs:20:30
9 |
10LL | type AliasConstUnused<T: Copy> = (T, I32<{ DATA }>);
11 | ^^^^ required by this bound in `AliasConstUnused`
12
13error[E0277]: the trait bound `String: Copy` is not satisfied
14 --> $DIR/type-alias-bounds.rs:31:12
15 |
16LL | let _: AliasConstUnused;
17 | ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
18 |
19note: required by a bound in `ct_unused_1::AliasConstUnused`
20 --> $DIR/type-alias-bounds.rs:29:41
21 |
22LL | type AliasConstUnused where String: Copy = I32<{ 0; 0 }>;
23 | ^^^^ required by this bound in `AliasConstUnused`
24
25error[E0277]: the trait bound `String: Copy` is not satisfied
26 --> $DIR/type-alias-bounds.rs:39:12
27 |
28LL | let _: AliasFnUnused<String>;
29 | ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
30 |
31note: required by a bound in `AliasFnUnused`
32 --> $DIR/type-alias-bounds.rs:36:27
33 |
34LL | type AliasFnUnused<T: Copy> = (T, I32<{ code() }>);
35 | ^^^^ required by this bound in `AliasFnUnused`
36
37error[E0277]: the trait bound `String: Copy` is not satisfied
38 --> $DIR/type-alias-bounds.rs:57:12
39 |
40LL | let _: AliasAssocConstUsed<String>;
41 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
42 |
43note: required by a bound in `AliasAssocConstUsed`
44 --> $DIR/type-alias-bounds.rs:55:41
45 |
46LL | type AliasAssocConstUsed<T: Trait + Copy> = I32<{ T::DATA }>;
47 | ^^^^ required by this bound in `AliasAssocConstUsed`
48
49error[E0277]: the trait bound `String: Copy` is not satisfied
50 --> $DIR/type-alias-bounds.rs:65:12
51 |
52LL | let _: AliasFnUsed<String>;
53 | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
54 |
55note: required by a bound in `AliasFnUsed`
56 --> $DIR/type-alias-bounds.rs:62:33
57 |
58LL | type AliasFnUsed<T: Trait + Copy> = I32<{ code::<T>() }>;
59 | ^^^^ required by this bound in `AliasFnUsed`
60
61error: aborting due to 5 previous errors
62
63For more information about this error, try `rustc --explain E0277`.
tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs created+71
...@@ -0,0 +1,71 @@
1//@ revisions: pos neg
2//@[pos] check-pass
3
4#![feature(generic_const_exprs)]
5#![feature(trivial_bounds)] // only used in test case `ct_unused_1`
6#![allow(incomplete_features)]
7
8// FIXME(generic_const_exprs): Revisit this before stabilization.
9// Check that we don't emit the lint `type_alias_bounds` for (eager) type aliases
10// whose RHS contains a const projection (aka uneval'ed const).
11// Since anon consts inherit the parent generics and predicates and we effectively
12// check them before and after instantiaton for well-formedness, the type alias
13// bounds are in every sense "enforced".
14// Note that the test cases whose name ends in "unused" just demonstrate that this
15// holds even if the const projections don't "visibly" capture any generics and/or
16// predicates.
17#![deny(type_alias_bounds)]
18
19fn ct_unused_0() {
20 type AliasConstUnused<T: Copy> = (T, I32<{ DATA }>);
21 const DATA: i32 = 0;
22 #[cfg(neg)]
23 let _: AliasConstUnused<String>;
24 //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
25}
26
27fn ct_unused_1() {
28 #[allow(trivial_bounds)]
29 type AliasConstUnused where String: Copy = I32<{ 0; 0 }>;
30 #[cfg(neg)]
31 let _: AliasConstUnused;
32 //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
33}
34
35fn fn_unused() {
36 type AliasFnUnused<T: Copy> = (T, I32<{ code() }>);
37 const fn code() -> i32 { 0 }
38 #[cfg(neg)]
39 let _: AliasFnUnused<String>;
40 //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
41}
42
43trait Trait {
44 type Proj;
45 const DATA: i32;
46}
47
48impl Trait for String {
49 type Proj = i32;
50 const DATA: i32 = 0;
51}
52
53// Regression test for issue #94398.
54fn assoc_ct_used() {
55 type AliasAssocConstUsed<T: Trait + Copy> = I32<{ T::DATA }>;
56 #[cfg(neg)]
57 let _: AliasAssocConstUsed<String>;
58 //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
59}
60
61fn fn_used() {
62 type AliasFnUsed<T: Trait + Copy> = I32<{ code::<T>() }>;
63 const fn code<T: Trait>() -> i32 { T::DATA }
64 #[cfg(neg)]
65 let _: AliasFnUsed<String>;
66 //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
67}
68
69struct I32<const N: i32>;
70
71fn main() {}
tests/ui/lint/dead-code/unused-impl-for-non-adts.rs created+45
...@@ -0,0 +1,45 @@
1#![deny(dead_code)]
2
3struct Foo; //~ ERROR struct `Foo` is never constructed
4
5trait Trait { //~ ERROR trait `Trait` is never used
6 fn foo(&self) {}
7}
8
9impl Trait for Foo {}
10
11impl Trait for [Foo] {}
12impl<const N: usize> Trait for [Foo; N] {}
13
14impl Trait for *const Foo {}
15impl Trait for *mut Foo {}
16
17impl Trait for &Foo {}
18impl Trait for &&Foo {}
19impl Trait for &mut Foo {}
20
21impl Trait for [&Foo] {}
22impl Trait for &[Foo] {}
23impl Trait for &*const Foo {}
24
25pub trait Trait2 {
26 fn foo(&self) {}
27}
28
29impl Trait2 for Foo {}
30
31impl Trait2 for [Foo] {}
32impl<const N: usize> Trait2 for [Foo; N] {}
33
34impl Trait2 for *const Foo {}
35impl Trait2 for *mut Foo {}
36
37impl Trait2 for &Foo {}
38impl Trait2 for &&Foo {}
39impl Trait2 for &mut Foo {}
40
41impl Trait2 for [&Foo] {}
42impl Trait2 for &[Foo] {}
43impl Trait2 for &*const Foo {}
44
45fn main() {}
tests/ui/lint/dead-code/unused-impl-for-non-adts.stderr created+20
...@@ -0,0 +1,20 @@
1error: struct `Foo` is never constructed
2 --> $DIR/unused-impl-for-non-adts.rs:3:8
3 |
4LL | struct Foo;
5 | ^^^
6 |
7note: the lint level is defined here
8 --> $DIR/unused-impl-for-non-adts.rs:1:9
9 |
10LL | #![deny(dead_code)]
11 | ^^^^^^^^^
12
13error: trait `Trait` is never used
14 --> $DIR/unused-impl-for-non-adts.rs:5:7
15 |
16LL | trait Trait {
17 | ^^^^^
18
19error: aborting due to 2 previous errors
20
tests/ui/macros/issue-118786.rs+1
...@@ -7,6 +7,7 @@ macro_rules! make_macro {...@@ -7,6 +7,7 @@ macro_rules! make_macro {
7 macro_rules! $macro_name {7 macro_rules! $macro_name {
8 //~^ ERROR macro expansion ignores token `{` and any following8 //~^ ERROR macro expansion ignores token `{` and any following
9 //~| ERROR cannot find macro `macro_rules` in this scope9 //~| ERROR cannot find macro `macro_rules` in this scope
10 //~| put a macro name here
10 () => {}11 () => {}
11 }12 }
12 }13 }
tests/ui/macros/issue-118786.stderr+3-3
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1error: macros that expand to items must be delimited with braces or followed by a semicolon1error: macros that expand to items must be delimited with braces or followed by a semicolon
2 --> $DIR/issue-118786.rs:15:132 --> $DIR/issue-118786.rs:16:13
3 |3 |
4LL | make_macro!((meow));4LL | make_macro!((meow));
5 | ^^^^^^5 | ^^^^^^
...@@ -34,10 +34,10 @@ LL | make_macro!((meow));...@@ -34,10 +34,10 @@ LL | make_macro!((meow));
34 | ------------------- in this macro invocation34 | ------------------- in this macro invocation
35 |35 |
36note: maybe you have forgotten to define a name for this `macro_rules!`36note: maybe you have forgotten to define a name for this `macro_rules!`
37 --> $DIR/issue-118786.rs:7:937 --> $DIR/issue-118786.rs:7:20
38 |38 |
39LL | macro_rules! $macro_name {39LL | macro_rules! $macro_name {
40 | ^^^^^^^^^^^40 | ^ put a macro name here
41...41...
42LL | make_macro!((meow));42LL | make_macro!((meow));
43 | ------------------- in this macro invocation43 | ------------------- in this macro invocation
tests/ui/privacy/private-in-public-warn.rs+2-2
...@@ -39,7 +39,7 @@ mod traits {...@@ -39,7 +39,7 @@ mod traits {
39 pub trait PubTr {}39 pub trait PubTr {}
4040
41 pub type Alias<T: PrivTr> = T; //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Alias`41 pub type Alias<T: PrivTr> = T; //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Alias`
42 //~^ WARNING bounds on generic parameters are not enforced in type aliases42 //~^ WARNING bounds on generic parameters in type aliases are not enforced
43 pub trait Tr1: PrivTr {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr1`43 pub trait Tr1: PrivTr {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr1`
44 pub trait Tr2<T: PrivTr> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr2`44 pub trait Tr2<T: PrivTr> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr2`
45 pub trait Tr3 {45 pub trait Tr3 {
...@@ -58,7 +58,7 @@ mod traits_where {...@@ -58,7 +58,7 @@ mod traits_where {
5858
59 pub type Alias<T> where T: PrivTr = T;59 pub type Alias<T> where T: PrivTr = T;
60 //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Alias`60 //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Alias`
61 //~| WARNING where clauses are not enforced in type aliases61 //~| WARNING where clauses on type aliases are not enforced
62 pub trait Tr2<T> where T: PrivTr {}62 pub trait Tr2<T> where T: PrivTr {}
63 //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2`63 //~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2`
64 pub trait Tr3 {64 pub trait Tr3 {
tests/ui/privacy/private-in-public-warn.stderr+18-16
...@@ -395,30 +395,32 @@ note: but type `Priv2` is only usable at visibility `pub(self)`...@@ -395,30 +395,32 @@ note: but type `Priv2` is only usable at visibility `pub(self)`
395LL | struct Priv2;395LL | struct Priv2;
396 | ^^^^^^^^^^^^396 | ^^^^^^^^^^^^
397397
398warning: bounds on generic parameters are not enforced in type aliases398warning: bounds on generic parameters in type aliases are not enforced
399 --> $DIR/private-in-public-warn.rs:41:23399 --> $DIR/private-in-public-warn.rs:41:23
400 |400 |
401LL | pub type Alias<T: PrivTr> = T;401LL | pub type Alias<T: PrivTr> = T;
402 | ^^^^^^402 | --^^^^^^
403 |403 | | |
404 | | will not be checked at usage sites of the type alias
405 | help: remove this bound
406 |
407 = note: this is a known limitation of the type checker that may be lifted in a future edition.
408 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
409 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
404 = note: `#[warn(type_alias_bounds)]` on by default410 = note: `#[warn(type_alias_bounds)]` on by default
405help: the bound will not be checked when the type alias is used, and should be removed
406 |
407LL - pub type Alias<T: PrivTr> = T;
408LL + pub type Alias<T> = T;
409 |
410411
411warning: where clauses are not enforced in type aliases412warning: where clauses on type aliases are not enforced
412 --> $DIR/private-in-public-warn.rs:59:29413 --> $DIR/private-in-public-warn.rs:59:29
413 |414 |
414LL | pub type Alias<T> where T: PrivTr = T;415LL | pub type Alias<T> where T: PrivTr = T;
415 | ^^^^^^^^^416 | ------^^^^^^^^^
416 |417 | | |
417help: the clause will not be checked when the type alias is used, and should be removed418 | | will not be checked at usage sites of the type alias
418 |419 | help: remove this where clause
419LL - pub type Alias<T> where T: PrivTr = T;420 |
420LL + pub type Alias<T> = T;421 = note: this is a known limitation of the type checker that may be lifted in a future edition.
421 |422 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
423 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
422424
423error: aborting due to 34 previous errors; 2 warnings emitted425error: aborting due to 34 previous errors; 2 warnings emitted
424426
tests/ui/resolve/issue-118295.rs+6
...@@ -1,5 +1,11 @@...@@ -1,5 +1,11 @@
1macro_rules! {}1macro_rules! {}
2//~^ ERROR cannot find macro `macro_rules` in this scope2//~^ ERROR cannot find macro `macro_rules` in this scope
3//~| NOTE maybe you have forgotten to define a name for this `macro_rules!`3//~| NOTE maybe you have forgotten to define a name for this `macro_rules!`
4//~| put a macro name here
5
6macro_rules!{}
7//~^ ERROR cannot find macro `macro_rules` in this scope
8//~| NOTE maybe you have forgotten to define a name for this `macro_rules!`
9//~| put a macro name here
410
5fn main() {}11fn main() {}
tests/ui/resolve/issue-118295.stderr+15-3
...@@ -1,14 +1,26 @@...@@ -1,14 +1,26 @@
1error: cannot find macro `macro_rules` in this scope1error: cannot find macro `macro_rules` in this scope
2 --> $DIR/issue-118295.rs:1:12 --> $DIR/issue-118295.rs:6:1
3 |3 |
4LL | macro_rules! {}4LL | macro_rules!{}
5 | ^^^^^^^^^^^5 | ^^^^^^^^^^^
6 |6 |
7note: maybe you have forgotten to define a name for this `macro_rules!`7note: maybe you have forgotten to define a name for this `macro_rules!`
8 --> $DIR/issue-118295.rs:6:12
9 |
10LL | macro_rules!{}
11 | ^ put a macro name here
12
13error: cannot find macro `macro_rules` in this scope
8 --> $DIR/issue-118295.rs:1:114 --> $DIR/issue-118295.rs:1:1
9 |15 |
10LL | macro_rules! {}16LL | macro_rules! {}
11 | ^^^^^^^^^^^17 | ^^^^^^^^^^^
18 |
19note: maybe you have forgotten to define a name for this `macro_rules!`
20 --> $DIR/issue-118295.rs:1:12
21 |
22LL | macro_rules! {}
23 | ^ put a macro name here
1224
13error: aborting due to 1 previous error25error: aborting due to 2 previous errors
1426
tests/ui/resolve/issue-55673.stderr+1-1
...@@ -19,7 +19,7 @@ help: consider further restricting type parameter `T`...@@ -19,7 +19,7 @@ help: consider further restricting type parameter `T`
19 |19 |
20LL | T::Baa: std::fmt::Debug, T: Foo20LL | T::Baa: std::fmt::Debug, T: Foo
21 | ~~~~~~~~21 | ~~~~~~~~
22help: and also change the associated type name22help: ...and changing the associated type name
23 |23 |
24LL | T::Bar: std::fmt::Debug,24LL | T::Bar: std::fmt::Debug,
25 | ~~~25 | ~~~
tests/ui/trivial-bounds/trivial-bounds-inconsistent.stderr+9-8
...@@ -24,18 +24,19 @@ warning: trait bound i32: Foo does not depend on any type or lifetime parameters...@@ -24,18 +24,19 @@ warning: trait bound i32: Foo does not depend on any type or lifetime parameters
24LL | union U where i32: Foo { f: i32 }24LL | union U where i32: Foo { f: i32 }
25 | ^^^25 | ^^^
2626
27warning: where clauses are not enforced in type aliases27warning: where clauses on type aliases are not enforced
28 --> $DIR/trivial-bounds-inconsistent.rs:22:1428 --> $DIR/trivial-bounds-inconsistent.rs:22:14
29 |29 |
30LL | type Y where i32: Foo = ();30LL | type Y where i32: Foo = ();
31 | ^^^^^^^^31 | ------^^^^^^^^
32 |32 | | |
33 | | will not be checked at usage sites of the type alias
34 | help: remove this where clause
35 |
36 = note: this is a known limitation of the type checker that may be lifted in a future edition.
37 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
38 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
33 = note: `#[warn(type_alias_bounds)]` on by default39 = note: `#[warn(type_alias_bounds)]` on by default
34help: the clause will not be checked when the type alias is used, and should be removed
35 |
36LL - type Y where i32: Foo = ();
37LL + type Y = ();
38 |
3940
40warning: trait bound i32: Foo does not depend on any type or lifetime parameters41warning: trait bound i32: Foo does not depend on any type or lifetime parameters
41 --> $DIR/trivial-bounds-inconsistent.rs:22:1942 --> $DIR/trivial-bounds-inconsistent.rs:22:19
tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.eager.stderr created+36
...@@ -0,0 +1,36 @@
1error[E0220]: associated type `Assoc` not found for `T`
2 --> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22
3 |
4LL | type AssocOf<T> = T::Assoc;
5 | ^^^^^ there is an associated type `Assoc` in the trait `Trait`
6 |
7help: consider fully qualifying the associated type
8 |
9LL | type AssocOf<T> = <T as Trait>::Assoc;
10 | + +++++++++
11
12error[E0220]: associated type `Assok` not found for `T`
13 --> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22
14 |
15LL | type AssokOf<T> = T::Assok;
16 | ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait`
17 |
18help: consider fully qualifying and renaming the associated type
19 |
20LL | type AssokOf<T> = <T as Trait>::Assoc;
21 | + +++++++++ ~~~~~
22
23error[E0220]: associated type `Proj` not found for `T`
24 --> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21
25 |
26LL | type ProjOf<T> = T::Proj;
27 | ^^^^ there is an associated type `Proj` in the trait `Parametrized`
28 |
29help: consider fully qualifying the associated type
30 |
31LL | type ProjOf<T> = <T as Parametrized</* 'a, T, N */>>::Proj;
32 | + ++++++++++++++++++++++++++++++++
33
34error: aborting due to 3 previous errors
35
36For more information about this error, try `rustc --explain E0220`.
tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.lazy.stderr created+40
...@@ -0,0 +1,40 @@
1error[E0220]: associated type `Assoc` not found for `T`
2 --> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22
3 |
4LL | type AssocOf<T> = T::Assoc;
5 | ^^^^^ there is an associated type `Assoc` in the trait `Trait`
6 |
7help: consider restricting type parameter `T`
8 |
9LL | type AssocOf<T: Trait> = T::Assoc;
10 | +++++++
11
12error[E0220]: associated type `Assok` not found for `T`
13 --> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22
14 |
15LL | type AssokOf<T> = T::Assok;
16 | ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait`
17 |
18help: consider restricting type parameter `T`
19 |
20LL | type AssokOf<T: Trait> = T::Assok;
21 | +++++++
22help: ...and changing the associated type name
23 |
24LL | type AssokOf<T> = T::Assoc;
25 | ~~~~~
26
27error[E0220]: associated type `Proj` not found for `T`
28 --> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21
29 |
30LL | type ProjOf<T> = T::Proj;
31 | ^^^^ there is an associated type `Proj` in the trait `Parametrized`
32 |
33help: consider restricting type parameter `T`
34 |
35LL | type ProjOf<T: Parametrized</* 'a, T, N */>> = T::Proj;
36 | ++++++++++++++++++++++++++++++
37
38error: aborting due to 3 previous errors
39
40For more information about this error, try `rustc --explain E0220`.
tests/ui/type-alias/unresolved-assoc-ty-suggest-trait.rs created+26
...@@ -0,0 +1,26 @@
1// Ensure that we don't suggest *type alias bounds* for **eager** type aliases.
2// issue: rust-lang/rust#125789
3
4//@ revisions: eager lazy
5#![cfg_attr(lazy, feature(lazy_type_alias), allow(incomplete_features))]
6
7trait Trait { type Assoc; }
8
9type AssocOf<T> = T::Assoc; //~ ERROR associated type `Assoc` not found for `T`
10//[eager]~^ HELP consider fully qualifying the associated type
11//[lazy]~| HELP consider restricting type parameter `T`
12
13type AssokOf<T> = T::Assok; //~ ERROR associated type `Assok` not found for `T`
14//[eager]~^ HELP consider fully qualifying and renaming the associated type
15//[lazy]~| HELP consider restricting type parameter `T`
16//[lazy]~| HELP and changing the associated type name
17
18trait Parametrized<'a, T, const N: usize> {
19 type Proj;
20}
21
22type ProjOf<T> = T::Proj; //~ ERROR associated type `Proj` not found for `T`
23//[eager]~^ HELP consider fully qualifying the associated type
24//[lazy]~| HELP consider restricting type parameter `T`
25
26fn main() {}
tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs+1-1
...@@ -3,6 +3,6 @@...@@ -3,6 +3,6 @@
33
4//@ check-pass4//@ check-pass
5pub type T<P: Send + Send + Send> = P;5pub type T<P: Send + Send + Send> = P;
6//~^ WARN bounds on generic parameters are not enforced in type aliases6//~^ WARN bounds on generic parameters in type aliases are not enforced
77
8fn main() {}8fn main() {}
tests/ui/type/issue-67690-type-alias-bound-diagnostic-crash.stderr+8-7
...@@ -1,15 +1,16 @@...@@ -1,15 +1,16 @@
1warning: bounds on generic parameters are not enforced in type aliases1warning: bounds on generic parameters in type aliases are not enforced
2 --> $DIR/issue-67690-type-alias-bound-diagnostic-crash.rs:5:152 --> $DIR/issue-67690-type-alias-bound-diagnostic-crash.rs:5:15
3 |3 |
4LL | pub type T<P: Send + Send + Send> = P;4LL | pub type T<P: Send + Send + Send> = P;
5 | ^^^^ ^^^^ ^^^^5 | --^^^^---^^^^---^^^^
6 | | |
7 | | will not be checked at usage sites of the type alias
8 | help: remove this bound
6 |9 |
10 = note: this is a known limitation of the type checker that may be lifted in a future edition.
11 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
12 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
7 = note: `#[warn(type_alias_bounds)]` on by default13 = note: `#[warn(type_alias_bounds)]` on by default
8help: the bound will not be checked when the type alias is used, and should be removed
9 |
10LL - pub type T<P: Send + Send + Send> = P;
11LL + pub type T<P> = P;
12 |
1314
14warning: 1 warning emitted15warning: 1 warning emitted
1516
tests/ui/type/type-alias-bounds.rs+11-10
...@@ -6,15 +6,15 @@...@@ -6,15 +6,15 @@
6use std::rc::Rc;6use std::rc::Rc;
77
8type SVec<T: Send + Send> = Vec<T>;8type SVec<T: Send + Send> = Vec<T>;
9//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]9//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds]
10type S2Vec<T> where T: Send = Vec<T>;10type S2Vec<T> where T: Send = Vec<T>;
11//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds]11//~^ WARN where clauses on type aliases are not enforced [type_alias_bounds]
12type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);12type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);
13//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]13//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds]
14type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);14type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);
15//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]15//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds]
16type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);16type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
17//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds]17//~^ WARN where clauses on type aliases are not enforced [type_alias_bounds]
1818
19static STATIC: u32 = 0;19static STATIC: u32 = 0;
2020
...@@ -42,10 +42,11 @@ fn foo<'a>(y: &'a i32) {...@@ -42,10 +42,11 @@ fn foo<'a>(y: &'a i32) {
42struct Sendable<T: Send>(T);42struct Sendable<T: Send>(T);
43type MySendable<T> = Sendable<T>; // no error here!43type MySendable<T> = Sendable<T>; // no error here!
4444
45// However, bounds *are* taken into account when accessing associated types45// Bounds on type params do enable shorthand type alias paths.
46// However, that doesn't actually mean that they are properly enforced.
46trait Bound { type Assoc; }47trait Bound { type Assoc; }
47type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases48type T1<U: Bound> = U::Assoc; //~ WARN are not enforced
48type T2<U> where U: Bound = U::Assoc; //~ WARN not enforced in type aliases49type T2<U> where U: Bound = U::Assoc; //~ WARN are not enforced
4950
50// This errors:51// This errors:
51// `type T3<U> = U::Assoc;`52// `type T3<U> = U::Assoc;`
...@@ -53,7 +54,7 @@ type T2<U> where U: Bound = U::Assoc; //~ WARN not enforced in type aliases...@@ -53,7 +54,7 @@ type T2<U> where U: Bound = U::Assoc; //~ WARN not enforced in type aliases
53type T4<U> = <U as Bound>::Assoc;54type T4<U> = <U as Bound>::Assoc;
5455
55// Make sure the help about associated types is not shown incorrectly56// Make sure the help about associated types is not shown incorrectly
56type T5<U: Bound> = <U as Bound>::Assoc; //~ WARN not enforced in type aliases57type T5<U: Bound> = <U as Bound>::Assoc; //~ WARN are not enforced
57type T6<U: Bound> = ::std::vec::Vec<U>; //~ WARN not enforced in type aliases58type T6<U: Bound> = ::std::vec::Vec<U>; //~ WARN are not enforced
5859
59fn main() {}60fn main() {}
tests/ui/type/type-alias-bounds.stderr+87-76
...@@ -1,121 +1,132 @@...@@ -1,121 +1,132 @@
1warning: bounds on generic parameters are not enforced in type aliases1warning: bounds on generic parameters in type aliases are not enforced
2 --> $DIR/type-alias-bounds.rs:8:142 --> $DIR/type-alias-bounds.rs:8:14
3 |3 |
4LL | type SVec<T: Send + Send> = Vec<T>;4LL | type SVec<T: Send + Send> = Vec<T>;
5 | ^^^^ ^^^^5 | --^^^^---^^^^
6 |6 | | |
7 | | will not be checked at usage sites of the type alias
8 | help: remove this bound
9 |
10 = note: this is a known limitation of the type checker that may be lifted in a future edition.
11 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
12 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
7 = note: `#[warn(type_alias_bounds)]` on by default13 = note: `#[warn(type_alias_bounds)]` on by default
8help: the bound will not be checked when the type alias is used, and should be removed
9 |
10LL - type SVec<T: Send + Send> = Vec<T>;
11LL + type SVec<T> = Vec<T>;
12 |
1314
14warning: where clauses are not enforced in type aliases15warning: where clauses on type aliases are not enforced
15 --> $DIR/type-alias-bounds.rs:10:2116 --> $DIR/type-alias-bounds.rs:10:21
16 |17 |
17LL | type S2Vec<T> where T: Send = Vec<T>;18LL | type S2Vec<T> where T: Send = Vec<T>;
18 | ^^^^^^^19 | ------^^^^^^^
19 |20 | | |
20help: the clause will not be checked when the type alias is used, and should be removed21 | | will not be checked at usage sites of the type alias
21 |22 | help: remove this where clause
22LL - type S2Vec<T> where T: Send = Vec<T>;23 |
23LL + type S2Vec<T> = Vec<T>;24 = note: this is a known limitation of the type checker that may be lifted in a future edition.
24 |25 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
26 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
2527
26warning: bounds on generic parameters are not enforced in type aliases28warning: bounds on generic parameters in type aliases are not enforced
27 --> $DIR/type-alias-bounds.rs:12:1929 --> $DIR/type-alias-bounds.rs:12:19
28 |30 |
29LL | type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);31LL | type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);
30 | ^^ ^^32 | --^^---^^
31 |33 | | |
32help: the bound will not be checked when the type alias is used, and should be removed34 | | will not be checked at usage sites of the type alias
33 |35 | help: remove this bound
34LL - type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);36 |
35LL + type VVec<'b, 'a> = (&'b u32, Vec<&'a i32>);37 = note: this is a known limitation of the type checker that may be lifted in a future edition.
36 |38 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
39 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
3740
38warning: bounds on generic parameters are not enforced in type aliases41warning: bounds on generic parameters in type aliases are not enforced
39 --> $DIR/type-alias-bounds.rs:14:1842 --> $DIR/type-alias-bounds.rs:14:18
40 |43 |
41LL | type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);44LL | type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);
42 | ^^ ^^45 | --^^---^^
43 |46 | | |
44help: the bound will not be checked when the type alias is used, and should be removed47 | | will not be checked at usage sites of the type alias
45 |48 | help: remove this bound
46LL - type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);49 |
47LL + type WVec<'b, T> = (&'b u32, Vec<T>);50 = note: this is a known limitation of the type checker that may be lifted in a future edition.
48 |51 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
52 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
4953
50warning: where clauses are not enforced in type aliases54warning: where clauses on type aliases are not enforced
51 --> $DIR/type-alias-bounds.rs:16:2555 --> $DIR/type-alias-bounds.rs:16:25
52 |56 |
53LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);57LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
54 | ^^^^^ ^^^^^58 | ------^^^^^--^^^^^
55 |59 | | |
56help: the clause will not be checked when the type alias is used, and should be removed60 | | will not be checked at usage sites of the type alias
57 |61 | help: remove this where clause
58LL - type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);62 |
59LL + type W2Vec<'b, T> = (&'b u32, Vec<T>);63 = note: this is a known limitation of the type checker that may be lifted in a future edition.
60 |64 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
65 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
6166
62warning: bounds on generic parameters are not enforced in type aliases67warning: bounds on generic parameters in type aliases are not enforced
63 --> $DIR/type-alias-bounds.rs:47:1268 --> $DIR/type-alias-bounds.rs:48:12
64 |69 |
65LL | type T1<U: Bound> = U::Assoc;70LL | type T1<U: Bound> = U::Assoc;
66 | ^^^^^71 | ^^^^^ will not be checked at usage sites of the type alias
67 |72 |
68help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases73 = note: this is a known limitation of the type checker that may be lifted in a future edition.
69 --> $DIR/type-alias-bounds.rs:47:2174 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
70 |75 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
71LL | type T1<U: Bound> = U::Assoc;76help: remove this bound
72 | ^^^^^^^^
73help: the bound will not be checked when the type alias is used, and should be removed
74 |77 |
75LL - type T1<U: Bound> = U::Assoc;78LL - type T1<U: Bound> = U::Assoc;
76LL + type T1<U> = U::Assoc;79LL + type T1<U> = U::Assoc;
77 |80 |
81help: fully qualify this associated type
82 |
83LL | type T1<U: Bound> = <U as /* Trait */>::Assoc;
84 | + +++++++++++++++
7885
79warning: where clauses are not enforced in type aliases86warning: where clauses on type aliases are not enforced
80 --> $DIR/type-alias-bounds.rs:48:1887 --> $DIR/type-alias-bounds.rs:49:18
81 |88 |
82LL | type T2<U> where U: Bound = U::Assoc;89LL | type T2<U> where U: Bound = U::Assoc;
83 | ^^^^^^^^90 | ^^^^^^^^ will not be checked at usage sites of the type alias
84 |91 |
85help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases92 = note: this is a known limitation of the type checker that may be lifted in a future edition.
86 --> $DIR/type-alias-bounds.rs:48:2993 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
87 |94 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
88LL | type T2<U> where U: Bound = U::Assoc;95help: remove this where clause
89 | ^^^^^^^^
90help: the clause will not be checked when the type alias is used, and should be removed
91 |96 |
92LL - type T2<U> where U: Bound = U::Assoc;97LL - type T2<U> where U: Bound = U::Assoc;
93LL + type T2<U> = U::Assoc;98LL + type T2<U> = U::Assoc;
94 |99 |
100help: fully qualify this associated type
101 |
102LL | type T2<U> where U: Bound = <U as /* Trait */>::Assoc;
103 | + +++++++++++++++
95104
96warning: bounds on generic parameters are not enforced in type aliases105warning: bounds on generic parameters in type aliases are not enforced
97 --> $DIR/type-alias-bounds.rs:56:12106 --> $DIR/type-alias-bounds.rs:57:12
98 |107 |
99LL | type T5<U: Bound> = <U as Bound>::Assoc;108LL | type T5<U: Bound> = <U as Bound>::Assoc;
100 | ^^^^^109 | --^^^^^
101 |110 | | |
102help: the bound will not be checked when the type alias is used, and should be removed111 | | will not be checked at usage sites of the type alias
103 |112 | help: remove this bound
104LL - type T5<U: Bound> = <U as Bound>::Assoc;113 |
105LL + type T5<U> = <U as Bound>::Assoc;114 = note: this is a known limitation of the type checker that may be lifted in a future edition.
106 |115 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
116 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
107117
108warning: bounds on generic parameters are not enforced in type aliases118warning: bounds on generic parameters in type aliases are not enforced
109 --> $DIR/type-alias-bounds.rs:57:12119 --> $DIR/type-alias-bounds.rs:58:12
110 |120 |
111LL | type T6<U: Bound> = ::std::vec::Vec<U>;121LL | type T6<U: Bound> = ::std::vec::Vec<U>;
112 | ^^^^^122 | --^^^^^
113 |123 | | |
114help: the bound will not be checked when the type alias is used, and should be removed124 | | will not be checked at usage sites of the type alias
115 |125 | help: remove this bound
116LL - type T6<U: Bound> = ::std::vec::Vec<U>;126 |
117LL + type T6<U> = ::std::vec::Vec<U>;127 = note: this is a known limitation of the type checker that may be lifted in a future edition.
118 |128 see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
129 = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
119130
120warning: 9 warnings emitted131warning: 9 warnings emitted
121132