Skip to content

Commit 185a3f0

Browse files
committed
Auto merge of rust-lang#95351 - Dylan-DPC:rollup-o1il7tx, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - rust-lang#91981 (Recover suggestions and useful information lost in previous PR) - rust-lang#93469 (Skip pointing out ambiguous impls in alloc/std crates too in inference errors) - rust-lang#95335 (Move resolve_path to rustc_builtin_macros and make it private) - rust-lang#95340 (interpret: with enforce_number_validity, ensure integers are truly Scalar::Int (i.e., no pointers)) - rust-lang#95341 (ARMv6K Horizon OS has_thread_local support) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 06c3c62 + 2ab4ad5 commit 185a3f0

File tree

51 files changed

+281
-149
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+281
-149
lines changed

compiler/rustc_builtin_macros/src/source_util.rs

+43-4
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ use rustc_ast::ptr::P;
33
use rustc_ast::token;
44
use rustc_ast::tokenstream::TokenStream;
55
use rustc_ast_pretty::pprust;
6+
use rustc_errors::PResult;
67
use rustc_expand::base::{self, *};
78
use rustc_expand::module::DirOwnership;
89
use rustc_parse::parser::{ForceCollect, Parser};
910
use rustc_parse::{self, new_parser_from_file};
1011
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
1112
use rustc_span::symbol::Symbol;
12-
use rustc_span::{self, Pos, Span};
13+
use rustc_span::{self, FileName, Pos, Span};
1314

1415
use smallvec::SmallVec;
16+
use std::path::PathBuf;
1517
use std::rc::Rc;
1618

