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
This commit is contained in:
bors 2024-07-26 08:26:17 +00:00
commit 83d67685ac
58 changed files with 1179 additions and 638 deletions

View File

@ -162,6 +162,7 @@ language_item_table! {
StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None;
Copy, sym::copy, copy_trait, Target::Trait, GenericRequirement::Exact(0);
Clone, sym::clone, clone_trait, Target::Trait, GenericRequirement::None;
CloneFn, sym::clone_fn, clone_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
Sync, sym::sync, sync_trait, Target::Trait, GenericRequirement::Exact(0);
DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, Target::Trait, GenericRequirement::None;
/// The associated item of the `DiscriminantKind` trait.

View File

@ -1,4 +1,4 @@
hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_name}` in bounds of `{$ty_param_name}`
hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_name}` in bounds of `{$qself}`
.label = ambiguous associated {$assoc_kind} `{$assoc_name}`
hir_analysis_ambiguous_lifetime_bound =
@ -12,16 +12,21 @@ hir_analysis_assoc_item_is_private = {$kind} `{$name}` is private
.label = private {$kind}
.defined_here_label = the {$kind} is defined here
hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$ty_param_name}`
hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$qself}`
hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named ->
[true] an
*[false] a similarly named
} associated {$assoc_kind} `{$suggested_name}` in the trait `{$trait_name}`
hir_analysis_assoc_item_not_found_label = associated {$assoc_kind} `{$assoc_name}` not found
hir_analysis_assoc_item_not_found_other_sugg = `{$ty_param_name}` has the following associated {$assoc_kind}
hir_analysis_assoc_item_not_found_other_sugg = `{$qself}` has the following associated {$assoc_kind}
hir_analysis_assoc_item_not_found_similar_in_other_trait_qpath_sugg =
consider fully qualifying{$identically_named ->
[true] {""}
*[false] {" "}and renaming
} the associated {$assoc_kind}
hir_analysis_assoc_item_not_found_similar_in_other_trait_sugg = change the associated {$assoc_kind} name to use `{$suggested_name}` from `{$trait_name}`
hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg = and also change the associated {$assoc_kind} name
hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg = ...and changing the associated {$assoc_kind} name
hir_analysis_assoc_item_not_found_similar_sugg = there is an associated {$assoc_kind} with a similar name
hir_analysis_assoc_kind_mismatch = expected {$expected}, found {$got}

View File

@ -22,7 +22,7 @@ pub struct AmbiguousAssocItem<'a> {
pub span: Span,
pub assoc_kind: &'static str,
pub assoc_name: Ident,
pub ty_param_name: &'a str,
pub qself: &'a str,
}
#[derive(Diagnostic)]
@ -75,7 +75,7 @@ pub struct AssocItemNotFound<'a> {
pub span: Span,
pub assoc_name: Ident,
pub assoc_kind: &'static str,
pub ty_param_name: &'a str,
pub qself: &'a str,
#[subdiagnostic]
pub label: Option<AssocItemNotFoundLabel<'a>>,
#[subdiagnostic]
@ -126,13 +126,32 @@ pub enum AssocItemNotFoundSugg<'a> {
assoc_kind: &'static str,
suggested_name: Symbol,
},
#[suggestion(hir_analysis_assoc_item_not_found_other_sugg, code = "{suggested_name}")]
#[multipart_suggestion(
hir_analysis_assoc_item_not_found_similar_in_other_trait_qpath_sugg,
style = "verbose"
)]
SimilarInOtherTraitQPath {
#[suggestion_part(code = "<")]
lo: Span,
#[suggestion_part(code = " as {trait_ref}>")]
mi: Span,
#[suggestion_part(code = "{suggested_name}")]
hi: Option<Span>,
trait_ref: String,
suggested_name: Symbol,
identically_named: bool,
#[applicability]
applicability: Applicability,
},
#[suggestion(
hir_analysis_assoc_item_not_found_other_sugg,
code = "{suggested_name}",
applicability = "maybe-incorrect"
)]
Other {
#[primary_span]
span: Span,
#[applicability]
applicability: Applicability,
ty_param_name: &'a str,
qself: &'a str,
assoc_kind: &'static str,
suggested_name: Symbol,
},

View File

@ -6,7 +6,6 @@ use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::bug;
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt};
use rustc_span::symbol::Ident;
use rustc_span::{ErrorGuaranteed, Span, Symbol};
@ -16,9 +15,8 @@ use smallvec::SmallVec;
use crate::bounds::Bounds;
use crate::errors;
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
use super::RegionInferReason;
use crate::hir_ty_lowering::HirTyLowerer;
use crate::hir_ty_lowering::{AssocItemQSelf, OnlySelfBounds, PredicateFilter, RegionInferReason};
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Add a `Sized` bound to the `bounds` if appropriate.
@ -288,8 +286,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// one that does define it.
self.probe_single_bound_for_assoc_item(
|| traits::supertraits(tcx, trait_ref),
trait_ref.skip_binder().print_only_trait_name(),
None,
AssocItemQSelf::Trait(trait_ref.def_id()),
assoc_kind,
constraint.ident,
path_span,

View File

@ -3,7 +3,7 @@ use crate::errors::{
ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits,
};
use crate::fluent_generated as fluent;
use crate::hir_ty_lowering::HirTyLowerer;
use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer};
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::unord::UnordMap;
@ -11,9 +11,9 @@ use rustc_errors::MultiSpan;
use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed,
};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, Node};
use rustc_hir::def_id::DefId;
use rustc_middle::bug;
use rustc_middle::query::Key;
use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
@ -116,8 +116,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
pub(super) fn complain_about_assoc_item_not_found<I>(
&self,
all_candidates: impl Fn() -> I,
ty_param_name: &str,
ty_param_def_id: Option<LocalDefId>,
qself: AssocItemQSelf,
assoc_kind: ty::AssocKind,
assoc_name: Ident,
span: Span,
@ -139,7 +138,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
);
}
let assoc_kind_str = super::assoc_kind_str(assoc_kind);
let assoc_kind_str = assoc_kind_str(assoc_kind);
let qself_str = qself.to_string(tcx);
// The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a
// valid span, so we point at the whole path segment instead.
@ -149,7 +149,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
span: if is_dummy { span } else { assoc_name.span },
assoc_name,
assoc_kind: assoc_kind_str,
ty_param_name,
qself: &qself_str,
label: None,
sugg: None,
};
@ -219,19 +219,28 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
suggested_name,
identically_named: suggested_name == assoc_name.name,
});
let hir = tcx.hir();
if let Some(def_id) = ty_param_def_id
&& let parent = hir.get_parent_item(tcx.local_def_id_to_hir_id(def_id))
&& let Some(generics) = hir.get_generics(parent.def_id)
if let AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span) = qself
// Not using `self.item_def_id()` here as that would yield the opaque type itself if we're
// inside an opaque type while we're interested in the overarching type alias (TAIT).
// FIXME: However, for trait aliases, this incorrectly returns the enclosing module...
&& let item_def_id =
tcx.hir().get_parent_item(tcx.local_def_id_to_hir_id(ty_param_def_id))
// FIXME: ...which obviously won't have any generics.
&& let Some(generics) = tcx.hir().get_generics(item_def_id.def_id)
{
if generics.bounds_for_param(def_id).flat_map(|pred| pred.bounds.iter()).any(
|b| match b {
// FIXME: Suggest adding supertrait bounds if we have a `Self` type param.
// FIXME(trait_alias): Suggest adding `Self: Trait` to
// `trait Alias = where Self::Proj:;` with `trait Trait { type Proj; }`.
if generics
.bounds_for_param(ty_param_def_id)
.flat_map(|pred| pred.bounds.iter())
.any(|b| match b {
hir::GenericBound::Trait(t, ..) => {
t.trait_ref.trait_def_id() == Some(best_trait)
}
_ => false,
},
) {
})
{
// The type param already has a bound for `trait_name`, we just need to
// change the associated item.
err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTrait {
@ -242,48 +251,60 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
return self.dcx().emit_err(err);
}
let mut err = self.dcx().create_err(err);
if suggest_constraining_type_param(
tcx,
generics,
&mut err,
&ty_param_name,
&trait_name,
None,
None,
) && suggested_name != assoc_name.name
let trait_args = &ty::GenericArgs::identity_for_item(tcx, best_trait)[1..];
let mut trait_ref = trait_name.clone();
let applicability = if let [arg, args @ ..] = trait_args {
use std::fmt::Write;
write!(trait_ref, "</* {arg}").unwrap();
args.iter().try_for_each(|arg| write!(trait_ref, ", {arg}")).unwrap();
trait_ref += " */>";
Applicability::HasPlaceholders
} else {
Applicability::MaybeIncorrect
};
let identically_named = suggested_name == assoc_name.name;
if let DefKind::TyAlias = tcx.def_kind(item_def_id)
&& !tcx.type_alias_is_lazy(item_def_id)
{
// We suggested constraining a type parameter, but the associated item on it
// was also not an exact match, so we also suggest changing it.
err.span_suggestion_verbose(
assoc_name.span,
fluent::hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg,
err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTraitQPath {
lo: ty_param_span.shrink_to_lo(),
mi: ty_param_span.shrink_to_hi(),
hi: (!identically_named).then_some(assoc_name.span),
trait_ref,
identically_named,
suggested_name,
Applicability::MaybeIncorrect,
);
applicability,
});
} else {
let mut err = self.dcx().create_err(err);
if suggest_constraining_type_param(
tcx, generics, &mut err, &qself_str, &trait_ref, None, None,
) && !identically_named
{
// We suggested constraining a type parameter, but the associated item on it
// was also not an exact match, so we also suggest changing it.
err.span_suggestion_verbose(
assoc_name.span,
fluent::hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg,
suggested_name,
Applicability::MaybeIncorrect,
);
}
return err.emit();
}
return err.emit();
}
return self.dcx().emit_err(err);
}
}
// If we still couldn't find any associated item, and only one associated item exists,
// suggests using it.
// suggest using it.
if let [candidate_name] = all_candidate_names.as_slice() {
// This should still compile, except on `#![feature(associated_type_defaults)]`
// where it could suggests `type A = Self::A`, thus recursing infinitely.
let applicability =
if assoc_kind == ty::AssocKind::Type && tcx.features().associated_type_defaults {
Applicability::Unspecified
} else {
Applicability::MaybeIncorrect
};
err.sugg = Some(errors::AssocItemNotFoundSugg::Other {
span: assoc_name.span,
applicability,
ty_param_name,
qself: &qself_str,
assoc_kind: assoc_kind_str,
suggested_name: *candidate_name,
});
@ -349,10 +370,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
self.dcx().emit_err(errors::AssocKindMismatch {
span,
expected: super::assoc_kind_str(expected),
got: super::assoc_kind_str(got),
expected: assoc_kind_str(expected),
got: assoc_kind_str(got),
expected_because_label,
assoc_kind: super::assoc_kind_str(assoc_item.kind),
assoc_kind: assoc_kind_str(assoc_item.kind),
def_span: tcx.def_span(assoc_item.def_id),
bound_on_assoc_const_label,
wrap_in_braces_sugg,
@ -746,7 +767,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) {
let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id));
in_expr_or_pat = match grandparent {
Node::Expr(_) | Node::Pat(_) => true,
hir::Node::Expr(_) | hir::Node::Pat(_) => true,
_ => false,
};
match bound.trait_ref.path.segments {
@ -1612,3 +1633,11 @@ fn generics_args_err_extend<'a>(
_ => {}
}
}
pub(super) fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
match kind {
ty::AssocKind::Fn => "function",
ty::AssocKind::Const => "constant",
ty::AssocKind::Type => "type",
}
}

