Skip to content

Rollup of 4 pull requests #112563

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

Merged
merged 10 commits into from
Jun 12, 2023
20 changes: 15 additions & 5 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,12 @@ impl<'a> AstValidator<'a> {
self.err_handler().emit_err(errors::BoundInContext { span, ctx });
}

fn check_foreign_ty_genericless(&self, generics: &Generics, where_span: Span) {
fn check_foreign_ty_genericless(
&self,
generics: &Generics,
before_where_clause: &TyAliasWhereClause,
after_where_clause: &TyAliasWhereClause,
) {
let cannot_have = |span, descr, remove_descr| {
self.err_handler().emit_err(errors::ExternTypesCannotHave {
span,
Expand All @@ -378,9 +383,14 @@ impl<'a> AstValidator<'a> {
cannot_have(generics.span, "generic parameters", "generic parameters");
}

if !generics.where_clause.predicates.is_empty() {
cannot_have(where_span, "`where` clauses", "`where` clause");
}
let check_where_clause = |where_clause: &TyAliasWhereClause| {
if let TyAliasWhereClause(true, where_clause_span) = where_clause {
cannot_have(*where_clause_span, "`where` clauses", "`where` clause");
}
};

check_where_clause(before_where_clause);
check_where_clause(after_where_clause);
}

fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body: Option<Span>) {
Expand Down Expand Up @@ -1039,7 +1049,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.check_defaultness(fi.span, *defaultness);
self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span));
self.check_type_no_bounds(bounds, "`extern` blocks");
self.check_foreign_ty_genericless(generics, where_clauses.0.1);
self.check_foreign_ty_genericless(generics, &where_clauses.0, &where_clauses.1);
self.check_foreign_item_ascii_only(fi.ident);
}
ForeignItemKind::Static(_, _, body) => {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_typeck/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ hir_typeck_suggest_boxing_note = for more on the distinction between the stack a

hir_typeck_suggest_boxing_when_appropriate = store this in the heap by calling `Box::new`

hir_typeck_suggest_ptr_null_mut = consider using `core::ptr::null_mut` instead

hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns

hir_typeck_union_pat_multiple_fields = union patterns should have exactly one field
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,17 @@ pub enum SuggestBoxing {
},
}

#[derive(Subdiagnostic)]
#[suggestion(
hir_typeck_suggest_ptr_null_mut,
applicability = "maybe-incorrect",
code = "core::ptr::null_mut()"
)]
pub struct SuggestPtrNullMut {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(hir_typeck_no_associated_item, code = "E0599")]
pub struct NoAssociatedItem {
Expand Down
30 changes: 30 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::coercion::CoerceMany;
use crate::errors::SuggestPtrNullMut;
use crate::fn_ctxt::arg_matrix::{ArgMatrix, Compatibility, Error, ExpectedIdx, ProvidedIdx};
use crate::gather_locals::Declaration;
use crate::method::MethodCallee;
Expand Down Expand Up @@ -814,6 +815,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
}

self.suggest_ptr_null_mut(
expected_ty,
provided_ty,
provided_args[*provided_idx],
&mut err,
);

// Call out where the function is defined
self.label_fn_like(
&mut err,
Expand Down Expand Up @@ -1271,6 +1279,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.emit();
}

fn suggest_ptr_null_mut(
&self,
expected_ty: Ty<'tcx>,
provided_ty: Ty<'tcx>,
arg: &hir::Expr<'tcx>,
err: &mut rustc_errors::DiagnosticBuilder<'tcx, ErrorGuaranteed>,
) {
if let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Mut, .. }) = expected_ty.kind()
&& let ty::RawPtr(ty::TypeAndMut { mutbl: hir::Mutability::Not, .. }) = provided_ty.kind()
&& let hir::ExprKind::Call(callee, _) = arg.kind
&& let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = callee.kind
&& let Res::Def(_, def_id) = path.res
&& self.tcx.get_diagnostic_item(sym::ptr_null) == Some(def_id)
{
// The user provided `ptr::null()`, but the function expects
// `ptr::null_mut()`.
err.subdiagnostic(SuggestPtrNullMut {
span: arg.span
});
}
}

// AST fragment checking
pub(in super::super) fn check_lit(
&self,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_infer/src/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::relate::{RelateResult, TypeRelation};
use rustc_middle::ty::{self, AliasKind, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{IntType, UintType};
use rustc_span::DUMMY_SP;

Expand Down Expand Up @@ -103,12 +103,12 @@ impl<'tcx> InferCtxt<'tcx> {

// We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
(
ty::Alias(AliasKind::Projection, _),
ty::Alias(..),
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
)
| (
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)),
ty::Alias(AliasKind::Projection, _),
ty::Alias(..),
) if self.next_trait_solver() => {
bug!()
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
candidates
}

/// If the self type of a goal is a projection, computing the relevant candidates is difficult.
/// If the self type of a goal is an alias, computing the relevant candidates is difficult.
///
/// To deal with this, we first try to normalize the self type and add the candidates for the normalized
/// self type to the list of candidates in case that succeeds. We also have to consider candidates with the
Expand Down
20 changes: 20 additions & 0 deletions library/std/src/sys/windows/c/windows_sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4275,3 +4275,23 @@ impl ::core::clone::Clone for XSAVE_FORMAT {
*self
}
}
// Begin of ARM32 shim
// The raw content of this file should be processed by `generate-windows-sys`
// to be merged with the generated binding. It is not supposed to be used as
// a normal Rust module.
cfg_if::cfg_if! {
if #[cfg(target_arch = "arm")] {
#[repr(C)]
pub struct WSADATA {
pub wVersion: u16,
pub wHighVersion: u16,
pub szDescription: [u8; 257],
pub szSystemStatus: [u8; 129],
pub iMaxSockets: u16,
pub iMaxUdpDg: u16,
pub lpVendorInfo: PSTR,
}
pub enum CONTEXT {}
}
}
// End of ARM32 shim
20 changes: 20 additions & 0 deletions src/tools/generate-windows-sys/src/arm_shim.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Begin of ARM32 shim
// The raw content of this file should be processed by `generate-windows-sys`
// to be merged with the generated binding. It is not supposed to be used as
// a normal Rust module.
cfg_if::cfg_if! {
if #[cfg(target_arch = "arm")] {
#[repr(C)]
pub struct WSADATA {
pub wVersion: u16,
pub wHighVersion: u16,
pub szDescription: [u8; 257],
pub szSystemStatus: [u8; 129],
pub iMaxSockets: u16,
pub iMaxUdpDg: u16,
pub lpVendorInfo: PSTR,
}
pub enum CONTEXT {}
}
}
// End of ARM32 shim
4 changes: 4 additions & 0 deletions src/tools/generate-windows-sys/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const PRELUDE: &str = r#"// This file is autogenerated.
// ignore-tidy-filelength
"#;

