Skip to content

Commit fbea61a

Browse files
authored
Rollup merge of rust-lang#67426 - Centril:rollup-rswp4rf, r=Centril
Rollup of 7 pull requests Successful merges: - rust-lang#66670 (Normalize ident) - rust-lang#66755 (Remove a const-if-hack in RawVec) - rust-lang#67127 (Use structured suggestion for disambiguating method calls) - rust-lang#67281 (add string.insert benchmarks) - rust-lang#67328 (Remove now-redundant range check on u128 -> f32 casts) - rust-lang#67392 (Fix unresolved type span inside async object) - rust-lang#67421 (Fix internal documentation typo) Failed merges: r? @ghost
2 parents 0de96d3 + 4ff4d6c commit fbea61a

31 files changed

+382
-149
lines changed

Cargo.lock

+6-2
Original file line numberDiff line numberDiff line change
@@ -3770,6 +3770,7 @@ dependencies = [
37703770
"smallvec 1.0.0",
37713771
"syntax",
37723772
"syntax_pos",
3773+
"unicode-normalization",
37733774
]
37743775

37753776
[[package]]
@@ -4976,9 +4977,12 @@ dependencies = [
49764977

49774978
[[package]]
49784979
name = "unicode-normalization"
4979-
version = "0.1.7"
4980+
version = "0.1.11"
49804981
source = "registry+https://github.com/rust-lang/crates.io-index"
4981-
checksum = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
4982+
checksum = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf"
4983+
dependencies = [
4984+
"smallvec 1.0.0",
4985+
]
49824986

49834987
[[package]]
49844988
name = "unicode-segmentation"

src/liballoc/benches/string.rs

+40
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,43 @@ fn bench_to_string(b: &mut Bencher) {
122122
Lorem ipsum dolor sit amet, consectetur. ";
123123
b.iter(|| s.to_string())
124124
}
125+
126+
#[bench]
127+
fn bench_insert_char_short(b: &mut Bencher) {
128+
let s = "Hello, World!";
129+
b.iter(|| {
130+
let mut x = String::from(s);
131+
black_box(&mut x).insert(6, black_box(' '));
132+
x
133+
})
134+
}
135+
136+
#[bench]
137+
fn bench_insert_char_long(b: &mut Bencher) {
138+
let s = "Hello, World!";
139+
b.iter(|| {
140+
let mut x = String::from(s);
141+
black_box(&mut x).insert(6, black_box('❤'));
142+
x
143+
})
144+
}
145+
146+
#[bench]
147+
fn bench_insert_str_short(b: &mut Bencher) {
148+
let s = "Hello, World!";
149+
b.iter(|| {
150+
let mut x = String::from(s);
151+
black_box(&mut x).insert_str(6, black_box(" "));
152+
x
153+
})
154+
}
155+
156+
#[bench]
157+
fn bench_insert_str_long(b: &mut Bencher) {
158+
let s = "Hello, World!";
159+
b.iter(|| {
160+
let mut x = String::from(s);
161+
black_box(&mut x).insert_str(6, black_box(" rustic "));
162+
x
163+
})
164+
}

src/liballoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
#![feature(const_generic_impls_guard)]
8686
#![feature(const_generics)]
8787
#![feature(const_in_array_repeat_expressions)]
88+
#![feature(const_if_match)]
8889
#![feature(cow_is_borrowed)]
8990
#![feature(dispatch_from_dyn)]
9091
#![feature(core_intrinsics)]

src/liballoc/raw_vec.rs

+3-18
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,12 @@ impl<T, A: Alloc> RawVec<T, A> {
5252
/// Like `new`, but parameterized over the choice of allocator for
5353
/// the returned `RawVec`.
5454
pub const fn new_in(a: A) -> Self {
55-
// `!0` is `usize::MAX`. This branch should be stripped at compile time.
56-
// FIXME(mark-i-m): use this line when `if`s are allowed in `const`:
57-
//let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
55+
let cap = if mem::size_of::<T>() == 0 { core::usize::MAX } else { 0 };
5856

5957
// `Unique::empty()` doubles as "unallocated" and "zero-sized allocation".
6058
RawVec {
6159
ptr: Unique::empty(),
62-
// FIXME(mark-i-m): use `cap` when ifs are allowed in const
63-
cap: [0, !0][(mem::size_of::<T>() == 0) as usize],
60+
cap,
6461
a,
6562
}
6663
}
@@ -132,19 +129,7 @@ impl<T> RawVec<T, Global> {
132129
/// `RawVec` with capacity `usize::MAX`. Useful for implementing
133130
/// delayed allocation.
134131
pub const fn new() -> Self {
135-
// FIXME(Centril): Reintegrate this with `fn new_in` when we can.
136-
137-
// `!0` is `usize::MAX`. This branch should be stripped at compile time.
138-
// FIXME(mark-i-m): use this line when `if`s are allowed in `const`:
139-
//let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
140-
141-
// `Unique::empty()` doubles as "unallocated" and "zero-sized allocation".
142-
RawVec {
143-
ptr: Unique::empty(),
144-
// FIXME(mark-i-m): use `cap` when ifs are allowed in const
145-
cap: [0, !0][(mem::size_of::<T>() == 0) as usize],
146-
a: Global,
147-
}
132+
Self::new_in(Global)
148133
}
149134

150135
/// Creates a `RawVec` (on the system heap) with exactly the

src/librustc/hir/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1857,6 +1857,16 @@ impl fmt::Display for YieldSource {
18571857
}
18581858
}
18591859

1860+
impl From<GeneratorKind> for YieldSource {
1861+
fn from(kind: GeneratorKind) -> Self {
1862+
match kind {
1863+
// Guess based on the kind of the current generator.
1864+
GeneratorKind::Gen => Self::Yield,
1865+
GeneratorKind::Async(_) => Self::Await,
1866+
}
1867+
}
1868+
}
1869+
18601870
// N.B., if you change this, you'll probably want to change the corresponding
18611871
// type structure in middle/ty.rs as well.
18621872
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]

src/librustc/ty/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,17 @@ pub enum AssocKind {
212212
Type
213213
}
214214

215+
impl AssocKind {
216+
pub fn suggestion_descr(&self) -> &'static str {
217+
match self {
218+
ty::AssocKind::Method => "method call",
219+
ty::AssocKind::Type |
220+
ty::AssocKind::OpaqueTy => "associated type",
221+
ty::AssocKind::Const => "associated constant",
222+
}
223+
}
224+
}
225+
215226
impl AssocItem {
216227
pub fn def_kind(&self) -> DefKind {
217228
match self.kind {

src/librustc_codegen_ssa/mir/rvalue.rs

+7-36
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
341341
llval
342342
}
343343
}
344+
(CastTy::Int(_), CastTy::Float) => {
345+
if signed {
346+
bx.sitofp(llval, ll_t_out)
347+
} else {
348+
bx.uitofp(llval, ll_t_out)
349+
}
350+
}
344351
(CastTy::Ptr(_), CastTy::Ptr(_)) |
345352
(CastTy::FnPtr, CastTy::Ptr(_)) |
346353
(CastTy::RPtr(_), CastTy::Ptr(_)) =>
@@ -352,8 +359,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
352359
let usize_llval = bx.intcast(llval, bx.cx().type_isize(), signed);
353360
bx.inttoptr(usize_llval, ll_t_out)
354361
}
355-
(CastTy::Int(_), CastTy::Float) =>
356-
cast_int_to_float(&mut bx, signed, llval, ll_t_in, ll_t_out),
357362
(CastTy::Float, CastTy::Int(IntTy::I)) =>
358363
cast_float_to_int(&mut bx, true, llval, ll_t_in, ll_t_out),
359364
(CastTy::Float, CastTy::Int(_)) =>
@@ -720,40 +725,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
720725
}
721726
}
722727

