Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #96904

Merged
merged 17 commits into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use rustc_index::vec::Idx;
use rustc_middle::lint::{in_external_macro, LintDiagnosticBuilder};
use rustc_middle::ty::layout::{LayoutError, LayoutOf};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::subst::{GenericArgKind, Subst};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::Instance;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason};
Expand Down Expand Up @@ -2777,7 +2777,7 @@ impl ClashingExternDeclarations {
let mut ty = ty;
loop {
if let ty::Adt(def, substs) = *ty.kind() {
let is_transparent = def.subst(tcx, substs).repr().transparent();
let is_transparent = def.repr().transparent();
let is_non_null = crate::types::nonnull_optimization_guaranteed(tcx, def);
debug!(
"non_transparent_ty({:?}) -- type is transparent? {}, type is non-null? {}",
Expand Down Expand Up @@ -2837,11 +2837,7 @@ impl ClashingExternDeclarations {

ensure_sufficient_stack(|| {
match (a_kind, b_kind) {
(Adt(a_def, a_substs), Adt(b_def, b_substs)) => {
let a = a.subst(cx.tcx, a_substs);
let b = b.subst(cx.tcx, b_substs);
debug!("Comparing {:?} and {:?}", a, b);

(Adt(a_def, _), Adt(b_def, _)) => {
// We can immediately rule out these types as structurally same if
// their layouts differ.
match compare_layouts(a, b) {
Expand Down
167 changes: 116 additions & 51 deletions compiler/rustc_typeck/src/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use rustc_hir::intravisit;
use rustc_hir::{GenericParamKind, ImplItemKind, TraitItemKind};
use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
use rustc_infer::traits::util;
use rustc_middle::ty;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::subst::{InternalSubsts, Subst};
use rustc_middle::ty::util::ExplicitSelf;
use rustc_middle::ty::{self, DefIdTree};
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
Expand Down Expand Up @@ -48,6 +48,10 @@ crate fn compare_impl_method<'tcx>(
return;
}

if let Err(_) = compare_generic_param_kinds(tcx, impl_m, trait_m) {
return;
}

if let Err(_) =
compare_number_of_method_arguments(tcx, impl_m, impl_m_span, trait_m, trait_item_span)
{
Expand All @@ -62,10 +66,6 @@ crate fn compare_impl_method<'tcx>(
{
return;
}

if let Err(_) = compare_const_param_types(tcx, impl_m, trait_m, trait_item_span) {
return;
}
}

fn compare_predicate_entailment<'tcx>(
Expand Down Expand Up @@ -579,6 +579,27 @@ fn compare_self_type<'tcx>(
Ok(())
}

/// Checks that the number of generics on a given assoc item in a trait impl is the same
/// as the number of generics on the respective assoc item in the trait definition.
///
/// For example this code emits the errors in the following code:
/// ```
/// trait Trait {
/// fn foo();
/// type Assoc<T>;
/// }
///
/// impl Trait for () {
/// fn foo<T>() {}
/// //~^ error
/// type Assoc = u32;
/// //~^ error
/// }
/// ```
///
/// Notably this does not error on `foo<T>` implemented as `foo<const N: u8>` or
/// `foo<const N: u8>` implemented as `foo<const N: u32>`. This is handled in
/// [`compare_generic_param_kinds`]. This function also does not handle lifetime parameters
fn compare_number_of_generics<'tcx>(
tcx: TyCtxt<'tcx>,
impl_: &ty::AssocItem,
Expand All @@ -589,6 +610,15 @@ fn compare_number_of_generics<'tcx>(
let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
let impl_own_counts = tcx.generics_of(impl_.def_id).own_counts();

// This avoids us erroring on `foo<T>` implemented as `foo<const N: u8>` as this is implemented
// in `compare_generic_param_kinds` which will give a nicer error message than something like:
// "expected 1 type parameter, found 0 type parameters"
if (trait_own_counts.types + trait_own_counts.consts)
== (impl_own_counts.types + impl_own_counts.consts)
{
return Ok(());
}

let matchings = [
("type", trait_own_counts.types, impl_own_counts.types),
("const", trait_own_counts.consts, impl_own_counts.consts),
Expand Down Expand Up @@ -914,60 +944,93 @@ fn compare_synthetic_generics<'tcx>(
if let Some(reported) = error_found { Err(reported) } else { Ok(()) }
}

fn compare_const_param_types<'tcx>(
/// Checks that all parameters in the generics of a given assoc item in a trait impl have
/// the same kind as the respective generic parameter in the trait def.
///
/// For example all 4 errors in the following code are emitted here:
/// ```
/// trait Foo {
/// fn foo<const N: u8>();
/// type bar<const N: u8>;
/// fn baz<const N: u32>();
/// type blah<T>;
/// }
///
/// impl Foo for () {
/// fn foo<const N: u64>() {}
/// //~^ error
/// type bar<const N: u64> {}
/// //~^ error
/// fn baz<T>() {}
/// //~^ error
/// type blah<const N: i64> = u32;
/// //~^ error
/// }
/// ```
///
/// This function does not handle lifetime parameters
fn compare_generic_param_kinds<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m: &ty::AssocItem,
trait_m: &ty::AssocItem,
trait_item_span: Option<Span>,
impl_item: &ty::AssocItem,
trait_item: &ty::AssocItem,
) -> Result<(), ErrorGuaranteed> {
let const_params_of = |def_id| {
tcx.generics_of(def_id).params.iter().filter_map(|param| match param.kind {
GenericParamDefKind::Const { .. } => Some(param.def_id),
_ => None,
assert_eq!(impl_item.kind, trait_item.kind);

let ty_const_params_of = |def_id| {
tcx.generics_of(def_id).params.iter().filter(|param| {
matches!(
param.kind,
GenericParamDefKind::Const { .. } | GenericParamDefKind::Type { .. }
)
})
};
let const_params_impl = const_params_of(impl_m.def_id);
let const_params_trait = const_params_of(trait_m.def_id);

for (const_param_impl, const_param_trait) in iter::zip(const_params_impl, const_params_trait) {
let impl_ty = tcx.type_of(const_param_impl);
let trait_ty = tcx.type_of(const_param_trait);
if impl_ty != trait_ty {
let (impl_span, impl_ident) = match tcx.hir().get_if_local(const_param_impl) {
Some(hir::Node::GenericParam(hir::GenericParam { span, name, .. })) => (
span,
match name {
hir::ParamName::Plain(ident) => Some(ident),
_ => None,
},
),
other => bug!(
"expected GenericParam, found {:?}",
other.map_or_else(|| "nothing".to_string(), |n| format!("{:?}", n))
),
};
let trait_span = match tcx.hir().get_if_local(const_param_trait) {
Some(hir::Node::GenericParam(hir::GenericParam { span, .. })) => Some(span),
_ => None,
};

for (param_impl, param_trait) in
iter::zip(ty_const_params_of(impl_item.def_id), ty_const_params_of(trait_item.def_id))
{
use GenericParamDefKind::*;
if match (&param_impl.kind, &param_trait.kind) {
(Const { .. }, Const { .. })
if tcx.type_of(param_impl.def_id) != tcx.type_of(param_trait.def_id) =>
{
true
}
(Const { .. }, Type { .. }) | (Type { .. }, Const { .. }) => true,
// this is exhaustive so that anyone adding new generic param kinds knows
// to make sure this error is reported for them.
(Const { .. }, Const { .. }) | (Type { .. }, Type { .. }) => false,
(Lifetime { .. }, _) | (_, Lifetime { .. }) => unreachable!(),
} {
let param_impl_span = tcx.def_span(param_impl.def_id);
let param_trait_span = tcx.def_span(param_trait.def_id);

let mut err = struct_span_err!(
tcx.sess,
*impl_span,
param_impl_span,
E0053,
"method `{}` has an incompatible const parameter type for trait",
trait_m.name
);
err.span_note(
trait_span.map_or_else(|| trait_item_span.unwrap_or(*impl_span), |span| *span),
&format!(
"the const parameter{} has type `{}`, but the declaration \
in trait `{}` has type `{}`",
&impl_ident.map_or_else(|| "".to_string(), |ident| format!(" `{ident}`")),
impl_ty,
tcx.def_path_str(trait_m.def_id),
trait_ty
),
"{} `{}` has an incompatible generic parameter for trait `{}`",
assoc_item_kind_str(&impl_item),
trait_item.name,
&tcx.def_path_str(tcx.parent(trait_item.def_id))
);

let make_param_message = |prefix: &str, param: &ty::GenericParamDef| match param.kind {
Const { .. } => {
format!("{} const parameter of type `{}`", prefix, tcx.type_of(param.def_id))
}
Type { .. } => format!("{} type parameter", prefix),
Lifetime { .. } => unreachable!(),
};

let trait_header_span = tcx.def_ident_span(tcx.parent(trait_item.def_id)).unwrap();
err.span_label(trait_header_span, "");
err.span_label(param_trait_span, make_param_message("expected", param_trait));

let impl_header_span =
tcx.sess.source_map().guess_head_span(tcx.def_span(tcx.parent(impl_item.def_id)));
err.span_label(impl_header_span, "");
err.span_label(param_impl_span, make_param_message("found", param_impl));

let reported = err.emit();
return Err(reported);
}
Expand Down Expand Up @@ -1095,6 +1158,8 @@ crate fn compare_ty_impl<'tcx>(
let _: Result<(), ErrorGuaranteed> = (|| {
compare_number_of_generics(tcx, impl_ty, impl_ty_span, trait_ty, trait_item_span)?;

compare_generic_param_kinds(tcx, impl_ty, trait_ty)?;

let sp = tcx.def_span(impl_ty.def_id);
compare_type_predicate_entailment(tcx, impl_ty, sp, trait_ty, impl_trait_ref)?;

Expand Down
2 changes: 1 addition & 1 deletion library/std/src/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::collections::TryReserveErrorKind;
use crate::fmt::{self, Debug};
#[allow(deprecated)]
use crate::hash::{BuildHasher, Hash, Hasher, SipHasher13};
use crate::iter::{FromIterator, FusedIterator};
use crate::iter::FusedIterator;
use crate::ops::Index;
use crate::sys;

Expand Down
2 changes: 1 addition & 1 deletion library/std/src/collections/hash/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::borrow::Borrow;
use crate::collections::TryReserveError;
use crate::fmt;
use crate::hash::{BuildHasher, Hash};
use crate::iter::{Chain, FromIterator, FusedIterator};
use crate::iter::{Chain, FusedIterator};
use crate::ops::{BitAnd, BitOr, BitXor, Sub};

use super::map::{map_try_reserve_error, RandomState};
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/ffi/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::cmp;
use crate::collections::TryReserveError;
use crate::fmt;
use crate::hash::{Hash, Hasher};
use crate::iter::{Extend, FromIterator};
use crate::iter::Extend;
use crate::ops;
use crate::rc::Rc;
use crate::str::FromStr;
Expand Down
2 changes: 0 additions & 2 deletions library/std/src/io/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ use crate::alloc::Allocator;
use crate::cmp;
use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, ReadBuf, SeekFrom};

use core::convert::TryInto;

/// A `Cursor` wraps an in-memory buffer and provides it with a
/// [`Seek`] implementation.
///
Expand Down
1 change: 0 additions & 1 deletion library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,6 @@
mod tests;

use crate::cmp;
use crate::convert::TryInto;
use crate::fmt;
use crate::mem::replace;
use crate::ops::{Deref, DerefMut};
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@
// to import the prelude implicitly when building crates that depend on std.
#[prelude_import]
#[allow(unused)]
use prelude::v1::*;
use prelude::rust_2021::*;

// Access to Bencher, etc.
#[cfg(test)]
Expand Down
1 change: 0 additions & 1 deletion library/std/src/net/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
mod tests;

use crate::cmp::Ordering;
use crate::convert::TryInto;
use crate::fmt;
use crate::hash;
use crate::io::{self, Write};
Expand Down
1 change: 0 additions & 1 deletion library/std/src/net/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#[cfg(test)]
mod tests;

use crate::convert::TryInto as _;
use crate::error::Error;
use crate::fmt;
use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
Expand Down
1 change: 0 additions & 1 deletion library/std/src/os/unix/net/ancillary.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::{sockaddr_un, SocketAddr};
use crate::convert::TryFrom;
use crate::io::{self, IoSlice, IoSliceMut};
use crate::marker::PhantomData;
use crate::mem::{size_of, zeroed};
Expand Down
1 change: 0 additions & 1 deletion library/std/src/os/unix/net/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
target_os = "netbsd",
target_os = "openbsd",
))]
use crate::iter::FromIterator;
#[cfg(any(
target_os = "android",
target_os = "dragonfly",
Expand Down
1 change: 0 additions & 1 deletion library/std/src/os/windows/io/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#![unstable(feature = "io_safety", issue = "87074")]

use super::raw::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
use crate::convert::TryFrom;
use crate::fmt;
use crate::fs;
use crate::io;
Expand Down
14 changes: 14 additions & 0 deletions library/std/src/os/windows/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,17 @@ impl CommandExt for process::Command {
self
}
}

#[unstable(feature = "windows_process_extensions_main_thread_handle", issue = "96723")]
pub trait ChildExt: Sealed {
/// Extracts the main thread raw handle, without taking ownership
#[unstable(feature = "windows_process_extensions_main_thread_handle", issue = "96723")]
fn main_thread_handle(&self) -> BorrowedHandle<'_>;
}

#[unstable(feature = "windows_process_extensions_main_thread_handle", issue = "96723")]
impl ChildExt for process::Child {
fn main_thread_handle(&self) -> BorrowedHandle<'_> {
self.handle.main_thread_handle()
}
}
1 change: 0 additions & 1 deletion library/std/src/sys/hermit/net.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::convert::TryFrom;
use crate::fmt;
use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
Expand Down
1 change: 0 additions & 1 deletion library/std/src/sys/hermit/time.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#![allow(dead_code)]

use crate::cmp::Ordering;
use crate::convert::TryInto;
use crate::sys::hermit::abi;
use crate::sys::hermit::abi::timespec;
use crate::sys::hermit::abi::{CLOCK_MONOTONIC, CLOCK_REALTIME, NSEC_PER_SEC};
Expand Down
1 change: 0 additions & 1 deletion library/std/src/sys/itron/spin.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use super::abi;
use crate::{
cell::UnsafeCell,
convert::TryFrom,
mem::MaybeUninit,
sync::atomic::{AtomicBool, AtomicUsize, Ordering},
};
Expand Down
1 change: 0 additions & 1 deletion library/std/src/sys/itron/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use super::{
};
use crate::{
cell::UnsafeCell,
convert::TryFrom,
ffi::CStr,
hint, io,
mem::ManuallyDrop,
Expand Down
Loading