Skip to content

Rollup of 5 pull requests #41413

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

Merged
merged 11 commits into from
Apr 20, 2017
Merged
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
10 changes: 7 additions & 3 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
@@ -1597,9 +1597,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// generic so we don't have to do anything quite this
// terrible.
let trace = TypeTrace::dummy(self.tcx);
self.equate(true, trace, a, b).map(|InferOk { obligations, .. }| {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
self.equate(true, trace, a, b).map(|InferOk { obligations: _, .. }| {
// We can intentionally ignore obligations here, since
// this is part of a simple test for general
// "equatability". However, it's not entirely clear
// that we *ought* to be, perhaps a better thing would
// be to use a mini-fulfillment context or something
// like that.
})
})
}
8 changes: 4 additions & 4 deletions src/librustc/traits/coherence.rs
Original file line number Diff line number Diff line change
@@ -55,16 +55,15 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
debug!("overlap: b_impl_header={:?}", b_impl_header);

// Do `a` and `b` unify? If not, no overlap.
match selcx.infcx().eq_impl_headers(true,
let obligations = match selcx.infcx().eq_impl_headers(true,
&ObligationCause::dummy(),
&a_impl_header,
&b_impl_header) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
obligations
}
Err(_) => return None
}
};

debug!("overlap: unification check succeeded");

@@ -78,6 +77,7 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
.map(|p| Obligation { cause: ObligationCause::dummy(),
recursion_depth: 0,
predicate: p })
.chain(obligations)
.find(|o| !selcx.evaluate_obligation(o));

if let Some(failing_obligation) = opt_failing_obligation {
28 changes: 13 additions & 15 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
@@ -329,22 +329,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
Some(val) => Some(val),
None => {
span_err!(self.tcx.sess, err_sp, E0272,
"the #[rustc_on_unimplemented] \
attribute on \
trait definition for {} refers to \
non-existent type parameter {}",
trait_str, s);
"the #[rustc_on_unimplemented] attribute on trait \
definition for {} refers to non-existent type \
parameter {}",
trait_str, s);
errored = true;
None
}
},
_ => {
span_err!(self.tcx.sess, err_sp, E0273,
"the #[rustc_on_unimplemented] attribute \
on trait definition for {} must have \
named format arguments, eg \
`#[rustc_on_unimplemented = \
\"foo {{T}}\"]`", trait_str);
"the #[rustc_on_unimplemented] attribute on trait \
definition for {} must have named format arguments, eg \
`#[rustc_on_unimplemented = \"foo {{T}}\"]`",
trait_str);
errored = true;
None
}
@@ -485,8 +483,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
"impl has stricter requirements than trait");

if let Some(trait_item_span) = self.tcx.hir.span_if_local(trait_item_def_id) {
err.span_label(trait_item_span,
&format!("definition of `{}` from trait", item_name));
let span = self.tcx.sess.codemap().def_span(trait_item_span);
err.span_label(span, &format!("definition of `{}` from trait", item_name));
}