723-
fn cast_int_to_float<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
724-
bx: &mut Bx,
725-
signed: bool,
726-
x: Bx::Value,
727-
int_ty: Bx::Type,
728-
float_ty: Bx::Type
729-
) -> Bx::Value {
730-
// Most integer types, even i128, fit into [-f32::MAX, f32::MAX] after rounding.
731-
// It's only u128 -> f32 that can cause overflows (i.e., should yield infinity).
732-
// LLVM's uitofp produces undef in those cases, so we manually check for that case.
733-
let is_u128_to_f32 = !signed &&
734-
bx.cx().int_width(int_ty) == 128 &&
735-
bx.cx().float_width(float_ty) == 32;
736-
if is_u128_to_f32 {
737-
// All inputs greater or equal to (f32::MAX + 0.5 ULP) are rounded to infinity,
738-
// and for everything else LLVM's uitofp works just fine.
739-
use rustc_apfloat::ieee::Single;
740-
const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1)
741-
<< (Single::MAX_EXP - Single::PRECISION as i16);
742-
let max = bx.cx().const_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP);
743-
let overflow = bx.icmp(IntPredicate::IntUGE, x, max);
744-
let infinity_bits = bx.cx().const_u32(ieee::Single::INFINITY.to_bits() as u32);
745-
let infinity = bx.bitcast(infinity_bits, float_ty);
746-
let fp = bx.uitofp(x, float_ty);
747-
bx.select(overflow, infinity, fp)
748-
} else {
749-
if signed {
750-
bx.sitofp(x, float_ty)
751-
} else {
752-
bx.uitofp(x, float_ty)
753-
}
754-
}
755-
}
756-
757728
fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
758729
bx: &mut Bx,
759730
signed: bool,