1719
// These macros all relate to the file system; they either return
@@ -102,7 +104,7 @@ pub fn expand_include<'cx>(
102104
return DummyResult::any(sp);
103105
};
104106
// The file will be added to the code map by the parser
105-
let file = match cx.resolve_path(file, sp) {
107+
let file = match resolve_path(cx, file, sp) {
106108
Ok(f) => f,
107109
Err(mut err) => {
108110
err.emit();
@@ -171,7 +173,7 @@ pub fn expand_include_str(
171173
let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_str!") else {
172174
return DummyResult::any(sp);
173175
};
174-
let file = match cx.resolve_path(file, sp) {
176+
let file = match resolve_path(cx, file, sp) {
175177
Ok(f) => f,
176178
Err(mut err) => {
177179
err.emit();
@@ -205,7 +207,7 @@ pub fn expand_include_bytes(
205207
let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_bytes!") else {
206208
return DummyResult::any(sp);
207209
};
208-
let file = match cx.resolve_path(file, sp) {
210+
let file = match resolve_path(cx, file, sp) {
209211
Ok(f) => f,
210212
Err(mut err) => {
211213
err.emit();
@@ -220,3 +222,40 @@ pub fn expand_include_bytes(
220222
}
221223
}
222224
}
225+
226+
/// Resolves a `path` mentioned inside Rust code, returning an absolute path.
227+
///
228+
/// This unifies the logic used for resolving `include_X!`.
229+
fn resolve_path<'a>(
230+
cx: &mut ExtCtxt<'a>,
231+
path: impl Into<PathBuf>,
232+
span: Span,
233+
) -> PResult<'a, PathBuf> {
234+
let path = path.into();
235+
236+
// Relative paths are resolved relative to the file in which they are found
237+
// after macro expansion (that is, they are unhygienic).
238+
if !path.is_absolute() {
239+
let callsite = span.source_callsite();
240+
let mut result = match cx.source_map().span_to_filename(callsite) {
241+
FileName::Real(name) => name
242+
.into_local_path()
243+
.expect("attempting to resolve a file path in an external file"),
244+
FileName::DocTest(path, _) => path,
245+
other => {
246+
return Err(cx.struct_span_err(
247+
span,
248+
&format!(
249+
"cannot resolve relative path in non-file source `{}`",
250+
cx.source_map().filename_for_diagnostics(&other)
251+
),
252+
));
253+
}
254+
};
255+
result.pop();
256+
result.push(path);
257+
Ok(result)
258+
} else {
259+
Ok(path)
260+
}
261+
}

compiler/rustc_const_eval/src/interpret/eval_context.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
444444
match scalar.try_to_int() {
445445
Ok(int) => int.is_null(),
446446
Err(_) => {
447+
// Can only happen during CTFE.
447448
let ptr = self.scalar_to_ptr(scalar);
448449
match self.memory.ptr_try_get_alloc(ptr) {
449450
Ok((alloc_id, offset, _)) => {
@@ -455,7 +456,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
455456
// Note that one-past-the-end (offset == size) is still inbounds, and never null.
456457
offset > size
457458
}
458-
Err(offset) => offset == 0,
459+
Err(_offset) => bug!("a non-int scalar is always a pointer"),
459460
}
460461
}
461462
}

compiler/rustc_const_eval/src/interpret/validity.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::hash::Hash;
2121

2222
use super::{
2323
alloc_range, CheckInAllocMsg, GlobalAlloc, InterpCx, InterpResult, MPlaceTy, Machine,
24-
MemPlaceMeta, OpTy, ScalarMaybeUninit, ValueVisitor,
24+
MemPlaceMeta, OpTy, Scalar, ScalarMaybeUninit, ValueVisitor,
2525
};
2626

2727
macro_rules! throw_validation_failure {
@@ -521,8 +521,11 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
521521
// NOTE: Keep this in sync with the array optimization for int/float
522522
// types below!
523523
if M::enforce_number_validity(self.ecx) {
524-
// Integers/floats in CTFE: Must be scalar bits, pointers are dangerous
525-
let is_bits = value.check_init().map_or(false, |v| v.try_to_int().is_ok());
524+
// Integers/floats with number validity: Must be scalar bits, pointers are dangerous.
525+
// As a special exception we *do* match on a `Scalar` here, since we truly want
526+
// to know its underlying representation (and *not* cast it to an integer).
527+
let is_bits =
528+
value.check_init().map_or(false, |v| matches!(v, Scalar::Int(..)));
526529
if !is_bits {
527530
throw_validation_failure!(self.path,
528531
{ "{:x}", value } expected { "initialized plain (non-pointer) bytes" }

compiler/rustc_expand/src/base.rs

+2-37
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_ast::{self as ast, AstLike, Attribute, Item, NodeId, PatKind};
1010
use rustc_attr::{self as attr, Deprecation, Stability};
1111
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1212
use rustc_data_structures::sync::{self, Lrc};
13-
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult};
13+
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed};
1414
use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
1515
use rustc_lint_defs::BuiltinLintDiagnostics;
1616
use rustc_parse::{self, nt_to_tokenstream, parser, MACRO_ARGUMENTS};
@@ -20,7 +20,7 @@ use rustc_span::edition::Edition;
2020
use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId};
2121
use rustc_span::source_map::SourceMap;
2222
use rustc_span::symbol::{kw, sym, Ident, Symbol};
23-
use rustc_span::{FileName, MultiSpan, Span, DUMMY_SP};
23+
use rustc_span::{MultiSpan, Span, DUMMY_SP};
2424
use smallvec::{smallvec, SmallVec};
2525

2626
use std::default::Default;
@@ -1128,41 +1128,6 @@ impl<'a> ExtCtxt<'a> {
11281128
pub fn check_unused_macros(&mut self) {
11291129
self.resolver.check_unused_macros();
11301130
}
1131-
1132-
/// Resolves a `path` mentioned inside Rust code, returning an absolute path.
1133-
///
1134-
/// This unifies the logic used for resolving `include_X!`.
1135-
///
1136-
/// FIXME: move this to `rustc_builtin_macros` and make it private.
1137-
pub fn resolve_path(&self, path: impl Into<PathBuf>, span: Span) -> PResult<'a, PathBuf> {
1138-
let path = path.into();
1139-
1140-
// Relative paths are resolved relative to the file in which they are found
1141-
// after macro expansion (that is, they are unhygienic).
1142-
if !path.is_absolute() {
1143-
let callsite = span.source_callsite();
1144-
let mut result = match self.source_map().span_to_filename(callsite) {
1145-
FileName::Real(name) => name
1146-
.into_local_path()
1147-
.expect("attempting to resolve a file path in an external file"),
1148-
FileName::DocTest(path, _) => path,
1149-
other => {
1150-
return Err(self.struct_span_err(
1151-
span,
1152-
&format!(
1153-
"cannot resolve relative path in non-file source `{}`",
1154-
self.source_map().filename_for_diagnostics(&other)
1155-
),
1156-
));
1157-
}
1158-
};
1159-
result.pop();
1160-
result.push(path);
1161-
Ok(result)
1162-
} else {
1163-
Ok(path)
1164-
}
1165-
}
11661131
}
11671132

11681133
/// Extracts a string literal from the macro expanded version of `expr`,

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ pub fn same_type_modulo_infer<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
333333
)
334334
| (&ty::Infer(ty::InferTy::TyVar(_)), _)
335335
| (_, &ty::Infer(ty::InferTy::TyVar(_))) => true,
336+
(&ty::Ref(reg_a, ty_a, mut_a), &ty::Ref(reg_b, ty_b, mut_b)) => {
337+
reg_a == reg_b && mut_a == mut_b && same_type_modulo_infer(*ty_a, *ty_b)
338+
}
336339
_ => a == b,
337340
}
338341
}
@@ -602,7 +605,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
602605
match *cause.code() {
603606
ObligationCauseCode::Pattern { origin_expr: true, span: Some(span), root_ty } => {
604607
let ty = self.resolve_vars_if_possible(root_ty);
605-
if ty.is_suggestable() {
608+
if !matches!(ty.kind(), ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_)))
609+
{
606610
// don't show type `_`
607611
err.span_label(span, format!("this expression has type `{}`", ty));
608612
}

compiler/rustc_infer/src/infer/mod.rs

+31
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
14341434
value.fold_with(&mut r)
14351435
}
14361436

1437+
pub fn resolve_numeric_literals_with_default<T>(&self, value: T) -> T
1438+
where
1439+
T: TypeFoldable<'tcx>,
1440+
{
1441+
if !value.needs_infer() {
1442+
return value; // Avoid duplicated subst-folding.
1443+
}
1444+
let mut r = InferenceLiteralEraser { tcx: self.tcx };
1445+
value.fold_with(&mut r)
1446+
}
1447+
14371448
/// Returns the first unresolved variable contained in `T`. In the
14381449
/// process of visiting `T`, this will resolve (where possible)
14391450
/// type variables in `T`, but it never constructs the final,
@@ -1785,6 +1796,26 @@ impl<'tcx> TyOrConstInferVar<'tcx> {
17851796
}
17861797
}
17871798

1799+
/// Replace `{integer}` with `i32` and `{float}` with `f64`.
1800+
/// Used only for diagnostics.
1801+
struct InferenceLiteralEraser<'tcx> {
1802+
tcx: TyCtxt<'tcx>,
1803+
}
1804+
1805+
impl<'tcx> TypeFolder<'tcx> for InferenceLiteralEraser<'tcx> {
1806+
fn tcx(&self) -> TyCtxt<'tcx> {
1807+
self.tcx
1808+
}
1809+
1810+
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
1811+
match ty.kind() {
1812+
ty::Infer(ty::IntVar(_) | ty::FreshIntTy(_)) => self.tcx.types.i32,
1813+
ty::Infer(ty::FloatVar(_) | ty::FreshFloatTy(_)) => self.tcx.types.f64,
1814+
_ => ty.super_fold_with(self),
1815+
}
1816+
}
1817+
}
1818+
17881819
struct ShallowResolver<'a, 'tcx> {
17891820
infcx: &'a InferCtxt<'a, 'tcx>,
17901821
}

compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ pub fn target() -> Target {
3737
pre_link_args,
3838
exe_suffix: ".elf".to_string(),
3939
no_default_libraries: false,
40+
has_thread_local: true,
4041
..Default::default()
4142
},
4243
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1954,7 +1954,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
19541954

19551955
if self.is_tainted_by_errors()
19561956
&& crate_names.len() == 1
1957-
&& crate_names[0] == "`core`"
1957+
&& ["`core`", "`alloc`", "`std`"].contains(&crate_names[0].as_str())
19581958
&& spans.len() == 0
19591959
{
19601960
// Avoid complaining about other inference issues for expressions like

compiler/rustc_typeck/src/astconv/generics.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_hir as hir;
1111
use rustc_hir::def::{DefKind, Res};
1212
use rustc_hir::def_id::DefId;
1313
use rustc_hir::GenericArg;
14+
use rustc_infer::infer::TyCtxtInferExt;
1415
use rustc_middle::ty::{
1516
self, subst, subst::SubstsRef, GenericParamDef, GenericParamDefKind, Ty, TyCtxt,
1617
};
@@ -83,7 +84,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
8384
if let Some(param_local_id) = param.def_id.as_local() {
8485
let param_hir_id = tcx.hir().local_def_id_to_hir_id(param_local_id);
8586
let param_name = tcx.hir().ty_param_name(param_hir_id);
86-
let param_type = tcx.type_of(param.def_id);
87+
let param_type = tcx.infer_ctxt().enter(|infcx| {
88+
infcx.resolve_numeric_literals_with_default(tcx.type_of(param.def_id))
89+
});
8790
if param_type.is_suggestable() {
8891
err.span_suggestion(
8992
tcx.def_span(src_def_id),

compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -521,20 +521,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
521521
can_suggest: bool,
522522
fn_id: hir::HirId,
523523
) -> bool {
524+
let found =
525+
self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found));
524526
// Only suggest changing the return type for methods that
525527
// haven't set a return type at all (and aren't `fn main()` or an impl).
526528
match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
527529
(&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
528530
err.span_suggestion(
529531
span,
530532
"try adding a return type",
531-
format!("-> {} ", self.resolve_vars_with_obligations(found)),
533+
format!("-> {} ", found),
532534
Applicability::MachineApplicable,
533535
);
534536
true
535537
}
536538
(&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
537-
err.span_label(span, "possibly return type missing here?");
539+
// FIXME: if `found` could be `impl Iterator` or `impl Fn*`, we should suggest
540+
// that.
541+
err.span_suggestion(
542+
span,
543+
"a return type might be missing here",
544+
"-> _ ".to_string(),
545+
Applicability::HasPlaceholders,
546+
);
538547
true
539548
}
540549
(&hir::FnRetTy::DefaultReturn(span), _, false, true) => {

src/test/ui/async-await/issue-61076.rs

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ async fn baz() -> Result<(), ()> {
8787

8888
async fn match_() {
8989
match tuple() { //~ HELP consider `await`ing on the `Future`
90+
//~^ NOTE this expression has type `impl Future<Output = Tuple>`
9091
Tuple(_) => {} //~ ERROR mismatched types
9192
//~^ NOTE expected opaque type, found struct `Tuple`
9293
//~| NOTE expected opaque type `impl Future<Output = Tuple>`

src/test/ui/async-await/issue-61076.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,11 @@ LL | struct_().await.method();
5656
| ++++++
5757

5858
error[E0308]: mismatched types
59-
--> $DIR/issue-61076.rs:90:9
59+
--> $DIR/issue-61076.rs:91:9
6060
|
61+
LL | match tuple() {
62+
| ------- this expression has type `impl Future<Output = Tuple>`
63+
LL |
6164
LL | Tuple(_) => {}
6265
| ^^^^^^^^ expected opaque type, found struct `Tuple`
6366
|

src/test/ui/async-await/suggest-missing-await.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ LL ~ 1 => dummy().await,
9191
error[E0308]: mismatched types
9292
--> $DIR/suggest-missing-await.rs:53:9
9393
|
94+
LL | let _x = match dummy() {
95+
| ------- this expression has type `impl Future<Output = ()>`
9496
LL | () => {}
9597
| ^^ expected opaque type, found `()`
9698
|
@@ -109,6 +111,9 @@ LL | let _x = match dummy().await {
109111
error[E0308]: mismatched types
110112
--> $DIR/suggest-missing-await.rs:67:9
111113
|
114+
LL | match dummy_result() {
115+
| -------------- this expression has type `impl Future<Output = Result<(), ()>>`
116+
...
112117
LL | Ok(_) => {}
113118
| ^^^^^ expected opaque type, found enum `Result`
114119
|
@@ -127,6 +132,9 @@ LL | match dummy_result().await {
127132
error[E0308]: mismatched types
128133
--> $DIR/suggest-missing-await.rs:69:9
129134
|
135+
LL | match dummy_result() {
136+
| -------------- this expression has type `impl Future<Output = Result<(), ()>>`
137+
...
130138
LL | Err(_) => {}
131139
| ^^^^^^ expected opaque type, found enum `Result`
132140
|

src/test/ui/blind/blind-item-block-middle.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | mod foo { pub struct bar; }
55
| --------------- unit struct defined here
66
...
77
LL | let bar = 5;
8-
| ^^^
8+
| ^^^ - this expression has type `{integer}`
99
| |
1010
| expected integer, found struct `bar`
1111
| `bar` is interpreted as a unit struct, not a new binding

src/test/ui/block-result/issue-20862.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
22
--> $DIR/issue-20862.rs:2:5
33
|
44
LL | fn foo(x: i32) {
5-
| - possibly return type missing here?
5+
| - help: a return type might be missing here: `-> _`
66
LL | |y| x + y
77
| ^^^^^^^^^ expected `()`, found closure
88
|

src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/default-match-bindings-forbidden.rs:4:5
33
|
44
LL | (x, y) = &(1, 2);
5-
| ^^^^^^ expected reference, found tuple
5+
| ^^^^^^ ------- this expression has type `&({integer}, {integer})`
6+
| |
7+
| expected reference, found tuple
68
|
79
= note: expected type `&({integer}, {integer})`
810
found tuple `(_, _)`

0 commit comments

Comments
 (0)