View File

@ -55,7 +55,6 @@ use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::wf::object_region_bounds;
use rustc_trait_selection::traits::{self, ObligationCtxt};
use std::fmt::Display;
use std::slice;
/// A path segment that is semantically allowed to have generic arguments.
@ -193,6 +192,25 @@ pub trait HirTyLowerer<'tcx> {
}
}
/// The "qualified self" of an associated item path.
///
/// For diagnostic purposes only.
enum AssocItemQSelf {
Trait(DefId),
TyParam(LocalDefId, Span),
SelfTyAlias,
}
impl AssocItemQSelf {
fn to_string(&self, tcx: TyCtxt<'_>) -> String {
match *self {
Self::Trait(def_id) => tcx.def_path_str(def_id),
Self::TyParam(def_id, _) => tcx.hir().ty_param_name(def_id).to_string(),
Self::SelfTyAlias => kw::SelfUpper.to_string(),
}
}
}
/// New-typed boolean indicating whether explicit late-bound lifetimes
/// are present in a set of generic arguments.
///
@ -802,6 +820,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
fn probe_single_ty_param_bound_for_assoc_ty(
&self,
ty_param_def_id: LocalDefId,
ty_param_span: Span,
assoc_name: Ident,
span: Span,
) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
@ -811,19 +830,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_name).predicates;
debug!("predicates={:#?}", predicates);
let param_name = tcx.hir().ty_param_name(ty_param_def_id);
self.probe_single_bound_for_assoc_item(
|| {
traits::transitive_bounds_that_define_assoc_item(
tcx,
predicates
.iter()
.filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref))),
assoc_name,
)
let trait_refs = predicates
.iter()
.filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_name)
},
param_name,
Some(ty_param_def_id),
AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
ty::AssocKind::Type,
assoc_name,
span,
@ -835,12 +849,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
///
/// This fails if there is no such bound in the list of candidates or if there are multiple
/// candidates in which case it reports ambiguity.
#[instrument(level = "debug", skip(self, all_candidates, ty_param_name, constraint), ret)]
#[instrument(level = "debug", skip(self, all_candidates, qself, constraint), ret)]
fn probe_single_bound_for_assoc_item<I>(
&self,
all_candidates: impl Fn() -> I,
ty_param_name: impl Display,
ty_param_def_id: Option<LocalDefId>,
qself: AssocItemQSelf,
assoc_kind: ty::AssocKind,
assoc_name: Ident,
span: Span,
@ -858,8 +871,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let Some(bound) = matching_candidates.next() else {
let reported = self.complain_about_assoc_item_not_found(
all_candidates,
&ty_param_name.to_string(),
ty_param_def_id,
qself,
assoc_kind,
assoc_name,
span,
@ -872,13 +884,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
if let Some(bound2) = matching_candidates.next() {
debug!(?bound2);
let assoc_kind_str = assoc_kind_str(assoc_kind);
let ty_param_name = &ty_param_name.to_string();
let assoc_kind_str = errors::assoc_kind_str(assoc_kind);
let qself_str = qself.to_string(tcx);
let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
span,
assoc_kind: assoc_kind_str,
assoc_name,
ty_param_name,
qself: &qself_str,
});
// Provide a more specific error code index entry for equality bindings.
err.code(
@ -929,7 +941,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
err.span_suggestion_verbose(
span.with_hi(assoc_name.span.lo()),
"use fully-qualified syntax to disambiguate",
format!("<{ty_param_name} as {}>::", bound.print_only_trait_path()),
format!("<{qself_str} as {}>::", bound.print_only_trait_path()),
Applicability::MaybeIncorrect,
);
}
@ -943,7 +955,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
if !where_bounds.is_empty() {
err.help(format!(
"consider introducing a new type parameter `T` and adding `where` constraints:\
\n where\n T: {ty_param_name},\n{}",
\n where\n T: {qself_str},\n{}",
where_bounds.join(",\n"),
));
}
@ -997,11 +1009,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let tcx = self.tcx();
let assoc_ident = assoc_segment.ident;
let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
path.res
} else {
Res::Err
};
// Check if we have an enum variant or an inherent associated type.
let mut variant_resolution = None;
@ -1038,6 +1045,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
}
let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
path.res
} else {
Res::Err
};
// Find the type of the associated item, and the trait where the associated
// item is declared.
let bound = match (&qself_ty.kind(), qself_res) {
@ -1056,8 +1069,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
ty::Binder::dummy(trait_ref.instantiate_identity()),
)
},
kw::SelfUpper,
None,
AssocItemQSelf::SelfTyAlias,
ty::AssocKind::Type,
assoc_ident,
span,
@ -1069,6 +1081,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
) => self.probe_single_ty_param_bound_for_assoc_ty(
param_did.expect_local(),
qself.span,
assoc_ident,
span,
)?,
@ -2522,11 +2535,3 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
Some(r)
}
}
fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
match kind {
ty::AssocKind::Fn => "function",
ty::AssocKind::Const => "constant",
ty::AssocKind::Type => "type",
}
}

View File

@ -144,13 +144,18 @@ lint_builtin_special_module_name_used_main = found module declaration for main.r
lint_builtin_trivial_bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters
lint_builtin_type_alias_bounds_help = use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
lint_builtin_type_alias_generic_bounds = bounds on generic parameters are not enforced in type aliases
.suggestion = the bound will not be checked when the type alias is used, and should be removed
lint_builtin_type_alias_where_clause = where clauses are not enforced in type aliases
.suggestion = the clause will not be checked when the type alias is used, and should be removed
lint_builtin_type_alias_bounds_enable_feat_help = add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
lint_builtin_type_alias_bounds_label = will not be checked at usage sites of the type alias
lint_builtin_type_alias_bounds_limitation_note = this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
lint_builtin_type_alias_bounds_param_bounds = bounds on generic parameters in type aliases are not enforced
.suggestion = remove {$count ->
[one] this bound
*[other] these bounds
}
lint_builtin_type_alias_bounds_qualify_assoc_tys_sugg = fully qualify this associated type
lint_builtin_type_alias_bounds_where_clause = where clauses on type aliases are not enforced
.suggestion = remove this where clause
lint_builtin_unpermitted_type_init_label = this code causes undefined behavior when executed
lint_builtin_unpermitted_type_init_label_suggestion = help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done

View File