err.span_label(
@@ -692,6 +690,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
{
assert!(type_def_id.is_local());
let span = self.hir.span_if_local(type_def_id).unwrap();
let span = self.sess.codemap().def_span(span);
let mut err = struct_span_err!(self.sess, span, E0072,
"recursive type `{}` has infinite size",
self.item_path_str(type_def_id));
@@ -709,13 +708,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-> DiagnosticBuilder<'tcx>
{
let trait_str = self.item_path_str(trait_def_id);
let span = self.sess.codemap().def_span(span);
let mut err = struct_span_err!(
self.sess, span, E0038,
"the trait `{}` cannot be made into an object",
trait_str);
err.span_label(span, &format!(
"the trait `{}` cannot be made into an object", trait_str
));
err.span_label(span, &format!("the trait `{}` cannot be made into an object", trait_str));

let mut reported_violations = FxHashSet();
for violation in violations {
10 changes: 10 additions & 0 deletions src/librustc/traits/fulfill.rs
Original file line number Diff line number Diff line change
@@ -184,6 +184,16 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
});
}

pub fn register_predicate_obligations(&mut self,
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
obligations: Vec<PredicateObligation<'tcx>>)
{
for obligation in obligations {
self.register_predicate_obligation(infcx, obligation);
}
}


pub fn region_obligations(&self,
body_id: ast::NodeId)
-> &[RegionObligation<'tcx>]
7 changes: 3 additions & 4 deletions src/librustc/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
@@ -218,7 +218,7 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
-> Result<&'tcx Substs<'tcx>, ()> {
let selcx = &mut SelectionContext::new(&infcx);
let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl);
let (target_trait_ref, obligations) = impl_trait_ref_and_oblig(selcx,
let (target_trait_ref, mut obligations) = impl_trait_ref_and_oblig(selcx,
target_impl,
target_substs);

@@ -227,9 +227,8 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
&ObligationCause::dummy(),
source_trait_ref,
target_trait_ref) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty())
Ok(InferOk { obligations: o, .. }) => {
obligations.extend(o);
}
Err(_) => {
debug!("fulfill_implication: {:?} does not unify with {:?}",
6 changes: 3 additions & 3 deletions src/librustc_driver/test.rs
Original file line number Diff line number Diff line change
@@ -376,7 +376,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
match self.sub(t1, t2) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) once obligations are being propagated, assert the right thing.
// None of these tests should require nested obligations:
assert!(obligations.is_empty());
}
Err(ref e) => {
@@ -400,7 +400,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) {
match self.lub(t1, t2) {
Ok(InferOk { obligations, value: t }) => {
// FIXME(#32730) once obligations are being propagated, assert the right thing.
// None of these tests should require nested obligations:
assert!(obligations.is_empty());

self.assert_eq(t, t_lub);
@@ -415,7 +415,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
match self.glb(t1, t2) {
Err(e) => panic!("unexpected error computing LUB: {:?}", e),
Ok(InferOk { obligations, value: t }) => {
// FIXME(#32730) once obligations are being propagated, assert the right thing.
// None of these tests should require nested obligations:
assert!(obligations.is_empty());

self.assert_eq(t, t_glb);
6 changes: 3 additions & 3 deletions src/librustc_trans/cabi_x86_64.rs
Original file line number Diff line number Diff line change
@@ -229,12 +229,12 @@ pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType
};

if in_mem {
// `sret` / `byval` parameter thus one less integer register available
int_regs -= 1;

arg.make_indirect(ccx);
if is_arg {
arg.attrs.set(ArgAttribute::ByVal);
} else {
// `sret` parameter thus one less integer register available
int_regs -= 1;
}
} else {
// split into sized chunks passed individually
7 changes: 3 additions & 4 deletions src/librustc_typeck/check/compare_method.rs
Original file line number Diff line number Diff line change
@@ -294,10 +294,9 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!("compare_impl_method: trait_fty={:?}", trait_fty);

let sub_result = infcx.sub_types(false, &cause, impl_fty, trait_fty)
.map(|InferOk { obligations, .. }| {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
});
.map(|InferOk { obligations, .. }| {
inh.register_predicates(obligations);
});

if let Err(terr) = sub_result {
debug!("sub_types failed: impl ty {:?}, trait ty {:?}",
5 changes: 2 additions & 3 deletions src/librustc_typeck/check/dropck.rs
Original file line number Diff line number Diff line change
@@ -82,7 +82,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
// check that the impl type can be made to match the trait type.

let impl_param_env = ty::ParameterEnvironment::for_item(tcx, self_type_node_id);
tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|ref infcx| {
let tcx = infcx.tcx;
let mut fulfillment_cx = traits::FulfillmentContext::new();

@@ -97,8 +97,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
let cause = &ObligationCause::misc(drop_impl_span, drop_impl_node_id);
match infcx.eq_types(true, cause, named_type, fresh_impl_self_ty) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
fulfillment_cx.register_predicate_obligations(infcx, obligations);
}
Err(_) => {
let item_span = tcx.hir.span(self_type_node_id);
17 changes: 12 additions & 5 deletions src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
@@ -109,7 +109,7 @@ use rustc::infer::InferOk;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::maps::Providers;
use rustc::traits::{ObligationCause, ObligationCauseCode, Reveal};
use rustc::traits::{FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal};
use session::config;
use util::common::time;

@@ -153,15 +153,22 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
expected: Ty<'tcx>,
actual: Ty<'tcx>)
-> bool {
tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt((), Reveal::UserFacing).enter(|ref infcx| {
let mut fulfill_cx = FulfillmentContext::new();
match infcx.eq_types(false, &cause, expected, actual) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
true
fulfill_cx.register_predicate_obligations(infcx, obligations);
}
Err(err) => {
infcx.report_mismatched_types(cause, expected, actual, err).emit();
return false;
}
}

match fulfill_cx.select_all_or_error(infcx) {
Ok(()) => true,
Err(errors) => {
infcx.report_fulfillment_errors(&errors);
false
}
}
18 changes: 17 additions & 1 deletion src/libstd/ffi/os_str.rs
Original file line number Diff line number Diff line change
@@ -677,7 +677,13 @@ impl Borrow<OsStr> for OsString {
#[stable(feature = "rust1", since = "1.0.0")]
impl ToOwned for OsStr {
type Owned = OsString;
fn to_owned(&self) -> OsString { self.to_os_string() }
fn to_owned(&self) -> OsString {
self.to_os_string()
}
fn clone_into(&self, target: &mut OsString) {
target.clear();
target.push(self);
}
}

#[stable(feature = "rust1", since = "1.0.0")]
@@ -863,4 +869,14 @@ mod tests {
let boxed = <Box<OsStr>>::default();
assert!(boxed.is_empty());
}

#[test]
fn test_os_str_clone_into() {
let mut os_string = OsString::with_capacity(123);
os_string.push("hello");
let os_str = OsStr::new("bonjour");
os_str.clone_into(&mut os_string);
assert_eq!(os_str, os_string);
assert!(os_string.capacity() >= 123);
}
}
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
@@ -311,6 +311,7 @@
#![feature(str_utf16)]
#![feature(test, rustc_private)]
#![feature(thread_local)]
#![feature(toowned_clone_into)]
#![feature(try_from)]
#![feature(unboxed_closures)]
#![feature(unicode)]
12 changes: 12 additions & 0 deletions src/libstd/path.rs
Original file line number Diff line number Diff line change
@@ -1414,6 +1414,9 @@ impl ToOwned for Path {
fn to_owned(&self) -> PathBuf {
self.to_path_buf()
}
fn clone_into(&self, target: &mut PathBuf) {
self.inner.clone_into(&mut target.inner);
}
}

#[stable(feature = "rust1", since = "1.0.0")]
@@ -3859,4 +3862,13 @@ mod tests {
assert_eq!(&*boxed, &*path_buf);
assert_eq!(&*path_buf, path);
}

#[test]
fn test_clone_into() {
let mut path_buf = PathBuf::from("supercalifragilisticexpialidocious");
let path = Path::new("short");
path.clone_into(&mut path_buf);
assert_eq!(path, path_buf);
assert!(path_buf.into_os_string().capacity() >= 15);
}
}
19 changes: 19 additions & 0 deletions src/libsyntax/codemap.rs
Original file line number Diff line number Diff line change
@@ -441,6 +441,25 @@ impl CodeMap {
}
}

/// Given a `Span`, try to get a shorter span ending before the first occurrence of `c` `char`
pub fn span_until_char(&self, sp: Span, c: char) -> Span {
match self.span_to_snippet(sp) {
Ok(snippet) => {
let snippet = snippet.split(c).nth(0).unwrap_or("").trim_right();
if snippet.len() > 0 && !snippet.contains('\n') {
Span { hi: BytePos(sp.lo.0 + snippet.len() as u32), ..sp }
} else {
sp
}
}
_ => sp,
}
}

pub fn def_span(&self, sp: Span) -> Span {
self.span_until_char(sp, '{')
}

pub fn get_filemap(&self, filename: &str) -> Option<Rc<FileMap>> {
for fm in self.files.borrow().iter() {
if filename == fm.name {
2 changes: 1 addition & 1 deletion src/stage0.txt
Original file line number Diff line number Diff line change
@@ -12,4 +12,4 @@
# tarball for a stable release you'll likely see `1.x.0-$date` where `1.x.0` was
# released on `$date`

rustc: beta-2017-03-21
rustc: beta-2017-04-05
15 changes: 15 additions & 0 deletions src/test/run-make/extern-fn-struct-passing-abi/test.c
Original file line number Diff line number Diff line change
@@ -137,6 +137,21 @@ void byval_rect_with_float(int32_t a, int32_t b, float c, int32_t d,
assert(s.d == 556);
}

// System V x86_64 ABI:
// a, b, d, e, f should be byval pointer (on the stack)
// g passed via register (fixes #41375)
//
// Win64 ABI:
// a, b, d, e, f, g should be byval pointer
void byval_rect_with_many_huge(struct Huge a, struct Huge b, struct Huge c,
struct Huge d, struct Huge e, struct Huge f,
struct Rect g) {
assert(g.a == 123);
assert(g.b == 456);
assert(g.c == 789);
assert(g.d == 420);
}

// System V x86_64 & Win64 ABI:
// a, b should be in registers
// s should be split across 2 integer registers
8 changes: 8 additions & 0 deletions src/test/run-make/extern-fn-struct-passing-abi/test.rs
Original file line number Diff line number Diff line change
@@ -64,6 +64,8 @@ extern {

fn byval_rect_with_float(a: i32, b: i32, c: f32, d: i32, e: i32, f: i32, s: Rect);

fn byval_rect_with_many_huge(a: Huge, b: Huge, c: Huge, d: Huge, e: Huge, f: Huge, g: Rect);

fn split_rect(a: i32, b: i32, s: Rect);

fn split_rect_floats(a: f32, b: f32, s: FloatRect);
@@ -95,6 +97,12 @@ fn main() {
byval_many_rect(1, 2, 3, 4, 5, 6, s);
byval_rect_floats(1., 2., 3., 4., 5., 6., 7., s, u);
byval_rect_with_float(1, 2, 3.0, 4, 5, 6, s);
byval_rect_with_many_huge(v, v, v, v, v, v, Rect {
a: 123,
b: 456,
c: 789,
d: 420
});
split_rect(1, 2, s);
split_rect_floats(1., 2., u);
split_rect_with_floats(1, 2, 3.0, 4, 5.0, 6, s);
16 changes: 16 additions & 0 deletions src/test/run-pass/issue-41298.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct Function<T, F> { t: T, f: F }

impl<T, R> Function<T, fn() -> R> { fn foo() { } }
impl<T, R> Function<T, fn() -> R> { fn bar() { } }

fn main() { }
2 changes: 1 addition & 1 deletion src/test/ui/resolve/issue-3907-2.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
--> $DIR/issue-3907-2.rs:20:1
|
20 | fn bar(_x: Foo) {}
| ^^^^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object
| ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object
|
= note: method `bar` has no receiver

3 changes: 1 addition & 2 deletions src/test/compile-fail/E0072.rs → src/test/ui/span/E0072.rs
Original file line number Diff line number Diff line change
@@ -8,8 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct ListNode { //~ ERROR E0072
//~| NOTE recursive type has infinite size
struct ListNode {
head: u8,
tail: Option<ListNode>,
}
10 changes: 10 additions & 0 deletions src/test/ui/span/E0072.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error[E0072]: recursive type `ListNode` has infinite size
--> $DIR/E0072.rs:11:1
|
11 | struct ListNode {
| ^^^^^^^^^^^^^^^ recursive type has infinite size
|
= help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable

error: aborting due to previous error

20 changes: 20 additions & 0 deletions src/test/ui/span/multiline-span-E0072.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// It should just use the entire body instead of pointing at the next two lines
struct
ListNode
{
head: u8,
tail: Option<ListNode>,
}

fn main() {
}
16 changes: 16 additions & 0 deletions src/test/ui/span/multiline-span-E0072.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error[E0072]: recursive type `ListNode` has infinite size
--> $DIR/multiline-span-E0072.rs:12:1
|
12 | struct
| _^ starting here...
13 | | ListNode
14 | | {
15 | | head: u8,
16 | | tail: Option<ListNode>,
17 | | }
| |_^ ...ending here: recursive type has infinite size
|
= help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable

error: aborting due to previous error