/// This is a shim for the ARM (32-bit) architecture, which is no longer supported by windows-rs.
const ARM_SHIM: &str = include_str!("arm_shim.rs");

fn main() -> io::Result<()> {
let mut path: PathBuf =
std::env::args_os().nth(1).expect("a path to the rust repository is required").into();
Expand All @@ -32,6 +35,7 @@ fn main() -> io::Result<()> {
let mut f = std::fs::File::create(&path)?;
f.write_all(PRELUDE.as_bytes())?;
f.write_all(bindings.as_bytes())?;
f.write_all(ARM_SHIM.as_bytes())?;

Ok(())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
extern "C" {
type Item = [T] where [T]: Sized;
//~^ incorrect `type` inside `extern` block
//~| `type`s inside `extern` blocks cannot have `where` clauses
//~| cannot find type `T` in this scope
//~| cannot find type `T` in this scope
//~| extern types are experimental
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
error: incorrect `type` inside `extern` block
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:10
|
LL | extern "C" {
| ---------- `extern` blocks define existing foreign types and types inside of them cannot have a body
LL | type Item = [T] where [T]: Sized;
| ^^^^ --- the invalid body
| |
| cannot have a body
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html

error: `type`s inside `extern` blocks cannot have `where` clauses
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:21
|
LL | extern "C" {
| ---------- `extern` block begins here
LL | type Item = [T] where [T]: Sized;
| ^^^^^^^^^^^^^^^^ help: remove the `where` clause
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html

error[E0412]: cannot find type `T` in this scope
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:28
|
LL | type Item = [T] where [T]: Sized;
| ^ not found in this scope

error[E0412]: cannot find type `T` in this scope
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:18
|
LL | type Item = [T] where [T]: Sized;
| ^ not found in this scope

error[E0658]: extern types are experimental
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:5
|
LL | type Item = [T] where [T]: Sized;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #43467 <https://github.com/rust-lang/rust/issues/43467> for more information
= help: add `#![feature(extern_types)]` to the crate attributes to enable

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0412, E0658.
For more information about an error, try `rustc --explain E0412`.
1 change: 1 addition & 0 deletions tests/ui/parser/foreign-ty-semantic-fail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ extern "C" {
//~^ ERROR incorrect `type` inside `extern` block

type E: where;
//~^ ERROR `type`s inside `extern` blocks cannot have `where` clauses
}
13 changes: 12 additions & 1 deletion tests/ui/parser/foreign-ty-semantic-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,16 @@ LL | type D = u8;
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html

error: aborting due to 6 previous errors
error: `type`s inside `extern` blocks cannot have `where` clauses
--> $DIR/foreign-ty-semantic-fail.rs:17:13
|
LL | extern "C" {
| ---------- `extern` block begins here
...
LL | type E: where;
| ^^^^^ help: remove the `where` clause
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html

error: aborting due to 7 previous errors

11 changes: 11 additions & 0 deletions tests/ui/typeck/ptr-null-mutability-suggestions.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// run-rustfix

#[allow(unused_imports)]
use std::ptr;

fn expecting_null_mut(_: *mut u8) {}

fn main() {
expecting_null_mut(core::ptr::null_mut());
//~^ ERROR mismatched types
}
11 changes: 11 additions & 0 deletions tests/ui/typeck/ptr-null-mutability-suggestions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// run-rustfix

#[allow(unused_imports)]
use std::ptr;

fn expecting_null_mut(_: *mut u8) {}

fn main() {
expecting_null_mut(ptr::null());
//~^ ERROR mismatched types
}
21 changes: 21 additions & 0 deletions tests/ui/typeck/ptr-null-mutability-suggestions.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0308]: mismatched types
--> $DIR/ptr-null-mutability-suggestions.rs:9:24
|
LL | expecting_null_mut(ptr::null());
| ------------------ ^^^^^^^^^^^
| | |
| | types differ in mutability
| | help: consider using `core::ptr::null_mut` instead: `core::ptr::null_mut()`
| arguments to this function are incorrect
|
= note: expected raw pointer `*mut u8`
found raw pointer `*const _`
note: function defined here
--> $DIR/ptr-null-mutability-suggestions.rs:6:4
|
LL | fn expecting_null_mut(_: *mut u8) {}
| ^^^^^^^^^^^^^^^^^^ ----------

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.