Skip to content

Commit

Permalink
Rollup merge of rust-lang#67426 - Centril:rollup-rswp4rf, r=Centril
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Centril committed Dec 19, 2019
2 parents 0de96d3 + 4ff4d6c commit fbea61a
Show file tree
Hide file tree
Showing 31 changed files with 382 additions and 149 deletions.
8 changes: 6 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3770,6 +3770,7 @@ dependencies = [
"smallvec 1.0.0",
"syntax",
"syntax_pos",
"unicode-normalization",
]

[[package]]
Expand Down Expand Up @@ -4976,9 +4977,12 @@ dependencies = [

[[package]]
name = "unicode-normalization"
version = "0.1.7"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
checksum = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf"
dependencies = [
"smallvec 1.0.0",
]

[[package]]
name = "unicode-segmentation"
Expand Down
40 changes: 40 additions & 0 deletions src/liballoc/benches/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,43 @@ fn bench_to_string(b: &mut Bencher) {
Lorem ipsum dolor sit amet, consectetur. ";
b.iter(|| s.to_string())
}

#[bench]
fn bench_insert_char_short(b: &mut Bencher) {
let s = "Hello, World!";
b.iter(|| {
let mut x = String::from(s);
black_box(&mut x).insert(6, black_box(' '));
x
})
}

#[bench]
fn bench_insert_char_long(b: &mut Bencher) {
let s = "Hello, World!";
b.iter(|| {
let mut x = String::from(s);
black_box(&mut x).insert(6, black_box('❤'));
x
})
}

#[bench]
fn bench_insert_str_short(b: &mut Bencher) {
let s = "Hello, World!";
b.iter(|| {
let mut x = String::from(s);
black_box(&mut x).insert_str(6, black_box(" "));
x
})
}

#[bench]
fn bench_insert_str_long(b: &mut Bencher) {
let s = "Hello, World!";
b.iter(|| {
let mut x = String::from(s);
black_box(&mut x).insert_str(6, black_box(" rustic "));
x
})
}
1 change: 1 addition & 0 deletions src/liballoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
#![feature(const_generic_impls_guard)]
#![feature(const_generics)]
#![feature(const_in_array_repeat_expressions)]
#![feature(const_if_match)]
#![feature(cow_is_borrowed)]
#![feature(dispatch_from_dyn)]
#![feature(core_intrinsics)]
Expand Down
21 changes: 3 additions & 18 deletions src/liballoc/raw_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,12 @@ impl<T, A: Alloc> RawVec<T, A> {
/// Like `new`, but parameterized over the choice of allocator for
/// the returned `RawVec`.
pub const fn new_in(a: A) -> Self {
// `!0` is `usize::MAX`. This branch should be stripped at compile time.
// FIXME(mark-i-m): use this line when `if`s are allowed in `const`:
//let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
let cap = if mem::size_of::<T>() == 0 { core::usize::MAX } else { 0 };

// `Unique::empty()` doubles as "unallocated" and "zero-sized allocation".
RawVec {
ptr: Unique::empty(),
// FIXME(mark-i-m): use `cap` when ifs are allowed in const
cap: [0, !0][(mem::size_of::<T>() == 0) as usize],
cap,
a,
}
}
Expand Down Expand Up @@ -132,19 +129,7 @@ impl<T> RawVec<T, Global> {
/// `RawVec` with capacity `usize::MAX`. Useful for implementing
/// delayed allocation.
pub const fn new() -> Self {
// FIXME(Centril): Reintegrate this with `fn new_in` when we can.

// `!0` is `usize::MAX`. This branch should be stripped at compile time.
// FIXME(mark-i-m): use this line when `if`s are allowed in `const`:
//let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };

// `Unique::empty()` doubles as "unallocated" and "zero-sized allocation".
RawVec {
ptr: Unique::empty(),
// FIXME(mark-i-m): use `cap` when ifs are allowed in const
cap: [0, !0][(mem::size_of::<T>() == 0) as usize],
a: Global,
}
Self::new_in(Global)
}

/// Creates a `RawVec` (on the system heap) with exactly the
Expand Down
10 changes: 10 additions & 0 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1857,6 +1857,16 @@ impl fmt::Display for YieldSource {
}
}

impl From<GeneratorKind> for YieldSource {
fn from(kind: GeneratorKind) -> Self {
match kind {
// Guess based on the kind of the current generator.
GeneratorKind::Gen => Self::Yield,
GeneratorKind::Async(_) => Self::Await,
}
}
}

// N.B., if you change this, you'll probably want to change the corresponding
// type structure in middle/ty.rs as well.
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
Expand Down
11 changes: 11 additions & 0 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,17 @@ pub enum AssocKind {
Type
}

impl AssocKind {
pub fn suggestion_descr(&self) -> &'static str {
match self {
ty::AssocKind::Method => "method call",
ty::AssocKind::Type |
ty::AssocKind::OpaqueTy => "associated type",
ty::AssocKind::Const => "associated constant",
}
}
}

impl AssocItem {
pub fn def_kind(&self) -> DefKind {
match self.kind {
Expand Down
43 changes: 7 additions & 36 deletions src/librustc_codegen_ssa/mir/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
llval
}
}
(CastTy::Int(_), CastTy::Float) => {
if signed {
bx.sitofp(llval, ll_t_out)
} else {
bx.uitofp(llval, ll_t_out)
}
}
(CastTy::Ptr(_), CastTy::Ptr(_)) |
(CastTy::FnPtr, CastTy::Ptr(_)) |
(CastTy::RPtr(_), CastTy::Ptr(_)) =>
Expand All @@ -352,8 +359,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let usize_llval = bx.intcast(llval, bx.cx().type_isize(), signed);
bx.inttoptr(usize_llval, ll_t_out)
}
(CastTy::Int(_), CastTy::Float) =>
cast_int_to_float(&mut bx, signed, llval, ll_t_in, ll_t_out),
(CastTy::Float, CastTy::Int(IntTy::I)) =>
cast_float_to_int(&mut bx, true, llval, ll_t_in, ll_t_out),
(CastTy::Float, CastTy::Int(_)) =>
Expand Down Expand Up @@ -720,40 +725,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}