src/librustc_interface/interface.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use syntax_pos::edition;
2525
pub type Result<T> = result::Result<T, ErrorReported>;
2626

2727
/// Represents a compiler session.
28-
/// Can be used run `rustc_interface` queries.
28+
/// Can be used to run `rustc_interface` queries.
2929
/// Created by passing `Config` to `run_compiler`.
3030
pub struct Compiler {
3131
pub(crate) sess: Lrc<Session>,

src/librustc_parse/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ rustc_error_codes = { path = "../librustc_error_codes" }
2020
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
2121
syntax_pos = { path = "../libsyntax_pos" }
2222
syntax = { path = "../libsyntax" }
23+
unicode-normalization = "0.1.11"

src/librustc_parse/lexer/mod.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,7 @@ impl<'a> StringReader<'a> {
219219
if is_raw_ident {
220220
ident_start = ident_start + BytePos(2);
221221
}
222-
// FIXME: perform NFKC normalization here. (Issue #2253)
223-
let sym = self.symbol_from(ident_start);
222+
let sym = self.nfc_symbol_from(ident_start);
224223
if is_raw_ident {
225224
let span = self.mk_sp(start, self.pos);
226225
if !sym.can_be_raw() {
@@ -465,6 +464,20 @@ impl<'a> StringReader<'a> {
465464
Symbol::intern(self.str_from_to(start, end))
466465
}
467466

467+
/// As symbol_from, with the text normalized into Unicode NFC form.
468+
fn nfc_symbol_from(&self, start: BytePos) -> Symbol {
469+
use unicode_normalization::{is_nfc_quick, IsNormalized, UnicodeNormalization};
470+
debug!("taking an normalized ident from {:?} to {:?}", start, self.pos);
471+
let sym = self.str_from(start);
472+
match is_nfc_quick(sym.chars()) {
473+
IsNormalized::Yes => Symbol::intern(sym),
474+
_ => {
475+
let sym_str: String = sym.chars().nfc().collect();
476+
Symbol::intern(&sym_str)
477+
}
478+
}
479+
}
480+
468481
/// Slice of the source text spanning from `start` up to but excluding `end`.
469482
fn str_from_to(&self, start: BytePos, end: BytePos) -> &str
470483
{

src/librustc_typeck/check/expr.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1425,8 +1425,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14251425
field: ast::Ident,
14261426
) -> Ty<'tcx> {
14271427
let expr_t = self.check_expr_with_needs(base, needs);
1428-
let expr_t = self.structurally_resolved_type(base.span,
1429-
expr_t);
1428+
let expr_t = self.structurally_resolved_type(base.span, expr_t);
14301429
let mut private_candidate = None;
14311430
let mut autoderef = self.autoderef(expr.span, expr_t);
14321431
while let Some((base_t, _)) = autoderef.next() {

src/librustc_typeck/check/generator_interior.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct InteriorVisitor<'a, 'tcx> {
1919
region_scope_tree: &'tcx region::ScopeTree,
2020
expr_count: usize,
2121
kind: hir::GeneratorKind,
22+
prev_unresolved_span: Option<Span>,
2223
}
2324

2425
impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
@@ -32,7 +33,6 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
3233
debug!("generator_interior: attempting to record type {:?} {:?} {:?} {:?}",
3334
ty, scope, expr, source_span);
3435

35-
3636
let live_across_yield = scope.map(|s| {
3737
self.region_scope_tree.yield_in_scope(s).and_then(|yield_data| {
3838
// If we are recording an expression that is the last yield
@@ -54,15 +54,11 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
5454
}).unwrap_or_else(|| Some(YieldData {
5555
span: DUMMY_SP,
5656
expr_and_pat_count: 0,
57-
source: match self.kind { // Guess based on the kind of the current generator.
58-
hir::GeneratorKind::Gen => hir::YieldSource::Yield,
59-
hir::GeneratorKind::Async(_) => hir::YieldSource::Await,
60-
},
57+
source: self.kind.into(),
6158
}));
6259

6360
if let Some(yield_data) = live_across_yield {
6461
let ty = self.fcx.resolve_vars_if_possible(&ty);
65-
6662
debug!("type in expr = {:?}, scope = {:?}, type = {:?}, count = {}, yield_span = {:?}",
6763
expr, scope, ty, self.expr_count, yield_data.span);
6864

@@ -74,9 +70,12 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
7470
yield_data.source);
7571

7672
// If unresolved type isn't a ty_var then unresolved_type_span is None
73+
let span = self.prev_unresolved_span.unwrap_or_else(
74+
|| unresolved_type_span.unwrap_or(source_span)
75+
);
7776
self.fcx.need_type_info_err_in_generator(
7877
self.kind,
79-
unresolved_type_span.unwrap_or(source_span),
78+
span,
8079
unresolved_type,
8180
)
8281
.span_note(yield_data.span, &*note)
@@ -94,6 +93,13 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
9493
} else {
9594
debug!("no type in expr = {:?}, count = {:?}, span = {:?}",
9695
expr, self.expr_count, expr.map(|e| e.span));
96+
let ty = self.fcx.resolve_vars_if_possible(&ty);
97+
if let Some((unresolved_type, unresolved_type_span))
98+
= self.fcx.unresolved_type_vars(&ty) {
99+
debug!("remained unresolved_type = {:?}, unresolved_type_span: {:?}",
100+
unresolved_type, unresolved_type_span);
101+
self.prev_unresolved_span = unresolved_type_span;
102+
}
97103
}
98104
}
99105
}
@@ -112,6 +118,7 @@ pub fn resolve_interior<'a, 'tcx>(
112118
region_scope_tree: fcx.tcx.region_scope_tree(def_id),
113119
expr_count: 0,
114120
kind,
121+
prev_unresolved_span: None,
115122
};
116123
intravisit::walk_body(&mut visitor, body);
117124

0 commit comments

Comments
 (0)