Skip to content

Commit 95cc330

Browse files
committed
---
yaml --- r: 179692 b: refs/heads/auto c: c177da6 h: refs/heads/master v: v3
1 parent 5b038ed commit 95cc330

File tree

85 files changed

+3563
-535
lines changed

Some content is hidden

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

85 files changed

+3563
-535
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1010
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
1111
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1212
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
13-
refs/heads/auto: a1b3189f4864f1ada755e9ebc2e0ce1ac5bf2e06
13+
refs/heads/auto: c177da6675e5e0c471101cd98d6a7d9040b0150e
1414
refs/heads/servo: af82457af293e2a842ba6b7759b70288da276167
1515
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c
1616
refs/tags/0.1: b19db808c2793fe2976759b85a355c3ad8c8b336

branches/auto/src/doc/grammar.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ token : simple_token | ident | literal | symbol | whitespace token ;
157157

158158
| | | | | |
159159
|----------|----------|----------|----------|--------|
160-
| abstract | alignof | as | be | box |
160+
| abstract | alignof | as | become | box |
161161
| break | const | continue | crate | do |
162162
| else | enum | extern | false | final |
163163
| fn | for | if | impl | in |

branches/auto/src/doc/reference.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ grammar as double-quoted strings. Other tokens have exact rules given.
189189

190190
| | | | | |
191191
|----------|----------|----------|----------|---------|
192-
| abstract | alignof | as | be | box |
192+
| abstract | alignof | as | become | box |
193193
| break | const | continue | crate | do |
194194
| else | enum | extern | false | final |
195195
| fn | for | if | impl | in |
@@ -2014,6 +2014,11 @@ type int8_t = i8;
20142014
- `no_start` - disable linking to the `native` crate, which specifies the
20152015
"start" language item.
20162016
- `no_std` - disable linking to the `std` crate.
2017+
- `plugin` — load a list of named crates as compiler plugins, e.g.
2018+
`#![plugin(foo, bar)]`. Optional arguments for each plugin,
2019+
i.e. `#![plugin(foo(... args ...))]`, are provided to the plugin's
2020+
registrar function. The `plugin` feature gate is required to use
2021+
this attribute.
20172022

20182023
### Module-only attributes
20192024

@@ -2082,7 +2087,7 @@ On `struct`s:
20822087
remove any padding between fields (note that this is very fragile and may
20832088
break platforms which require aligned access).
20842089

2085-
### Macro- and plugin-related attributes
2090+
### Macro-related attributes
20862091

20872092
- `macro_use` on a `mod` — macros defined in this module will be visible in the
20882093
module's parent, after this module has been included.
@@ -2097,13 +2102,8 @@ On `struct`s:
20972102

20982103
- `macro_export` - export a macro for cross-crate usage.
20992104

2100-
- `plugin` on an `extern crate` — load this crate as a [compiler
2101-
plugin][plugin]. The `plugin` feature gate is required. Any arguments to
2102-
the attribute, e.g. `#[plugin=...]` or `#[plugin(...)]`, are provided to the
2103-
plugin.
2104-
2105-
- `no_link` on an `extern crate` — even if we load this crate for macros or
2106-
compiler plugins, don't link it into the output.
2105+
- `no_link` on an `extern crate` — even if we load this crate for macros, don't
2106+
link it into the output.
21072107