fn cast_int_to_float<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &mut Bx,
signed: bool,
x: Bx::Value,
int_ty: Bx::Type,
float_ty: Bx::Type
) -> Bx::Value {
// Most integer types, even i128, fit into [-f32::MAX, f32::MAX] after rounding.
// It's only u128 -> f32 that can cause overflows (i.e., should yield infinity).
// LLVM's uitofp produces undef in those cases, so we manually check for that case.
let is_u128_to_f32 = !signed &&
bx.cx().int_width(int_ty) == 128 &&
bx.cx().float_width(float_ty) == 32;
if is_u128_to_f32 {
// All inputs greater or equal to (f32::MAX + 0.5 ULP) are rounded to infinity,
// and for everything else LLVM's uitofp works just fine.
use rustc_apfloat::ieee::Single;
const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1)
<< (Single::MAX_EXP - Single::PRECISION as i16);
let max = bx.cx().const_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP);
let overflow = bx.icmp(IntPredicate::IntUGE, x, max);
let infinity_bits = bx.cx().const_u32(ieee::Single::INFINITY.to_bits() as u32);
let infinity = bx.bitcast(infinity_bits, float_ty);
let fp = bx.uitofp(x, float_ty);
bx.select(overflow, infinity, fp)
} else {
if signed {
bx.sitofp(x, float_ty)
} else {
bx.uitofp(x, float_ty)
}
}
}

fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &mut Bx,
signed: bool,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_interface/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use syntax_pos::edition;
pub type Result<T> = result::Result<T, ErrorReported>;

