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 7 pull requests #93768

Closed
wants to merge 16 commits into from
Closed
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
22 changes: 12 additions & 10 deletions compiler/rustc_builtin_macros/src/global_allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ pub fn expand(

// Allow using `#[global_allocator]` on an item statement
// FIXME - if we get deref patterns, use them to reduce duplication here
let (item, is_stmt) = match &item {
let (item, is_stmt, ty_span) = match &item {
Annotatable::Item(item) => match item.kind {
ItemKind::Static(..) => (item, false),
ItemKind::Static(ref ty, ..) => (item, false, ecx.with_def_site_ctxt(ty.span)),
_ => return not_static(),
},
Annotatable::Stmt(stmt) => match &stmt.kind {
StmtKind::Item(item_) => match item_.kind {
ItemKind::Static(..) => (item_, true),
ItemKind::Static(ref ty, ..) => (item_, true, ecx.with_def_site_ctxt(ty.span)),
_ => return not_static(),
},
_ => return not_static(),
Expand All @@ -43,13 +43,14 @@ pub fn expand(

// Generate a bunch of new items using the AllocFnFactory
let span = ecx.with_def_site_ctxt(item.span);
let f = AllocFnFactory { span, kind: AllocatorKind::Global, global: item.ident, cx: ecx };
let f =
AllocFnFactory { span, ty_span, kind: AllocatorKind::Global, global: item.ident, cx: ecx };

// Generate item statements for the allocator methods.
let stmts = ALLOCATOR_METHODS.iter().map(|method| f.allocator_fn(method)).collect();

// Generate anonymous constant serving as container for the allocator methods.
let const_ty = ecx.ty(span, TyKind::Tup(Vec::new()));
let const_ty = ecx.ty(ty_span, TyKind::Tup(Vec::new()));
let const_body = ecx.expr_block(ecx.block(span, stmts));
let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
let const_item = if is_stmt {
Expand All @@ -64,6 +65,7 @@ pub fn expand(

struct AllocFnFactory<'a, 'b> {
span: Span,
ty_span: Span,
kind: AllocatorKind,
global: Ident,
cx: &'b ExtCtxt<'a>,
Expand Down Expand Up @@ -97,18 +99,18 @@ impl AllocFnFactory<'_, '_> {
self.attrs(),
kind,
);
self.cx.stmt_item(self.span, item)
self.cx.stmt_item(self.ty_span, item)
}

fn call_allocator(&self, method: Symbol, mut args: Vec<P<Expr>>) -> P<Expr> {
let method = self.cx.std_path(&[sym::alloc, sym::GlobalAlloc, method]);
let method = self.cx.expr_path(self.cx.path(self.span, method));
let allocator = self.cx.path_ident(self.span, self.global);
let method = self.cx.expr_path(self.cx.path(self.ty_span, method));
let allocator = self.cx.path_ident(self.ty_span, self.global);
let allocator = self.cx.expr_path(allocator);
let allocator = self.cx.expr_addr_of(self.span, allocator);
let allocator = self.cx.expr_addr_of(self.ty_span, allocator);
args.insert(0, allocator);

self.cx.expr_call(self.span, method, args)
self.cx.expr_call(self.ty_span, method, args)
}

fn attrs(&self) -> Vec<Attribute> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2053,7 +2053,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
if let Some(code) =
code.strip_prefix('"').and_then(|s| s.strip_suffix('"'))
{
if code.chars().nth(1).is_none() {
if code.chars().count() == 1 {
err.span_suggestion(
span,
"if you meant to write a `char` literal, use single quotes",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2473,7 +2473,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// `T`
substs: self.tcx.mk_substs_trait(
trait_pred.self_ty().skip_binder(),
self.fresh_substs_for_item(span, item_def_id),
&self.fresh_substs_for_item(span, item_def_id)[1..],
),
// `Future::Output`
item_def_id,
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,16 @@ fn project<'cx, 'tcx>(
return Ok(Projected::Progress(Progress::error(selcx.tcx())));
}

// If the obligation contains any inference types or consts in associated
// type substs, then we don't assemble any candidates.
// This isn't really correct, but otherwise we can end up in a case where
// we constrain inference variables by selecting a single predicate, when
// we need to stay general. See issue #91762.
let (_, predicate_own_substs) = obligation.predicate.trait_ref_and_own_substs(selcx.tcx());
if predicate_own_substs.iter().any(|g| g.has_infer_types_or_consts()) {
return Err(ProjectionError::TooManyCandidates);
}

let mut candidates = ProjectionCandidateSet::None;

// Make sure that the following procedures are kept in order. ParamEnv
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2044,7 +2044,7 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
///
/// This function currently corresponds to `openat`, `fdopendir`, `unlinkat` and `lstat` functions
/// on Unix (except for macOS before version 10.10 and REDOX) and the `CreateFileW`,
/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtOpenFile` functions on
/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtCreateFile` functions on
/// Windows. Note that, this [may change in the future][changes].
///
/// [changes]: io#platform-specific-behavior
Expand Down
12 changes: 9 additions & 3 deletions library/std/src/sys/windows/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub const FILE_SHARE_DELETE: DWORD = 0x4;
pub const FILE_SHARE_READ: DWORD = 0x1;
pub const FILE_SHARE_WRITE: DWORD = 0x2;

pub const FILE_OPEN: ULONG = 0x00000001;
pub const FILE_OPEN_REPARSE_POINT: ULONG = 0x200000;
pub const OBJ_DONT_REPARSE: ULONG = 0x1000;

Expand Down Expand Up @@ -1228,15 +1229,20 @@ compat_fn! {

compat_fn! {
"ntdll":
pub fn NtOpenFile(
pub fn NtCreateFile(
FileHandle: *mut HANDLE,
DesiredAccess: ACCESS_MASK,
ObjectAttributes: *const OBJECT_ATTRIBUTES,
IoStatusBlock: *mut IO_STATUS_BLOCK,
AllocationSize: *mut i64,
FileAttributes: ULONG,
ShareAccess: ULONG,
OpenOptions: ULONG
CreateDisposition: ULONG,
CreateOptions: ULONG,
EaBuffer: *mut c_void,
EaLength: ULONG
) -> NTSTATUS {
panic!("`NtOpenFile` not available");
panic!("`NtCreateFile` not available");
}
pub fn RtlNtStatusToDosError(
Status: NTSTATUS
Expand Down
11 changes: 8 additions & 3 deletions library/std/src/sys/windows/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -712,11 +712,11 @@ impl<'a> Iterator for DirBuffIter<'a> {

/// Open a link relative to the parent directory, ensure no symlinks are followed.
fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result<File> {
// This is implemented using the lower level `NtOpenFile` function as
// This is implemented using the lower level `NtCreateFile` function as
// unfortunately opening a file relative to a parent is not supported by
// win32 functions. It is however a fundamental feature of the NT kernel.
//
// See https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntopenfile
// See https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntcreatefile
unsafe {
let mut handle = ptr::null_mut();
let mut io_status = c::IO_STATUS_BLOCK::default();
Expand All @@ -732,14 +732,19 @@ fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result<
Attributes: ATTRIBUTES.load(Ordering::Relaxed),
..c::OBJECT_ATTRIBUTES::default()
};
let status = c::NtOpenFile(
let status = c::NtCreateFile(
&mut handle,
access,
&object,
&mut io_status,
crate::ptr::null_mut(),
0,
c::FILE_SHARE_DELETE | c::FILE_SHARE_READ | c::FILE_SHARE_WRITE,
c::FILE_OPEN,
// If `name` is a symlink then open the link rather than the target.
c::FILE_OPEN_REPARSE_POINT,
crate::ptr::null_mut(),
0,
);
// Convert an NTSTATUS to the more familiar Win32 error codes (aka "DosError")
if c::nt_success(status) {
Expand Down
1 change: 0 additions & 1 deletion src/bootstrap/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,6 @@ def bootstrap(help_triggered):
env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
env["BOOTSTRAP_PYTHON"] = sys.executable
env["BUILD_DIR"] = build.build_dir
env["RUSTC_BOOTSTRAP"] = '1'
if toml_path:
env["BOOTSTRAP_CONFIG"] = toml_path
if build.rustc_commit is not None:
Expand Down
16 changes: 8 additions & 8 deletions src/test/ui/allocator/not-an-allocator.stderr
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
--> $DIR/not-an-allocator.rs:2:1
--> $DIR/not-an-allocator.rs:2:11
|
LL | #[global_allocator]
| ------------------- in this procedural macro expansion
LL | static A: usize = 0;
| ^^^^^^^^^^^^^^^^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
| ^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
|
= note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
--> $DIR/not-an-allocator.rs:2:1
--> $DIR/not-an-allocator.rs:2:11
|
LL | #[global_allocator]
| ------------------- in this procedural macro expansion
LL | static A: usize = 0;
| ^^^^^^^^^^^^^^^^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
| ^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
|
= note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
--> $DIR/not-an-allocator.rs:2:1
--> $DIR/not-an-allocator.rs:2:11
|
LL | #[global_allocator]
| ------------------- in this procedural macro expansion
LL | static A: usize = 0;
| ^^^^^^^^^^^^^^^^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
| ^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
|
= note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
--> $DIR/not-an-allocator.rs:2:1
--> $DIR/not-an-allocator.rs:2:11
|
LL | #[global_allocator]
| ------------------- in this procedural macro expansion
LL | static A: usize = 0;
| ^^^^^^^^^^^^^^^^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
| ^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
|
= note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)

Expand Down
1 change: 1 addition & 0 deletions src/test/ui/generic-associated-types/issue-74824.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ impl<T> UnsafeCopy for T {}
fn main() {
let b = Box::new(42usize);
let copy = <()>::copy(&b);
//~^ type annotations needed

let raw_b = Box::deref(&b) as *const _;
let raw_copy = Box::deref(&copy) as *const _;
Expand Down
11 changes: 9 additions & 2 deletions src/test/ui/generic-associated-types/issue-74824.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ help: consider restricting type parameter `T`
LL | type Copy<T: std::clone::Clone>: Copy = Box<T>;
| +++++++++++++++++++

error: aborting due to 2 previous errors
error[E0282]: type annotations needed
--> $DIR/issue-74824.rs:19:16
|
LL | let copy = <()>::copy(&b);
| ^^^^^^^^^^ cannot infer type for type parameter `T` declared on the associated function `copy`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
Some errors have detailed explanations: E0277, E0282.
For more information about an error, try `rustc --explain E0277`.
30 changes: 30 additions & 0 deletions src/test/ui/generic-associated-types/issue-91762.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// check-fail

// FIXME(generic_associated_types): We almost certaintly want this to pass, but
// it's particularly difficult currently, because we need a way of specifying
// that `<Self::Base as Functor>::With<T> = Self` without using that when we have
// a `U`. See `https://github.com/rust-lang/rust/pull/92728` for a (hacky)
// solution. This might be better to just wait for Chalk.

#![feature(generic_associated_types)]

pub trait Functor {
type With<T>;

fn fmap<T, U>(this: Self::With<T>) -> Self::With<U>;
}

pub trait FunctorExt<T>: Sized {
type Base: Functor<With<T> = Self>;

fn fmap<U>(self) {
let arg: <Self::Base as Functor>::With<T>;
let ret: <Self::Base as Functor>::With<U>;

arg = self;
ret = <Self::Base as Functor>::fmap(arg);
//~^ type annotations needed
}
}

fn main() {}
9 changes: 9 additions & 0 deletions src/test/ui/generic-associated-types/issue-91762.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0282]: type annotations needed
--> $DIR/issue-91762.rs:25:15
|
LL | ret = <Self::Base as Functor>::fmap(arg);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the associated function `fmap`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0282`.
51 changes: 51 additions & 0 deletions src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// A test exploiting the bug behind #25860 except with
// implied trait bounds which currently don't exist without `-Zchalk`.
use std::marker::PhantomData;
struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>)
where
T: Convert<'a, 'b>;

trait Convert<'a, 'b>: Sized {
fn cast(&'a self) -> &'b Self;
}
impl<'long: 'short, 'short, T> Convert<'long, 'short> for T {
fn cast(&'long self) -> &'short T {
self
}
}

// This function will compile once we add implied trait bounds.
//
// If we're not careful with our impl, the transformations
// in `bad` would succeed, which is unsound ✨
//
// FIXME: the error is pretty bad, this should say
//
// `T: Convert<'in_, 'out>` is not implemented
//
// help: needed by `Foo<'in_, 'out, T>`
//
// Please ping @lcnr if your changes end up causing `badboi` to compile.
fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out T {
//~^ ERROR lifetime mismatch
sadness.cast()
}

fn bad<'short, T>(value: &'short T) -> &'static T {
let x: for<'in_, 'out> fn(Foo<'in_, 'out, T>, &'in_ T) -> &'out T = badboi;
let x: for<'out> fn(Foo<'short, 'out, T>, &'short T) -> &'out T = x;
let x: for<'out> fn(Foo<'static, 'out, T>, &'short T) -> &'out T = x;
let x: fn(Foo<'static, 'static, T>, &'short T) -> &'static T = x;
x(Foo(PhantomData), value)
}

// Use `bad` to cause a segfault.
fn main() {
let mut outer: Option<&'static u32> = Some(&3);
let static_ref: &'static &'static u32 = match outer {
Some(ref reference) => bad(reference),
None => unreachable!(),
};
outer = None;
println!("{}", static_ref);
}
12 changes: 12 additions & 0 deletions src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0623]: lifetime mismatch
--> $DIR/hrlt-implied-trait-bounds-guard.rs:29:29
|
LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out T {
| ^^^^^^^^^^^^^^^^^^ -------
| |
| this parameter and the return type are declared with different lifetimes...
| ...but data from `x` is returned here

error: aborting due to previous error

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