mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 23:12:02 +00:00
Auto merge of #123214 - compiler-errors:subst, r=estebank
Assert that ADTs have the right number of args
We're doing it for many other types, let's also do ADTs 😇
This commit is contained in:
commit
40116ad1ed
@ -295,6 +295,8 @@ hir_analysis_not_supported_delegation =
|
|||||||
{$descr} is not supported yet
|
{$descr} is not supported yet
|
||||||
.label = callee defined here
|
.label = callee defined here
|
||||||
|
|
||||||
|
hir_analysis_only_current_traits_adt = `{$name}` is not defined in the current crate
|
||||||
|
|
||||||
hir_analysis_only_current_traits_arbitrary = only traits defined in the current crate can be implemented for arbitrary types
|
hir_analysis_only_current_traits_arbitrary = only traits defined in the current crate can be implemented for arbitrary types
|
||||||
|
|
||||||
hir_analysis_only_current_traits_foreign = this is not defined in the current crate because this is a foreign trait
|
hir_analysis_only_current_traits_foreign = this is not defined in the current crate because this is a foreign trait
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use crate::errors;
|
use crate::errors;
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_middle::ty::{self, AliasKind, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, AliasKind, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::{self, IsFirstInputType};
|
use rustc_trait_selection::traits::{self, IsFirstInputType};
|
||||||
@ -283,9 +283,14 @@ fn emit_orphan_check_error<'tcx>(
|
|||||||
let self_ty = trait_ref.self_ty();
|
let self_ty = trait_ref.self_ty();
|
||||||
Err(match err {
|
Err(match err {
|
||||||
traits::OrphanCheckErr::NonLocalInputType(tys) => {
|
traits::OrphanCheckErr::NonLocalInputType(tys) => {
|
||||||
let (mut opaque, mut foreign, mut name, mut pointer, mut ty_diag) =
|
let mut diag = tcx.dcx().create_err(match self_ty.kind() {
|
||||||
(Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new());
|
ty::Adt(..) => errors::OnlyCurrentTraits::Outside { span: sp, note: () },
|
||||||
let mut sugg = None;
|
_ if self_ty.is_primitive() => {
|
||||||
|
errors::OnlyCurrentTraits::Primitive { span: sp, note: () }
|
||||||
|
}
|
||||||
|
_ => errors::OnlyCurrentTraits::Arbitrary { span: sp, note: () },
|
||||||
|
});
|
||||||
|
|
||||||
for &(mut ty, is_target_ty) in &tys {
|
for &(mut ty, is_target_ty) in &tys {
|
||||||
let span = if matches!(is_target_ty, IsFirstInputType::Yes) {
|
let span = if matches!(is_target_ty, IsFirstInputType::Yes) {
|
||||||
// Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
|
// Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
|
||||||
@ -296,113 +301,86 @@ fn emit_orphan_check_error<'tcx>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
ty = tcx.erase_regions(ty);
|
ty = tcx.erase_regions(ty);
|
||||||
ty = match ty.kind() {
|
|
||||||
// Remove the type arguments from the output, as they are not relevant.
|
|
||||||
// You can think of this as the reverse of `resolve_vars_if_possible`.
|
|
||||||
// That way if we had `Vec<MyType>`, we will properly attribute the
|
|
||||||
// problem to `Vec<T>` and avoid confusing the user if they were to see
|
|
||||||
// `MyType` in the error.
|
|
||||||
ty::Adt(def, _) => Ty::new_adt(tcx, *def, ty::List::empty()),
|
|
||||||
_ => ty,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn push_to_foreign_or_name<'tcx>(
|
|
||||||
is_foreign: bool,
|
|
||||||
foreign: &mut Vec<errors::OnlyCurrentTraitsForeign>,
|
|
||||||
name: &mut Vec<errors::OnlyCurrentTraitsName<'tcx>>,
|
|
||||||
span: Span,
|
|
||||||
sname: &'tcx str,
|
|
||||||
) {
|
|
||||||
if is_foreign {
|
|
||||||
foreign.push(errors::OnlyCurrentTraitsForeign { span })
|
|
||||||
} else {
|
|
||||||
name.push(errors::OnlyCurrentTraitsName { span, name: sname });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let is_foreign =
|
let is_foreign =
|
||||||
!trait_ref.def_id.is_local() && matches!(is_target_ty, IsFirstInputType::No);
|
!trait_ref.def_id.is_local() && matches!(is_target_ty, IsFirstInputType::No);
|
||||||
|
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Slice(_) => {
|
ty::Slice(_) => {
|
||||||
push_to_foreign_or_name(
|
if is_foreign {
|
||||||
is_foreign,
|
diag.subdiagnostic(
|
||||||
&mut foreign,
|
tcx.dcx(),
|
||||||
&mut name,
|
errors::OnlyCurrentTraitsForeign { span },
|
||||||
span,
|
);
|
||||||
"slices",
|
} else {
|
||||||
);
|
diag.subdiagnostic(
|
||||||
|
tcx.dcx(),
|
||||||
|
errors::OnlyCurrentTraitsName { span, name: "slices" },
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ty::Array(..) => {
|
ty::Array(..) => {
|
||||||
push_to_foreign_or_name(
|
if is_foreign {
|
||||||
is_foreign,
|
diag.subdiagnostic(
|
||||||
&mut foreign,
|
tcx.dcx(),
|
||||||
&mut name,
|
errors::OnlyCurrentTraitsForeign { span },
|
||||||
span,
|
);
|
||||||
"arrays",
|
} else {
|
||||||
);
|
diag.subdiagnostic(
|
||||||
|
tcx.dcx(),
|
||||||
|
errors::OnlyCurrentTraitsName { span, name: "arrays" },
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ty::Tuple(..) => {
|
ty::Tuple(..) => {
|
||||||
push_to_foreign_or_name(
|
if is_foreign {
|
||||||
is_foreign,
|
diag.subdiagnostic(
|
||||||
&mut foreign,
|
tcx.dcx(),
|
||||||
&mut name,
|
errors::OnlyCurrentTraitsForeign { span },
|
||||||
span,
|
);
|
||||||
"tuples",
|
} else {
|
||||||
);
|
diag.subdiagnostic(
|
||||||
|
tcx.dcx(),
|
||||||
|
errors::OnlyCurrentTraitsName { span, name: "tuples" },
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ty::Alias(ty::Opaque, ..) => {
|
ty::Alias(ty::Opaque, ..) => {
|
||||||
opaque.push(errors::OnlyCurrentTraitsOpaque { span })
|
diag.subdiagnostic(tcx.dcx(), errors::OnlyCurrentTraitsOpaque { span });
|
||||||
}
|
}
|
||||||
ty::RawPtr(ptr_ty, mutbl) => {
|
ty::RawPtr(ptr_ty, mutbl) => {
|
||||||
if !self_ty.has_param() {
|
if !self_ty.has_param() {
|
||||||
let mut_key = mutbl.prefix_str();
|
diag.subdiagnostic(
|
||||||
sugg = Some(errors::OnlyCurrentTraitsPointerSugg {
|
tcx.dcx(),
|
||||||
wrapper_span: self_ty_span,
|
errors::OnlyCurrentTraitsPointerSugg {
|
||||||
struct_span: full_impl_span.shrink_to_lo(),
|
wrapper_span: self_ty_span,
|
||||||
mut_key,
|
struct_span: full_impl_span.shrink_to_lo(),
|
||||||
ptr_ty,
|
mut_key: mutbl.prefix_str(),
|
||||||
});
|
ptr_ty,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
pointer.push(errors::OnlyCurrentTraitsPointer { span, pointer: ty });
|
diag.subdiagnostic(
|
||||||
|
tcx.dcx(),
|
||||||
|
errors::OnlyCurrentTraitsPointer { span, pointer: ty },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ty::Adt(adt_def, _) => {
|
||||||
|
diag.subdiagnostic(
|
||||||
|
tcx.dcx(),
|
||||||
|
errors::OnlyCurrentTraitsAdt {
|
||||||
|
span,
|
||||||
|
name: tcx.def_path_str(adt_def.did()),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
diag.subdiagnostic(tcx.dcx(), errors::OnlyCurrentTraitsTy { span, ty });
|
||||||
}
|
}
|
||||||
_ => ty_diag.push(errors::OnlyCurrentTraitsTy { span, ty }),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let err_struct = match self_ty.kind() {
|
diag.emit()
|
||||||
ty::Adt(..) => errors::OnlyCurrentTraits::Outside {
|
|
||||||
span: sp,
|
|
||||||
note: (),
|
|
||||||
opaque,
|
|
||||||
foreign,
|
|
||||||
name,
|
|
||||||
pointer,
|
|
||||||
ty: ty_diag,
|
|
||||||
sugg,
|
|
||||||
},
|
|
||||||
_ if self_ty.is_primitive() => errors::OnlyCurrentTraits::Primitive {
|
|
||||||
span: sp,
|
|
||||||
note: (),
|
|
||||||
opaque,
|
|
||||||
foreign,
|
|
||||||
name,
|
|
||||||
pointer,
|
|
||||||
ty: ty_diag,
|
|
||||||
sugg,
|
|
||||||
},
|
|
||||||
_ => errors::OnlyCurrentTraits::Arbitrary {
|
|
||||||
span: sp,
|
|
||||||
note: (),
|
|
||||||
opaque,
|
|
||||||
foreign,
|
|
||||||
name,
|
|
||||||
pointer,
|
|
||||||
ty: ty_diag,
|
|
||||||
sugg,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
tcx.dcx().emit_err(err_struct)
|
|
||||||
}
|
}
|
||||||
traits::OrphanCheckErr::UncoveredTy(param_ty, local_type) => {
|
traits::OrphanCheckErr::UncoveredTy(param_ty, local_type) => {
|
||||||
let mut sp = sp;
|
let mut sp = sp;
|
||||||
|
@ -1376,7 +1376,7 @@ pub struct TyParamSome<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
pub enum OnlyCurrentTraits<'a> {
|
pub enum OnlyCurrentTraits {
|
||||||
#[diag(hir_analysis_only_current_traits_outside, code = E0117)]
|
#[diag(hir_analysis_only_current_traits_outside, code = E0117)]
|
||||||
Outside {
|
Outside {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
@ -1384,18 +1384,6 @@ pub enum OnlyCurrentTraits<'a> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
#[note(hir_analysis_only_current_traits_note)]
|
#[note(hir_analysis_only_current_traits_note)]
|
||||||
note: (),
|
note: (),
|
||||||
#[subdiagnostic]
|
|
||||||
opaque: Vec<OnlyCurrentTraitsOpaque>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
foreign: Vec<OnlyCurrentTraitsForeign>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
name: Vec<OnlyCurrentTraitsName<'a>>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
pointer: Vec<OnlyCurrentTraitsPointer<'a>>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
ty: Vec<OnlyCurrentTraitsTy<'a>>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
|
|
||||||
},
|
},
|
||||||
#[diag(hir_analysis_only_current_traits_primitive, code = E0117)]
|
#[diag(hir_analysis_only_current_traits_primitive, code = E0117)]
|
||||||
Primitive {
|
Primitive {
|
||||||
@ -1404,18 +1392,6 @@ pub enum OnlyCurrentTraits<'a> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
#[note(hir_analysis_only_current_traits_note)]
|
#[note(hir_analysis_only_current_traits_note)]
|
||||||
note: (),
|
note: (),
|
||||||
#[subdiagnostic]
|
|
||||||
opaque: Vec<OnlyCurrentTraitsOpaque>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
foreign: Vec<OnlyCurrentTraitsForeign>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
name: Vec<OnlyCurrentTraitsName<'a>>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
pointer: Vec<OnlyCurrentTraitsPointer<'a>>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
ty: Vec<OnlyCurrentTraitsTy<'a>>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
|
|
||||||
},
|
},
|
||||||
#[diag(hir_analysis_only_current_traits_arbitrary, code = E0117)]
|
#[diag(hir_analysis_only_current_traits_arbitrary, code = E0117)]
|
||||||
Arbitrary {
|
Arbitrary {
|
||||||
@ -1424,18 +1400,6 @@ pub enum OnlyCurrentTraits<'a> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
#[note(hir_analysis_only_current_traits_note)]
|
#[note(hir_analysis_only_current_traits_note)]
|
||||||
note: (),
|
note: (),
|
||||||
#[subdiagnostic]
|
|
||||||
opaque: Vec<OnlyCurrentTraitsOpaque>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
foreign: Vec<OnlyCurrentTraitsForeign>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
name: Vec<OnlyCurrentTraitsName<'a>>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
pointer: Vec<OnlyCurrentTraitsPointer<'a>>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
ty: Vec<OnlyCurrentTraitsTy<'a>>,
|
|
||||||
#[subdiagnostic]
|
|
||||||
sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1445,7 +1409,6 @@ pub struct OnlyCurrentTraitsOpaque {
|
|||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[label(hir_analysis_only_current_traits_foreign)]
|
#[label(hir_analysis_only_current_traits_foreign)]
|
||||||
pub struct OnlyCurrentTraitsForeign {
|
pub struct OnlyCurrentTraitsForeign {
|
||||||
@ -1477,6 +1440,14 @@ pub struct OnlyCurrentTraitsTy<'a> {
|
|||||||
pub ty: Ty<'a>,
|
pub ty: Ty<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
#[label(hir_analysis_only_current_traits_adt)]
|
||||||
|
pub struct OnlyCurrentTraitsAdt {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[multipart_suggestion(
|
#[multipart_suggestion(
|
||||||
hir_analysis_only_current_traits_pointer_sugg,
|
hir_analysis_only_current_traits_pointer_sugg,
|
||||||
|
@ -1624,6 +1624,13 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
|
pub fn new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
|
||||||
|
debug_assert_eq!(
|
||||||
|
tcx.generics_of(def.did()).count(),
|
||||||
|
args.len(),
|
||||||
|
"wrong number of args for ADT: {:#?} vs {:#?}",
|
||||||
|
tcx.generics_of(def.did()).params,
|
||||||
|
args
|
||||||
|
);
|
||||||
Ty::new(tcx, Adt(def, args))
|
Ty::new(tcx, Adt(def, args))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user