/// Represents a compiler session.
/// Can be used run `rustc_interface` queries.
/// Can be used to run `rustc_interface` queries.
/// Created by passing `Config` to `run_compiler`.
pub struct Compiler {
pub(crate) sess: Lrc<Session>,
Expand Down
1 change: 1 addition & 0 deletions src/librustc_parse/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ rustc_error_codes = { path = "../librustc_error_codes" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
syntax_pos = { path = "../libsyntax_pos" }
syntax = { path = "../libsyntax" }
unicode-normalization = "0.1.11"
17 changes: 15 additions & 2 deletions src/librustc_parse/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,7 @@ impl<'a> StringReader<'a> {
if is_raw_ident {
ident_start = ident_start + BytePos(2);
}
// FIXME: perform NFKC normalization here. (Issue #2253)
let sym = self.symbol_from(ident_start);
let sym = self.nfc_symbol_from(ident_start);
if is_raw_ident {
let span = self.mk_sp(start, self.pos);
if !sym.can_be_raw() {
Expand Down Expand Up @@ -465,6 +464,20 @@ impl<'a> StringReader<'a> {
Symbol::intern(self.str_from_to(start, end))
}

/// As symbol_from, with the text normalized into Unicode NFC form.
fn nfc_symbol_from(&self, start: BytePos) -> Symbol {
use unicode_normalization::{is_nfc_quick, IsNormalized, UnicodeNormalization};
debug!("taking an normalized ident from {:?} to {:?}", start, self.pos);
let sym = self.str_from(start);
match is_nfc_quick(sym.chars()) {
IsNormalized::Yes => Symbol::intern(sym),
_ => {
let sym_str: String = sym.chars().nfc().collect();
Symbol::intern(&sym_str)
}
}
}

/// Slice of the source text spanning from `start` up to but excluding `end`.
fn str_from_to(&self, start: BytePos, end: BytePos) -> &str
{
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_typeck/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1425,8 +1425,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
field: ast::Ident,
) -> Ty<'tcx> {
let expr_t = self.check_expr_with_needs(base, needs);
let expr_t = self.structurally_resolved_type(base.span,
expr_t);
let expr_t = self.structurally_resolved_type(base.span, expr_t);
let mut private_candidate = None;
let mut autoderef = self.autoderef(expr.span, expr_t);
while let Some((base_t, _)) = autoderef.next() {
Expand Down
21 changes: 14 additions & 7 deletions src/librustc_typeck/check/generator_interior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct InteriorVisitor<'a, 'tcx> {
region_scope_tree: &'tcx region::ScopeTree,
expr_count: usize,
kind: hir::GeneratorKind,
prev_unresolved_span: Option<Span>,
}

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


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

if let Some(yield_data) = live_across_yield {
let ty = self.fcx.resolve_vars_if_possible(&ty);

debug!("type in expr = {:?}, scope = {:?}, type = {:?}, count = {}, yield_span = {:?}",
expr, scope, ty, self.expr_count, yield_data.span);

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

// If unresolved type isn't a ty_var then unresolved_type_span is None
let span = self.prev_unresolved_span.unwrap_or_else(
|| unresolved_type_span.unwrap_or(source_span)
);
self.fcx.need_type_info_err_in_generator(
self.kind,
unresolved_type_span.unwrap_or(source_span),
span,
unresolved_type,
)
.span_note(yield_data.span, &*note)
Expand All @@ -94,6 +93,13 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
} else {
debug!("no type in expr = {:?}, count = {:?}, span = {:?}",
expr, self.expr_count, expr.map(|e| e.span));
let ty = self.fcx.resolve_vars_if_possible(&ty);
if let Some((unresolved_type, unresolved_type_span))
= self.fcx.unresolved_type_vars(&ty) {
debug!("remained unresolved_type = {:?}, unresolved_type_span: {:?}",
unresolved_type, unresolved_type_span);
self.prev_unresolved_span = unresolved_type_span;
}
}
}
}
Expand All @@ -112,6 +118,7 @@ pub fn resolve_interior<'a, 'tcx>(
region_scope_tree: fcx.tcx.region_scope_tree(def_id),
expr_count: 0,
kind,
prev_unresolved_span: None,
};
intravisit::walk_body(&mut visitor, body);

Expand Down
Loading

0 comments on commit fbea61a

Please sign in to comment.