@ -31,12 +31,11 @@ use crate::{
BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents,
BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc,
BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns,
BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasGenericBounds,
BuiltinTypeAliasGenericBoundsSuggestion, BuiltinTypeAliasWhereClause,
BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasBounds,
BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit,
BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe,
BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub,
BuiltinWhileTrue, InvalidAsmLabel, SuggestChangingAssocTypes,
BuiltinWhileTrue, InvalidAsmLabel,
},
EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext,
};
@ -1391,64 +1390,80 @@ declare_lint! {
///
/// ### Explanation
///
/// The trait bounds in a type alias are currently ignored, and should not
/// be included to avoid confusion. This was previously allowed
/// unintentionally; this may become a hard error in the future.
/// Trait and lifetime bounds on generic parameters and in where clauses of
/// type aliases are not checked at usage sites of the type alias. Moreover,
/// they are not thoroughly checked for correctness at their definition site
/// either similar to the aliased type.
///
/// This is a known limitation of the type checker that may be lifted in a
/// future edition. Permitting such bounds in light of this was unintentional.
///
/// While these bounds may have secondary effects such as enabling the use of
/// "shorthand" associated type paths[^1] and affecting the default trait
/// object lifetime[^2] of trait object types passed to the type alias, this
/// should not have been allowed until the aforementioned restrictions of the
/// type checker have been lifted.
///
/// Using such bounds is highly discouraged as they are actively misleading.
///
/// [^1]: I.e., paths of the form `T::Assoc` where `T` is a type parameter
/// bounded by trait `Trait` which defines an associated type called `Assoc`
/// as opposed to a fully qualified path of the form `<T as Trait>::Assoc`.
/// [^2]: <https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes>
TYPE_ALIAS_BOUNDS,
Warn,
"bounds in type aliases are not enforced"
}
declare_lint_pass!(
/// Lint for trait and lifetime bounds in type aliases being mostly ignored.
/// They are relevant when using associated types, but otherwise neither checked
/// at definition site nor enforced at use site.
TypeAliasBounds => [TYPE_ALIAS_BOUNDS]
);
declare_lint_pass!(TypeAliasBounds => [TYPE_ALIAS_BOUNDS]);
impl TypeAliasBounds {
pub(crate) fn is_type_variable_assoc(qpath: &hir::QPath<'_>) -> bool {
match *qpath {
hir::QPath::TypeRelative(ty, _) => {
// If this is a type variable, we found a `T::Assoc`.
match ty.kind {
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => {
matches!(path.res, Res::Def(DefKind::TyParam, _))
}
_ => false,
}
}
hir::QPath::Resolved(..) | hir::QPath::LangItem(..) => false,
pub(crate) fn affects_object_lifetime_defaults(pred: &hir::WherePredicate<'_>) -> bool {
// Bounds of the form `T: 'a` with `T` type param affect object lifetime defaults.
if let hir::WherePredicate::BoundPredicate(pred) = pred
&& pred.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Outlives(_)))
&& pred.bound_generic_params.is_empty() // indeed, even if absent from the RHS
&& pred.bounded_ty.as_generic_param().is_some()
{
return true;
}
false
}
}
impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
let hir::ItemKind::TyAlias(hir_ty, type_alias_generics) = &item.kind else { return };
let hir::ItemKind::TyAlias(hir_ty, generics) = item.kind else { return };
// There must not be a where clause.
if generics.predicates.is_empty() {
return;
}
// Bounds of lazy type aliases and TAITs are respected.
if cx.tcx.type_alias_is_lazy(item.owner_id) {
return;
}
let ty = cx.tcx.type_of(item.owner_id).skip_binder();
if ty.has_inherent_projections() {
// Bounds of type aliases that contain opaque types or inherent projections are
// respected. E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`, `type X =
// Type::Inherent;`.
// FIXME(generic_const_exprs): Revisit this before stabilization.
// See also `tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs`.
let ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
if ty.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION)
&& cx.tcx.features().generic_const_exprs
{
return;
}
// There must not be a where clause
if type_alias_generics.predicates.is_empty() {
return;
}
// NOTE(inherent_associated_types): While we currently do take some bounds in type
// aliases into consideration during IAT *selection*, we don't perform full use+def
// site wfchecking for such type aliases. Therefore TAB should still trigger.
// See also `tests/ui/associated-inherent-types/type-alias-bounds.rs`.
let mut where_spans = Vec::new();
let mut inline_spans = Vec::new();
let mut inline_sugg = Vec::new();
for p in type_alias_generics.predicates {
for p in generics.predicates {
let span = p.span();
if p.in_where_clause() {
where_spans.push(span);
@ -1460,37 +1475,57 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
}
}
let mut suggested_changing_assoc_types = false;
if !where_spans.is_empty() {
let sub = (!suggested_changing_assoc_types).then(|| {
suggested_changing_assoc_types = true;
SuggestChangingAssocTypes { ty: hir_ty }
});
let mut ty = Some(hir_ty);
let enable_feat_help = cx.tcx.sess.is_nightly_build();
if let [.., label_sp] = *where_spans {
cx.emit_span_lint(
TYPE_ALIAS_BOUNDS,
where_spans,
BuiltinTypeAliasWhereClause {
suggestion: type_alias_generics.where_clause_span,
sub,
BuiltinTypeAliasBounds {
in_where_clause: true,
label: label_sp,
enable_feat_help,
suggestions: vec![(generics.where_clause_span, String::new())],
preds: generics.predicates,
ty: ty.take(),
},
);
}
if !inline_spans.is_empty() {
let suggestion = BuiltinTypeAliasGenericBoundsSuggestion { suggestions: inline_sugg };
let sub = (!suggested_changing_assoc_types).then(|| {
suggested_changing_assoc_types = true;
SuggestChangingAssocTypes { ty: hir_ty }
});
if let [.., label_sp] = *inline_spans {
cx.emit_span_lint(
TYPE_ALIAS_BOUNDS,
inline_spans,
BuiltinTypeAliasGenericBounds { suggestion, sub },
BuiltinTypeAliasBounds {
in_where_clause: false,
label: label_sp,
enable_feat_help,
suggestions: inline_sugg,
preds: generics.predicates,
ty,
},
);
}
}
}
pub(crate) struct ShorthandAssocTyCollector {
pub(crate) qselves: Vec<Span>,
}
impl hir::intravisit::Visitor<'_> for ShorthandAssocTyCollector {
fn visit_qpath(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, _: Span) {
// Look for "type-parameter shorthand-associated-types". I.e., paths of the
// form `T::Assoc` with `T` type param. These are reliant on trait bounds.
if let hir::QPath::TypeRelative(qself, _) = qpath
&& qself.as_generic_param().is_some()
{
self.qselves.push(qself.span);
}
hir::intravisit::walk_qpath(self, qpath, id)
}
}
declare_lint! {
/// The `trivial_bounds` lint detects trait bounds that don't depend on
/// any type parameters.

View File

@ -2,14 +2,16 @@
#![allow(rustc::untranslatable_diagnostic)]
use std::num::NonZero;
use crate::errors::RequestedLevel;
use crate::builtin::{InitError, ShorthandAssocTyCollector, TypeAliasBounds};
use crate::errors::{OverruledAttributeSub, RequestedLevel};
use crate::fluent_generated as fluent;
use crate::LateContext;
use rustc_errors::{
codes::*, Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString,
ElidedLifetimeInPathSubdiag, EmissionGuarantee, LintDiagnostic, MultiSpan, SubdiagMessageOp,
Subdiagnostic, SuggestionStyle,
};
use rustc_hir::{def::Namespace, def_id::DefId};
use rustc_hir::{self as hir, def::Namespace, def_id::DefId};
use rustc_macros::{LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::{
inhabitedness::InhabitedPredicate, Clause, PolyExistentialTraitRef, Ty, TyCtxt,
@ -22,10 +24,6 @@ use rustc_span::{
Span, Symbol,
};
use crate::{
builtin::InitError, builtin::TypeAliasBounds, errors::OverruledAttributeSub, LateContext,
};
// array_into_iter.rs
#[derive(LintDiagnostic)]
#[diag(lint_shadowed_into_iter)]
@ -263,62 +261,6 @@ pub struct BuiltinUnreachablePub<'a> {
pub help: Option<()>,
}
pub struct SuggestChangingAssocTypes<'a, 'b> {
pub ty: &'a rustc_hir::Ty<'b>,
}
impl<'a, 'b> Subdiagnostic for SuggestChangingAssocTypes<'a, 'b> {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_f: &F,
) {
// Access to associates types should use `<T as Bound>::Assoc`, which does not need a
// bound. Let's see if this type does that.
// We use a HIR visitor to walk the type.
use rustc_hir::intravisit::{self, Visitor};
struct WalkAssocTypes<'a, 'b, G: EmissionGuarantee> {
err: &'a mut Diag<'b, G>,
}
impl<'a, 'b, G: EmissionGuarantee> Visitor<'_> for WalkAssocTypes<'a, 'b, G> {
fn visit_qpath(
&mut self,
qpath: &rustc_hir::QPath<'_>,
id: rustc_hir::HirId,
span: Span,
) {
if TypeAliasBounds::is_type_variable_assoc(qpath) {
self.err.span_help(span, fluent::lint_builtin_type_alias_bounds_help);
}
intravisit::walk_qpath(self, qpath, id)
}
}
// Let's go for a walk!
let mut visitor = WalkAssocTypes { err: diag };
visitor.visit_ty(self.ty);
}
}
#[derive(LintDiagnostic)]
#[diag(lint_builtin_type_alias_where_clause)]
pub struct BuiltinTypeAliasWhereClause<'a, 'b> {
#[suggestion(code = "", applicability = "machine-applicable")]
pub suggestion: Span,
#[subdiagnostic]
pub sub: Option<SuggestChangingAssocTypes<'a, 'b>>,
}
#[derive(LintDiagnostic)]
#[diag(lint_builtin_type_alias_generic_bounds)]
pub struct BuiltinTypeAliasGenericBounds<'a, 'b> {
#[subdiagnostic]
pub suggestion: BuiltinTypeAliasGenericBoundsSuggestion,
#[subdiagnostic]
pub sub: Option<SuggestChangingAssocTypes<'a, 'b>>,
}
#[derive(LintDiagnostic)]
#[diag(lint_macro_expr_fragment_specifier_2024_migration)]
pub struct MacroExprFragment2024 {
@ -326,21 +268,72 @@ pub struct MacroExprFragment2024 {
pub suggestion: Span,
}
pub struct BuiltinTypeAliasGenericBoundsSuggestion {
pub struct BuiltinTypeAliasBounds<'a, 'hir> {
pub in_where_clause: bool,
pub label: Span,
pub enable_feat_help: bool,
pub suggestions: Vec<(Span, String)>,
pub preds: &'hir [hir::WherePredicate<'hir>],
pub ty: Option<&'a hir::Ty<'hir>>,
}
impl Subdiagnostic for BuiltinTypeAliasGenericBoundsSuggestion {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
_f: &F,
) {
diag.multipart_suggestion(
fluent::lint_suggestion,
self.suggestions,
Applicability::MachineApplicable,
);
impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_, '_> {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.primary_message(if self.in_where_clause {
fluent::lint_builtin_type_alias_bounds_where_clause
} else {
fluent::lint_builtin_type_alias_bounds_param_bounds
});
diag.span_label(self.label, fluent::lint_builtin_type_alias_bounds_label);
diag.note(fluent::lint_builtin_type_alias_bounds_limitation_note);
if self.enable_feat_help {
diag.help(fluent::lint_builtin_type_alias_bounds_enable_feat_help);
}
// We perform the walk in here instead of in `<TypeAliasBounds as LateLintPass>` to
// avoid doing throwaway work in case the lint ends up getting suppressed.
let mut collector = ShorthandAssocTyCollector { qselves: Vec::new() };
if let Some(ty) = self.ty {
hir::intravisit::Visitor::visit_ty(&mut collector, ty);
}
let affect_object_lifetime_defaults = self
.preds
.iter()
.filter(|pred| pred.in_where_clause() == self.in_where_clause)
.any(|pred| TypeAliasBounds::affects_object_lifetime_defaults(pred));
// If there are any shorthand assoc tys, then the bounds can't be removed automatically.
// The user first needs to fully qualify the assoc tys.
let applicability = if !collector.qselves.is_empty() || affect_object_lifetime_defaults {
Applicability::MaybeIncorrect
} else {
Applicability::MachineApplicable
};
diag.arg("count", self.suggestions.len());
diag.multipart_suggestion(fluent::lint_suggestion, self.suggestions, applicability);
// Suggest fully qualifying paths of the form `T::Assoc` with `T` type param via
// `<T as /* Trait */>::Assoc` to remove their reliance on any type param bounds.
//
// Instead of attempting to figure out the necessary trait ref, just use a
// placeholder. Since we don't record type-dependent resolutions for non-body
// items like type aliases, we can't simply deduce the corresp. trait from
// the HIR path alone without rerunning parts of HIR ty lowering here
// (namely `probe_single_ty_param_bound_for_assoc_ty`) which is infeasible.
//
// (We could employ some simple heuristics but that's likely not worth it).
for qself in collector.qselves {
diag.multipart_suggestion(
fluent::lint_builtin_type_alias_bounds_qualify_assoc_tys_sugg,
vec![
(qself.shrink_to_lo(), "<".into()),
(qself.shrink_to_hi(), " as /* Trait */>".into()),
],
Applicability::HasPlaceholders,
);
}
}
}

