Skip to content

Commit 9a5a961

Browse files
committed
Auto merge of rust-lang#93778 - matthiaskrgr:rollup-yfngdao, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#91950 (Point at type when a `static` `#[global_allocator]` doesn't `impl` `GlobalAlloc`) - rust-lang#92715 (Do not suggest char literal for zero-length strings) - rust-lang#92917 (Don't constrain projection predicates with inference vars in GAT substs) - rust-lang#93206 (Use `NtCreateFile` instead of `NtOpenFile` to open a file) - rust-lang#93732 (add fut/back compat tests for implied trait bounds) - rust-lang#93764 (:arrow_up: rust-analyzer) - rust-lang#93767 (deduplicate `lcnr` in mailmap) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents cc38176 + ff3324c commit 9a5a961

File tree

19 files changed

+210
-33
lines changed

19 files changed

+210
-33
lines changed

.mailmap

+1-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ Kyle J Strand <[email protected]> <[email protected]>
173173
174174
175175
Laurențiu Nicola <[email protected]>
176-
176+
177177
Lee Jeffery <[email protected]> Lee Jeffery <[email protected]>
178178
Lee Wondong <[email protected]>
179179
Lennart Kudling <[email protected]>

compiler/rustc_builtin_macros/src/global_allocator.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ pub fn expand(
2626

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

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

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

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

6566
struct AllocFnFactory<'a, 'b> {
6667
span: Span,
68+
ty_span: Span,
6769
kind: AllocatorKind,
6870
global: Ident,
6971
cx: &'b ExtCtxt<'a>,
@@ -97,18 +99,18 @@ impl AllocFnFactory<'_, '_> {
9799
self.attrs(),
98100
kind,
99101
);
100-
self.cx.stmt_item(self.span, item)
102+
self.cx.stmt_item(self.ty_span, item)
101103
}
102104

103105
fn call_allocator(&self, method: Symbol, mut args: Vec<P<Expr>>) -> P<Expr> {
104106
let method = self.cx.std_path(&[sym::alloc, sym::GlobalAlloc, method]);
105-
let method = self.cx.expr_path(self.cx.path(self.span, method));
106-
let allocator = self.cx.path_ident(self.span, self.global);
107+
let method = self.cx.expr_path(self.cx.path(self.ty_span, method));
108+
let allocator = self.cx.path_ident(self.ty_span, self.global);
107109
let allocator = self.cx.expr_path(allocator);
108-
let allocator = self.cx.expr_addr_of(self.span, allocator);
110+
let allocator = self.cx.expr_addr_of(self.ty_span, allocator);
109111
args.insert(0, allocator);
110112

111-
self.cx.expr_call(self.span, method, args)
113+
self.cx.expr_call(self.ty_span, method, args)
112114
}
113115

114116
fn attrs(&self) -> Vec<Attribute> {

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2053,7 +2053,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
20532053
if let Some(code) =
20542054
code.strip_prefix('"').and_then(|s| s.strip_suffix('"'))
20552055
{
2056-
if code.chars().nth(1).is_none() {
2056+
if code.chars().count() == 1 {
20572057
err.span_suggestion(
20582058
span,
20592059
"if you meant to write a `char` literal, use single quotes",

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2473,7 +2473,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
24732473
// `T`
24742474
substs: self.tcx.mk_substs_trait(
24752475
trait_pred.self_ty().skip_binder(),
2476-
self.fresh_substs_for_item(span, item_def_id),
2476+
&self.fresh_substs_for_item(span, item_def_id)[1..],
24772477
),
24782478
// `Future::Output`
24792479
item_def_id,

compiler/rustc_trait_selection/src/traits/project.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,16 @@ fn project<'cx, 'tcx>(
10731073
return Ok(Projected::Progress(Progress::error(selcx.tcx())));
10741074
}
10751075

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

10781088
// Make sure that the following procedures are kept in order. ParamEnv

library/std/src/fs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2044,7 +2044,7 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
20442044
///
20452045
/// This function currently corresponds to `openat`, `fdopendir`, `unlinkat` and `lstat` functions
20462046
/// on Unix (except for macOS before version 10.10 and REDOX) and the `CreateFileW`,
2047-
/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtOpenFile` functions on
2047+
/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtCreateFile` functions on
20482048
/// Windows. Note that, this [may change in the future][changes].
20492049
///
20502050
/// [changes]: io#platform-specific-behavior

library/std/src/sys/windows/c.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub const FILE_SHARE_DELETE: DWORD = 0x4;
8888
pub const FILE_SHARE_READ: DWORD = 0x1;
8989
pub const FILE_SHARE_WRITE: DWORD = 0x2;
9090

91+
pub const FILE_OPEN: ULONG = 0x00000001;
9192
pub const FILE_OPEN_REPARSE_POINT: ULONG = 0x200000;
9293
pub const OBJ_DONT_REPARSE: ULONG = 0x1000;
9394

@@ -1228,15 +1229,20 @@ compat_fn! {
12281229

12291230
compat_fn! {
12301231
"ntdll":
1231-
pub fn NtOpenFile(
1232+
pub fn NtCreateFile(
12321233
FileHandle: *mut HANDLE,
12331234
DesiredAccess: ACCESS_MASK,
12341235
ObjectAttributes: *const OBJECT_ATTRIBUTES,
12351236
IoStatusBlock: *mut IO_STATUS_BLOCK,
1237+
AllocationSize: *mut i64,
1238+
FileAttributes: ULONG,
12361239
ShareAccess: ULONG,
1237-
OpenOptions: ULONG
1240+
CreateDisposition: ULONG,
1241+
CreateOptions: ULONG,
1242+
EaBuffer: *mut c_void,
1243+
EaLength: ULONG
12381244
) -> NTSTATUS {
1239-
panic!("`NtOpenFile` not available");
1245+
panic!("`NtCreateFile` not available");
12401246
}
12411247
pub fn RtlNtStatusToDosError(
12421248
Status: NTSTATUS

library/std/src/sys/windows/fs.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -712,11 +712,11 @@ impl<'a> Iterator for DirBuffIter<'a> {
712712

713713
/// Open a link relative to the parent directory, ensure no symlinks are followed.
714714
fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result<File> {
715-
// This is implemented using the lower level `NtOpenFile` function as
715+
// This is implemented using the lower level `NtCreateFile` function as
716716
// unfortunately opening a file relative to a parent is not supported by
717717
// win32 functions. It is however a fundamental feature of the NT kernel.
718718
//
719-
// See https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntopenfile
719+
// See https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntcreatefile
720720
unsafe {
721721
let mut handle = ptr::null_mut();
722722
let mut io_status = c::IO_STATUS_BLOCK::default();
@@ -732,14 +732,19 @@ fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result<
732732
Attributes: ATTRIBUTES.load(Ordering::Relaxed),
733733
..c::OBJECT_ATTRIBUTES::default()
734734
};
735-
let status = c::NtOpenFile(
735+
let status = c::NtCreateFile(
736736
&mut handle,
737737
access,
738738
&object,
739739
&mut io_status,
740+
crate::ptr::null_mut(),
741+
0,
740742
c::FILE_SHARE_DELETE | c::FILE_SHARE_READ | c::FILE_SHARE_WRITE,
743+
c::FILE_OPEN,
741744
// If `name` is a symlink then open the link rather than the target.
742745
c::FILE_OPEN_REPARSE_POINT,
746+
crate::ptr::null_mut(),
747+
0,
743748
);
744749
// Convert an NTSTATUS to the more familiar Win32 error codes (aka "DosError")
745750
if c::nt_success(status) {

src/test/ui/allocator/not-an-allocator.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
11
error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
2-
--> $DIR/not-an-allocator.rs:2:1
2+
--> $DIR/not-an-allocator.rs:2:11
33
|
44
LL | #[global_allocator]
55
| ------------------- in this procedural macro expansion
66
LL | static A: usize = 0;
7-
| ^^^^^^^^^^^^^^^^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
7+
| ^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
88
|
99
= note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)
1010

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

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

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

src/test/ui/generic-associated-types/issue-74824.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ impl<T> UnsafeCopy for T {}
1717
fn main() {
1818
let b = Box::new(42usize);
1919
let copy = <()>::copy(&b);
20+
//~^ type annotations needed
2021

2122
let raw_b = Box::deref(&b) as *const _;
2223
let raw_copy = Box::deref(&copy) as *const _;

src/test/ui/generic-associated-types/issue-74824.stderr

+9-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ help: consider restricting type parameter `T`
2727
LL | type Copy<T: std::clone::Clone>: Copy = Box<T>;
2828
| +++++++++++++++++++
2929

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

32-
For more information about this error, try `rustc --explain E0277`.
38+
Some errors have detailed explanations: E0277, E0282.
39+
For more information about an error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// check-fail
2+
3+
// FIXME(generic_associated_types): We almost certaintly want this to pass, but
4+
// it's particularly difficult currently, because we need a way of specifying
5+
// that `<Self::Base as Functor>::With<T> = Self` without using that when we have
6+
// a `U`. See `https://github.com/rust-lang/rust/pull/92728` for a (hacky)
7+
// solution. This might be better to just wait for Chalk.
8+
9+
#![feature(generic_associated_types)]
10+
11+
pub trait Functor {
12+
type With<T>;
13+
14+
fn fmap<T, U>(this: Self::With<T>) -> Self::With<U>;
15+
}
16+
17+
pub trait FunctorExt<T>: Sized {
18+
type Base: Functor<With<T> = Self>;
19+
20+
fn fmap<U>(self) {
21+
let arg: <Self::Base as Functor>::With<T>;
22+
let ret: <Self::Base as Functor>::With<U>;
23+
24+
arg = self;
25+
ret = <Self::Base as Functor>::fmap(arg);
26+
//~^ type annotations needed
27+
}
28+
}
29+
30+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/issue-91762.rs:25:15
3+
|
4+
LL | ret = <Self::Base as Functor>::fmap(arg);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the associated function `fmap`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0282`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// A test exploiting the bug behind #25860 except with
2+
// implied trait bounds which currently don't exist without `-Zchalk`.
3+
use std::marker::PhantomData;
4+
struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>)
5+
where
6+
T: Convert<'a, 'b>;
7+
8+
trait Convert<'a, 'b>: Sized {
9+
fn cast(&'a self) -> &'b Self;
10+
}
11+
impl<'long: 'short, 'short, T> Convert<'long, 'short> for T {
12+
fn cast(&'long self) -> &'short T {
13+
self
14+
}
15+
}
16+
17+
// This function will compile once we add implied trait bounds.
18+
//
19+
// If we're not careful with our impl, the transformations
20+
// in `bad` would succeed, which is unsound ✨
21+
//
22+
// FIXME: the error is pretty bad, this should say
23+
//
24+
// `T: Convert<'in_, 'out>` is not implemented
25+
//
26+
// help: needed by `Foo<'in_, 'out, T>`
27+
//
28+
// Please ping @lcnr if your changes end up causing `badboi` to compile.
29+
fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out T {
30+
//~^ ERROR lifetime mismatch
31+
sadness.cast()
32+
}
33+
34+
fn bad<'short, T>(value: &'short T) -> &'static T {
35+
let x: for<'in_, 'out> fn(Foo<'in_, 'out, T>, &'in_ T) -> &'out T = badboi;
36+
let x: for<'out> fn(Foo<'short, 'out, T>, &'short T) -> &'out T = x;
37+
let x: for<'out> fn(Foo<'static, 'out, T>, &'short T) -> &'out T = x;
38+
let x: fn(Foo<'static, 'static, T>, &'short T) -> &'static T = x;
39+
x(Foo(PhantomData), value)
40+
}
41+
42+
// Use `bad` to cause a segfault.
43+
fn main() {
44+
let mut outer: Option<&'static u32> = Some(&3);
45+
let static_ref: &'static &'static u32 = match outer {
46+
Some(ref reference) => bad(reference),
47+
None => unreachable!(),
48+
};
49+
outer = None;
50+
println!("{}", static_ref);
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0623]: lifetime mismatch
2+
--> $DIR/hrlt-implied-trait-bounds-guard.rs:29:29
3+
|
4+
LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out T {
5+
| ^^^^^^^^^^^^^^^^^^ -------
6+
| |
7+
| this parameter and the return type are declared with different lifetimes...
8+
| ...but data from `x` is returned here
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0623`.

0 commit comments

Comments
 (0)