21082108
See the [macros section of the
21092109
book](book/macros.html#scoping-and-macro-import/export) for more information on

branches/auto/src/doc/trpl/compound-data-types.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,20 @@ if x == y {
7272

7373
This will print `no`, because some of the values aren't equal.
7474

75+
Note that the order of the values is considered when checking for equality,
76+
so the following example will also print `no`.
77+
78+
```rust
79+
let x = (1, 2, 3);
80+
let y = (2, 1, 3);
81+
82+
if x == y {
83+
println!("yes");
84+
} else {
85+
println!("no");
86+
}
87+
```
88+
7589
One other use of tuples is to return multiple values from a function:
7690

7791
```rust

branches/auto/src/doc/trpl/plugins.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ information.
3030
extend the compiler's behavior with new syntax extensions, lint checks, etc.
3131

3232
A plugin is a dynamic library crate with a designated *registrar* function that
33-
registers extensions with `rustc`. Other crates can use these extensions by
34-
loading the plugin crate with `#[plugin] extern crate`. See the
33+
registers extensions with `rustc`. Other crates can load these extensions using
34+
the crate attribute `#![plugin(...)]`. See the
3535
[`rustc::plugin`](../rustc/plugin/index.html) documentation for more about the
3636
mechanics of defining and loading a plugin.
3737

38-
Arguments passed as `#[plugin=...]` or `#[plugin(...)]` are not interpreted by
39-
rustc itself. They are provided to the plugin through the `Registry`'s [`args`
40-
method](../rustc/plugin/registry/struct.Registry.html#method.args).
38+
If present, arguments passed as `#![plugin(foo(... args ...))]` are not
39+
interpreted by rustc itself. They are provided to the plugin through the
40+
`Registry`'s [`args` method](../rustc/plugin/registry/struct.Registry.html#method.args).
4141

4242
# Syntax extensions
4343

@@ -110,8 +110,7 @@ Then we can use `rn!()` like any other macro:
110110

111111
```ignore
112112
#![feature(plugin)]
113-
114-
#[plugin] extern crate roman_numerals;
113+
#![plugin(roman_numerals)]
115114
116115
fn main() {
117116
assert_eq!(rn!(MMXV), 2015);
@@ -219,7 +218,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
219218
Then code like
220219

221220
```ignore
222-
#[plugin] extern crate lint_plugin_test;
221+
#![plugin(lint_plugin_test)]
223222
224223
fn lintme() { }
225224
```

branches/auto/src/libcollections/str.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub use core::str::{Lines, LinesAny, MatchIndices, SplitStr, CharRange};
8080
pub use core::str::{Split, SplitTerminator};
8181
pub use core::str::{SplitN, RSplitN};
8282
pub use core::str::{from_utf8, CharEq, Chars, CharIndices, Bytes};
83-
pub use core::str::{from_utf8_unchecked, from_c_str};
83+
pub use core::str::{from_utf8_unchecked, from_c_str, ParseBoolError};
8484
pub use unicode::str::{Words, Graphemes, GraphemeIndices};
8585

8686
/*

branches/auto/src/librustc/diagnostics.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ register_diagnostics! {
126126
E0312, // lifetime of reference outlives lifetime of borrowed content
127127
E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
128128
E0314, // closure outlives stack frame
129-
E0315 // cannot invoke closure outside of its lifetime
129+
E0315, // cannot invoke closure outside of its lifetime
130+
E0316 // nested quantification of lifetimes
130131
}
131132

132133
__build_diagnostic_array! { DIAGNOSTICS }

branches/auto/src/librustc/metadata/creader.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use syntax::ast;
2626
use syntax::abi;
2727
use syntax::attr;
2828
use syntax::attr::AttrMetaMethods;
29-
use syntax::codemap::{COMMAND_LINE_SP, Span, mk_sp};
29+
use syntax::codemap::{Span, mk_sp};
3030
use syntax::parse;
3131
use syntax::parse::token::InternedString;
3232
use syntax::parse::token;
@@ -457,13 +457,13 @@ impl<'a> CrateReader<'a> {
457457
CrateOrString::Krate(c) => {
458458
(self.extract_crate_info(c).unwrap(), c.span)
459459
}
460-
CrateOrString::Str(s) => {
460+
CrateOrString::Str(sp, s) => {
461461
(CrateInfo {
462462
name: s.to_string(),
463463
ident: s.to_string(),
464464
id: ast::DUMMY_NODE_ID,
465465
should_link: true,
466-
}, COMMAND_LINE_SP)
466+
}, sp)
467467
}
468468
};
469469
let target_triple = &self.sess.opts.target_triple[];
@@ -531,7 +531,7 @@ impl<'a> CrateReader<'a> {
531531
#[derive(Copy)]
532532
pub enum CrateOrString<'a> {
533533
Krate(&'a ast::Item),
534-
Str(&'a str)
534+
Str(Span, &'a str)
535535
}
536536

537537
impl<'a> PluginMetadata<'a> {

branches/auto/src/librustc/middle/infer/error_reporting.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,8 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
10761076
trait_ref: ast::TraitRef {
10771077
path: new_path,
10781078
ref_id: tr.ref_id,
1079-
}
1079+
},
1080+
span: poly_tr.span,
10801081
}, modifier)
10811082
}
10821083
}

branches/auto/src/librustc/middle/resolve_lifetime.rs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,31 @@ pub enum DefRegion {
4545
/* lifetime decl */ ast::NodeId),
4646
}
4747

48-
// maps the id of each lifetime reference to the lifetime decl
49-
// that it corresponds to
48+
// Maps the id of each lifetime reference to the lifetime decl
49+
// that it corresponds to.
5050
pub type NamedRegionMap = NodeMap<DefRegion>;
5151

5252
struct LifetimeContext<'a> {
5353
sess: &'a Session,
5454
named_region_map: &'a mut NamedRegionMap,
5555
scope: Scope<'a>,
5656
def_map: &'a DefMap,
57+
// Deep breath. Our representation for poly trait refs contains a single
58+
// binder and thus we only allow a single level of quantification. However,
59+
// the syntax of Rust permits quantification in two places, e.g., `T: for <'a> Foo<'a>`
60+
// and `for <'a, 'b> &'b T: Foo<'a>`. In order to get the de Bruijn indices
61+
// correct when representing these constraints, we should only introduce one
62+
// scope. However, we want to support both locations for the quantifier and
63+
// during lifetime resolution we want precise information (so we can't
64+
// desugar in an earlier phase).
65+
66+
// SO, if we encounter a quantifier at the outer scope, we set
67+
// trait_ref_hack to true (and introduce a scope), and then if we encounter
68+
// a quantifier at the inner scope, we error. If trait_ref_hack is false,
69+
// then we introduce the scope at the inner quantifier.
70+
71+
// I'm sorry.
72+
trait_ref_hack: bool,
5773
}
5874

5975
enum ScopeChain<'a> {
@@ -80,6 +96,7 @@ pub fn krate(sess: &Session, krate: &ast::Crate, def_map: &DefMap) -> NamedRegio
8096
named_region_map: &mut named_region_map,
8197
scope: &ROOT_SCOPE,
8298
def_map: def_map,
99+
trait_ref_hack: false,
83100
}, krate);
84101
sess.abort_if_errors();
85102
named_region_map
@@ -198,9 +215,22 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
198215
match predicate {
199216
&ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ ref bounded_ty,
200217
ref bounds,
218+
ref bound_lifetimes,
201219
.. }) => {
202-
self.visit_ty(&**bounded_ty);
203-
visit::walk_ty_param_bounds_helper(self, bounds);
220+
if bound_lifetimes.len() > 0 {
221+
self.trait_ref_hack = true;
222+
let result = self.with(LateScope(bound_lifetimes, self.scope),
223+
|old_scope, this| {
224+
this.check_lifetime_defs(old_scope, bound_lifetimes);
225+
this.visit_ty(&**bounded_ty);
226+
visit::walk_ty_param_bounds_helper(this, bounds);
227+
});
228+
self.trait_ref_hack = false;
229+
result
230+
} else {
231+
self.visit_ty(&**bounded_ty);
232+
visit::walk_ty_param_bounds_helper(self, bounds);
233+
}
204234
}
205235
&ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
206236
ref bounds,
@@ -222,18 +252,27 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
222252
}
223253
}
224254

225-
fn visit_poly_trait_ref(&mut self, trait_ref:
226-
&ast::PolyTraitRef,
255+
fn visit_poly_trait_ref(&mut self,
256+
trait_ref: &ast::PolyTraitRef,
227257
_modifier: &ast::TraitBoundModifier) {
228258
debug!("visit_poly_trait_ref trait_ref={:?}", trait_ref);
229259

230-
self.with(LateScope(&trait_ref.bound_lifetimes, self.scope), |old_scope, this| {
231-
this.check_lifetime_defs(old_scope, &trait_ref.bound_lifetimes);
232-
for lifetime in &trait_ref.bound_lifetimes {
233-
this.visit_lifetime_def(lifetime);
260+
if !self.trait_ref_hack || trait_ref.bound_lifetimes.len() > 0 {
261+
if self.trait_ref_hack {
262+
println!("{:?}", trait_ref.span);
263+
span_err!(self.sess, trait_ref.span, E0316,
264+
"nested quantification of lifetimes");
234265
}
235-
this.visit_trait_ref(&trait_ref.trait_ref)
236-
})
266+
self.with(LateScope(&trait_ref.bound_lifetimes, self.scope), |old_scope, this| {
267+
this.check_lifetime_defs(old_scope, &trait_ref.bound_lifetimes);
268+
for lifetime in &trait_ref.bound_lifetimes {
269+
this.visit_lifetime_def(lifetime);
270+
}
271+
this.visit_trait_ref(&trait_ref.trait_ref)
272+
})
273+
} else {
274+
self.visit_trait_ref(&trait_ref.trait_ref)
275+
}
237276
}
238277

239278
fn visit_trait_ref(&mut self, trait_ref: &ast::TraitRef) {
@@ -251,6 +290,7 @@ impl<'a> LifetimeContext<'a> {
251290
named_region_map: *named_region_map,
252291
scope: &wrap_scope,
253292
def_map: self.def_map,
293+
trait_ref_hack: self.trait_ref_hack,
254294
};
255295
debug!("entering scope {:?}", this.scope);
256296
f(self.scope, &mut this);

branches/auto/src/librustc/middle/traits/doc.rs

Lines changed: 6 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -434,87 +434,11 @@ attached to the `ParameterEnvironment` and the global cache attached
434434
to the `tcx`. We use the local cache whenever the result might depend
435435
on the where clauses that are in scope. The determination of which
436436
cache to use is done by the method `pick_candidate_cache` in
437-
`select.rs`.
438-
439-
There are two cases where we currently use the local cache. The
440-
current rules are probably more conservative than necessary.
441-
442-
### Trait references that involve parameter types
443-
444-
The most obvious case where you need the local environment is
445-
when the trait reference includes parameter types. For example,
446-
consider the following function:
447-
448-
impl<T> Vec<T> {
449-
fn foo(x: T)
450-
where T : Foo
451-
{ ... }
452-
453-
fn bar(x: T)
454-
{ ... }
455-
}
456-
457-
If there is an obligation `T : Foo`, or `int : Bar<T>`, or whatever,
458-
clearly the results from `foo` and `bar` are potentially different,
459-
since the set of where clauses in scope are different.
460-
461-
### Trait references with unbound variables when where clauses are in scope
462-
463-
There is another less obvious interaction which involves unbound variables
464-
where *only* where clauses are in scope (no impls). This manifested as
465-
issue #18209 (`run-pass/trait-cache-issue-18209.rs`). Consider
466-
this snippet:
467-
468-
```
469-
pub trait Foo {
470-
fn load_from() -> Box<Self>;
471-
fn load() -> Box<Self> {
472-
Foo::load_from()
473-
}
474-
}
475-
```
476-
477-
The default method will incur an obligation `$0 : Foo` from the call
478-
to `load_from`. If there are no impls, this can be eagerly resolved to
479-
`VtableParam(Self : Foo)` and cached. Because the trait reference
480-
doesn't involve any parameters types (only the resolution does), this
481-
result was stored in the global cache, causing later calls to
482-
`Foo::load_from()` to get nonsense.
483-
484-
To fix this, we always use the local cache if there are unbound
485-
variables and where clauses in scope. This is more conservative than
486-
necessary as far as I can tell. However, it still seems to be a simple
487-
rule and I observe ~99% hit rate on rustc, so it doesn't seem to hurt
488-
us in particular.
489-
490-
Here is an example of the kind of subtle case that I would be worried
491-
about with a more complex rule (although this particular case works
492-
out ok). Imagine the trait reference doesn't directly reference a
493-
where clause, but the where clause plays a role in the winnowing
494-
phase. Something like this:
495-
496-
```
497-
pub trait Foo<T> { ... }
498-
pub trait Bar { ... }
499-
impl<U,T:Bar> Foo<U> for T { ... } // Impl A
500-
impl Foo<char> for uint { ... } // Impl B
501-
```
502-
503-
Now, in some function, we have no where clauses in scope, and we have
504-
an obligation `$1 : Foo<$0>`. We might then conclude that `$0=char`
505-
and `$1=uint`: this is because for impl A to apply, `uint:Bar` would
506-
have to hold, and we know it does not or else the coherence check
507-
would have failed. So we might enter into our global cache: `$1 :
508-
Foo<$0> => Impl B`. Then we come along in a different scope, where a
509-
generic type `A` is around with the bound `A:Bar`. Now suddenly the
510-
impl is viable.
511-
512-
The flaw in this imaginary DOOMSDAY SCENARIO is that we would not
513-
currently conclude that `$1 : Foo<$0>` implies that `$0 == uint` and
514-
`$1 == char`, even though it is true that (absent type parameters)
515-
there is no other type the user could enter. However, it is not
516-
*completely* implausible that we *could* draw this conclusion in the
517-
future; we wouldn't have to guess types, in particular, we could be
518-
led by the impls.
437+
`select.rs`. At the moment, we use a very simple, conservative rule:
438+
if there are any where-clauses in scope, then we use the local cache.
439+
We used to try and draw finer-grained distinctions, but that led to a
440+
serious of annoying and weird bugs like #22019 and #18290. This simple
441+
rule seems to be pretty clearly safe and also still retains a very
442+
high hit rate (~95% when compiling rustc).
519443
520444
*/

0 commit comments

Comments
 (0)