View File

@ -3,6 +3,7 @@
use crate::simplify::simplify_duplicate_switch_targets;
use crate::take_array;
use rustc_ast::attr;
use rustc_hir::LangItem;
use rustc_middle::bug;
use rustc_middle::mir::*;
use rustc_middle::ty::layout;
@ -271,8 +272,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
return;
}
let trait_def_id = self.tcx.trait_of_item(fn_def_id);
if trait_def_id.is_none() || trait_def_id != self.tcx.lang_items().clone_trait() {
if !self.tcx.is_lang_item(fn_def_id, LangItem::CloneFn) {
return;
}

View File

@ -54,7 +54,24 @@ impl Publicness {
}
}
fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: DefId) -> bool {
fn adt_of<'tcx>(ty: &hir::Ty<'tcx>) -> Option<(LocalDefId, DefKind)> {
match ty.kind {
TyKind::Path(hir::QPath::Resolved(_, path)) => {
if let Res::Def(def_kind, def_id) = path.res
&& let Some(local_def_id) = def_id.as_local()
{
Some((local_def_id, def_kind))
} else {
None
}
}
TyKind::Slice(ty) | TyKind::Array(ty, _) => adt_of(ty),
TyKind::Ptr(ty) | TyKind::Ref(_, ty) => adt_of(ty.ty),
_ => None,
}
}
fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: LocalDefId) -> bool {
// treat PhantomData and positional ZST as public,
// we don't want to lint types which only have them,
// 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 {
/// for enum and union, just check they are public,
/// and doesn't solve types like &T for now, just skip them
fn ty_ref_to_pub_struct(tcx: TyCtxt<'_>, ty: &hir::Ty<'_>) -> Publicness {
if let TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
&& let Res::Def(def_kind, def_id) = path.res
&& def_id.is_local()
{
if let Some((def_id, def_kind)) = adt_of(ty) {
return match def_kind {
DefKind::Enum | DefKind::Union => {
let ty_is_public = tcx.visibility(def_id).is_public();
@ -565,10 +579,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
}
fn impl_item_with_used_self(&mut self, impl_id: hir::ItemId, impl_item_id: LocalDefId) -> bool {
if let TyKind::Path(hir::QPath::Resolved(_, path)) =
self.tcx.hir().item(impl_id).expect_impl().self_ty.kind
&& let Res::Def(def_kind, def_id) = path.res
&& let Some(local_def_id) = def_id.as_local()
if let Some((local_def_id, def_kind)) =
adt_of(self.tcx.hir().item(impl_id).expect_impl().self_ty)
&& matches!(def_kind, DefKind::Struct | DefKind::Enum | DefKind::Union)
{
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(
match tcx.def_kind(id) {
DefKind::Impl { .. } => false,
DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => !matches!(tcx.associated_item(id).container, AssocItemContainer::ImplContainer),
DefKind::Struct => struct_all_fields_are_public(tcx, id.to_def_id()) || has_allow_dead_code_or_lang_attr(tcx, id).is_some(),
DefKind::Struct => struct_all_fields_are_public(tcx, id) || has_allow_dead_code_or_lang_attr(tcx, id).is_some(),
_ => true
})
.map(|id| (id, ComesFromAllowExpect::No))

View File

@ -1448,7 +1448,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
);
if macro_kind == MacroKind::Bang && ident.name == sym::macro_rules {
err.subdiagnostic(MaybeMissingMacroRulesName { span: ident.span });
let label_span = ident.span.shrink_to_hi();
let mut spans = MultiSpan::from_span(label_span);
spans.push_span_label(label_span, "put a macro name here");
err.subdiagnostic(MaybeMissingMacroRulesName { spans: spans });
return;
}

View File

@ -669,7 +669,7 @@ pub(crate) struct MacroSuggMovePosition {
#[note(resolve_missing_macro_rules_name)]
pub(crate) struct MaybeMissingMacroRulesName {
#[primary_span]
pub(crate) span: Span,
pub(crate) spans: MultiSpan,
}
#[derive(Subdiagnostic)]

View File

@ -557,6 +557,7 @@ symbols! {
clobber_abi,
clone,
clone_closures,
clone_fn,
clone_from,
closure,
closure_lifetime_binder,

View File

@ -241,10 +241,6 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
self.has_type_flags(TypeFlags::HAS_ALIAS)
}
fn has_inherent_projections(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_INHERENT)
}
fn has_opaque_types(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
}

View File

@ -160,6 +160,9 @@ pub trait Clone: Sized {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "cloning is often expensive and is not expected to have side effects"]
// Clone::clone is special because the compiler generates MIR to implement it for some types.
// See InstanceKind::CloneShim.
#[cfg_attr(not(bootstrap), lang = "clone_fn")]
fn clone(&self) -> Self;
/// Performs copy-assignment from `source`.

View File

@ -201,6 +201,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"only-wasm32-wasip1",
"only-watchos",
"only-windows",
"only-windows-gnu",
"only-x86",
"only-x86_64",
"only-x86_64-fortanix-unknown-sgx",

View File

@ -15,6 +15,13 @@ pub fn cc() -> Cc {
Cc::new()
}
/// Construct a new platform-specific CXX compiler invocation.
/// CXX_DEFAULT_FLAGS is passed from compiletest.
#[track_caller]
pub fn cxx() -> Cc {
Cc::new_cxx()
}
/// A platform-specific C compiler invocation builder. The specific C compiler used is
/// passed down from compiletest.
#[derive(Debug)]
@ -44,6 +51,22 @@ impl Cc {
Self { cmd }
}
/// Construct a new platform-specific CXX compiler invocation.
/// CXX_DEFAULT_FLAGS is passed from compiletest.
#[track_caller]
pub fn new_cxx() -> Self {
let compiler = env_var("CXX");
let mut cmd = Command::new(compiler);
let default_cflags = env_var("CXX_DEFAULT_FLAGS");
for flag in default_cflags.split(char::is_whitespace) {
cmd.arg(flag);
}
Self { cmd }
}
/// Specify path of the input file.
pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.arg(path.as_ref());

View File

@ -44,7 +44,7 @@ pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rust
// These rely on external dependencies.
pub use c_build::{build_native_dynamic_lib, build_native_static_lib};
pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc};
pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
pub use clang::{clang, Clang};
pub use htmldocck::htmldocck;
pub use llvm::{

View File

@ -2,7 +2,6 @@ run-make/branch-protection-check-IBT/Makefile
run-make/c-unwind-abi-catch-lib-panic/Makefile
run-make/cat-and-grep-sanity-check/Makefile
run-make/cdylib-dylib-linkage/Makefile
run-make/compiler-rt-works-on-mingw/Makefile
run-make/cross-lang-lto-clang/Makefile
run-make/cross-lang-lto-pgo-smoketest/Makefile
run-make/cross-lang-lto-upstream-rlibs/Makefile
@ -10,18 +9,14 @@ run-make/cross-lang-lto/Makefile
run-make/dep-info-doesnt-run-much/Makefile
run-make/dep-info-spaces/Makefile
run-make/dep-info/Makefile
run-make/dump-ice-to-disk/Makefile
run-make/emit-to-stdout/Makefile
run-make/export-executable-symbols/Makefile
run-make/extern-flag-disambiguates/Makefile
run-make/extern-fn-reachable/Makefile
run-make/fmt-write-bloat/Makefile
run-make/foreign-double-unwind/Makefile
run-make/foreign-exceptions/Makefile
run-make/foreign-rust-exceptions/Makefile
run-make/incr-add-rust-src-component/Makefile
run-make/incr-foreign-head-span/Makefile
run-make/interdependent-c-libraries/Makefile
run-make/issue-35164/Makefile
run-make/issue-36710/Makefile
run-make/issue-47551/Makefile
@ -42,7 +37,6 @@ run-make/native-link-modifier-bundle/Makefile
run-make/native-link-modifier-whole-archive/Makefile
run-make/no-alloc-shim/Makefile
run-make/no-builtins-attribute/Makefile
run-make/panic-abort-eh_frame/Makefile
run-make/pdb-buildinfo-cl-cmd/Makefile
run-make/pgo-gen-lto/Makefile
run-make/pgo-indirect-call-promotion/Makefile

View File

@ -41,3 +41,8 @@ The setup for the `rmake.rs` version is a 3-stage process:
[`run_make_support`]: ../../src/tools/run-make-support
[extern_prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude
### Formatting
Note that files under `tests/` are not formatted by `./x fmt`,
use `rustfmt tests/path/to/file.rs` to format a specific file if desired.

View File

@ -1,9 +0,0 @@
include ../tools.mk
# only-windows-gnu
all:
$(CXX) foo.cpp -c -o $(TMPDIR)/foo.o
$(AR) crus $(TMPDIR)/libfoo.a $(TMPDIR)/foo.o
$(RUSTC) foo.rs -lfoo -lstdc++
$(call RUN,foo)

View File

@ -0,0 +1,15 @@
// `compiler-rt` ("runtime") is a suite of LLVM features compatible with rustc.
// After building it was enabled on Windows-gnu in #29874, this test is a basic smoke test to
// check if building and linking to it can work at all.
// See https://github.com/rust-lang/rust/pull/29478
//@ only-windows-gnu
use run_make_support::{cxx, is_msvc, llvm_ar, run, rustc, static_lib_name};
fn main() {
cxx().input("foo.cpp").arg("-c").out_exe("foo.o").run();
llvm_ar().obj_to_ar().output_input(static_lib_name("foo"), "foo.o").run();
rustc().input("foo.rs").arg("-lfoo").arg("-lstdc++").run();
run("foo");
}

View File

@ -1,10 +0,0 @@
include ../tools.mk
# ignore-windows
export RUSTC := $(RUSTC_ORIGINAL)
export LD_LIBRARY_PATH := $(HOST_RPATH_DIR)
export TMPDIR := $(TMPDIR)
all:
bash check.sh

View File

@ -1,64 +0,0 @@
#!/bin/sh
# Default nightly behavior (write ICE to current directory)
# FIXME(estebank): these are failing on CI, but passing locally.
# $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-default.log 2>&1
# default=$(cat ./rustc-ice-*.txt | wc -l)
# rm ./rustc-ice-*.txt
# Explicit directory set
export RUSTC_ICE=$TMPDIR
$RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-default-set.log 2>&1
default_set=$(cat $TMPDIR/rustc-ice-*.txt | wc -l)
content=$(cat $TMPDIR/rustc-ice-*.txt)
# Ensure that the ICE dump path doesn't contain `:` because they cause problems on Windows
windows_safe=$(echo rustc-ice-*.txt | grep ':')
if [ ! -z "$windows_safe" ]; then
exit 1
fi
rm $TMPDIR/rustc-ice-*.txt
RUST_BACKTRACE=short $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-short.log 2>&1
short=$(cat $TMPDIR/rustc-ice-*.txt | wc -l)
rm $TMPDIR/rustc-ice-*.txt
RUST_BACKTRACE=full $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-full.log 2>&1
full=$(cat $TMPDIR/rustc-ice-*.txt | wc -l)
rm $TMPDIR/rustc-ice-*.txt
# Explicitly disabling ICE dump
export RUSTC_ICE=0
$RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-disabled.log 2>&1
should_be_empty_tmp=$(ls -l $TMPDIR/rustc-ice-*.txt 2>/dev/null | wc -l)
should_be_empty_dot=$(ls -l ./rustc-ice-*.txt 2>/dev/null | wc -l)
echo "#### ICE Dump content:"
echo $content
echo "#### default length:"
echo $default
echo "#### short length:"
echo $short
echo "#### default_set length:"
echo $default_set
echo "#### full length:"
echo $full
echo "#### should_be_empty_dot length:"
echo $should_be_empty_dot
echo "#### should_be_empty_tmp length:"
echo $should_be_empty_tmp
## Verify that a the ICE dump file is created in the appropriate directories, that
## their lengths are the same regardless of other backtrace configuration options,
## that the file is not created when asked to (RUSTC_ICE=0) and that the file
## contains at least part of the expected content.
if [ $short -eq $default_set ] &&
#[ $default -eq $short ] &&
[ $default_set -eq $full ] &&
[[ $content == *"thread 'rustc' panicked at "* ]] &&
[[ $content == *"stack backtrace:"* ]] &&
#[ $default -gt 0 ] &&
[ $should_be_empty_dot -eq 0 ] &&
[ $should_be_empty_tmp -eq 0 ]; then
exit 0
else
exit 1
fi

View File

@ -0,0 +1,81 @@
// This test checks if internal compilation error (ICE) log files work as expected.
// - Get the number of lines from the log files without any configuration options,
// then check that the line count doesn't change if the backtrace gets configured to be short
// or full.
// - Check that disabling ICE logging results in zero files created.
// - Check that the ICE files contain some of the expected strings.
// See https://github.com/rust-lang/rust/pull/108714
use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files};
fn main() {
rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
let default = get_text_from_ice(".").lines().count();
clear_ice_files();
rustc().env("RUSTC_ICE", cwd()).input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
let ice_text = get_text_from_ice(cwd());
let default_set = ice_text.lines().count();
let content = ice_text;
let ice_files = shallow_find_files(cwd(), |path| {
has_prefix(path, "rustc-ice") && has_extension(path, "txt")
});
assert_eq!(ice_files.len(), 1); // There should only be 1 ICE file.
let ice_file_name =
ice_files.first().and_then(|f| f.file_name()).and_then(|n| n.to_str()).unwrap();
// Ensure that the ICE dump path doesn't contain `:`, because they cause problems on Windows.
assert!(!ice_file_name.contains(":"), "{ice_file_name}");
clear_ice_files();
rustc()
.env("RUSTC_ICE", cwd())
.input("lib.rs")
.env("RUST_BACKTRACE", "short")
.arg("-Ztreat-err-as-bug=1")
.run_fail();
let short = get_text_from_ice(cwd()).lines().count();
clear_ice_files();
rustc()
.env("RUSTC_ICE", cwd())
.input("lib.rs")
.env("RUST_BACKTRACE", "full")
.arg("-Ztreat-err-as-bug=1")
.run_fail();
let full = get_text_from_ice(cwd()).lines().count();
clear_ice_files();
// The ICE dump is explicitly disabled. Therefore, this should produce no files.
rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
let ice_files = shallow_find_files(cwd(), |path| {
has_prefix(path, "rustc-ice") && has_extension(path, "txt")
});
assert!(ice_files.is_empty()); // There should be 0 ICE files.
// The line count should not change.
assert_eq!(short, default_set);
assert_eq!(short, default);
assert_eq!(full, default_set);
assert!(default > 0);
// Some of the expected strings in an ICE file should appear.
assert!(content.contains("thread 'rustc' panicked at"));
assert!(content.contains("stack backtrace:"));
}
fn clear_ice_files() {
let ice_files = shallow_find_files(cwd(), |path| {
has_prefix(path, "rustc-ice") && has_extension(path, "txt")
});
for file in ice_files {
rfs::remove_file(file);
}
}
#[track_caller]
fn get_text_from_ice(dir: impl AsRef<std::path::Path>) -> String {
let ice_files =
shallow_find_files(dir, |path| has_prefix(path, "rustc-ice") && has_extension(path, "txt"));
assert_eq!(ice_files.len(), 1); // There should only be 1 ICE file.
let ice_file = ice_files.get(0).unwrap();
let output = rfs::read_to_string(ice_file);
output
}

View File

@ -1,26 +0,0 @@
# ignore-cross-compile
include ../tools.mk
# Attempt to build this dependency tree:
#
# A.1 A.2
# |\ |
# | \ |
# B \ C
# \ | /
# \|/
# D
#
# Note that A.1 and A.2 are crates with the same name.
all:
$(RUSTC) -C metadata=1 -C extra-filename=-1 a.rs
$(RUSTC) -C metadata=2 -C extra-filename=-2 a.rs
$(RUSTC) b.rs --extern a=$(TMPDIR)/liba-1.rlib
$(RUSTC) c.rs --extern a=$(TMPDIR)/liba-2.rlib
@echo before
$(RUSTC) --cfg before d.rs --extern a=$(TMPDIR)/liba-1.rlib
$(call RUN,d)
@echo after
$(RUSTC) --cfg after d.rs --extern a=$(TMPDIR)/liba-1.rlib
$(call RUN,d)

View File

@ -0,0 +1,30 @@
//@ ignore-cross-compile
use run_make_support::{cwd, run, rustc};
// Attempt to build this dependency tree:
//
// A.1 A.2
// |\ |
// | \ |
// B \ C
// \ | /
// \|/
// D
//
// Note that A.1 and A.2 are crates with the same name.
// original Makefile at https://github.com/rust-lang/rust/issues/14469
fn main() {
rustc().metadata("1").extra_filename("-1").input("a.rs").run();
rustc().metadata("2").extra_filename("-2").input("a.rs").run();
rustc().input("b.rs").extern_("a", "liba-1.rlib").run();
rustc().input("c.rs").extern_("a", "liba-2.rlib").run();
println!("before");
rustc().cfg("before").input("d.rs").extern_("a", "liba-1.rlib").run();
run("d");
println!("after");
rustc().cfg("after").input("d.rs").extern_("a", "liba-1.rlib").run();
run("d");
}

View File

@ -1,21 +0,0 @@
include ../tools.mk
# ignore-none no-std is not supported
# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for 'std'
# Ensure that modifying a crate on disk (without recompiling it)
# does not cause ICEs in downstream crates.
# Previously, we would call `SourceMap.guess_head_span` on a span
# from an external crate, which would cause us to read an upstream
# source file from disk during compilation of a downstream crate
# See #86480 for more details
INCR=$(TMPDIR)/incr
all:
cp first_crate.rs second_crate.rs $(TMPDIR)
$(RUSTC) $(TMPDIR)/first_crate.rs -C incremental=$(INCR) --target $(TARGET) --crate-type lib
$(RUSTC) $(TMPDIR)/second_crate.rs -C incremental=$(INCR) --target $(TARGET) --extern first_crate=$(TMPDIR)/libfirst_crate.rlib --crate-type lib
rm $(TMPDIR)/first_crate.rs
$(RUSTC) $(TMPDIR)/second_crate.rs -C incremental=$(INCR) --target $(TARGET) --cfg second_run --crate-type lib

View File

@ -0,0 +1,25 @@
// Ensure that modifying a crate on disk (without recompiling it)
// does not cause ICEs (internal compiler errors) in downstream crates.
// Previously, we would call `SourceMap.guess_head_span` on a span
// from an external crate, which would cause us to read an upstream
// source file from disk during compilation of a downstream crate.
// See https://github.com/rust-lang/rust/issues/86480
//@ ignore-none
// Reason: no-std is not supported
//@ ignore-nvptx64-nvidia-cuda
// Reason: can't find crate for 'std'
use run_make_support::{rfs, rust_lib_name, rustc};
fn main() {
rustc().input("first_crate.rs").incremental("incr").crate_type("lib").run();
rustc()
.input("second_crate.rs")
.incremental("incr")
.extern_("first_crate", rust_lib_name("first_crate"))
.crate_type("lib")
.run();
rfs::remove_file("first_crate.rs");
rustc().input("second_crate.rs").incremental("incr").cfg("second_run").crate_type("lib").run();
}

View File

@ -1,15 +0,0 @@
# ignore-cross-compile
include ../tools.mk
# The rust crate foo will link to the native library foo, while the rust crate
# bar will link to the native library bar. There is also a dependency between
# the native library bar to the natibe library foo.
#
# This test ensures that the ordering of -lfoo and -lbar on the command line is
# correct to complete the linkage. If passed as "-lfoo -lbar", then the 'foo'
# library will be stripped out, and the linkage will fail.
all: $(call NATIVE_STATICLIB,foo) $(call NATIVE_STATICLIB,bar)
$(RUSTC) foo.rs
$(RUSTC) bar.rs
$(RUSTC) main.rs --print link-args

View File

@ -0,0 +1,21 @@
// The rust crate foo will link to the native library foo, while the rust crate
// bar will link to the native library bar. There is also a dependency between
// the native library bar to the natibe library foo.
// This test ensures that the ordering of -lfoo and -lbar on the command line is
// correct to complete the linkage. If passed as "-lfoo -lbar", then the 'foo'
// library will be stripped out, and the linkage will fail.
// See https://github.com/rust-lang/rust/commit/e6072fa0c4c22d62acf3dcb78c8ee260a1368bd7
//@ ignore-cross-compile
// Reason: linkage still fails as the object files produced are not in the correct
// format in the `build_native_static_lib` step
use run_make_support::{build_native_static_lib, rustc};
fn main() {
build_native_static_lib("foo");
build_native_static_lib("bar");
rustc().input("foo.rs").run();
rustc().input("bar.rs").run();
rustc().input("main.rs").print("link-args").run();
}

View File

@ -1,10 +0,0 @@
# only-linux
#
# This test ensures that `panic=abort` code (without `C-unwind`, that is) should not have any
# unwinding related `.eh_frame` sections emitted.
include ../tools.mk
all:
$(RUSTC) foo.rs --crate-type=lib --emit=obj=$(TMPDIR)/foo.o -Cpanic=abort --edition 2021 -Z validate-mir
objdump --dwarf=frames $(TMPDIR)/foo.o | $(CGREP) -v 'DW_CFA'

View File

@ -0,0 +1,24 @@
// An `.eh_frame` section in an object file is a symptom of an UnwindAction::Terminate
// being inserted, useful for determining whether or not unwinding is necessary.
// This is useless when panics would NEVER unwind due to -C panic=abort. This section should
// therefore never appear in the emit file of a -C panic=abort compilation, and this test
// checks that this is respected.
// See https://github.com/rust-lang/rust/pull/112403
//@ only-linux
// FIXME(Oneirical): the DW_CFA symbol appears on Windows-gnu, because uwtable
// is forced to true on Windows targets (see #128136).
use run_make_support::{llvm_objdump, rustc};
fn main() {
rustc()
.input("foo.rs")
.crate_type("lib")
.emit("obj=foo.o")
.panic("abort")
.edition("2021")
.arg("-Zvalidate-mir")
.run();
llvm_objdump().arg("--dwarf=frames").input("foo.o").run().assert_stdout_not_contains("DW_CFA");
}

View File

@ -1,20 +0,0 @@
//@ compile-flags: --crate-type=lib
//@ check-pass
#![feature(inherent_associated_types)]
#![allow(incomplete_features)]
// Bounds on the self type play a major role in the resolution of inherent associated types (*).
// As a result of that, if a type alias contains any then its bounds have to be respected and the
// lint `type_alias_bounds` should not fire.
#![deny(type_alias_bounds)]
pub type Alias<T: Bound> = (Source<T>::Assoc,);
pub struct Source<T>(T);
pub trait Bound {}
impl<T: Bound> Source<T> {
pub type Assoc = ();
}

View File

@ -0,0 +1,29 @@
//@ compile-flags: --crate-type=lib
//@ check-pass
#![feature(inherent_associated_types)]
#![allow(incomplete_features)]
// FIXME(inherent_associated_types):
// While we currently do take some clauses of the ParamEnv into consideration
// when performing IAT selection, we do not perform full well-formedness checking
// for (eager) type alias definition and usage sites.
//
// Therefore it's *correct* for lint `type_alias_bounds` to fire here despite the
// fact that removing `Bound` from `T` in `Alias` would lead to an error!
//
// Obviously, the present situation isn't ideal and we should fix it in one way
// or another. Either we somehow delay IAT selection until after HIR ty lowering
// to avoid the need to specify any bounds inside (eager) type aliases or we
// force the overarching type alias to be *lazy* (similar to TAITs) which would
// automatically lead to full wfchecking and lint TAB getting suppressed.
pub type Alias<T: Bound> = (Source<T>::Assoc,);
//~^ WARN bounds on generic parameters in type aliases are not enforced
pub struct Source<T>(T);
pub trait Bound {}
impl<T: Bound> Source<T> {
pub type Assoc = ();
}

View File

@ -0,0 +1,16 @@
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/type-alias-bounds.rs:21:19
|
LL | pub type Alias<T: Bound> = (Source<T>::Assoc,);
| --^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
= note: `#[warn(type_alias_bounds)]` on by default
warning: 1 warning emitted

View File

@ -1,147 +1,159 @@
warning: where clauses are not enforced in type aliases
warning: where clauses on type aliases are not enforced
--> $DIR/type-alias.rs:3:25
|
LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
| ^^^^^^^^^^^^^^^^^^^^^^^
| ------^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this where clause
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
= note: `#[warn(type_alias_bounds)]` on by default
help: the clause will not be checked when the type alias is used, and should be removed
|
LL - type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
LL + type _TaWhere1<T> = T;
|
warning: where clauses are not enforced in type aliases
warning: where clauses on type aliases are not enforced
--> $DIR/type-alias.rs:4:25
|
LL | type _TaWhere2<T> where T: Iterator<Item: 'static> = T;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: the clause will not be checked when the type alias is used, and should be removed
|
LL - type _TaWhere2<T> where T: Iterator<Item: 'static> = T;
LL + type _TaWhere2<T> = T;
| ------^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this where clause
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: where clauses are not enforced in type aliases
warning: where clauses on type aliases are not enforced
--> $DIR/type-alias.rs:5:25
|
LL | type _TaWhere3<T> where T: Iterator<Item: 'static> = T;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: the clause will not be checked when the type alias is used, and should be removed
|
LL - type _TaWhere3<T> where T: Iterator<Item: 'static> = T;
LL + type _TaWhere3<T> = T;
| ------^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this where clause
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: where clauses are not enforced in type aliases
warning: where clauses on type aliases are not enforced
--> $DIR/type-alias.rs:6:25
|
LL | type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: the clause will not be checked when the type alias is used, and should be removed
|
LL - type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T;
LL + type _TaWhere4<T> = T;
| ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this where clause
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: where clauses are not enforced in type aliases
warning: where clauses on type aliases are not enforced
--> $DIR/type-alias.rs:7:25
|
LL | type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: the clause will not be checked when the type alias is used, and should be removed
|
LL - type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T;
LL + type _TaWhere5<T> = T;
| ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this where clause
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: where clauses are not enforced in type aliases
warning: where clauses on type aliases are not enforced
--> $DIR/type-alias.rs:8:25
|
LL | type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: the clause will not be checked when the type alias is used, and should be removed
|
LL - type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T;
LL + type _TaWhere6<T> = T;
| ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this where clause
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: bounds on generic parameters are not enforced in type aliases
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/type-alias.rs:10:20
|
LL | type _TaInline1<T: Iterator<Item: Copy>> = T;
| ^^^^^^^^^^^^^^^^^^^^
|
help: the bound will not be checked when the type alias is used, and should be removed
|
LL - type _TaInline1<T: Iterator<Item: Copy>> = T;
LL + type _TaInline1<T> = T;
| --^^^^^^^^^^^^^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: bounds on generic parameters are not enforced in type aliases
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/type-alias.rs:11:20
|
LL | type _TaInline2<T: Iterator<Item: 'static>> = T;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: the bound will not be checked when the type alias is used, and should be removed
|
LL - type _TaInline2<T: Iterator<Item: 'static>> = T;
LL + type _TaInline2<T> = T;
| --^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: bounds on generic parameters are not enforced in type aliases
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/type-alias.rs:12:20
|
LL | type _TaInline3<T: Iterator<Item: 'static>> = T;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: the bound will not be checked when the type alias is used, and should be removed
|
LL - type _TaInline3<T: Iterator<Item: 'static>> = T;
LL + type _TaInline3<T> = T;
| --^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: bounds on generic parameters are not enforced in type aliases
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/type-alias.rs:13:20
|
LL | type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: the bound will not be checked when the type alias is used, and should be removed
|
LL - type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T;
LL + type _TaInline4<T> = T;
| --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: bounds on generic parameters are not enforced in type aliases
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/type-alias.rs:14:20
|
LL | type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: the bound will not be checked when the type alias is used, and should be removed
|
LL - type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T;
LL + type _TaInline5<T> = T;
| --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: bounds on generic parameters are not enforced in type aliases
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/type-alias.rs:15:20
|
LL | type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: the bound will not be checked when the type alias is used, and should be removed
|
LL - type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T;
LL + type _TaInline6<T> = T;
| --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: 12 warnings emitted

View File

@ -0,0 +1,63 @@
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/type-alias-bounds.rs:23:12
|
LL | let _: AliasConstUnused<String>;
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
|
note: required by a bound in `ct_unused_0::AliasConstUnused`
--> $DIR/type-alias-bounds.rs:20:30
|
LL | type AliasConstUnused<T: Copy> = (T, I32<{ DATA }>);
| ^^^^ required by this bound in `AliasConstUnused`
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/type-alias-bounds.rs:31:12
|
LL | let _: AliasConstUnused;
| ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
|
note: required by a bound in `ct_unused_1::AliasConstUnused`
--> $DIR/type-alias-bounds.rs:29:41
|
LL | type AliasConstUnused where String: Copy = I32<{ 0; 0 }>;
| ^^^^ required by this bound in `AliasConstUnused`
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/type-alias-bounds.rs:39:12
|
LL | let _: AliasFnUnused<String>;
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
|
note: required by a bound in `AliasFnUnused`
--> $DIR/type-alias-bounds.rs:36:27
|
LL | type AliasFnUnused<T: Copy> = (T, I32<{ code() }>);
| ^^^^ required by this bound in `AliasFnUnused`
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/type-alias-bounds.rs:57:12
|
LL | let _: AliasAssocConstUsed<String>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
|
note: required by a bound in `AliasAssocConstUsed`
--> $DIR/type-alias-bounds.rs:55:41
|
LL | type AliasAssocConstUsed<T: Trait + Copy> = I32<{ T::DATA }>;
| ^^^^ required by this bound in `AliasAssocConstUsed`
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/type-alias-bounds.rs:65:12
|
LL | let _: AliasFnUsed<String>;
| ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
|
note: required by a bound in `AliasFnUsed`
--> $DIR/type-alias-bounds.rs:62:33
|
LL | type AliasFnUsed<T: Trait + Copy> = I32<{ code::<T>() }>;
| ^^^^ required by this bound in `AliasFnUsed`
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -0,0 +1,71 @@
//@ revisions: pos neg
//@[pos] check-pass
#![feature(generic_const_exprs)]
#![feature(trivial_bounds)] // only used in test case `ct_unused_1`
#![allow(incomplete_features)]
// FIXME(generic_const_exprs): Revisit this before stabilization.
// Check that we don't emit the lint `type_alias_bounds` for (eager) type aliases
// whose RHS contains a const projection (aka uneval'ed const).
// Since anon consts inherit the parent generics and predicates and we effectively
// check them before and after instantiaton for well-formedness, the type alias
// bounds are in every sense "enforced".
// Note that the test cases whose name ends in "unused" just demonstrate that this
// holds even if the const projections don't "visibly" capture any generics and/or
// predicates.
#![deny(type_alias_bounds)]
fn ct_unused_0() {
type AliasConstUnused<T: Copy> = (T, I32<{ DATA }>);
const DATA: i32 = 0;
#[cfg(neg)]
let _: AliasConstUnused<String>;
//[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
}
fn ct_unused_1() {
#[allow(trivial_bounds)]
type AliasConstUnused where String: Copy = I32<{ 0; 0 }>;
#[cfg(neg)]
let _: AliasConstUnused;
//[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
}
fn fn_unused() {
type AliasFnUnused<T: Copy> = (T, I32<{ code() }>);
const fn code() -> i32 { 0 }
#[cfg(neg)]
let _: AliasFnUnused<String>;
//[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
}
trait Trait {
type Proj;
const DATA: i32;
}
impl Trait for String {
type Proj = i32;
const DATA: i32 = 0;
}
// Regression test for issue #94398.
fn assoc_ct_used() {
type AliasAssocConstUsed<T: Trait + Copy> = I32<{ T::DATA }>;
#[cfg(neg)]
let _: AliasAssocConstUsed<String>;
//[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
}
fn fn_used() {
type AliasFnUsed<T: Trait + Copy> = I32<{ code::<T>() }>;
const fn code<T: Trait>() -> i32 { T::DATA }
#[cfg(neg)]
let _: AliasFnUsed<String>;
//[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
}
struct I32<const N: i32>;
fn main() {}

View File

@ -0,0 +1,45 @@
#![deny(dead_code)]
struct Foo; //~ ERROR struct `Foo` is never constructed
trait Trait { //~ ERROR trait `Trait` is never used
fn foo(&self) {}
}
impl Trait for Foo {}
impl Trait for [Foo] {}
impl<const N: usize> Trait for [Foo; N] {}
impl Trait for *const Foo {}
impl Trait for *mut Foo {}
impl Trait for &Foo {}
impl Trait for &&Foo {}
impl Trait for &mut Foo {}
impl Trait for [&Foo] {}
impl Trait for &[Foo] {}
impl Trait for &*const Foo {}
pub trait Trait2 {
fn foo(&self) {}
}
impl Trait2 for Foo {}
impl Trait2 for [Foo] {}
impl<const N: usize> Trait2 for [Foo; N] {}
impl Trait2 for *const Foo {}
impl Trait2 for *mut Foo {}
impl Trait2 for &Foo {}
impl Trait2 for &&Foo {}
impl Trait2 for &mut Foo {}
impl Trait2 for [&Foo] {}
impl Trait2 for &[Foo] {}
impl Trait2 for &*const Foo {}
fn main() {}

View File

@ -0,0 +1,20 @@
error: struct `Foo` is never constructed
--> $DIR/unused-impl-for-non-adts.rs:3:8
|
LL | struct Foo;
| ^^^
|
note: the lint level is defined here
--> $DIR/unused-impl-for-non-adts.rs:1:9
|
LL | #![deny(dead_code)]
| ^^^^^^^^^
error: trait `Trait` is never used
--> $DIR/unused-impl-for-non-adts.rs:5:7
|
LL | trait Trait {
| ^^^^^
error: aborting due to 2 previous errors

View File

@ -7,6 +7,7 @@ macro_rules! make_macro {
macro_rules! $macro_name {
//~^ ERROR macro expansion ignores token `{` and any following
//~| ERROR cannot find macro `macro_rules` in this scope
//~| put a macro name here
() => {}
}
}

View File

@ -1,5 +1,5 @@
error: macros that expand to items must be delimited with braces or followed by a semicolon
--> $DIR/issue-118786.rs:15:13
--> $DIR/issue-118786.rs:16:13
|
LL | make_macro!((meow));
| ^^^^^^
@ -34,10 +34,10 @@ LL | make_macro!((meow));
| ------------------- in this macro invocation
|
note: maybe you have forgotten to define a name for this `macro_rules!`
--> $DIR/issue-118786.rs:7:9
--> $DIR/issue-118786.rs:7:20
|
LL | macro_rules! $macro_name {
| ^^^^^^^^^^^
| ^ put a macro name here
...
LL | make_macro!((meow));
| ------------------- in this macro invocation

View File

@ -39,7 +39,7 @@ mod traits {
pub trait PubTr {}
pub type Alias<T: PrivTr> = T; //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Alias`
//~^ WARNING bounds on generic parameters are not enforced in type aliases
//~^ WARNING bounds on generic parameters in type aliases are not enforced
pub trait Tr1: PrivTr {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr1`
pub trait Tr2<T: PrivTr> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr2`
pub trait Tr3 {
@ -58,7 +58,7 @@ mod traits_where {
pub type Alias<T> where T: PrivTr = T;
//~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Alias`
//~| WARNING where clauses are not enforced in type aliases
//~| WARNING where clauses on type aliases are not enforced
pub trait Tr2<T> where T: PrivTr {}
//~^ ERROR trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2`
pub trait Tr3 {

View File

@ -395,30 +395,32 @@ note: but type `Priv2` is only usable at visibility `pub(self)`
LL | struct Priv2;
| ^^^^^^^^^^^^
warning: bounds on generic parameters are not enforced in type aliases
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/private-in-public-warn.rs:41:23
|
LL | pub type Alias<T: PrivTr> = T;
| ^^^^^^
| --^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
= note: `#[warn(type_alias_bounds)]` on by default
help: the bound will not be checked when the type alias is used, and should be removed
|
LL - pub type Alias<T: PrivTr> = T;
LL + pub type Alias<T> = T;
|
warning: where clauses are not enforced in type aliases
warning: where clauses on type aliases are not enforced
--> $DIR/private-in-public-warn.rs:59:29
|
LL | pub type Alias<T> where T: PrivTr = T;
| ^^^^^^^^^
|
help: the clause will not be checked when the type alias is used, and should be removed
|
LL - pub type Alias<T> where T: PrivTr = T;
LL + pub type Alias<T> = T;
| ------^^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this where clause
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
error: aborting due to 34 previous errors; 2 warnings emitted

View File

@ -1,5 +1,11 @@
macro_rules! {}
//~^ ERROR cannot find macro `macro_rules` in this scope
//~| NOTE maybe you have forgotten to define a name for this `macro_rules!`
//~| put a macro name here
macro_rules!{}
//~^ ERROR cannot find macro `macro_rules` in this scope
//~| NOTE maybe you have forgotten to define a name for this `macro_rules!`
//~| put a macro name here
fn main() {}

View File

@ -1,3 +1,15 @@
error: cannot find macro `macro_rules` in this scope
--> $DIR/issue-118295.rs:6:1
|
LL | macro_rules!{}
| ^^^^^^^^^^^
|
note: maybe you have forgotten to define a name for this `macro_rules!`
--> $DIR/issue-118295.rs:6:12
|
LL | macro_rules!{}
| ^ put a macro name here
error: cannot find macro `macro_rules` in this scope
--> $DIR/issue-118295.rs:1:1
|
@ -5,10 +17,10 @@ LL | macro_rules! {}
| ^^^^^^^^^^^
|
note: maybe you have forgotten to define a name for this `macro_rules!`
--> $DIR/issue-118295.rs:1:1
--> $DIR/issue-118295.rs:1:12
|
LL | macro_rules! {}
| ^^^^^^^^^^^
| ^ put a macro name here
error: aborting due to 1 previous error
error: aborting due to 2 previous errors

View File

@ -19,7 +19,7 @@ help: consider further restricting type parameter `T`
|
LL | T::Baa: std::fmt::Debug, T: Foo
| ~~~~~~~~
help: and also change the associated type name
help: ...and changing the associated type name
|
LL | T::Bar: std::fmt::Debug,
| ~~~

View File

@ -24,18 +24,19 @@ warning: trait bound i32: Foo does not depend on any type or lifetime parameters
LL | union U where i32: Foo { f: i32 }
| ^^^
warning: where clauses are not enforced in type aliases
warning: where clauses on type aliases are not enforced
--> $DIR/trivial-bounds-inconsistent.rs:22:14
|
LL | type Y where i32: Foo = ();
| ^^^^^^^^
| ------^^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this where clause
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
= note: `#[warn(type_alias_bounds)]` on by default
help: the clause will not be checked when the type alias is used, and should be removed
|
LL - type Y where i32: Foo = ();
LL + type Y = ();
|
warning: trait bound i32: Foo does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:22:19

View File

@ -0,0 +1,36 @@
error[E0220]: associated type `Assoc` not found for `T`
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22
|
LL | type AssocOf<T> = T::Assoc;
| ^^^^^ there is an associated type `Assoc` in the trait `Trait`
|
help: consider fully qualifying the associated type
|
LL | type AssocOf<T> = <T as Trait>::Assoc;
| + +++++++++
error[E0220]: associated type `Assok` not found for `T`
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22
|
LL | type AssokOf<T> = T::Assok;
| ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait`
|
help: consider fully qualifying and renaming the associated type
|
LL | type AssokOf<T> = <T as Trait>::Assoc;
| + +++++++++ ~~~~~
error[E0220]: associated type `Proj` not found for `T`
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21
|
LL | type ProjOf<T> = T::Proj;
| ^^^^ there is an associated type `Proj` in the trait `Parametrized`
|
help: consider fully qualifying the associated type
|
LL | type ProjOf<T> = <T as Parametrized</* 'a, T, N */>>::Proj;
| + ++++++++++++++++++++++++++++++++
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0220`.

View File

@ -0,0 +1,40 @@
error[E0220]: associated type `Assoc` not found for `T`
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:9:22
|
LL | type AssocOf<T> = T::Assoc;
| ^^^^^ there is an associated type `Assoc` in the trait `Trait`
|
help: consider restricting type parameter `T`
|
LL | type AssocOf<T: Trait> = T::Assoc;
| +++++++
error[E0220]: associated type `Assok` not found for `T`
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:13:22
|
LL | type AssokOf<T> = T::Assok;
| ^^^^^ there is a similarly named associated type `Assoc` in the trait `Trait`
|
help: consider restricting type parameter `T`
|
LL | type AssokOf<T: Trait> = T::Assok;
| +++++++
help: ...and changing the associated type name
|
LL | type AssokOf<T> = T::Assoc;
| ~~~~~
error[E0220]: associated type `Proj` not found for `T`
--> $DIR/unresolved-assoc-ty-suggest-trait.rs:22:21
|
LL | type ProjOf<T> = T::Proj;
| ^^^^ there is an associated type `Proj` in the trait `Parametrized`
|
help: consider restricting type parameter `T`
|
LL | type ProjOf<T: Parametrized</* 'a, T, N */>> = T::Proj;
| ++++++++++++++++++++++++++++++
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0220`.

View File

@ -0,0 +1,26 @@
// Ensure that we don't suggest *type alias bounds* for **eager** type aliases.
// issue: rust-lang/rust#125789
//@ revisions: eager lazy
#![cfg_attr(lazy, feature(lazy_type_alias), allow(incomplete_features))]
trait Trait { type Assoc; }
type AssocOf<T> = T::Assoc; //~ ERROR associated type `Assoc` not found for `T`
//[eager]~^ HELP consider fully qualifying the associated type
//[lazy]~| HELP consider restricting type parameter `T`
type AssokOf<T> = T::Assok; //~ ERROR associated type `Assok` not found for `T`
//[eager]~^ HELP consider fully qualifying and renaming the associated type
//[lazy]~| HELP consider restricting type parameter `T`
//[lazy]~| HELP and changing the associated type name
trait Parametrized<'a, T, const N: usize> {
type Proj;
}
type ProjOf<T> = T::Proj; //~ ERROR associated type `Proj` not found for `T`
//[eager]~^ HELP consider fully qualifying the associated type
//[lazy]~| HELP consider restricting type parameter `T`
fn main() {}

View File

@ -3,6 +3,6 @@
//@ check-pass
pub type T<P: Send + Send + Send> = P;
//~^ WARN bounds on generic parameters are not enforced in type aliases
//~^ WARN bounds on generic parameters in type aliases are not enforced
fn main() {}

View File

@ -1,15 +1,16 @@
warning: bounds on generic parameters are not enforced in type aliases
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/issue-67690-type-alias-bound-diagnostic-crash.rs:5:15
|
LL | pub type T<P: Send + Send + Send> = P;
| ^^^^ ^^^^ ^^^^
| --^^^^---^^^^---^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
= note: `#[warn(type_alias_bounds)]` on by default
help: the bound will not be checked when the type alias is used, and should be removed
|
LL - pub type T<P: Send + Send + Send> = P;
LL + pub type T<P> = P;
|
warning: 1 warning emitted

View File

@ -6,15 +6,15 @@
use std::rc::Rc;
type SVec<T: Send + Send> = Vec<T>;
//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds]
type S2Vec<T> where T: Send = Vec<T>;
//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds]
//~^ WARN where clauses on type aliases are not enforced [type_alias_bounds]
type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);
//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds]
type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);
//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds]
//~^ WARN bounds on generic parameters in type aliases are not enforced [type_alias_bounds]
type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds]
//~^ WARN where clauses on type aliases are not enforced [type_alias_bounds]
static STATIC: u32 = 0;
@ -42,10 +42,11 @@ fn foo<'a>(y: &'a i32) {
struct Sendable<T: Send>(T);
type MySendable<T> = Sendable<T>; // no error here!
// However, bounds *are* taken into account when accessing associated types
// Bounds on type params do enable shorthand type alias paths.
// However, that doesn't actually mean that they are properly enforced.
trait Bound { type Assoc; }
type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases
type T2<U> where U: Bound = U::Assoc; //~ WARN not enforced in type aliases
type T1<U: Bound> = U::Assoc; //~ WARN are not enforced
type T2<U> where U: Bound = U::Assoc; //~ WARN are not enforced
// This errors:
// `type T3<U> = U::Assoc;`
@ -53,7 +54,7 @@ type T2<U> where U: Bound = U::Assoc; //~ WARN not enforced in type aliases
type T4<U> = <U as Bound>::Assoc;
// Make sure the help about associated types is not shown incorrectly
type T5<U: Bound> = <U as Bound>::Assoc; //~ WARN not enforced in type aliases
type T6<U: Bound> = ::std::vec::Vec<U>; //~ WARN not enforced in type aliases
type T5<U: Bound> = <U as Bound>::Assoc; //~ WARN are not enforced
type T6<U: Bound> = ::std::vec::Vec<U>; //~ WARN are not enforced
fn main() {}

View File

@ -1,121 +1,132 @@
warning: bounds on generic parameters are not enforced in type aliases
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/type-alias-bounds.rs:8:14
|
LL | type SVec<T: Send + Send> = Vec<T>;
| ^^^^ ^^^^
| --^^^^---^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
= note: `#[warn(type_alias_bounds)]` on by default
help: the bound will not be checked when the type alias is used, and should be removed
|
LL - type SVec<T: Send + Send> = Vec<T>;
LL + type SVec<T> = Vec<T>;
|
warning: where clauses are not enforced in type aliases
warning: where clauses on type aliases are not enforced
--> $DIR/type-alias-bounds.rs:10:21
|
LL | type S2Vec<T> where T: Send = Vec<T>;
| ^^^^^^^
|
help: the clause will not be checked when the type alias is used, and should be removed
|
LL - type S2Vec<T> where T: Send = Vec<T>;
LL + type S2Vec<T> = Vec<T>;
| ------^^^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this where clause
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: bounds on generic parameters are not enforced in type aliases
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/type-alias-bounds.rs:12:19
|
LL | type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);
| ^^ ^^
|
help: the bound will not be checked when the type alias is used, and should be removed
|
LL - type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>);
LL + type VVec<'b, 'a> = (&'b u32, Vec<&'a i32>);
| --^^---^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: bounds on generic parameters are not enforced in type aliases
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/type-alias-bounds.rs:14:18
|
LL | type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);
| ^^ ^^
|
help: the bound will not be checked when the type alias is used, and should be removed
|
LL - type WVec<'b, T: 'b + 'b> = (&'b u32, Vec<T>);
LL + type WVec<'b, T> = (&'b u32, Vec<T>);
| --^^---^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: where clauses are not enforced in type aliases
warning: where clauses on type aliases are not enforced
--> $DIR/type-alias-bounds.rs:16:25
|
LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
| ^^^^^ ^^^^^
|
help: the clause will not be checked when the type alias is used, and should be removed
|
LL - type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec<T>);
LL + type W2Vec<'b, T> = (&'b u32, Vec<T>);
| ------^^^^^--^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this where clause
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: bounds on generic parameters are not enforced in type aliases
--> $DIR/type-alias-bounds.rs:47:12
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/type-alias-bounds.rs:48:12
|
LL | type T1<U: Bound> = U::Assoc;
| ^^^^^
| ^^^^^ will not be checked at usage sites of the type alias
|
help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
--> $DIR/type-alias-bounds.rs:47:21
|
LL | type T1<U: Bound> = U::Assoc;
| ^^^^^^^^
help: the bound will not be checked when the type alias is used, and should be removed
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
help: remove this bound
|
LL - type T1<U: Bound> = U::Assoc;
LL + type T1<U> = U::Assoc;
|
help: fully qualify this associated type
|
LL | type T1<U: Bound> = <U as /* Trait */>::Assoc;
| + +++++++++++++++
warning: where clauses are not enforced in type aliases
--> $DIR/type-alias-bounds.rs:48:18
warning: where clauses on type aliases are not enforced
--> $DIR/type-alias-bounds.rs:49:18
|
LL | type T2<U> where U: Bound = U::Assoc;
| ^^^^^^^^
| ^^^^^^^^ will not be checked at usage sites of the type alias
|
help: use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
--> $DIR/type-alias-bounds.rs:48:29
|
LL | type T2<U> where U: Bound = U::Assoc;
| ^^^^^^^^
help: the clause will not be checked when the type alias is used, and should be removed
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
help: remove this where clause
|
LL - type T2<U> where U: Bound = U::Assoc;
LL + type T2<U> = U::Assoc;
|
help: fully qualify this associated type
|
LL | type T2<U> where U: Bound = <U as /* Trait */>::Assoc;
| + +++++++++++++++
warning: bounds on generic parameters are not enforced in type aliases
--> $DIR/type-alias-bounds.rs:56:12
|
LL | type T5<U: Bound> = <U as Bound>::Assoc;
| ^^^^^
|
help: the bound will not be checked when the type alias is used, and should be removed
|
LL - type T5<U: Bound> = <U as Bound>::Assoc;
LL + type T5<U> = <U as Bound>::Assoc;
|
warning: bounds on generic parameters are not enforced in type aliases
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/type-alias-bounds.rs:57:12
|
LL | type T5<U: Bound> = <U as Bound>::Assoc;
| --^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/type-alias-bounds.rs:58:12
|
LL | type T6<U: Bound> = ::std::vec::Vec<U>;
| ^^^^^
|
help: the bound will not be checked when the type alias is used, and should be removed
|
LL - type T6<U: Bound> = ::std::vec::Vec<U>;
LL + type T6<U> = ::std::vec::Vec<U>;
| --^^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
warning: 9 warnings emitted